@asd20/ui-next 2.24.4 → 2.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
# [2.25.0](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.24.4...ui-next-v2.25.0) (2026-09-21)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* support public form date limits and fallback guidance ([4ef8551](https://github.com/academydistrict20/asd20-ui-next/commit/4ef8551aaa98cf66f48395a9bf98d68f107a0486))
|
|
9
|
+
|
|
3
10
|
## [2.24.4](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.24.3...ui-next-v2.24.4) (2026-09-17)
|
|
4
11
|
|
|
5
12
|
|
package/package.json
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
:required="field.required"
|
|
26
26
|
:minlength="field.minLength"
|
|
27
27
|
:maxlength="field.maxLength"
|
|
28
|
+
:max="dateMaximum"
|
|
28
29
|
:show-character-count="showCharacterCount"
|
|
29
30
|
:show-pristine-validation-errors="showPristineValidationErrors"
|
|
30
31
|
:autocomplete="field.autocomplete || undefined"
|
|
@@ -123,6 +124,19 @@ import Asd20Checkbox from '../../atoms/Asd20Checkbox'
|
|
|
123
124
|
import Asd20TextAreaInput from '../Asd20TextAreaInput'
|
|
124
125
|
import Asd20TextInput from '../Asd20TextInput'
|
|
125
126
|
|
|
127
|
+
function districtToday() {
|
|
128
|
+
const parts = new Intl.DateTimeFormat('en-US', {
|
|
129
|
+
timeZone: 'America/Denver',
|
|
130
|
+
year: 'numeric',
|
|
131
|
+
month: '2-digit',
|
|
132
|
+
day: '2-digit',
|
|
133
|
+
}).formatToParts(new Date())
|
|
134
|
+
const values = Object.fromEntries(
|
|
135
|
+
parts.map(({ type, value }) => [type, value])
|
|
136
|
+
)
|
|
137
|
+
return `${values.year}-${values.month}-${values.day}`
|
|
138
|
+
}
|
|
139
|
+
|
|
126
140
|
export default {
|
|
127
141
|
name: 'Asd20PublicFormField',
|
|
128
142
|
components: { Asd20Checkbox, Asd20TextAreaInput, Asd20TextInput },
|
|
@@ -141,6 +155,11 @@ export default {
|
|
|
141
155
|
}
|
|
142
156
|
},
|
|
143
157
|
computed: {
|
|
158
|
+
dateMaximum() {
|
|
159
|
+
return this.field.type === 'date' && this.field.maxDate === 'today'
|
|
160
|
+
? districtToday()
|
|
161
|
+
: undefined
|
|
162
|
+
},
|
|
144
163
|
displayLabel() {
|
|
145
164
|
return this.field.required
|
|
146
165
|
? `${this.field.label} (required)`
|
|
@@ -102,7 +102,10 @@
|
|
|
102
102
|
class="asd20-public-form-modal__fallback"
|
|
103
103
|
>
|
|
104
104
|
<p>
|
|
105
|
-
|
|
105
|
+
{{
|
|
106
|
+
formDefinition.fallbackContact.instructions ||
|
|
107
|
+
'If you cannot submit this form, use one of these contact options:'
|
|
108
|
+
}}
|
|
106
109
|
</p>
|
|
107
110
|
<a
|
|
108
111
|
v-if="formDefinition.fallbackContact.email"
|
|
@@ -34,6 +34,12 @@ function optionalLength(value, label) {
|
|
|
34
34
|
return value
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
function optionalMaxDate(value, type) {
|
|
38
|
+
if (value == null) return undefined
|
|
39
|
+
if (type === 'date' && value === 'today') return 'today'
|
|
40
|
+
throw new Error('Maximum date is invalid.')
|
|
41
|
+
}
|
|
42
|
+
|
|
37
43
|
function normalizeOptions(field) {
|
|
38
44
|
if (!['select', 'radio'].includes(field.type)) return undefined
|
|
39
45
|
if (
|
|
@@ -81,6 +87,7 @@ function normalizeField(field) {
|
|
|
81
87
|
required: field.required === true,
|
|
82
88
|
minLength: optionalLength(field.minLength, 'Minimum length'),
|
|
83
89
|
maxLength: optionalLength(field.maxLength, 'Maximum length'),
|
|
90
|
+
maxDate: optionalMaxDate(field.maxDate, type),
|
|
84
91
|
autocomplete: boundedText(field.autocomplete, 'Autocomplete value', 100),
|
|
85
92
|
options: undefined,
|
|
86
93
|
}
|
|
@@ -134,9 +141,14 @@ export function normalizePublicFormDefinition(definition) {
|
|
|
134
141
|
}
|
|
135
142
|
const email = boundedText(fallbackContact.email, 'Fallback email', 320)
|
|
136
143
|
const phone = boundedText(fallbackContact.phone, 'Fallback phone', 50)
|
|
144
|
+
const instructions = boundedText(
|
|
145
|
+
fallbackContact.instructions,
|
|
146
|
+
'Fallback instructions',
|
|
147
|
+
1000
|
|
148
|
+
)
|
|
137
149
|
if (email && !EMAIL_PATTERN.test(email))
|
|
138
150
|
throw new Error('The public form fallback email is invalid.')
|
|
139
|
-
normalizedFallback = { email, phone }
|
|
151
|
+
normalizedFallback = { email, phone, instructions }
|
|
140
152
|
}
|
|
141
153
|
|
|
142
154
|
const id = boundedText(definition.id, 'Form ID', 100, true)
|
|
@@ -183,6 +195,19 @@ function validDate(value) {
|
|
|
183
195
|
)
|
|
184
196
|
}
|
|
185
197
|
|
|
198
|
+
function districtToday() {
|
|
199
|
+
const parts = new Intl.DateTimeFormat('en-US', {
|
|
200
|
+
timeZone: 'America/Denver',
|
|
201
|
+
year: 'numeric',
|
|
202
|
+
month: '2-digit',
|
|
203
|
+
day: '2-digit',
|
|
204
|
+
}).formatToParts(new Date())
|
|
205
|
+
const values = Object.fromEntries(
|
|
206
|
+
parts.map(({ type, value }) => [type, value])
|
|
207
|
+
)
|
|
208
|
+
return `${values.year}-${values.month}-${values.day}`
|
|
209
|
+
}
|
|
210
|
+
|
|
186
211
|
export function validatePublicFormValues(definition, sourceValues = {}) {
|
|
187
212
|
const errors = {}
|
|
188
213
|
const values = {}
|
|
@@ -220,6 +245,14 @@ export function validatePublicFormValues(definition, sourceValues = {}) {
|
|
|
220
245
|
if (value && field.type === 'date' && !validDate(value)) {
|
|
221
246
|
fieldErrors.push(`Enter a valid ${field.label.toLowerCase()}.`)
|
|
222
247
|
}
|
|
248
|
+
if (
|
|
249
|
+
value &&
|
|
250
|
+
field.type === 'date' &&
|
|
251
|
+
field.maxDate === 'today' &&
|
|
252
|
+
value > districtToday()
|
|
253
|
+
) {
|
|
254
|
+
fieldErrors.push(`${field.label} cannot be in the future.`)
|
|
255
|
+
}
|
|
223
256
|
if (value && ['select', 'radio'].includes(field.type)) {
|
|
224
257
|
const allowedValues = new Set(
|
|
225
258
|
(field.options || []).map(option => option.value)
|