@asd20/ui-next 2.24.2 → 2.24.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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.24.3](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.24.2...ui-next-v2.24.3) (2026-09-17)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * fix accessibility form verbiage; add native trigger support for public forms ([54f5b47](https://github.com/academydistrict20/asd20-ui-next/commit/54f5b47b2bb80fbf807439fcfd376e911806e053))
9
+ * fix release verifier from last commit ([b7b8d8f](https://github.com/academydistrict20/asd20-ui-next/commit/b7b8d8f996c757ddd727ab2272f38ea11737ddb7))
10
+
3
11
  ## [2.24.2](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.24.1...ui-next-v2.24.2) (2026-09-17)
4
12
 
5
13
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asd20/ui-next",
3
- "version": "2.24.2",
3
+ "version": "2.24.3",
4
4
  "private": false,
5
5
  "description": "ASD20 UI component library for Vue 3.",
6
6
  "license": "MIT",
@@ -39,6 +39,7 @@ export default {
39
39
  hideLabel: { type: Boolean, default: false },
40
40
  link: { type: String, default: '' },
41
41
  trackingCode: { type: String, default: '' }, // e.g., 'data-analytics-id'
42
+ publicFormId: { type: String, default: '' },
42
43
  icon: { type: String, default: '' },
43
44
  badge: { type: Number, default: 0 },
44
45
  size: {
@@ -73,7 +74,13 @@ export default {
73
74
  }
74
75
  },
75
76
  tag() {
76
- return !this.link || this.link === ' ' ? 'button' : 'a'
77
+ return this.normalizedPublicFormId || !this.link || this.link === ' '
78
+ ? 'button'
79
+ : 'a'
80
+ },
81
+ normalizedPublicFormId() {
82
+ const formId = String(this.publicFormId || '').trim()
83
+ return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(formId) ? formId : ''
77
84
  },
78
85
  isExternal() {
79
86
  return shouldOpenInNewWindow(this.link)
@@ -109,16 +116,21 @@ export default {
109
116
 
110
117
  // Optional tracking code (dynamic attribute key)
111
118
  if (this.trackingCode) a[this.trackingCode] = ''
119
+ if (this.normalizedPublicFormId) {
120
+ a['data-public-form'] = this.normalizedPublicFormId
121
+ }
112
122
 
113
123
  return a
114
124
  },
115
125
  },
116
126
  methods: {
117
127
  handleClick(event) {
118
- navigateInternalHref(this, event, this.link, {
119
- target: event.currentTarget?.getAttribute?.('target'),
120
- download: event.currentTarget?.hasAttribute?.('download'),
121
- })
128
+ if (!this.normalizedPublicFormId) {
129
+ navigateInternalHref(this, event, this.link, {
130
+ target: event.currentTarget?.getAttribute?.('target'),
131
+ download: event.currentTarget?.hasAttribute?.('download'),
132
+ })
133
+ }
122
134
  this.forwardEvent('click', event)
123
135
  },
124
136
  forwardEvent(name, event) {
@@ -8,6 +8,8 @@
8
8
  :required="field.required"
9
9
  :minlength="field.minLength"
10
10
  :maxlength="field.maxLength"
11
+ :show-character-count="showCharacterCount"
12
+ :show-pristine-validation-errors="showPristineValidationErrors"
11
13
  :autocomplete="field.autocomplete || undefined"
12
14
  :aria-describedby="describedBy"
13
15
  :aria-invalid="hasErrors ? 'true' : undefined"
@@ -23,6 +25,8 @@
23
25
  :required="field.required"
24
26
  :minlength="field.minLength"
25
27
  :maxlength="field.maxLength"
28
+ :show-character-count="showCharacterCount"
29
+ :show-pristine-validation-errors="showPristineValidationErrors"
26
30
  :autocomplete="field.autocomplete || undefined"
27
31
  :aria-describedby="describedBy"
28
32
  :aria-invalid="hasErrors ? 'true' : undefined"
@@ -127,6 +131,8 @@ export default {
127
131
  modelValue: { type: [String, Boolean], default: '' },
128
132
  errors: { type: Array, default: () => [] },
129
133
  inputId: { type: String, required: true },
134
+ showCharacterCount: { type: Boolean, default: true },
135
+ showPristineValidationErrors: { type: Boolean, default: true },
130
136
  },
131
137
  emits: ['update:modelValue'],
132
138
  data() {
@@ -25,7 +25,7 @@
25
25
  <slot name="suffix" />
26
26
  </div>
27
27
  <div
28
- v-if="validationErrors.length || maxLength !== null"
28
+ v-if="renderedValidationErrors.length || hasCharacterCount"
29
29
  class="asd20-text-area-input__validation-row"
30
30
  >
31
31
  <div class="asd20-text-area-input__validation-errors">
@@ -37,7 +37,7 @@
37
37
  />
38
38
  </div>
39
39
  <span
40
- v-if="maxLength !== null"
40
+ v-if="hasCharacterCount"
41
41
  class="asd20-text-area-input__character-count"
42
42
  >{{ characterCountText }}</span>
43
43
  </div>
@@ -21,7 +21,7 @@
21
21
  <slot name="suffix" />
22
22
  </div>
23
23
  <div
24
- v-if="validationErrors.length || maxLength !== null"
24
+ v-if="renderedValidationErrors.length || hasCharacterCount"
25
25
  class="asd20-text-input__validation-row"
26
26
  >
27
27
  <div class="asd20-text-input__validation-errors">
@@ -33,7 +33,7 @@
33
33
  />
34
34
  </div>
35
35
  <span
36
- v-if="maxLength !== null"
36
+ v-if="hasCharacterCount"
37
37
  class="asd20-text-input__character-count"
38
38
  >{{ characterCountText }}</span>
39
39
  </div>
@@ -67,6 +67,8 @@
67
67
  :label="cta.label"
68
68
  :icon="cta.icon"
69
69
  :link="cta.url"
70
+ :tracking-code="cta.trackingCode"
71
+ :public-form-id="cta.publicFormId"
70
72
  reversed
71
73
  horizontal
72
74
  centered
@@ -158,6 +158,8 @@
158
158
  :label="callsToAction[0].label"
159
159
  :icon="callsToAction[0].icon"
160
160
  :link="callsToAction[0].url"
161
+ :tracking-code="callsToAction[0].trackingCode"
162
+ :public-form-id="callsToAction[0].publicFormId"
161
163
  reversed
162
164
  horizontal
163
165
  centered
@@ -168,6 +170,8 @@
168
170
  :label="callsToAction[1].label"
169
171
  :icon="callsToAction[1].icon"
170
172
  :link="callsToAction[1].url"
173
+ :tracking-code="callsToAction[1].trackingCode"
174
+ :public-form-id="callsToAction[1].publicFormId"
171
175
  reversed
172
176
  horizontal
173
177
  centered
@@ -150,6 +150,7 @@
150
150
  :icon="callsToAction[0].icon"
151
151
  :link="callsToAction[0].url"
152
152
  :tracking-code="callsToAction[0].trackingCode"
153
+ :public-form-id="callsToAction[0].publicFormId"
153
154
  reversed
154
155
  horizontal
155
156
  centered
@@ -162,6 +163,7 @@
162
163
  :icon="callsToAction[1].icon"
163
164
  :link="callsToAction[1].url"
164
165
  :tracking-code="callsToAction[1].trackingCode"
166
+ :public-form-id="callsToAction[1].publicFormId"
165
167
  reversed
166
168
  horizontal
167
169
  centered
@@ -2,7 +2,7 @@
2
2
  <asd20-modal
3
3
  :open="open"
4
4
  :title="modalTitle"
5
- icon="contact"
5
+ icon="website"
6
6
  dismissable
7
7
  class="asd20-public-form-modal"
8
8
  @dismiss="dismiss"
@@ -77,6 +77,8 @@
77
77
  :input-id="fieldId(field.name)"
78
78
  :model-value="values[field.name]"
79
79
  :errors="validationErrors[field.name] || []"
80
+ :show-character-count="shouldShowCharacterCount(field)"
81
+ :show-pristine-validation-errors="showPristineValidationErrors"
80
82
  @update:modelValue="updateValue(field.name, $event)"
81
83
  />
82
84
 
@@ -230,6 +232,9 @@ export default {
230
232
  modalTitle() {
231
233
  return this.formDefinition?.title || 'Public Form'
232
234
  },
235
+ showPristineValidationErrors() {
236
+ return this.formDefinition?.id !== 'accessibility-issue'
237
+ },
233
238
  errorEntries() {
234
239
  if (!this.formDefinition) return []
235
240
  return this.formDefinition.fields
@@ -321,6 +326,9 @@ export default {
321
326
  fieldId(name) {
322
327
  return `${this.instanceId}-${name}`
323
328
  },
329
+ shouldShowCharacterCount(field) {
330
+ return this.formDefinition.id !== 'accessibility-issue' || field.name === 'issue'
331
+ },
324
332
  updateValue(name, value) {
325
333
  this.values[name] = value
326
334
  if (this.validationAttempted) this.validate(false)
@@ -352,7 +360,7 @@ export default {
352
360
  },
353
361
  captchaFailed() {
354
362
  this.showFeedback(
355
- 'The verification service could not start. Please try again or use the contact options below.'
363
+ 'The verification service could not start. Please try again or use the contact options listed.'
356
364
  )
357
365
  },
358
366
  captchaExpired() {
@@ -368,15 +376,15 @@ export default {
368
376
  if (status === 403)
369
377
  return 'The verification was not accepted. Please try again.'
370
378
  if (status === 429) {
371
- return 'Too many submissions were received recently. Please wait and try again, or use the contact options below.'
379
+ return 'Too many submissions were received recently. Please wait and try again, or use the contact options listed.'
372
380
  }
373
381
  if (status === 502) {
374
- return 'The form could not be delivered right now. Please try again later or use the contact options below.'
382
+ return 'The form could not be delivered right now. Please try again later or use the contact options listed.'
375
383
  }
376
384
  if (status === 503) {
377
- return 'This form is temporarily unavailable. Please use the contact options below.'
385
+ return 'This form is temporarily unavailable. Please use the contact options listed.'
378
386
  }
379
- return 'Something went wrong while submitting the form. Please try again later or use the contact options below.'
387
+ return 'Something went wrong while submitting the form. Please try again later or use the contact options listed.'
380
388
  },
381
389
  showFeedback(message, role = 'alert') {
382
390
  this.feedbackMessage = message
@@ -62,6 +62,8 @@
62
62
  :label="cta.label"
63
63
  :icon="cta.icon"
64
64
  :link="cta.url"
65
+ :tracking-code="cta.trackingCode"
66
+ :public-form-id="cta.publicFormId"
65
67
  reversed
66
68
  horizontal
67
69
  centered
@@ -88,6 +88,8 @@
88
88
  :label="cta.label"
89
89
  :icon="cta.icon"
90
90
  :link="cta.url"
91
+ :tracking-code="cta.trackingCode"
92
+ :public-form-id="cta.publicFormId"
91
93
  reversed
92
94
  horizontal
93
95
  centered
@@ -57,6 +57,8 @@
57
57
  :label="cta.label"
58
58
  :icon="cta.icon"
59
59
  :link="cta.url"
60
+ :tracking-code="cta.trackingCode"
61
+ :public-form-id="cta.publicFormId"
60
62
  bordered
61
63
  reversed
62
64
  horizontal
@@ -25,6 +25,7 @@ query($pageId: uuid!, $now: String) {
25
25
  id
26
26
  title
27
27
  trackingCode
28
+ publicFormId
28
29
  url
29
30
  description
30
31
  }
@@ -84,6 +85,7 @@ query($pageId: uuid!, $now: String) {
84
85
  id
85
86
  title
86
87
  trackingCode
88
+ publicFormId
87
89
  url
88
90
  }
89
91
  }
@@ -25,6 +25,8 @@ export default {
25
25
  modelValue: { default: '' },
26
26
  label: { type: String, default: '' },
27
27
  hideLabel: { type: Boolean, default: false },
28
+ showCharacterCount: { type: Boolean, default: true },
29
+ showPristineValidationErrors: { type: Boolean, default: true },
28
30
  helpText: { type: String, default: '' },
29
31
  items: { type: Array, default: () => [] },
30
32
  itemDefault: { type: Object, default: null },
@@ -101,6 +103,8 @@ export default {
101
103
  return this.validationErrors.length === 0
102
104
  },
103
105
  renderedValidationErrors() {
106
+ if (!this.isDirty && !this.showPristineValidationErrors) return []
107
+
104
108
  return this.validationErrors.map(error =>
105
109
  !this.isDirty && error === REQUIRED_VALIDATION_ERROR
106
110
  ? 'Required'
@@ -127,13 +131,16 @@ export default {
127
131
  },
128
132
 
129
133
  computedHelpText() {
130
- if (this.maxLength !== null) {
134
+ if (this.hasCharacterCount) {
131
135
  return [this.helpText, this.characterCountText].filter(Boolean).join(' ')
132
136
  }
133
137
  return this.helpText
134
138
  },
139
+ hasCharacterCount() {
140
+ return this.showCharacterCount && this.maxLength !== null
141
+ },
135
142
  characterCountText() {
136
- if (this.maxLength === null) return ''
143
+ if (!this.hasCharacterCount) return ''
137
144
  return `${(this.resolvedValue || '').length}/${this.maxLength}`
138
145
  },
139
146
  maxLength() {