@vonage/vivid 3.53.0 → 3.54.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.
Files changed (60) hide show
  1. package/appearance-ui/index.cjs +1 -1
  2. package/appearance-ui/index.js +1 -1
  3. package/custom-elements.json +444 -94
  4. package/lib/appearance-ui/appearance-ui.d.ts +1 -1
  5. package/lib/audio-player/audio-player.d.ts +4 -0
  6. package/lib/audio-player/locale.d.ts +2 -0
  7. package/lib/dial-pad/dial-pad.d.ts +3 -0
  8. package/lib/enums.d.ts +1 -0
  9. package/lib/menu/menu.d.ts +1 -0
  10. package/lib/nav-disclosure/nav-disclosure.d.ts +5 -0
  11. package/lib/text-anchor/text-anchor.d.ts +1 -1
  12. package/lib/video-player/vivid-video-svg.d.ts +1 -0
  13. package/locales/en-GB.cjs +3 -1
  14. package/locales/en-GB.js +3 -1
  15. package/locales/en-US.cjs +3 -1
  16. package/locales/en-US.js +3 -1
  17. package/locales/ja-JP.cjs +3 -1
  18. package/locales/ja-JP.js +3 -1
  19. package/locales/zh-CN.cjs +3 -1
  20. package/locales/zh-CN.js +3 -1
  21. package/package.json +1 -1
  22. package/shared/definition20.cjs +15 -2
  23. package/shared/definition20.js +15 -2
  24. package/shared/definition27.cjs +1 -1
  25. package/shared/definition27.js +1 -1
  26. package/shared/definition29.cjs +39 -10
  27. package/shared/definition29.js +39 -10
  28. package/shared/definition30.cjs +1 -1
  29. package/shared/definition30.js +1 -1
  30. package/shared/definition31.cjs +14 -2
  31. package/shared/definition31.js +14 -2
  32. package/shared/definition32.cjs +1 -1
  33. package/shared/definition32.js +1 -1
  34. package/shared/definition35.cjs +1 -1
  35. package/shared/definition35.js +1 -1
  36. package/shared/definition43.cjs +1 -1
  37. package/shared/definition43.js +1 -1
  38. package/shared/definition5.cjs +99 -18
  39. package/shared/definition5.js +99 -18
  40. package/shared/definition55.cjs +120 -52
  41. package/shared/definition55.js +120 -52
  42. package/shared/definition61.cjs +307 -1
  43. package/shared/definition61.js +307 -1
  44. package/shared/enums.cjs +1 -0
  45. package/shared/enums.js +1 -0
  46. package/shared/icon.cjs +20 -2
  47. package/shared/icon.js +21 -3
  48. package/shared/index2.cjs +15 -8
  49. package/shared/index2.js +15 -8
  50. package/shared/text-field.cjs +1 -1
  51. package/shared/text-field.js +1 -1
  52. package/shared/utils/numberConverter.d.ts +2 -0
  53. package/styles/core/all.css +1 -1
  54. package/styles/core/theme.css +1 -1
  55. package/styles/core/typography.css +1 -1
  56. package/styles/tokens/theme-dark.css +4 -4
  57. package/styles/tokens/theme-light.css +4 -4
  58. package/styles/tokens/vivid-2-compat.css +1 -1
  59. package/vivid.api.json +21 -0
  60. package/style.css +0 -1
@@ -1,6 +1,7 @@
1
1
  import { a as attr, F as FoundationElement, o as observable, h as html, r as registerFactory } from './index.js';
2
2
  import { B as Button, a as buttonRegistries } from './definition11.js';
3
3
  import { S as Slider, a as sliderRegistries } from './definition46.js';
4
+ import { M as MediaSkipBy } from './enums.js';
4
5
  import './affix.js';
5
6
  import './index2.js';
6
7
  import { L as Localized } from './localized.js';
@@ -22,12 +23,22 @@ var __decorateClass = (decorators, target, key, kind) => {
22
23
  __defProp(target, key, result);
23
24
  return result;
24
25
  };
26
+ const validSkipByConverter = {
27
+ toView(value) {
28
+ return value;
29
+ },
30
+ fromView(value) {
31
+ return Object.values(MediaSkipBy).includes(value) ? value : void 0;
32
+ }
33
+ };
25
34
  class AudioPlayer extends FoundationElement {
26
35
  constructor() {
27
36
  super(...arguments);
28
37
  this.playButtonAriaLabel = null;
29
38
  this.pauseButtonAriaLabel = null;
30
39
  this.sliderAriaLabel = null;
40
+ this.skipForwardButtonAriaLabel = null;
41
+ this.skipBackwardButtonAriaLabel = null;
31
42
  this.disabled = false;
32
43
  this.notime = false;
33
44
  this.paused = true;
@@ -35,26 +46,18 @@ class AudioPlayer extends FoundationElement {
35
46
  * @internal
36
47
  */
37
48
  this._rewind = () => {
38
- this.paused = true;
39
49
  if (this._playerEl) {
40
- this._playerEl.pause();
41
50
  this._playerEl.currentTime = this._playerEl.duration * (Number(this._sliderEl.value) / 100);
42
51
  }
43
52
  };
44
53
  }
45
54
  connectedCallback() {
46
55
  super.connectedCallback();
47
- this.addEventListener("keydown", this._rewind);
48
- this.addEventListener("mousedown", this._rewind);
49
- this.addEventListener("keyup", this._rewind);
50
56
  document.addEventListener("mouseup", this._rewind);
51
57
  }
52
58
  disconnectedCallback() {
53
59
  super.disconnectedCallback();
54
- this.removeEventListener("keydown", this._rewind);
55
- this.removeEventListener("mousedown", this._rewind);
56
- this.removeEventListener("keyup", this._rewind);
57
- document.removeEventListener("mouseup", this._rewind);
60
+ document.addEventListener("mouseup", this._rewind);
58
61
  }
59
62
  /**
60
63
  * @internal
@@ -68,6 +71,22 @@ class AudioPlayer extends FoundationElement {
68
71
  }
69
72
  this.paused = !this.paused;
70
73
  }
74
+ /**
75
+ * @internal
76
+ */
77
+ _onSkipButtonClick(isForward) {
78
+ if (this._playerEl) {
79
+ const currentTime = this._playerEl.currentTime;
80
+ const skipDirection = isForward ? 1 : -1;
81
+ const skipValue = parseInt(this.skipBy) * skipDirection;
82
+ const newTime = currentTime + skipValue;
83
+ this._playerEl.currentTime = Math.max(
84
+ 0,
85
+ Math.min(this._playerEl.duration, newTime)
86
+ );
87
+ this._updateProgress();
88
+ }
89
+ }
71
90
  /**
72
91
  * @internal
73
92
  */
@@ -101,6 +120,19 @@ class AudioPlayer extends FoundationElement {
101
120
  totalTime.textContent = this._formatTime(this._playerEl.duration);
102
121
  }
103
122
  }
123
+ /**
124
+ * @internal
125
+ */
126
+ _handleSliderEvent(event) {
127
+ if (event.target === this._sliderEl) {
128
+ this.paused = true;
129
+ if (this._playerEl) {
130
+ this._playerEl.pause();
131
+ }
132
+ this._rewind();
133
+ }
134
+ return true;
135
+ }
104
136
  /**
105
137
  * @internal
106
138
  */
@@ -119,6 +151,12 @@ __decorateClass([
119
151
  __decorateClass([
120
152
  attr({ attribute: "slider-aria-label" })
121
153
  ], AudioPlayer.prototype, "sliderAriaLabel", 2);
154
+ __decorateClass([
155
+ attr({ attribute: "skip-forward-aria-label" })
156
+ ], AudioPlayer.prototype, "skipForwardButtonAriaLabel", 2);
157
+ __decorateClass([
158
+ attr({ attribute: "skip-backward-aria-label" })
159
+ ], AudioPlayer.prototype, "skipBackwardButtonAriaLabel", 2);
122
160
  __decorateClass([
123
161
  attr
124
162
  ], AudioPlayer.prototype, "connotation", 2);
@@ -131,6 +169,12 @@ __decorateClass([
131
169
  __decorateClass([
132
170
  attr({ mode: "boolean" })
133
171
  ], AudioPlayer.prototype, "notime", 2);
172
+ __decorateClass([
173
+ attr({
174
+ attribute: "skip-by",
175
+ converter: validSkipByConverter
176
+ })
177
+ ], AudioPlayer.prototype, "skipBy", 2);
134
178
  __decorateClass([
135
179
  observable
136
180
  ], AudioPlayer.prototype, "paused", 2);
@@ -143,19 +187,43 @@ const getClasses = ({ disabled, duration }) => classNames(["disabled", Boolean(d
143
187
  function renderButton(context) {
144
188
  const buttonTag = context.tagFor(Button);
145
189
  return html`<${buttonTag} class="pause" @click="${(x) => x._togglePlay()}"
146
- icon="${(x) => x.paused ? "play-solid" : "pause-solid"}"
147
- aria-label="${(x) => x.paused ? x.playButtonAriaLabel || x.locale.audioPlayer.playButtonLabel : x.pauseButtonAriaLabel || x.locale.audioPlayer.playButtonLabel}"
148
- size='condensed'
190
+ icon="${(x) => x.paused ? "play-solid" : "pause-solid"}"
191
+ aria-label="${(x) => x.paused ? x.playButtonAriaLabel || x.locale.audioPlayer.playButtonLabel : x.pauseButtonAriaLabel || x.locale.audioPlayer.pauseButtonLabel}"
192
+ size='condensed'
149
193
  connotation="${(x) => x.connotation}"
150
- ?disabled="${(x) => x.disabled || !x.duration}"
194
+ ?disabled="${(x) => x.disabled || !x.duration}"
151
195
  ></${buttonTag}>`;
152
196
  }
197
+ function renderBackwardSkipButtons(context) {
198
+ const buttonTag = context.tagFor(Button);
199
+ return html`
200
+ <${buttonTag} class="skip backward" @click="${(x) => x._onSkipButtonClick(false)}"
201
+ icon="${(x) => x.skipBy == MediaSkipBy.Five ? "5-sec-backward-line" : x.skipBy == MediaSkipBy.Thirty ? "30-sec-backward-line" : "10-sec-backward-line"}"
202
+ size='condensed'
203
+ aria-label="${(x) => x.skipBackwardButtonAriaLabel || x.locale.audioPlayer.skipBackwardButton}"
204
+ connotation="${(x) => x.connotation}"
205
+ ?disabled="${(x) => x.disabled || !x.duration}"
206
+ ></${buttonTag}>
207
+ `;
208
+ }
209
+ function renderForwardSkipButtons(context) {
210
+ const buttonTag = context.tagFor(Button);
211
+ return html`
212
+ <${buttonTag} class="skip forward" @click="${(x) => x._onSkipButtonClick(true)}"
213
+ icon="${(x) => x.skipBy == MediaSkipBy.Five ? "5-sec-forward-line" : x.skipBy == MediaSkipBy.Thirty ? "30-sec-forward-line" : "10-sec-forward-line"}"
214
+ size='condensed'
215
+ aria-label="${(x) => x.skipForwardButtonAriaLabel || x.locale.audioPlayer.skipForwardButton}"
216
+ connotation="${(x) => x.connotation}"
217
+ ?disabled="${(x) => x.disabled || !x.duration}"
218
+ ></${buttonTag}>
219
+ `;
220
+ }
153
221
  function renderSlider(context) {
154
222
  const sliderTag = context.tagFor(Slider);
155
223
  return html`<${sliderTag}
156
- ${ref("_sliderEl")} class="slider"
224
+ ${ref("_sliderEl")} class="slider"
157
225
  aria-label="${(x) => x.sliderAriaLabel || x.locale.audioPlayer.sliderLabel}"
158
- value="0" max="100"
226
+ value="0" max="100"
159
227
  connotation="${(x) => x.connotation}"
160
228
  ?disabled="${(x) => x.disabled || !x.duration}">
161
229
  </${sliderTag}>`;
@@ -168,10 +236,23 @@ function renderTimestamp() {
168
236
  </div>`;
169
237
  }
170
238
  const AudioPlayerTemplate = (context) => {
171
- return html` <div class="base ${getClasses}">
239
+ return html` <div
240
+ class="base ${getClasses}"
241
+ @keyup="${(x, c) => x._handleSliderEvent(c.event)}"
242
+ @keydown="${(x, c) => x._handleSliderEvent(c.event)}"
243
+ @mousedown="${(x, c) => x._handleSliderEvent(c.event)}"
244
+ >
172
245
  <div class="controls">
173
- ${renderButton(context)} ${when((x) => !x.notime, renderTimestamp())}
174
- ${renderSlider(context)}
246
+ ${when(
247
+ (x) => x.skipBy && x.skipBy != MediaSkipBy.Zero,
248
+ renderBackwardSkipButtons(context)
249
+ )}
250
+ ${renderButton(context)}
251
+ ${when(
252
+ (x) => x.skipBy && x.skipBy != MediaSkipBy.Zero,
253
+ renderForwardSkipButtons(context)
254
+ )}
255
+ ${when((x) => !x.notime, renderTimestamp())} ${renderSlider(context)}
175
256
  </div>
176
257
  <audio
177
258
  ${ref("_playerEl")}
@@ -113,7 +113,7 @@ var __privateMethod = (obj, member, method) => {
113
113
  __accessCheck(obj, member, "access private method");
114
114
  return method;
115
115
  };
116
- var _handleLabelChange, handleLabelChange_fn, _reflectToInput;
116
+ var _handleLabelChange, handleLabelChange_fn, _reflectToInput, _helperTextMirrorEl, _helperTextSlotMutationObserver, _updateHelperTextMutationObserver, updateHelperTextMutationObserver_fn, _updateMirroredHelperText, updateMirroredHelperText_fn;
117
117
  const safariWorkaroundClassName = "_vvd-3-text-field-safari-workaround";
118
118
  const getSafariWorkaroundStyleSheet = icon.memoizeWith(
119
119
  () => "",
@@ -148,11 +148,15 @@ exports.TextField = class TextField extends textField.TextField {
148
148
  constructor() {
149
149
  super(...arguments);
150
150
  __privateAdd(this, _handleLabelChange);
151
+ __privateAdd(this, _updateHelperTextMutationObserver);
152
+ __privateAdd(this, _updateMirroredHelperText);
151
153
  /**
152
154
  * @internal
153
155
  */
154
156
  this._labelEl = null;
155
157
  __privateAdd(this, _reflectToInput, void 0);
158
+ __privateAdd(this, _helperTextMirrorEl, void 0);
159
+ __privateAdd(this, _helperTextSlotMutationObserver, void 0);
156
160
  }
157
161
  /**
158
162
  * @internal
@@ -167,42 +171,12 @@ exports.TextField = class TextField extends textField.TextField {
167
171
  if (!this.control) {
168
172
  const uniqueId = this.id || generateRandomId();
169
173
  const controlId = `vvd-text-field-control-${uniqueId}`;
174
+ const helperTextId = `vvd-text-field-helper-text-${uniqueId}`;
170
175
  const input = document.createElement("input");
171
176
  input.slot = "_control";
172
177
  input.id = controlId;
173
178
  input.className = safariWorkaroundClassName;
174
179
  this.control = input;
175
- __privateSet(this, _reflectToInput, new Reflector.Reflector(this, input));
176
- __privateGet(this, _reflectToInput).booleanAttribute("autofocus", "autofocus");
177
- __privateGet(this, _reflectToInput).booleanAttribute("disabled", "disabled");
178
- __privateGet(this, _reflectToInput).booleanAttribute("readOnly", "readonly");
179
- __privateGet(this, _reflectToInput).booleanAttribute("required", "required");
180
- __privateGet(this, _reflectToInput).booleanAttribute("spellcheck", "spellcheck");
181
- __privateGet(this, _reflectToInput).attribute("list", "list");
182
- __privateGet(this, _reflectToInput).attribute("maxlength", "maxlength");
183
- __privateGet(this, _reflectToInput).attribute("minlength", "minlength");
184
- __privateGet(this, _reflectToInput).attribute("pattern", "pattern");
185
- __privateGet(this, _reflectToInput).attribute("placeholder", "placeholder");
186
- __privateGet(this, _reflectToInput).attribute("size", "size");
187
- __privateGet(this, _reflectToInput).attribute("autoComplete", "autocomplete");
188
- __privateGet(this, _reflectToInput).attribute("type", "type");
189
- __privateGet(this, _reflectToInput).attribute("ariaAtomic", "aria-atomic");
190
- __privateGet(this, _reflectToInput).attribute("ariaBusy", "aria-busy");
191
- __privateGet(this, _reflectToInput).attribute("ariaCurrent", "aria-current");
192
- __privateGet(this, _reflectToInput).attribute("ariaDetails", "aria-details");
193
- __privateGet(this, _reflectToInput).attribute("ariaDisabled", "aria-disabled");
194
- __privateGet(this, _reflectToInput).attribute("ariaHaspopup", "aria-haspopup");
195
- __privateGet(this, _reflectToInput).attribute("ariaHidden", "aria-hidden");
196
- __privateGet(this, _reflectToInput).attribute("ariaInvalid", "aria-invalid");
197
- __privateGet(this, _reflectToInput).attribute("ariaKeyshortcuts", "aria-keyshortcuts");
198
- __privateGet(this, _reflectToInput).attribute("ariaLabel", "aria-label");
199
- __privateGet(this, _reflectToInput).attribute("ariaLive", "aria-live");
200
- __privateGet(this, _reflectToInput).attribute("ariaRelevant", "aria-relevant");
201
- __privateGet(this, _reflectToInput).attribute(
202
- "ariaRoledescription",
203
- "aria-roledescription"
204
- );
205
- __privateGet(this, _reflectToInput).property("value", "value", true);
206
180
  input.addEventListener("input", () => {
207
181
  this.handleTextInput();
208
182
  });
@@ -221,16 +195,68 @@ exports.TextField = class TextField extends textField.TextField {
221
195
  label.htmlFor = controlId;
222
196
  this._labelEl = label;
223
197
  __privateMethod(this, _handleLabelChange, handleLabelChange_fn).call(this, label);
198
+ __privateSet(this, _helperTextMirrorEl, document.createElement("div"));
199
+ __privateGet(this, _helperTextMirrorEl).id = helperTextId;
200
+ __privateGet(this, _helperTextMirrorEl).slot = "_mirrored-helper-text";
201
+ __privateMethod(this, _updateMirroredHelperText, updateMirroredHelperText_fn).call(this);
202
+ this.appendChild(__privateGet(this, _helperTextMirrorEl));
224
203
  installSafariWorkaroundStyle(this);
225
204
  }
205
+ __privateSet(this, _reflectToInput, new Reflector.Reflector(this, this.control));
206
+ __privateGet(this, _reflectToInput).booleanAttribute("autofocus", "autofocus");
207
+ __privateGet(this, _reflectToInput).booleanAttribute("disabled", "disabled");
208
+ __privateGet(this, _reflectToInput).booleanAttribute("readOnly", "readonly");
209
+ __privateGet(this, _reflectToInput).booleanAttribute("required", "required");
210
+ __privateGet(this, _reflectToInput).booleanAttribute("spellcheck", "spellcheck");
211
+ __privateGet(this, _reflectToInput).attribute("list", "list");
212
+ __privateGet(this, _reflectToInput).attribute("maxlength", "maxlength");
213
+ __privateGet(this, _reflectToInput).attribute("minlength", "minlength");
214
+ __privateGet(this, _reflectToInput).attribute("pattern", "pattern");
215
+ __privateGet(this, _reflectToInput).attribute("placeholder", "placeholder");
216
+ __privateGet(this, _reflectToInput).attribute("size", "size");
217
+ __privateGet(this, _reflectToInput).attribute("autoComplete", "autocomplete");
218
+ __privateGet(this, _reflectToInput).attribute("type", "type");
219
+ __privateGet(this, _reflectToInput).attribute("ariaAtomic", "aria-atomic");
220
+ __privateGet(this, _reflectToInput).attribute("ariaBusy", "aria-busy");
221
+ __privateGet(this, _reflectToInput).attribute("ariaCurrent", "aria-current");
222
+ __privateGet(this, _reflectToInput).attribute("ariaDetails", "aria-details");
223
+ __privateGet(this, _reflectToInput).attribute("ariaDisabled", "aria-disabled");
224
+ __privateGet(this, _reflectToInput).attribute("ariaHaspopup", "aria-haspopup");
225
+ __privateGet(this, _reflectToInput).attribute("ariaHidden", "aria-hidden");
226
+ __privateGet(this, _reflectToInput).attribute("ariaInvalid", "aria-invalid");
227
+ __privateGet(this, _reflectToInput).attribute("ariaKeyshortcuts", "aria-keyshortcuts");
228
+ __privateGet(this, _reflectToInput).attribute("ariaLabel", "aria-label");
229
+ __privateGet(this, _reflectToInput).attribute("ariaLive", "aria-live");
230
+ __privateGet(this, _reflectToInput).attribute("ariaRelevant", "aria-relevant");
231
+ __privateGet(this, _reflectToInput).attribute(
232
+ "ariaRoledescription",
233
+ "aria-roledescription"
234
+ );
235
+ __privateGet(this, _reflectToInput).property("value", "value", true);
236
+ __privateMethod(this, _updateHelperTextMutationObserver, updateHelperTextMutationObserver_fn).call(this);
226
237
  }
227
238
  disconnectedCallback() {
228
239
  super.disconnectedCallback();
229
240
  __privateGet(this, _reflectToInput).destroy();
241
+ __privateSet(this, _reflectToInput, void 0);
242
+ __privateMethod(this, _updateHelperTextMutationObserver, updateHelperTextMutationObserver_fn).call(this);
230
243
  }
231
244
  focus() {
232
245
  this.control?.focus();
233
246
  }
247
+ /**
248
+ * @internal
249
+ */
250
+ helperTextChanged() {
251
+ __privateMethod(this, _updateMirroredHelperText, updateMirroredHelperText_fn).call(this);
252
+ }
253
+ /**
254
+ * @internal
255
+ */
256
+ _helperTextSlottedContentChanged() {
257
+ __privateMethod(this, _updateMirroredHelperText, updateMirroredHelperText_fn).call(this);
258
+ __privateMethod(this, _updateHelperTextMutationObserver, updateHelperTextMutationObserver_fn).call(this);
259
+ }
234
260
  };
235
261
  _handleLabelChange = new WeakSet();
236
262
  handleLabelChange_fn = function(labelEl) {
@@ -244,6 +270,47 @@ handleLabelChange_fn = function(labelEl) {
244
270
  }
245
271
  };
246
272
  _reflectToInput = new WeakMap();
273
+ _helperTextMirrorEl = new WeakMap();
274
+ _helperTextSlotMutationObserver = new WeakMap();
275
+ _updateHelperTextMutationObserver = new WeakSet();
276
+ updateHelperTextMutationObserver_fn = function() {
277
+ const usesHelperTextSlot = this._helperTextSlottedContent.length;
278
+ const shouldHaveMutationObserver = usesHelperTextSlot && this.isConnected;
279
+ if (shouldHaveMutationObserver && !__privateGet(this, _helperTextSlotMutationObserver)) {
280
+ __privateSet(this, _helperTextSlotMutationObserver, new MutationObserver((records) => {
281
+ if (records.some((record) => record.target !== __privateGet(this, _helperTextMirrorEl))) {
282
+ __privateMethod(this, _updateMirroredHelperText, updateMirroredHelperText_fn).call(this);
283
+ }
284
+ }));
285
+ __privateGet(this, _helperTextSlotMutationObserver).observe(this, {
286
+ subtree: true,
287
+ childList: true,
288
+ characterData: true
289
+ });
290
+ }
291
+ if (!shouldHaveMutationObserver && __privateGet(this, _helperTextSlotMutationObserver)) {
292
+ __privateGet(this, _helperTextSlotMutationObserver).disconnect();
293
+ __privateSet(this, _helperTextSlotMutationObserver, void 0);
294
+ }
295
+ };
296
+ _updateMirroredHelperText = new WeakSet();
297
+ updateMirroredHelperText_fn = function() {
298
+ let helperText = this.helperText ?? "";
299
+ if (this._helperTextSlottedContent?.length) {
300
+ helperText = this._helperTextSlottedContent.map((node) => node.innerText).join(" ");
301
+ }
302
+ if (__privateGet(this, _helperTextMirrorEl)) {
303
+ __privateGet(this, _helperTextMirrorEl).textContent = helperText;
304
+ if (helperText) {
305
+ this.control.setAttribute(
306
+ "aria-describedby",
307
+ __privateGet(this, _helperTextMirrorEl).id
308
+ );
309
+ } else {
310
+ this.control.removeAttribute("aria-describedby");
311
+ }
312
+ }
313
+ };
247
314
  __decorateClass([
248
315
  index.attr
249
316
  ], exports.TextField.prototype, "appearance", 2);
@@ -309,29 +376,30 @@ function renderCharCount() {
309
376
  const TextfieldTemplate = (context) => {
310
377
  const affixIconTemplate = affix.affixIconTemplateFactory(context);
311
378
  return index.html` <div class="base ${getStateClasses}">
312
- ${when.when((x) => x.charCount && x.maxlength, renderCharCount())}
313
- <slot class="label" name="_label"></slot>
314
- <div class="fieldset">
315
- <div class="leading-items-wrapper">
316
- <slot
317
- name="leading-action-items"
318
- ${slotted.slotted("leadingActionItemsSlottedContent")}
319
- ></slot>
320
- ${(x) => affixIconTemplate(x.icon)}
321
- </div>
379
+ ${when.when((x) => x.charCount && x.maxlength, renderCharCount())}
380
+ <slot class="label" name="_label"></slot>
381
+ <div class="fieldset">
382
+ <div class="leading-items-wrapper">
383
+ <slot
384
+ name="leading-action-items"
385
+ ${slotted.slotted("leadingActionItemsSlottedContent")}
386
+ ></slot>
387
+ ${(x) => affixIconTemplate(x.icon)}
388
+ </div>
322
389
 
323
- <div class="wrapper">
324
- <slot class="control" name="_control"></slot>
325
- </div>
326
- <div class="action-items-wrapper">
327
- <slot
328
- name="action-items"
329
- ${slotted.slotted("actionItemsSlottedContent")}
330
- ></slot>
390
+ <div class="wrapper">
391
+ <slot class="control" name="_control"></slot>
392
+ </div>
393
+ <div class="action-items-wrapper">
394
+ <slot
395
+ name="action-items"
396
+ ${slotted.slotted("actionItemsSlottedContent")}
397
+ ></slot>
398
+ </div>
331
399
  </div>
400
+ ${index$1.getFeedbackTemplate(context)}
332
401
  </div>
333
- ${index$1.getFeedbackTemplate(context)}
334
- </div>`;
402
+ <slot name="_mirrored-helper-text"></slot>`;
335
403
  };
336
404
 
337
405
  const textFieldDefinition = exports.TextField.compose({
@@ -111,7 +111,7 @@ var __privateMethod = (obj, member, method) => {
111
111
  __accessCheck(obj, member, "access private method");
112
112
  return method;
113
113
  };
114
- var _handleLabelChange, handleLabelChange_fn, _reflectToInput;
114
+ var _handleLabelChange, handleLabelChange_fn, _reflectToInput, _helperTextMirrorEl, _helperTextSlotMutationObserver, _updateHelperTextMutationObserver, updateHelperTextMutationObserver_fn, _updateMirroredHelperText, updateMirroredHelperText_fn;
115
115
  const safariWorkaroundClassName = "_vvd-3-text-field-safari-workaround";
116
116
  const getSafariWorkaroundStyleSheet = memoizeWith(
117
117
  () => "",
@@ -146,11 +146,15 @@ let TextField = class extends TextField$1 {
146
146
  constructor() {
147
147
  super(...arguments);
148
148
  __privateAdd(this, _handleLabelChange);
149
+ __privateAdd(this, _updateHelperTextMutationObserver);
150
+ __privateAdd(this, _updateMirroredHelperText);
149
151
  /**
150
152
  * @internal
151
153
  */
152
154
  this._labelEl = null;
153
155
  __privateAdd(this, _reflectToInput, void 0);
156
+ __privateAdd(this, _helperTextMirrorEl, void 0);
157
+ __privateAdd(this, _helperTextSlotMutationObserver, void 0);
154
158
  }
155
159
  /**
156
160
  * @internal
@@ -165,42 +169,12 @@ let TextField = class extends TextField$1 {
165
169
  if (!this.control) {
166
170
  const uniqueId = this.id || generateRandomId();
167
171
  const controlId = `vvd-text-field-control-${uniqueId}`;
172
+ const helperTextId = `vvd-text-field-helper-text-${uniqueId}`;
168
173
  const input = document.createElement("input");
169
174
  input.slot = "_control";
170
175
  input.id = controlId;
171
176
  input.className = safariWorkaroundClassName;
172
177
  this.control = input;
173
- __privateSet(this, _reflectToInput, new Reflector(this, input));
174
- __privateGet(this, _reflectToInput).booleanAttribute("autofocus", "autofocus");
175
- __privateGet(this, _reflectToInput).booleanAttribute("disabled", "disabled");
176
- __privateGet(this, _reflectToInput).booleanAttribute("readOnly", "readonly");
177
- __privateGet(this, _reflectToInput).booleanAttribute("required", "required");
178
- __privateGet(this, _reflectToInput).booleanAttribute("spellcheck", "spellcheck");
179
- __privateGet(this, _reflectToInput).attribute("list", "list");
180
- __privateGet(this, _reflectToInput).attribute("maxlength", "maxlength");
181
- __privateGet(this, _reflectToInput).attribute("minlength", "minlength");
182
- __privateGet(this, _reflectToInput).attribute("pattern", "pattern");
183
- __privateGet(this, _reflectToInput).attribute("placeholder", "placeholder");
184
- __privateGet(this, _reflectToInput).attribute("size", "size");
185
- __privateGet(this, _reflectToInput).attribute("autoComplete", "autocomplete");
186
- __privateGet(this, _reflectToInput).attribute("type", "type");
187
- __privateGet(this, _reflectToInput).attribute("ariaAtomic", "aria-atomic");
188
- __privateGet(this, _reflectToInput).attribute("ariaBusy", "aria-busy");
189
- __privateGet(this, _reflectToInput).attribute("ariaCurrent", "aria-current");
190
- __privateGet(this, _reflectToInput).attribute("ariaDetails", "aria-details");
191
- __privateGet(this, _reflectToInput).attribute("ariaDisabled", "aria-disabled");
192
- __privateGet(this, _reflectToInput).attribute("ariaHaspopup", "aria-haspopup");
193
- __privateGet(this, _reflectToInput).attribute("ariaHidden", "aria-hidden");
194
- __privateGet(this, _reflectToInput).attribute("ariaInvalid", "aria-invalid");
195
- __privateGet(this, _reflectToInput).attribute("ariaKeyshortcuts", "aria-keyshortcuts");
196
- __privateGet(this, _reflectToInput).attribute("ariaLabel", "aria-label");
197
- __privateGet(this, _reflectToInput).attribute("ariaLive", "aria-live");
198
- __privateGet(this, _reflectToInput).attribute("ariaRelevant", "aria-relevant");
199
- __privateGet(this, _reflectToInput).attribute(
200
- "ariaRoledescription",
201
- "aria-roledescription"
202
- );
203
- __privateGet(this, _reflectToInput).property("value", "value", true);
204
178
  input.addEventListener("input", () => {
205
179
  this.handleTextInput();
206
180
  });
@@ -219,16 +193,68 @@ let TextField = class extends TextField$1 {
219
193
  label.htmlFor = controlId;
220
194
  this._labelEl = label;
221
195
  __privateMethod(this, _handleLabelChange, handleLabelChange_fn).call(this, label);
196
+ __privateSet(this, _helperTextMirrorEl, document.createElement("div"));
197
+ __privateGet(this, _helperTextMirrorEl).id = helperTextId;
198
+ __privateGet(this, _helperTextMirrorEl).slot = "_mirrored-helper-text";
199
+ __privateMethod(this, _updateMirroredHelperText, updateMirroredHelperText_fn).call(this);
200
+ this.appendChild(__privateGet(this, _helperTextMirrorEl));
222
201
  installSafariWorkaroundStyle(this);
223
202
  }
203
+ __privateSet(this, _reflectToInput, new Reflector(this, this.control));
204
+ __privateGet(this, _reflectToInput).booleanAttribute("autofocus", "autofocus");
205
+ __privateGet(this, _reflectToInput).booleanAttribute("disabled", "disabled");
206
+ __privateGet(this, _reflectToInput).booleanAttribute("readOnly", "readonly");
207
+ __privateGet(this, _reflectToInput).booleanAttribute("required", "required");
208
+ __privateGet(this, _reflectToInput).booleanAttribute("spellcheck", "spellcheck");
209
+ __privateGet(this, _reflectToInput).attribute("list", "list");
210
+ __privateGet(this, _reflectToInput).attribute("maxlength", "maxlength");
211
+ __privateGet(this, _reflectToInput).attribute("minlength", "minlength");
212
+ __privateGet(this, _reflectToInput).attribute("pattern", "pattern");
213
+ __privateGet(this, _reflectToInput).attribute("placeholder", "placeholder");
214
+ __privateGet(this, _reflectToInput).attribute("size", "size");
215
+ __privateGet(this, _reflectToInput).attribute("autoComplete", "autocomplete");
216
+ __privateGet(this, _reflectToInput).attribute("type", "type");
217
+ __privateGet(this, _reflectToInput).attribute("ariaAtomic", "aria-atomic");
218
+ __privateGet(this, _reflectToInput).attribute("ariaBusy", "aria-busy");
219
+ __privateGet(this, _reflectToInput).attribute("ariaCurrent", "aria-current");
220
+ __privateGet(this, _reflectToInput).attribute("ariaDetails", "aria-details");
221
+ __privateGet(this, _reflectToInput).attribute("ariaDisabled", "aria-disabled");
222
+ __privateGet(this, _reflectToInput).attribute("ariaHaspopup", "aria-haspopup");
223
+ __privateGet(this, _reflectToInput).attribute("ariaHidden", "aria-hidden");
224
+ __privateGet(this, _reflectToInput).attribute("ariaInvalid", "aria-invalid");
225
+ __privateGet(this, _reflectToInput).attribute("ariaKeyshortcuts", "aria-keyshortcuts");
226
+ __privateGet(this, _reflectToInput).attribute("ariaLabel", "aria-label");
227
+ __privateGet(this, _reflectToInput).attribute("ariaLive", "aria-live");
228
+ __privateGet(this, _reflectToInput).attribute("ariaRelevant", "aria-relevant");
229
+ __privateGet(this, _reflectToInput).attribute(
230
+ "ariaRoledescription",
231
+ "aria-roledescription"
232
+ );
233
+ __privateGet(this, _reflectToInput).property("value", "value", true);
234
+ __privateMethod(this, _updateHelperTextMutationObserver, updateHelperTextMutationObserver_fn).call(this);
224
235
  }
225
236
  disconnectedCallback() {
226
237
  super.disconnectedCallback();
227
238
  __privateGet(this, _reflectToInput).destroy();
239
+ __privateSet(this, _reflectToInput, void 0);
240
+ __privateMethod(this, _updateHelperTextMutationObserver, updateHelperTextMutationObserver_fn).call(this);
228
241
  }
229
242
  focus() {
230
243
  this.control?.focus();
231
244
  }
245
+ /**
246
+ * @internal
247
+ */
248
+ helperTextChanged() {
249
+ __privateMethod(this, _updateMirroredHelperText, updateMirroredHelperText_fn).call(this);
250
+ }
251
+ /**
252
+ * @internal
253
+ */
254
+ _helperTextSlottedContentChanged() {
255
+ __privateMethod(this, _updateMirroredHelperText, updateMirroredHelperText_fn).call(this);
256
+ __privateMethod(this, _updateHelperTextMutationObserver, updateHelperTextMutationObserver_fn).call(this);
257
+ }
232
258
  };
233
259
  _handleLabelChange = new WeakSet();
234
260
  handleLabelChange_fn = function(labelEl) {
@@ -242,6 +268,47 @@ handleLabelChange_fn = function(labelEl) {
242
268
  }
243
269
  };
244
270
  _reflectToInput = new WeakMap();
271
+ _helperTextMirrorEl = new WeakMap();
272
+ _helperTextSlotMutationObserver = new WeakMap();
273
+ _updateHelperTextMutationObserver = new WeakSet();
274
+ updateHelperTextMutationObserver_fn = function() {
275
+ const usesHelperTextSlot = this._helperTextSlottedContent.length;
276
+ const shouldHaveMutationObserver = usesHelperTextSlot && this.isConnected;
277
+ if (shouldHaveMutationObserver && !__privateGet(this, _helperTextSlotMutationObserver)) {
278
+ __privateSet(this, _helperTextSlotMutationObserver, new MutationObserver((records) => {
279
+ if (records.some((record) => record.target !== __privateGet(this, _helperTextMirrorEl))) {
280
+ __privateMethod(this, _updateMirroredHelperText, updateMirroredHelperText_fn).call(this);
281
+ }
282
+ }));
283
+ __privateGet(this, _helperTextSlotMutationObserver).observe(this, {
284
+ subtree: true,
285
+ childList: true,
286
+ characterData: true
287
+ });
288
+ }
289
+ if (!shouldHaveMutationObserver && __privateGet(this, _helperTextSlotMutationObserver)) {
290
+ __privateGet(this, _helperTextSlotMutationObserver).disconnect();
291
+ __privateSet(this, _helperTextSlotMutationObserver, void 0);
292
+ }
293
+ };
294
+ _updateMirroredHelperText = new WeakSet();
295
+ updateMirroredHelperText_fn = function() {
296
+ let helperText = this.helperText ?? "";
297
+ if (this._helperTextSlottedContent?.length) {
298
+ helperText = this._helperTextSlottedContent.map((node) => node.innerText).join(" ");
299
+ }
300
+ if (__privateGet(this, _helperTextMirrorEl)) {
301
+ __privateGet(this, _helperTextMirrorEl).textContent = helperText;
302
+ if (helperText) {
303
+ this.control.setAttribute(
304
+ "aria-describedby",
305
+ __privateGet(this, _helperTextMirrorEl).id
306
+ );
307
+ } else {
308
+ this.control.removeAttribute("aria-describedby");
309
+ }
310
+ }
311
+ };
245
312
  __decorateClass([
246
313
  attr
247
314
  ], TextField.prototype, "appearance", 2);
@@ -307,29 +374,30 @@ function renderCharCount() {
307
374
  const TextfieldTemplate = (context) => {
308
375
  const affixIconTemplate = affixIconTemplateFactory(context);
309
376
  return html` <div class="base ${getStateClasses}">
310
- ${when((x) => x.charCount && x.maxlength, renderCharCount())}
311
- <slot class="label" name="_label"></slot>
312
- <div class="fieldset">
313
- <div class="leading-items-wrapper">
314
- <slot
315
- name="leading-action-items"
316
- ${slotted("leadingActionItemsSlottedContent")}
317
- ></slot>
318
- ${(x) => affixIconTemplate(x.icon)}
319
- </div>
377
+ ${when((x) => x.charCount && x.maxlength, renderCharCount())}
378
+ <slot class="label" name="_label"></slot>
379
+ <div class="fieldset">
380
+ <div class="leading-items-wrapper">
381
+ <slot
382
+ name="leading-action-items"
383
+ ${slotted("leadingActionItemsSlottedContent")}
384
+ ></slot>
385
+ ${(x) => affixIconTemplate(x.icon)}
386
+ </div>
320
387
 
321
- <div class="wrapper">
322
- <slot class="control" name="_control"></slot>
323
- </div>
324
- <div class="action-items-wrapper">
325
- <slot
326
- name="action-items"
327
- ${slotted("actionItemsSlottedContent")}
328
- ></slot>
388
+ <div class="wrapper">
389
+ <slot class="control" name="_control"></slot>
390
+ </div>
391
+ <div class="action-items-wrapper">
392
+ <slot
393
+ name="action-items"
394
+ ${slotted("actionItemsSlottedContent")}
395
+ ></slot>
396
+ </div>
329
397
  </div>
398
+ ${getFeedbackTemplate(context)}
330
399
  </div>
331
- ${getFeedbackTemplate(context)}
332
- </div>`;
400
+ <slot name="_mirrored-helper-text"></slot>`;
333
401
  };
334
402
 
335
403
  const textFieldDefinition = TextField.compose({