@asd20/ui-next 2.23.2 → 2.23.3
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/CHANGELOG.md +7 -0
- package/package.json +1 -1
- package/src/components/atoms/Asd20MultiselectInput/index.vue +4 -13
- package/src/components/atoms/Asd20SelectInput/index.vue +7 -16
- package/src/components/molecules/Asd20FileInput/index.vue +3 -9
- package/src/components/molecules/Asd20TextAreaInput/index.vue +30 -20
- package/src/components/molecules/Asd20TextInput/index.vue +30 -20
- package/src/components/organisms/Asd20AccessibilityIssueModal/index.vue +1 -1
- package/src/components/organisms/Asd20ComposeEmailModal/index.vue +4 -5
- package/src/mixins/inputComponentMixin.js +11 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.23.3](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.23.2...ui-next-v2.23.3) (2026-09-10)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* revise api contract to accommodate previous changes ([79ea872](https://github.com/academydistrict20/asd20-ui-next/commit/79ea8729f75b5aa382d69fd936d05b523d7f63d7))
|
|
9
|
+
|
|
3
10
|
## [2.23.2](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.23.1...ui-next-v2.23.2) (2026-09-10)
|
|
4
11
|
|
|
5
12
|
## [2.23.1](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.23.0...ui-next-v2.23.1) (2026-09-09)
|
package/package.json
CHANGED
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
v-html="computedHelpText"
|
|
54
54
|
/>
|
|
55
55
|
<div
|
|
56
|
-
v-for="(v, index) in
|
|
56
|
+
v-for="(v, index) in renderedValidationErrors"
|
|
57
57
|
:key="index"
|
|
58
58
|
class="asd20-multiselect-input__validation-error"
|
|
59
59
|
v-html="v"
|
|
@@ -168,6 +168,8 @@ export default {
|
|
|
168
168
|
},
|
|
169
169
|
methods: {
|
|
170
170
|
emitValue(value) {
|
|
171
|
+
this.isDirty = true
|
|
172
|
+
this.validate(value)
|
|
171
173
|
this.$emit('update:modelValue', value)
|
|
172
174
|
},
|
|
173
175
|
resolveSelectedItem(item) {
|
|
@@ -417,24 +419,13 @@ $input-reversed-text-color: var(--color__accent-t100);
|
|
|
417
419
|
|
|
418
420
|
&__validation-error {
|
|
419
421
|
flex-basis: 100%;
|
|
420
|
-
color: darkred;
|
|
421
422
|
font-size: 0.75rem;
|
|
422
423
|
margin-top: space(0.125);
|
|
423
424
|
}
|
|
424
425
|
|
|
425
426
|
&--has-errors {
|
|
426
|
-
label {
|
|
427
|
-
color: darkred;
|
|
428
|
-
}
|
|
429
427
|
& :deep(.multiselect__tags) {
|
|
430
|
-
border: 2px solid
|
|
431
|
-
}
|
|
432
|
-
& :deep(.multiselect--active .multiselect__tags) {
|
|
433
|
-
box-shadow: 0 0 0 5px darkred inset;
|
|
434
|
-
}
|
|
435
|
-
& :deep(.multiselect__select:before) {
|
|
436
|
-
color: darkred;
|
|
437
|
-
/* border-color: var(--color__danger) transparent transparent transparent;*/
|
|
428
|
+
border: 2px solid asd20-swatch('emergency', -1);
|
|
438
429
|
}
|
|
439
430
|
}
|
|
440
431
|
}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
<div class="asd20-select-input__select-wrapper">
|
|
15
15
|
<select
|
|
16
16
|
v-bind="mergedInputAttrs"
|
|
17
|
+
@blur="onBlur"
|
|
17
18
|
@input="input"
|
|
18
19
|
>
|
|
19
20
|
<option
|
|
@@ -43,7 +44,7 @@
|
|
|
43
44
|
v-html="computedHelpText"
|
|
44
45
|
/>
|
|
45
46
|
<div
|
|
46
|
-
v-for="(v, index) in
|
|
47
|
+
v-for="(v, index) in renderedValidationErrors"
|
|
47
48
|
:key="index"
|
|
48
49
|
class="asd20-select-input__validation-error"
|
|
49
50
|
v-html="v"
|
|
@@ -215,25 +216,15 @@ $input-reversed-text-color: var(--color__accent-t100);
|
|
|
215
216
|
}
|
|
216
217
|
|
|
217
218
|
&__validation-error {
|
|
218
|
-
color: var(--color__danger-s20);
|
|
219
219
|
font-size: 0.75rem;
|
|
220
220
|
margin-top: space(0.125);
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
&--has-errors
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
select:focus ~ label {
|
|
229
|
-
@include asd20-focus;
|
|
230
|
-
}
|
|
231
|
-
input {
|
|
232
|
-
border-color: var(--color__danger);
|
|
233
|
-
&:focus {
|
|
234
|
-
@include asd20-focus;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
223
|
+
&--has-errors .asd20-select-input__field-wrapper,
|
|
224
|
+
&--has-errors.asd20-select-input--bordered
|
|
225
|
+
.asd20-select-input__field-wrapper {
|
|
226
|
+
box-shadow: 0 0 0 $input-border-width
|
|
227
|
+
asd20-swatch('emergency', -1) inset;
|
|
237
228
|
}
|
|
238
229
|
}
|
|
239
230
|
</style>
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
<input
|
|
16
16
|
v-bind="mergedInputAttrs"
|
|
17
|
+
@blur="onBlur"
|
|
17
18
|
@input="input"
|
|
18
19
|
/>
|
|
19
20
|
|
|
@@ -25,7 +26,7 @@
|
|
|
25
26
|
v-html="computedHelpText"
|
|
26
27
|
/>
|
|
27
28
|
<div
|
|
28
|
-
v-for="(v, index) in
|
|
29
|
+
v-for="(v, index) in renderedValidationErrors"
|
|
29
30
|
:key="index"
|
|
30
31
|
class="asd20-file-input__validation-error"
|
|
31
32
|
v-html="v"
|
|
@@ -140,20 +141,13 @@ $input-focus-color: var(--color__accent-t50);
|
|
|
140
141
|
}
|
|
141
142
|
|
|
142
143
|
&__validation-error {
|
|
143
|
-
color: var(--color__danger-s20);
|
|
144
144
|
font-size: 0.75rem;
|
|
145
145
|
margin-top: space(0.125);
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
&--has-errors {
|
|
149
|
-
label {
|
|
150
|
-
color: var(--color__danger-s20);
|
|
151
|
-
}
|
|
152
149
|
input {
|
|
153
|
-
border-color:
|
|
154
|
-
&:focus {
|
|
155
|
-
box-shadow: 0 0 0 5px var(--color__danger) inset;
|
|
156
|
-
}
|
|
150
|
+
border-color: asd20-swatch('emergency', -1);
|
|
157
151
|
}
|
|
158
152
|
}
|
|
159
153
|
}
|
|
@@ -18,30 +18,35 @@
|
|
|
18
18
|
|
|
19
19
|
<textarea
|
|
20
20
|
v-bind="mergedInputAttrs"
|
|
21
|
+
@blur="onBlur"
|
|
21
22
|
@input="input"
|
|
22
23
|
/>
|
|
23
24
|
|
|
24
25
|
<slot name="suffix" />
|
|
25
26
|
</div>
|
|
26
27
|
<div
|
|
27
|
-
v-if="
|
|
28
|
-
class="asd20-text-area-
|
|
28
|
+
v-if="validationErrors.length || maxLength !== null"
|
|
29
|
+
class="asd20-text-area-input__validation-row"
|
|
29
30
|
>
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
<div class="asd20-text-area-input__validation-errors">
|
|
32
|
+
<div
|
|
33
|
+
v-for="(v, index) in renderedValidationErrors"
|
|
34
|
+
:key="index"
|
|
35
|
+
class="asd20-text-area-input__validation-error"
|
|
36
|
+
v-html="v"
|
|
37
|
+
/>
|
|
38
|
+
</div>
|
|
34
39
|
<span
|
|
35
40
|
v-if="maxLength !== null"
|
|
36
41
|
class="asd20-text-area-input__character-count"
|
|
37
42
|
>{{ characterCountText }}</span>
|
|
38
43
|
</div>
|
|
39
44
|
<div
|
|
40
|
-
v-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
v-html="
|
|
44
|
-
|
|
45
|
+
v-if="helpText"
|
|
46
|
+
class="asd20-text-area-input__help-text"
|
|
47
|
+
>
|
|
48
|
+
<span v-html="helpText" />
|
|
49
|
+
</div>
|
|
45
50
|
</div>
|
|
46
51
|
</template>
|
|
47
52
|
|
|
@@ -144,6 +149,13 @@ $input-focus-color: var(--color__accent-t50);
|
|
|
144
149
|
}
|
|
145
150
|
|
|
146
151
|
&__help-text {
|
|
152
|
+
width: 100%;
|
|
153
|
+
color: var(--website-card__reverse-background-color);
|
|
154
|
+
font-size: 0.75rem;
|
|
155
|
+
margin-top: space(0.125);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
&__validation-row {
|
|
147
159
|
display: flex;
|
|
148
160
|
align-items: baseline;
|
|
149
161
|
justify-content: space-between;
|
|
@@ -154,27 +166,25 @@ $input-focus-color: var(--color__accent-t50);
|
|
|
154
166
|
margin-top: space(0.125);
|
|
155
167
|
}
|
|
156
168
|
|
|
169
|
+
&__validation-errors {
|
|
170
|
+
flex: 1 1 auto;
|
|
171
|
+
min-width: 0;
|
|
172
|
+
}
|
|
173
|
+
|
|
157
174
|
&__character-count {
|
|
175
|
+
flex: 0 0 auto;
|
|
158
176
|
margin-left: auto;
|
|
159
177
|
text-align: right;
|
|
160
178
|
white-space: nowrap;
|
|
161
179
|
}
|
|
162
180
|
|
|
163
181
|
&__validation-error {
|
|
164
|
-
color: var(--color__danger-s20);
|
|
165
182
|
font-size: 0.75rem;
|
|
166
|
-
margin-top: space(0.125);
|
|
167
183
|
}
|
|
168
184
|
|
|
169
185
|
&--has-errors {
|
|
170
|
-
label {
|
|
171
|
-
color: var(--color__danger-s20);
|
|
172
|
-
}
|
|
173
186
|
textarea {
|
|
174
|
-
border-color:
|
|
175
|
-
&:focus {
|
|
176
|
-
box-shadow: 0 0 0 5px var(--color__danger) inset;
|
|
177
|
-
}
|
|
187
|
+
border-color: asd20-swatch('emergency', -1);
|
|
178
188
|
}
|
|
179
189
|
}
|
|
180
190
|
}
|
|
@@ -14,30 +14,35 @@
|
|
|
14
14
|
|
|
15
15
|
<input
|
|
16
16
|
v-bind="mergedInputAttrs"
|
|
17
|
+
@blur="onBlur"
|
|
17
18
|
@input="input"
|
|
18
19
|
/>
|
|
19
20
|
|
|
20
21
|
<slot name="suffix" />
|
|
21
22
|
</div>
|
|
22
23
|
<div
|
|
23
|
-
v-if="
|
|
24
|
-
class="asd20-text-
|
|
24
|
+
v-if="validationErrors.length || maxLength !== null"
|
|
25
|
+
class="asd20-text-input__validation-row"
|
|
25
26
|
>
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
<div class="asd20-text-input__validation-errors">
|
|
28
|
+
<div
|
|
29
|
+
v-for="(v, index) in renderedValidationErrors"
|
|
30
|
+
:key="index"
|
|
31
|
+
class="asd20-text-input__validation-error"
|
|
32
|
+
v-html="v"
|
|
33
|
+
/>
|
|
34
|
+
</div>
|
|
30
35
|
<span
|
|
31
36
|
v-if="maxLength !== null"
|
|
32
37
|
class="asd20-text-input__character-count"
|
|
33
38
|
>{{ characterCountText }}</span>
|
|
34
39
|
</div>
|
|
35
40
|
<div
|
|
36
|
-
v-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
v-html="
|
|
40
|
-
|
|
41
|
+
v-if="helpText"
|
|
42
|
+
class="asd20-text-input__help-text"
|
|
43
|
+
>
|
|
44
|
+
<span v-html="helpText" />
|
|
45
|
+
</div>
|
|
41
46
|
</div>
|
|
42
47
|
</template>
|
|
43
48
|
|
|
@@ -137,6 +142,13 @@ $input-focus-color: var(--color__accent-t50);
|
|
|
137
142
|
}
|
|
138
143
|
|
|
139
144
|
&__help-text {
|
|
145
|
+
width: 100%;
|
|
146
|
+
color: var(--website-card__reverse-background-color);
|
|
147
|
+
font-size: 0.75rem;
|
|
148
|
+
margin-top: space(0.125);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
&__validation-row {
|
|
140
152
|
display: flex;
|
|
141
153
|
align-items: baseline;
|
|
142
154
|
justify-content: space-between;
|
|
@@ -147,27 +159,25 @@ $input-focus-color: var(--color__accent-t50);
|
|
|
147
159
|
margin-top: space(0.125);
|
|
148
160
|
}
|
|
149
161
|
|
|
162
|
+
&__validation-errors {
|
|
163
|
+
flex: 1 1 auto;
|
|
164
|
+
min-width: 0;
|
|
165
|
+
}
|
|
166
|
+
|
|
150
167
|
&__character-count {
|
|
168
|
+
flex: 0 0 auto;
|
|
151
169
|
margin-left: auto;
|
|
152
170
|
text-align: right;
|
|
153
171
|
white-space: nowrap;
|
|
154
172
|
}
|
|
155
173
|
|
|
156
174
|
&__validation-error {
|
|
157
|
-
color: var(--color__danger-s20);
|
|
158
175
|
font-size: 0.75rem;
|
|
159
|
-
margin-top: space(0.125);
|
|
160
176
|
}
|
|
161
177
|
|
|
162
178
|
&--has-errors {
|
|
163
|
-
label {
|
|
164
|
-
color: var(--color__danger-s20);
|
|
165
|
-
}
|
|
166
179
|
input {
|
|
167
|
-
border-color:
|
|
168
|
-
&:focus {
|
|
169
|
-
box-shadow: 0 0 0 5px var(--color__danger) inset;
|
|
170
|
-
}
|
|
180
|
+
border-color: asd20-swatch('emergency', -1);
|
|
171
181
|
}
|
|
172
182
|
}
|
|
173
183
|
}
|
|
@@ -189,7 +189,7 @@ export default {
|
|
|
189
189
|
& :deep(.asd20-modal__content .asd20-viewport) {
|
|
190
190
|
padding: space(1);
|
|
191
191
|
}
|
|
192
|
-
:deep(.asd20-text-area-input textarea) {
|
|
192
|
+
& :deep(.asd20-text-area-input textarea) {
|
|
193
193
|
font-family: Arial, sans-serif;
|
|
194
194
|
font-size: 1rem;
|
|
195
195
|
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
id="senderName"
|
|
14
14
|
v-model="emailMessage.senderName"
|
|
15
15
|
label="Your Full Name"
|
|
16
|
-
|
|
16
|
+
required
|
|
17
17
|
@validated="validationErrors.senderName = $event"
|
|
18
18
|
/>
|
|
19
19
|
<asd20-text-input
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
type="email"
|
|
23
23
|
:validator="validateEmailAddress"
|
|
24
24
|
label="Your Email Address"
|
|
25
|
-
|
|
25
|
+
required
|
|
26
26
|
@validated="validationErrors.senderEmail = $event"
|
|
27
27
|
/>
|
|
28
28
|
<asd20-text-input
|
|
@@ -30,16 +30,15 @@
|
|
|
30
30
|
v-model="emailMessage.subject"
|
|
31
31
|
label="Subject"
|
|
32
32
|
maxlength="200"
|
|
33
|
-
|
|
33
|
+
required
|
|
34
34
|
@validated="validationErrors.subject = $event"
|
|
35
35
|
/>
|
|
36
36
|
<asd20-text-area-input
|
|
37
37
|
id="messageBody"
|
|
38
38
|
v-model="emailMessage.messageBody"
|
|
39
39
|
label="Message"
|
|
40
|
-
help-text="All fields are required."
|
|
41
40
|
maxlength="8000"
|
|
42
|
-
|
|
41
|
+
required
|
|
43
42
|
@validated="validationErrors.messageBody = $event"
|
|
44
43
|
/>
|
|
45
44
|
<div
|
|
@@ -3,6 +3,7 @@ import createComponentInstanceId from '../utils/createComponentInstanceId'
|
|
|
3
3
|
|
|
4
4
|
const INPUT_MODEL_LISTENER_KEYS = ['onInput', 'onUpdate:modelValue']
|
|
5
5
|
const DEFAULT_INPUT_COMPONENT_NAME = 'asd20-input'
|
|
6
|
+
const REQUIRED_VALIDATION_ERROR = 'This field is required.'
|
|
6
7
|
|
|
7
8
|
function resolveKebabComponentName(componentName = DEFAULT_INPUT_COMPONENT_NAME) {
|
|
8
9
|
return kebabCase(componentName).replace(/-([0-9])/g, '$1')
|
|
@@ -75,7 +76,8 @@ export default {
|
|
|
75
76
|
classes[`${this.kebabComponentName}`] = true
|
|
76
77
|
classes[`${this.kebabComponentName}--hide-label`] = this.hideLabel
|
|
77
78
|
classes[`${this.kebabComponentName}--is-valid`] = this.isValid
|
|
78
|
-
classes[`${this.kebabComponentName}--has-errors`] =
|
|
79
|
+
classes[`${this.kebabComponentName}--has-errors`] =
|
|
80
|
+
this.isDirty && !this.isValid
|
|
79
81
|
classes[`${this.kebabComponentName}--horizontal`] = this.horizontal
|
|
80
82
|
classes[`${this.kebabComponentName}--transparent`] = this.transparent
|
|
81
83
|
classes[`${this.kebabComponentName}--expanded`] = this.expanded
|
|
@@ -98,6 +100,13 @@ export default {
|
|
|
98
100
|
isValid() {
|
|
99
101
|
return this.validationErrors.length === 0
|
|
100
102
|
},
|
|
103
|
+
renderedValidationErrors() {
|
|
104
|
+
return this.validationErrors.map(error =>
|
|
105
|
+
!this.isDirty && error === REQUIRED_VALIDATION_ERROR
|
|
106
|
+
? 'Required'
|
|
107
|
+
: error
|
|
108
|
+
)
|
|
109
|
+
},
|
|
101
110
|
resolvedValue() {
|
|
102
111
|
return this.modelValue
|
|
103
112
|
},
|
|
@@ -163,7 +172,7 @@ export default {
|
|
|
163
172
|
this.$attrs.required.toString().toLowerCase() !== 'false'
|
|
164
173
|
) {
|
|
165
174
|
if (!value) {
|
|
166
|
-
this.validationErrors.push(
|
|
175
|
+
this.validationErrors.push(REQUIRED_VALIDATION_ERROR)
|
|
167
176
|
}
|
|
168
177
|
}
|
|
169
178
|
|