@matter-server/dashboard 0.2.6 → 0.2.7-alpha.0-20260118-45c7af0

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 (53) hide show
  1. package/README.md +16 -0
  2. package/dist/esm/client/models/descriptions.js +1754 -1754
  3. package/dist/esm/components/dialogs/binding/node-binding-dialog.d.ts.map +1 -1
  4. package/dist/esm/components/dialogs/binding/node-binding-dialog.js +8 -4
  5. package/dist/esm/components/dialogs/binding/node-binding-dialog.js.map +1 -1
  6. package/dist/esm/components/dialogs/settings/log-level-dialog.d.ts +33 -0
  7. package/dist/esm/components/dialogs/settings/log-level-dialog.d.ts.map +1 -0
  8. package/dist/esm/components/dialogs/settings/log-level-dialog.js +185 -0
  9. package/dist/esm/components/dialogs/settings/log-level-dialog.js.map +6 -0
  10. package/dist/esm/components/dialogs/settings/show-log-level-dialog.d.ts +8 -0
  11. package/dist/esm/components/dialogs/settings/show-log-level-dialog.d.ts.map +1 -0
  12. package/dist/esm/components/dialogs/settings/show-log-level-dialog.js +15 -0
  13. package/dist/esm/components/dialogs/settings/show-log-level-dialog.js.map +6 -0
  14. package/dist/esm/entrypoint/main.d.ts +1 -1
  15. package/dist/esm/entrypoint/main.d.ts.map +1 -1
  16. package/dist/esm/entrypoint/main.js +1 -0
  17. package/dist/esm/entrypoint/main.js.map +1 -1
  18. package/dist/esm/pages/components/header.d.ts +9 -0
  19. package/dist/esm/pages/components/header.d.ts.map +1 -1
  20. package/dist/esm/pages/components/header.js +68 -6
  21. package/dist/esm/pages/components/header.js.map +1 -1
  22. package/dist/esm/pages/matter-dashboard-app.d.ts +6 -1
  23. package/dist/esm/pages/matter-dashboard-app.d.ts.map +1 -1
  24. package/dist/esm/pages/matter-dashboard-app.js +119 -24
  25. package/dist/esm/pages/matter-dashboard-app.js.map +1 -1
  26. package/dist/esm/util/theme-service.d.ts +27 -0
  27. package/dist/esm/util/theme-service.d.ts.map +1 -0
  28. package/dist/esm/util/theme-service.js +71 -0
  29. package/dist/esm/util/theme-service.js.map +6 -0
  30. package/dist/web/index.html +35 -0
  31. package/dist/web/js/{commission-node-dialog--19-sX9D.js → commission-node-dialog-CoaDIV2Y.js} +5 -5
  32. package/dist/web/js/{commission-node-existing-DY6SnsHb.js → commission-node-existing-DEU_mJjO.js} +5 -4
  33. package/dist/web/js/{commission-node-thread-CXquVvK5.js → commission-node-thread-DZ6DghSs.js} +5 -4
  34. package/dist/web/js/{commission-node-wifi-VQGVOrr7.js → commission-node-wifi-DOyin0q3.js} +5 -4
  35. package/dist/web/js/{dialog-box-qX-alVZJ.js → dialog-box-B5sunUPv.js} +2 -2
  36. package/dist/web/js/{fire_event-B13DcOc9.js → fire_event-C9Duc1j-.js} +1 -1
  37. package/dist/web/js/log-level-dialog-B7LsZYUL.js +3232 -0
  38. package/dist/web/js/main.js +163 -8
  39. package/dist/web/js/{matter-dashboard-app-CU3-L2nl.js → matter-dashboard-app-DlHSE_Qh.js} +13253 -13039
  40. package/dist/web/js/{node-binding-dialog-D4rr_G9I.js → node-binding-dialog-BifZsigR.js} +12 -7
  41. package/dist/web/js/outlined-text-field-D2BOt1yD.js +968 -0
  42. package/dist/web/js/{prevent_default-Dw7ifAL-.js → prevent_default-CuW2EnKR.js} +1 -1
  43. package/dist/web/js/validator-MOJiFndw.js +1122 -0
  44. package/package.json +4 -4
  45. package/src/client/models/descriptions.ts +1754 -1754
  46. package/src/components/dialogs/binding/node-binding-dialog.ts +8 -4
  47. package/src/components/dialogs/settings/log-level-dialog.ts +179 -0
  48. package/src/components/dialogs/settings/show-log-level-dialog.ts +14 -0
  49. package/src/entrypoint/main.ts +1 -0
  50. package/src/pages/components/header.ts +72 -8
  51. package/src/pages/matter-dashboard-app.ts +123 -26
  52. package/src/util/theme-service.ts +98 -0
  53. package/dist/web/js/outlined-text-field-CtlEkpbk.js +0 -2086
@@ -0,0 +1,1122 @@
1
+ import { _ as __decorate, n as n$1, o as o$1, r, a as e, i as i$1, f as e$1, A, h as b, D, E as EASING, j as i$2, t, s as e$2, v as i$3, w as t$1, x as E, y as internals } from './matter-dashboard-app-DlHSE_Qh.js';
2
+
3
+ /**
4
+ * @license
5
+ * Copyright 2021 Google LLC
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
8
+ /**
9
+ * A field component.
10
+ */
11
+ class Field extends i$1 {
12
+ constructor() {
13
+ super(...arguments);
14
+ this.disabled = false;
15
+ this.error = false;
16
+ this.focused = false;
17
+ this.label = '';
18
+ this.noAsterisk = false;
19
+ this.populated = false;
20
+ this.required = false;
21
+ this.resizable = false;
22
+ this.supportingText = '';
23
+ this.errorText = '';
24
+ this.count = -1;
25
+ this.max = -1;
26
+ /**
27
+ * Whether or not the field has leading content.
28
+ */
29
+ this.hasStart = false;
30
+ /**
31
+ * Whether or not the field has trailing content.
32
+ */
33
+ this.hasEnd = false;
34
+ this.isAnimating = false;
35
+ /**
36
+ * When set to true, the error text's `role="alert"` will be removed, then
37
+ * re-added after an animation frame. This will re-announce an error message
38
+ * to screen readers.
39
+ */
40
+ this.refreshErrorAlert = false;
41
+ this.disableTransitions = false;
42
+ }
43
+ get counterText() {
44
+ // Count and max are typed as number, but can be set to null when Lit removes
45
+ // their attributes. These getters coerce back to a number for calculations.
46
+ const countAsNumber = this.count ?? -1;
47
+ const maxAsNumber = this.max ?? -1;
48
+ // Counter does not show if count is negative, or max is negative or 0.
49
+ if (countAsNumber < 0 || maxAsNumber <= 0) {
50
+ return '';
51
+ }
52
+ return `${countAsNumber} / ${maxAsNumber}`;
53
+ }
54
+ get supportingOrErrorText() {
55
+ return this.error && this.errorText ? this.errorText : this.supportingText;
56
+ }
57
+ /**
58
+ * Re-announces the field's error supporting text to screen readers.
59
+ *
60
+ * Error text announces to screen readers anytime it is visible and changes.
61
+ * Use the method to re-announce the message when the text has not changed,
62
+ * but announcement is still needed (such as for `reportValidity()`).
63
+ */
64
+ reannounceError() {
65
+ this.refreshErrorAlert = true;
66
+ }
67
+ update(props) {
68
+ // Client-side property updates
69
+ const isDisabledChanging = props.has('disabled') && props.get('disabled') !== undefined;
70
+ if (isDisabledChanging) {
71
+ this.disableTransitions = true;
72
+ }
73
+ // When disabling, remove focus styles if focused.
74
+ if (this.disabled && this.focused) {
75
+ props.set('focused', true);
76
+ this.focused = false;
77
+ }
78
+ // Animate if focused or populated change.
79
+ this.animateLabelIfNeeded({
80
+ wasFocused: props.get('focused'),
81
+ wasPopulated: props.get('populated')
82
+ });
83
+ super.update(props);
84
+ }
85
+ render() {
86
+ var _this$renderOutline, _this$renderBackgroun, _this$renderStateLaye, _this$renderIndicator;
87
+ const floatingLabel = this.renderLabel(/*isFloating*/true);
88
+ const restingLabel = this.renderLabel(/*isFloating*/false);
89
+ const outline = (_this$renderOutline = this.renderOutline) === null || _this$renderOutline === void 0 ? void 0 : _this$renderOutline.call(this, floatingLabel);
90
+ const classes = {
91
+ 'disabled': this.disabled,
92
+ 'disable-transitions': this.disableTransitions,
93
+ 'error': this.error && !this.disabled,
94
+ 'focused': this.focused,
95
+ 'with-start': this.hasStart,
96
+ 'with-end': this.hasEnd,
97
+ 'populated': this.populated,
98
+ 'resizable': this.resizable,
99
+ 'required': this.required,
100
+ 'no-label': !this.label
101
+ };
102
+ return b`
103
+ <div class="field ${e$1(classes)}">
104
+ <div class="container-overflow">
105
+ ${(_this$renderBackgroun = this.renderBackground) === null || _this$renderBackgroun === void 0 ? void 0 : _this$renderBackgroun.call(this)}
106
+ <slot name="container"></slot>
107
+ ${(_this$renderStateLaye = this.renderStateLayer) === null || _this$renderStateLaye === void 0 ? void 0 : _this$renderStateLaye.call(this)} ${(_this$renderIndicator = this.renderIndicator) === null || _this$renderIndicator === void 0 ? void 0 : _this$renderIndicator.call(this)} ${outline}
108
+ <div class="container">
109
+ <div class="start">
110
+ <slot name="start"></slot>
111
+ </div>
112
+ <div class="middle">
113
+ <div class="label-wrapper">
114
+ ${restingLabel} ${outline ? A : floatingLabel}
115
+ </div>
116
+ <div class="content">
117
+ <slot></slot>
118
+ </div>
119
+ </div>
120
+ <div class="end">
121
+ <slot name="end"></slot>
122
+ </div>
123
+ </div>
124
+ </div>
125
+ ${this.renderSupportingText()}
126
+ </div>
127
+ `;
128
+ }
129
+ updated(changed) {
130
+ if (changed.has('supportingText') || changed.has('errorText') || changed.has('count') || changed.has('max')) {
131
+ this.updateSlottedAriaDescribedBy();
132
+ }
133
+ if (this.refreshErrorAlert) {
134
+ // The past render cycle removed the role="alert" from the error message.
135
+ // Re-add it after an animation frame to re-announce the error.
136
+ requestAnimationFrame(() => {
137
+ this.refreshErrorAlert = false;
138
+ });
139
+ }
140
+ if (this.disableTransitions) {
141
+ requestAnimationFrame(() => {
142
+ this.disableTransitions = false;
143
+ });
144
+ }
145
+ }
146
+ renderSupportingText() {
147
+ const {
148
+ supportingOrErrorText,
149
+ counterText
150
+ } = this;
151
+ if (!supportingOrErrorText && !counterText) {
152
+ return A;
153
+ }
154
+ // Always render the supporting text span so that our `space-around`
155
+ // container puts the counter at the end.
156
+ const start = b`<span>${supportingOrErrorText}</span>`;
157
+ // Conditionally render counter so we don't render the extra `gap`.
158
+ // TODO(b/244473435): add aria-label and announcements
159
+ const end = counterText ? b`<span class="counter">${counterText}</span>` : A;
160
+ // Announce if there is an error and error text visible.
161
+ // If refreshErrorAlert is true, do not announce. This will remove the
162
+ // role="alert" attribute. Another render cycle will happen after an
163
+ // animation frame to re-add the role.
164
+ const shouldErrorAnnounce = this.error && this.errorText && !this.refreshErrorAlert;
165
+ const role = shouldErrorAnnounce ? 'alert' : A;
166
+ return b`
167
+ <div class="supporting-text" role=${role}>${start}${end}</div>
168
+ <slot
169
+ name="aria-describedby"
170
+ @slotchange=${this.updateSlottedAriaDescribedBy}></slot>
171
+ `;
172
+ }
173
+ updateSlottedAriaDescribedBy() {
174
+ for (const element of this.slottedAriaDescribedBy) {
175
+ D(b`${this.supportingOrErrorText} ${this.counterText}`, element);
176
+ element.setAttribute('hidden', '');
177
+ }
178
+ }
179
+ renderLabel(isFloating) {
180
+ if (!this.label) {
181
+ return A;
182
+ }
183
+ let visible;
184
+ if (isFloating) {
185
+ // Floating label is visible when focused/populated or when animating.
186
+ visible = this.focused || this.populated || this.isAnimating;
187
+ } else {
188
+ // Resting label is visible when unfocused. It is never visible while
189
+ // animating.
190
+ visible = !this.focused && !this.populated && !this.isAnimating;
191
+ }
192
+ const classes = {
193
+ 'hidden': !visible,
194
+ 'floating': isFloating,
195
+ 'resting': !isFloating
196
+ };
197
+ // Add '*' if a label is present and the field is required
198
+ const labelText = `${this.label}${this.required && !this.noAsterisk ? '*' : ''}`;
199
+ return b`
200
+ <span class="label ${e$1(classes)}" aria-hidden=${!visible}
201
+ >${labelText}</span
202
+ >
203
+ `;
204
+ }
205
+ animateLabelIfNeeded({
206
+ wasFocused,
207
+ wasPopulated
208
+ }) {
209
+ var _this$labelAnimation, _this$floatingLabelEl, _this$labelAnimation2;
210
+ if (!this.label) {
211
+ return;
212
+ }
213
+ wasFocused ?? (wasFocused = this.focused);
214
+ wasPopulated ?? (wasPopulated = this.populated);
215
+ const wasFloating = wasFocused || wasPopulated;
216
+ const shouldBeFloating = this.focused || this.populated;
217
+ if (wasFloating === shouldBeFloating) {
218
+ return;
219
+ }
220
+ this.isAnimating = true;
221
+ (_this$labelAnimation = this.labelAnimation) === null || _this$labelAnimation === void 0 || _this$labelAnimation.cancel();
222
+ // Only one label is visible at a time for clearer text rendering.
223
+ // The floating label is visible and used during animation. At the end of
224
+ // the animation, it will either remain visible (if floating) or hide and
225
+ // the resting label will be shown.
226
+ //
227
+ // We don't use forward filling because if the dimensions of the text field
228
+ // change (leading icon removed, density changes, etc), then the animation
229
+ // will be inaccurate.
230
+ //
231
+ // Re-calculating the animation each time will prevent any visual glitches
232
+ // from appearing.
233
+ // TODO(b/241113345): use animation tokens
234
+ this.labelAnimation = (_this$floatingLabelEl = this.floatingLabelEl) === null || _this$floatingLabelEl === void 0 ? void 0 : _this$floatingLabelEl.animate(this.getLabelKeyframes(), {
235
+ duration: 150,
236
+ easing: EASING.STANDARD
237
+ });
238
+ (_this$labelAnimation2 = this.labelAnimation) === null || _this$labelAnimation2 === void 0 || _this$labelAnimation2.addEventListener('finish', () => {
239
+ // At the end of the animation, update the visible label.
240
+ this.isAnimating = false;
241
+ });
242
+ }
243
+ getLabelKeyframes() {
244
+ const {
245
+ floatingLabelEl,
246
+ restingLabelEl
247
+ } = this;
248
+ if (!floatingLabelEl || !restingLabelEl) {
249
+ return [];
250
+ }
251
+ const {
252
+ x: floatingX,
253
+ y: floatingY,
254
+ height: floatingHeight
255
+ } = floatingLabelEl.getBoundingClientRect();
256
+ const {
257
+ x: restingX,
258
+ y: restingY,
259
+ height: restingHeight
260
+ } = restingLabelEl.getBoundingClientRect();
261
+ const floatingScrollWidth = floatingLabelEl.scrollWidth;
262
+ const restingScrollWidth = restingLabelEl.scrollWidth;
263
+ // Scale by width ratio instead of font size since letter-spacing will scale
264
+ // incorrectly. Using the width we can better approximate the adjusted
265
+ // scale and compensate for tracking and overflow.
266
+ // (use scrollWidth instead of width to account for clipped labels)
267
+ const scale = restingScrollWidth / floatingScrollWidth;
268
+ const xDelta = restingX - floatingX;
269
+ // The line-height of the resting and floating label are different. When
270
+ // we move the floating label down to the resting label's position, it won't
271
+ // exactly match because of this. We need to adjust by half of what the
272
+ // final scaled floating label's height will be.
273
+ const yDelta = restingY - floatingY + Math.round((restingHeight - floatingHeight * scale) / 2);
274
+ // Create the two transforms: floating to resting (using the calculations
275
+ // above), and resting to floating (re-setting the transform to initial
276
+ // values).
277
+ const restTransform = `translateX(${xDelta}px) translateY(${yDelta}px) scale(${scale})`;
278
+ const floatTransform = `translateX(0) translateY(0) scale(1)`;
279
+ // Constrain the floating labels width to a scaled percentage of the
280
+ // resting label's width. This will prevent long clipped labels from
281
+ // overflowing the container.
282
+ const restingClientWidth = restingLabelEl.clientWidth;
283
+ const isRestingClipped = restingScrollWidth > restingClientWidth;
284
+ const width = isRestingClipped ? `${restingClientWidth / scale}px` : '';
285
+ if (this.focused || this.populated) {
286
+ return [{
287
+ transform: restTransform,
288
+ width
289
+ }, {
290
+ transform: floatTransform,
291
+ width
292
+ }];
293
+ }
294
+ return [{
295
+ transform: floatTransform,
296
+ width
297
+ }, {
298
+ transform: restTransform,
299
+ width
300
+ }];
301
+ }
302
+ getSurfacePositionClientRect() {
303
+ return this.containerEl.getBoundingClientRect();
304
+ }
305
+ }
306
+ __decorate([n$1({
307
+ type: Boolean
308
+ })], Field.prototype, "disabled", void 0);
309
+ __decorate([n$1({
310
+ type: Boolean
311
+ })], Field.prototype, "error", void 0);
312
+ __decorate([n$1({
313
+ type: Boolean
314
+ })], Field.prototype, "focused", void 0);
315
+ __decorate([n$1()], Field.prototype, "label", void 0);
316
+ __decorate([n$1({
317
+ type: Boolean,
318
+ attribute: 'no-asterisk'
319
+ })], Field.prototype, "noAsterisk", void 0);
320
+ __decorate([n$1({
321
+ type: Boolean
322
+ })], Field.prototype, "populated", void 0);
323
+ __decorate([n$1({
324
+ type: Boolean
325
+ })], Field.prototype, "required", void 0);
326
+ __decorate([n$1({
327
+ type: Boolean
328
+ })], Field.prototype, "resizable", void 0);
329
+ __decorate([n$1({
330
+ attribute: 'supporting-text'
331
+ })], Field.prototype, "supportingText", void 0);
332
+ __decorate([n$1({
333
+ attribute: 'error-text'
334
+ })], Field.prototype, "errorText", void 0);
335
+ __decorate([n$1({
336
+ type: Number
337
+ })], Field.prototype, "count", void 0);
338
+ __decorate([n$1({
339
+ type: Number
340
+ })], Field.prototype, "max", void 0);
341
+ __decorate([n$1({
342
+ type: Boolean,
343
+ attribute: 'has-start'
344
+ })], Field.prototype, "hasStart", void 0);
345
+ __decorate([n$1({
346
+ type: Boolean,
347
+ attribute: 'has-end'
348
+ })], Field.prototype, "hasEnd", void 0);
349
+ __decorate([o$1({
350
+ slot: 'aria-describedby'
351
+ })], Field.prototype, "slottedAriaDescribedBy", void 0);
352
+ __decorate([r()], Field.prototype, "isAnimating", void 0);
353
+ __decorate([r()], Field.prototype, "refreshErrorAlert", void 0);
354
+ __decorate([r()], Field.prototype, "disableTransitions", void 0);
355
+ __decorate([e('.label.floating')], Field.prototype, "floatingLabelEl", void 0);
356
+ __decorate([e('.label.resting')], Field.prototype, "restingLabelEl", void 0);
357
+ __decorate([e('.container')], Field.prototype, "containerEl", void 0);
358
+
359
+ /**
360
+ * @license
361
+ * Copyright 2021 Google LLC
362
+ * SPDX-License-Identifier: Apache-2.0
363
+ */
364
+ /**
365
+ * An outlined field component.
366
+ */
367
+ class OutlinedField extends Field {
368
+ renderOutline(floatingLabel) {
369
+ return b`
370
+ <div class="outline">
371
+ <div class="outline-start"></div>
372
+ <div class="outline-notch">
373
+ <div class="outline-panel-inactive"></div>
374
+ <div class="outline-panel-active"></div>
375
+ <div class="outline-label">${floatingLabel}</div>
376
+ </div>
377
+ <div class="outline-end"></div>
378
+ </div>
379
+ `;
380
+ }
381
+ }
382
+
383
+ /**
384
+ * @license
385
+ * Copyright 2024 Google LLC
386
+ * SPDX-License-Identifier: Apache-2.0
387
+ */
388
+ // Generated stylesheet for ./field/internal/outlined-styles.css.
389
+ const styles$1 = i$2`@layer styles{:host{--_bottom-space: var(--md-outlined-field-bottom-space, 16px);--_content-color: var(--md-outlined-field-content-color, var(--md-sys-color-on-surface, #1d1b20));--_content-font: var(--md-outlined-field-content-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));--_content-line-height: var(--md-outlined-field-content-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));--_content-size: var(--md-outlined-field-content-size, var(--md-sys-typescale-body-large-size, 1rem));--_content-space: var(--md-outlined-field-content-space, 16px);--_content-weight: var(--md-outlined-field-content-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));--_disabled-content-color: var(--md-outlined-field-disabled-content-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-content-opacity: var(--md-outlined-field-disabled-content-opacity, 0.38);--_disabled-label-text-color: var(--md-outlined-field-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-outlined-field-disabled-label-text-opacity, 0.38);--_disabled-leading-content-color: var(--md-outlined-field-disabled-leading-content-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-leading-content-opacity: var(--md-outlined-field-disabled-leading-content-opacity, 0.38);--_disabled-outline-color: var(--md-outlined-field-disabled-outline-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-outline-opacity: var(--md-outlined-field-disabled-outline-opacity, 0.12);--_disabled-outline-width: var(--md-outlined-field-disabled-outline-width, 1px);--_disabled-supporting-text-color: var(--md-outlined-field-disabled-supporting-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-supporting-text-opacity: var(--md-outlined-field-disabled-supporting-text-opacity, 0.38);--_disabled-trailing-content-color: var(--md-outlined-field-disabled-trailing-content-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-trailing-content-opacity: var(--md-outlined-field-disabled-trailing-content-opacity, 0.38);--_error-content-color: var(--md-outlined-field-error-content-color, var(--md-sys-color-on-surface, #1d1b20));--_error-focus-content-color: var(--md-outlined-field-error-focus-content-color, var(--md-sys-color-on-surface, #1d1b20));--_error-focus-label-text-color: var(--md-outlined-field-error-focus-label-text-color, var(--md-sys-color-error, #b3261e));--_error-focus-leading-content-color: var(--md-outlined-field-error-focus-leading-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-focus-outline-color: var(--md-outlined-field-error-focus-outline-color, var(--md-sys-color-error, #b3261e));--_error-focus-supporting-text-color: var(--md-outlined-field-error-focus-supporting-text-color, var(--md-sys-color-error, #b3261e));--_error-focus-trailing-content-color: var(--md-outlined-field-error-focus-trailing-content-color, var(--md-sys-color-error, #b3261e));--_error-hover-content-color: var(--md-outlined-field-error-hover-content-color, var(--md-sys-color-on-surface, #1d1b20));--_error-hover-label-text-color: var(--md-outlined-field-error-hover-label-text-color, var(--md-sys-color-on-error-container, #410e0b));--_error-hover-leading-content-color: var(--md-outlined-field-error-hover-leading-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-hover-outline-color: var(--md-outlined-field-error-hover-outline-color, var(--md-sys-color-on-error-container, #410e0b));--_error-hover-supporting-text-color: var(--md-outlined-field-error-hover-supporting-text-color, var(--md-sys-color-error, #b3261e));--_error-hover-trailing-content-color: var(--md-outlined-field-error-hover-trailing-content-color, var(--md-sys-color-on-error-container, #410e0b));--_error-label-text-color: var(--md-outlined-field-error-label-text-color, var(--md-sys-color-error, #b3261e));--_error-leading-content-color: var(--md-outlined-field-error-leading-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_error-outline-color: var(--md-outlined-field-error-outline-color, var(--md-sys-color-error, #b3261e));--_error-supporting-text-color: var(--md-outlined-field-error-supporting-text-color, var(--md-sys-color-error, #b3261e));--_error-trailing-content-color: var(--md-outlined-field-error-trailing-content-color, var(--md-sys-color-error, #b3261e));--_focus-content-color: var(--md-outlined-field-focus-content-color, var(--md-sys-color-on-surface, #1d1b20));--_focus-label-text-color: var(--md-outlined-field-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_focus-leading-content-color: var(--md-outlined-field-focus-leading-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_focus-outline-color: var(--md-outlined-field-focus-outline-color, var(--md-sys-color-primary, #6750a4));--_focus-outline-width: var(--md-outlined-field-focus-outline-width, 3px);--_focus-supporting-text-color: var(--md-outlined-field-focus-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_focus-trailing-content-color: var(--md-outlined-field-focus-trailing-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-content-color: var(--md-outlined-field-hover-content-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-label-text-color: var(--md-outlined-field-hover-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-leading-content-color: var(--md-outlined-field-hover-leading-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-outline-color: var(--md-outlined-field-hover-outline-color, var(--md-sys-color-on-surface, #1d1b20));--_hover-outline-width: var(--md-outlined-field-hover-outline-width, 1px);--_hover-supporting-text-color: var(--md-outlined-field-hover-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_hover-trailing-content-color: var(--md-outlined-field-hover-trailing-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_label-text-color: var(--md-outlined-field-label-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_label-text-font: var(--md-outlined-field-label-text-font, var(--md-sys-typescale-body-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-outlined-field-label-text-line-height, var(--md-sys-typescale-body-large-line-height, 1.5rem));--_label-text-padding-bottom: var(--md-outlined-field-label-text-padding-bottom, 8px);--_label-text-populated-line-height: var(--md-outlined-field-label-text-populated-line-height, var(--md-sys-typescale-body-small-line-height, 1rem));--_label-text-populated-size: var(--md-outlined-field-label-text-populated-size, var(--md-sys-typescale-body-small-size, 0.75rem));--_label-text-size: var(--md-outlined-field-label-text-size, var(--md-sys-typescale-body-large-size, 1rem));--_label-text-weight: var(--md-outlined-field-label-text-weight, var(--md-sys-typescale-body-large-weight, var(--md-ref-typeface-weight-regular, 400)));--_leading-content-color: var(--md-outlined-field-leading-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_leading-space: var(--md-outlined-field-leading-space, 16px);--_outline-color: var(--md-outlined-field-outline-color, var(--md-sys-color-outline, #79747e));--_outline-label-padding: var(--md-outlined-field-outline-label-padding, 4px);--_outline-width: var(--md-outlined-field-outline-width, 1px);--_supporting-text-color: var(--md-outlined-field-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));--_supporting-text-font: var(--md-outlined-field-supporting-text-font, var(--md-sys-typescale-body-small-font, var(--md-ref-typeface-plain, Roboto)));--_supporting-text-leading-space: var(--md-outlined-field-supporting-text-leading-space, 16px);--_supporting-text-line-height: var(--md-outlined-field-supporting-text-line-height, var(--md-sys-typescale-body-small-line-height, 1rem));--_supporting-text-size: var(--md-outlined-field-supporting-text-size, var(--md-sys-typescale-body-small-size, 0.75rem));--_supporting-text-top-space: var(--md-outlined-field-supporting-text-top-space, 4px);--_supporting-text-trailing-space: var(--md-outlined-field-supporting-text-trailing-space, 16px);--_supporting-text-weight: var(--md-outlined-field-supporting-text-weight, var(--md-sys-typescale-body-small-weight, var(--md-ref-typeface-weight-regular, 400)));--_top-space: var(--md-outlined-field-top-space, 16px);--_trailing-content-color: var(--md-outlined-field-trailing-content-color, var(--md-sys-color-on-surface-variant, #49454f));--_trailing-space: var(--md-outlined-field-trailing-space, 16px);--_with-leading-content-leading-space: var(--md-outlined-field-with-leading-content-leading-space, 12px);--_with-trailing-content-trailing-space: var(--md-outlined-field-with-trailing-content-trailing-space, 12px);--_container-shape-start-start: var(--md-outlined-field-container-shape-start-start, var(--md-outlined-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_container-shape-start-end: var(--md-outlined-field-container-shape-start-end, var(--md-outlined-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_container-shape-end-end: var(--md-outlined-field-container-shape-end-end, var(--md-outlined-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)));--_container-shape-end-start: var(--md-outlined-field-container-shape-end-start, var(--md-outlined-field-container-shape, var(--md-sys-shape-corner-extra-small, 4px)))}.outline{border-color:var(--_outline-color);border-radius:inherit;display:flex;pointer-events:none;height:100%;position:absolute;width:100%;z-index:1}.outline-start::before,.outline-start::after,.outline-panel-inactive::before,.outline-panel-inactive::after,.outline-panel-active::before,.outline-panel-active::after,.outline-end::before,.outline-end::after{border:inherit;content:"";inset:0;position:absolute}.outline-start,.outline-end{border:inherit;border-radius:inherit;box-sizing:border-box;position:relative}.outline-start::before,.outline-start::after,.outline-end::before,.outline-end::after{border-bottom-style:solid;border-top-style:solid}.outline-start::after,.outline-end::after{opacity:0;transition:opacity 150ms cubic-bezier(0.2, 0, 0, 1)}.focused .outline-start::after,.focused .outline-end::after{opacity:1}.outline-start::before,.outline-start::after{border-inline-start-style:solid;border-inline-end-style:none;border-start-start-radius:inherit;border-start-end-radius:0;border-end-start-radius:inherit;border-end-end-radius:0;margin-inline-end:var(--_outline-label-padding)}.outline-end{flex-grow:1;margin-inline-start:calc(-1*var(--_outline-label-padding))}.outline-end::before,.outline-end::after{border-inline-start-style:none;border-inline-end-style:solid;border-start-start-radius:0;border-start-end-radius:inherit;border-end-start-radius:0;border-end-end-radius:inherit}.outline-notch{align-items:flex-start;border:inherit;display:flex;margin-inline-start:calc(-1*var(--_outline-label-padding));margin-inline-end:var(--_outline-label-padding);max-width:calc(100% - var(--_leading-space) - var(--_trailing-space));padding:0 var(--_outline-label-padding);position:relative}.no-label .outline-notch{display:none}.outline-panel-inactive,.outline-panel-active{border:inherit;border-bottom-style:solid;inset:0;position:absolute}.outline-panel-inactive::before,.outline-panel-inactive::after,.outline-panel-active::before,.outline-panel-active::after{border-top-style:solid;border-bottom:none;bottom:auto;transform:scaleX(1);transition:transform 150ms cubic-bezier(0.2, 0, 0, 1)}.outline-panel-inactive::before,.outline-panel-active::before{right:50%;transform-origin:top left}.outline-panel-inactive::after,.outline-panel-active::after{left:50%;transform-origin:top right}.populated .outline-panel-inactive::before,.populated .outline-panel-inactive::after,.populated .outline-panel-active::before,.populated .outline-panel-active::after,.focused .outline-panel-inactive::before,.focused .outline-panel-inactive::after,.focused .outline-panel-active::before,.focused .outline-panel-active::after{transform:scaleX(0)}.outline-panel-active{opacity:0;transition:opacity 150ms cubic-bezier(0.2, 0, 0, 1)}.focused .outline-panel-active{opacity:1}.outline-label{display:flex;max-width:100%;transform:translateY(calc(-100% + var(--_label-text-padding-bottom)))}.outline-start,.field:not(.with-start) .content ::slotted(*){padding-inline-start:max(var(--_leading-space),max(var(--_container-shape-start-start),var(--_container-shape-end-start)) + var(--_outline-label-padding))}.field:not(.with-start) .label-wrapper{margin-inline-start:max(var(--_leading-space),max(var(--_container-shape-start-start),var(--_container-shape-end-start)) + var(--_outline-label-padding))}.field:not(.with-end) .content ::slotted(*){padding-inline-end:max(var(--_trailing-space),max(var(--_container-shape-start-end),var(--_container-shape-end-end)))}.field:not(.with-end) .label-wrapper{margin-inline-end:max(var(--_trailing-space),max(var(--_container-shape-start-end),var(--_container-shape-end-end)))}.outline-start::before,.outline-end::before,.outline-panel-inactive,.outline-panel-inactive::before,.outline-panel-inactive::after{border-width:var(--_outline-width)}:hover .outline{border-color:var(--_hover-outline-color);color:var(--_hover-outline-color)}:hover .outline-start::before,:hover .outline-end::before,:hover .outline-panel-inactive,:hover .outline-panel-inactive::before,:hover .outline-panel-inactive::after{border-width:var(--_hover-outline-width)}.focused .outline{border-color:var(--_focus-outline-color);color:var(--_focus-outline-color)}.outline-start::after,.outline-end::after,.outline-panel-active,.outline-panel-active::before,.outline-panel-active::after{border-width:var(--_focus-outline-width)}.disabled .outline{border-color:var(--_disabled-outline-color);color:var(--_disabled-outline-color)}.disabled .outline-start,.disabled .outline-end,.disabled .outline-panel-inactive{opacity:var(--_disabled-outline-opacity)}.disabled .outline-start::before,.disabled .outline-end::before,.disabled .outline-panel-inactive,.disabled .outline-panel-inactive::before,.disabled .outline-panel-inactive::after{border-width:var(--_disabled-outline-width)}.error .outline{border-color:var(--_error-outline-color);color:var(--_error-outline-color)}.error:hover .outline{border-color:var(--_error-hover-outline-color);color:var(--_error-hover-outline-color)}.error.focused .outline{border-color:var(--_error-focus-outline-color);color:var(--_error-focus-outline-color)}.resizable .container{bottom:var(--_focus-outline-width);inset-inline-end:var(--_focus-outline-width);clip-path:inset(var(--_focus-outline-width) 0 0 var(--_focus-outline-width))}.resizable .container>*{top:var(--_focus-outline-width);inset-inline-start:var(--_focus-outline-width)}.resizable .container:dir(rtl){clip-path:inset(var(--_focus-outline-width) var(--_focus-outline-width) 0 0)}}@layer hcm{@media(forced-colors: active){.disabled .outline{border-color:GrayText;color:GrayText}.disabled :is(.outline-start,.outline-end,.outline-panel-inactive){opacity:1}}}
390
+ `;
391
+
392
+ /**
393
+ * @license
394
+ * Copyright 2024 Google LLC
395
+ * SPDX-License-Identifier: Apache-2.0
396
+ */
397
+ // Generated stylesheet for ./field/internal/shared-styles.css.
398
+ const styles = i$2`:host{display:inline-flex;resize:both}.field{display:flex;flex:1;flex-direction:column;writing-mode:horizontal-tb;max-width:100%}.container-overflow{border-start-start-radius:var(--_container-shape-start-start);border-start-end-radius:var(--_container-shape-start-end);border-end-end-radius:var(--_container-shape-end-end);border-end-start-radius:var(--_container-shape-end-start);display:flex;height:100%;position:relative}.container{align-items:center;border-radius:inherit;display:flex;flex:1;max-height:100%;min-height:100%;min-width:min-content;position:relative}.field,.container-overflow{resize:inherit}.resizable:not(.disabled) .container{resize:inherit;overflow:hidden}.disabled{pointer-events:none}slot[name=container]{border-radius:inherit}slot[name=container]::slotted(*){border-radius:inherit;inset:0;pointer-events:none;position:absolute}@layer styles{.start,.middle,.end{display:flex;box-sizing:border-box;height:100%;position:relative}.start{color:var(--_leading-content-color)}.end{color:var(--_trailing-content-color)}.start,.end{align-items:center;justify-content:center}.with-start .start{margin-inline:var(--_with-leading-content-leading-space) var(--_content-space)}.with-end .end{margin-inline:var(--_content-space) var(--_with-trailing-content-trailing-space)}.middle{align-items:stretch;align-self:baseline;flex:1}.content{color:var(--_content-color);display:flex;flex:1;opacity:0;transition:opacity 83ms cubic-bezier(0.2, 0, 0, 1)}.no-label .content,.focused .content,.populated .content{opacity:1;transition-delay:67ms}:is(.disabled,.disable-transitions) .content{transition:none}.content ::slotted(*){all:unset;color:currentColor;font-family:var(--_content-font);font-size:var(--_content-size);line-height:var(--_content-line-height);font-weight:var(--_content-weight);width:100%;overflow-wrap:revert;white-space:revert}.content ::slotted(:not(textarea)){padding-top:var(--_top-space);padding-bottom:var(--_bottom-space)}.content ::slotted(textarea){margin-top:var(--_top-space);margin-bottom:var(--_bottom-space)}:hover .content{color:var(--_hover-content-color)}:hover .start{color:var(--_hover-leading-content-color)}:hover .end{color:var(--_hover-trailing-content-color)}.focused .content{color:var(--_focus-content-color)}.focused .start{color:var(--_focus-leading-content-color)}.focused .end{color:var(--_focus-trailing-content-color)}.disabled .content{color:var(--_disabled-content-color)}.disabled.no-label .content,.disabled.focused .content,.disabled.populated .content{opacity:var(--_disabled-content-opacity)}.disabled .start{color:var(--_disabled-leading-content-color);opacity:var(--_disabled-leading-content-opacity)}.disabled .end{color:var(--_disabled-trailing-content-color);opacity:var(--_disabled-trailing-content-opacity)}.error .content{color:var(--_error-content-color)}.error .start{color:var(--_error-leading-content-color)}.error .end{color:var(--_error-trailing-content-color)}.error:hover .content{color:var(--_error-hover-content-color)}.error:hover .start{color:var(--_error-hover-leading-content-color)}.error:hover .end{color:var(--_error-hover-trailing-content-color)}.error.focused .content{color:var(--_error-focus-content-color)}.error.focused .start{color:var(--_error-focus-leading-content-color)}.error.focused .end{color:var(--_error-focus-trailing-content-color)}}@layer hcm{@media(forced-colors: active){.disabled :is(.start,.content,.end){color:GrayText;opacity:1}}}@layer styles{.label{box-sizing:border-box;color:var(--_label-text-color);overflow:hidden;max-width:100%;text-overflow:ellipsis;white-space:nowrap;z-index:1;font-family:var(--_label-text-font);font-size:var(--_label-text-size);line-height:var(--_label-text-line-height);font-weight:var(--_label-text-weight);width:min-content}.label-wrapper{inset:0;pointer-events:none;position:absolute}.label.resting{position:absolute;top:var(--_top-space)}.label.floating{font-size:var(--_label-text-populated-size);line-height:var(--_label-text-populated-line-height);transform-origin:top left}.label.hidden{opacity:0}.no-label .label{display:none}.label-wrapper{inset:0;position:absolute;text-align:initial}:hover .label{color:var(--_hover-label-text-color)}.focused .label{color:var(--_focus-label-text-color)}.disabled .label{color:var(--_disabled-label-text-color)}.disabled .label:not(.hidden){opacity:var(--_disabled-label-text-opacity)}.error .label{color:var(--_error-label-text-color)}.error:hover .label{color:var(--_error-hover-label-text-color)}.error.focused .label{color:var(--_error-focus-label-text-color)}}@layer hcm{@media(forced-colors: active){.disabled .label:not(.hidden){color:GrayText;opacity:1}}}@layer styles{.supporting-text{color:var(--_supporting-text-color);display:flex;font-family:var(--_supporting-text-font);font-size:var(--_supporting-text-size);line-height:var(--_supporting-text-line-height);font-weight:var(--_supporting-text-weight);gap:16px;justify-content:space-between;padding-inline-start:var(--_supporting-text-leading-space);padding-inline-end:var(--_supporting-text-trailing-space);padding-top:var(--_supporting-text-top-space)}.supporting-text :nth-child(2){flex-shrink:0}:hover .supporting-text{color:var(--_hover-supporting-text-color)}.focus .supporting-text{color:var(--_focus-supporting-text-color)}.disabled .supporting-text{color:var(--_disabled-supporting-text-color);opacity:var(--_disabled-supporting-text-opacity)}.error .supporting-text{color:var(--_error-supporting-text-color)}.error:hover .supporting-text{color:var(--_error-hover-supporting-text-color)}.error.focus .supporting-text{color:var(--_error-focus-supporting-text-color)}}@layer hcm{@media(forced-colors: active){.disabled .supporting-text{color:GrayText;opacity:1}}}
399
+ `;
400
+
401
+ /**
402
+ * @license
403
+ * Copyright 2021 Google LLC
404
+ * SPDX-License-Identifier: Apache-2.0
405
+ */
406
+ /**
407
+ * TODO(b/228525797): add docs
408
+ * @final
409
+ * @suppress {visibility}
410
+ */
411
+ let MdOutlinedField = class MdOutlinedField extends OutlinedField {};
412
+ MdOutlinedField.styles = [styles, styles$1];
413
+ MdOutlinedField = __decorate([t('md-outlined-field')], MdOutlinedField);
414
+
415
+ /**
416
+ * @license
417
+ * Copyright 2018 Google LLC
418
+ * SPDX-License-Identifier: BSD-3-Clause
419
+ */
420
+ const n = "important",
421
+ i = " !" + n,
422
+ o = e$2(class extends i$3 {
423
+ constructor(t) {
424
+ var _t$strings;
425
+ if (super(t), t.type !== t$1.ATTRIBUTE || "style" !== t.name || ((_t$strings = t.strings) === null || _t$strings === void 0 ? void 0 : _t$strings.length) > 2) throw Error("The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.");
426
+ }
427
+ render(t) {
428
+ return Object.keys(t).reduce((e, r) => {
429
+ const s = t[r];
430
+ return null == s ? e : e + `${r = r.includes("-") ? r : r.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g, "-$&").toLowerCase()}:${s};`;
431
+ }, "");
432
+ }
433
+ update(e, [r]) {
434
+ const {
435
+ style: s
436
+ } = e.element;
437
+ if (void 0 === this.ft) return this.ft = new Set(Object.keys(r)), this.render(r);
438
+ for (const t of this.ft) null == r[t] && (this.ft.delete(t), t.includes("-") ? s.removeProperty(t) : s[t] = null);
439
+ for (const t in r) {
440
+ const e = r[t];
441
+ if (null != e) {
442
+ this.ft.add(t);
443
+ const r = "string" == typeof e && e.endsWith(i);
444
+ t.includes("-") || r ? s.setProperty(t, r ? e.slice(0, -11) : e, r ? n : "") : s[t] = e;
445
+ }
446
+ }
447
+ return E;
448
+ }
449
+ });
450
+
451
+ /**
452
+ * @license
453
+ * Copyright 2023 Google LLC
454
+ * SPDX-License-Identifier: Apache-2.0
455
+ */
456
+ /**
457
+ * A symbol property used to create a constraint validation `Validator`.
458
+ * Required for all `mixinConstraintValidation()` elements.
459
+ */
460
+ const createValidator = Symbol('createValidator');
461
+ /**
462
+ * A symbol property used to return an anchor for constraint validation popups.
463
+ * Required for all `mixinConstraintValidation()` elements.
464
+ */
465
+ const getValidityAnchor = Symbol('getValidityAnchor');
466
+ // Private symbol members, used to avoid name clashing.
467
+ const privateValidator = Symbol('privateValidator');
468
+ const privateSyncValidity = Symbol('privateSyncValidity');
469
+ const privateCustomValidationMessage = Symbol('privateCustomValidationMessage');
470
+ /**
471
+ * Mixes in constraint validation APIs for an element.
472
+ *
473
+ * See https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation
474
+ * for more details.
475
+ *
476
+ * Implementations must provide a validator to cache and compute its validity,
477
+ * along with a shadow root element to anchor validation popups to.
478
+ *
479
+ * @example
480
+ * ```ts
481
+ * const baseClass = mixinConstraintValidation(
482
+ * mixinFormAssociated(mixinElementInternals(LitElement))
483
+ * );
484
+ *
485
+ * class MyCheckbox extends baseClass {
486
+ * \@property({type: Boolean}) checked = false;
487
+ * \@property({type: Boolean}) required = false;
488
+ *
489
+ * [createValidator]() {
490
+ * return new CheckboxValidator(() => this);
491
+ * }
492
+ *
493
+ * [getValidityAnchor]() {
494
+ * return this.renderRoot.querySelector('.root');
495
+ * }
496
+ * }
497
+ * ```
498
+ *
499
+ * @param base The class to mix functionality into.
500
+ * @return The provided class with `ConstraintValidation` mixed in.
501
+ */
502
+ function mixinConstraintValidation(base) {
503
+ var _a;
504
+ class ConstraintValidationElement extends base {
505
+ constructor() {
506
+ super(...arguments);
507
+ /**
508
+ * Needed for Safari, see https://bugs.webkit.org/show_bug.cgi?id=261432
509
+ * Replace with this[internals].validity.customError when resolved.
510
+ */
511
+ this[_a] = '';
512
+ }
513
+ get validity() {
514
+ this[privateSyncValidity]();
515
+ return this[internals].validity;
516
+ }
517
+ get validationMessage() {
518
+ this[privateSyncValidity]();
519
+ return this[internals].validationMessage;
520
+ }
521
+ get willValidate() {
522
+ this[privateSyncValidity]();
523
+ return this[internals].willValidate;
524
+ }
525
+ checkValidity() {
526
+ this[privateSyncValidity]();
527
+ return this[internals].checkValidity();
528
+ }
529
+ reportValidity() {
530
+ this[privateSyncValidity]();
531
+ return this[internals].reportValidity();
532
+ }
533
+ setCustomValidity(error) {
534
+ this[privateCustomValidationMessage] = error;
535
+ this[privateSyncValidity]();
536
+ }
537
+ requestUpdate(name, oldValue, options) {
538
+ super.requestUpdate(name, oldValue, options);
539
+ this[privateSyncValidity]();
540
+ }
541
+ firstUpdated(changed) {
542
+ super.firstUpdated(changed);
543
+ // Sync the validity again when the element first renders, since the
544
+ // validity anchor is now available.
545
+ //
546
+ // Elements that `delegatesFocus: true` to an `<input>` will throw an
547
+ // error in Chrome and Safari when a form tries to submit or call
548
+ // `form.reportValidity()`:
549
+ // "An invalid form control with name='' is not focusable"
550
+ //
551
+ // The validity anchor MUST be provided in `internals.setValidity()` and
552
+ // MUST be the `<input>` element rendered.
553
+ //
554
+ // See https://lit.dev/playground/#gist=6c26e418e0010f7a5aac15005cde8bde
555
+ // for a reproduction.
556
+ this[privateSyncValidity]();
557
+ }
558
+ [(_a = privateCustomValidationMessage, privateSyncValidity)]() {
559
+ if (!this[privateValidator]) {
560
+ this[privateValidator] = this[createValidator]();
561
+ }
562
+ const {
563
+ validity,
564
+ validationMessage: nonCustomValidationMessage
565
+ } = this[privateValidator].getValidity();
566
+ const customError = !!this[privateCustomValidationMessage];
567
+ const validationMessage = this[privateCustomValidationMessage] || nonCustomValidationMessage;
568
+ this[internals].setValidity({
569
+ ...validity,
570
+ customError
571
+ }, validationMessage, this[getValidityAnchor]() ?? undefined);
572
+ }
573
+ [createValidator]() {
574
+ throw new Error('Implement [createValidator]');
575
+ }
576
+ [getValidityAnchor]() {
577
+ throw new Error('Implement [getValidityAnchor]');
578
+ }
579
+ }
580
+ return ConstraintValidationElement;
581
+ }
582
+
583
+ /**
584
+ * @license
585
+ * Copyright 2023 Google LLC
586
+ * SPDX-License-Identifier: Apache-2.0
587
+ */
588
+ /**
589
+ * A symbol property to retrieve the form value for an element.
590
+ */
591
+ const getFormValue = Symbol('getFormValue');
592
+ /**
593
+ * A symbol property to retrieve the form state for an element.
594
+ */
595
+ const getFormState = Symbol('getFormState');
596
+ /**
597
+ * Mixes in form-associated behavior for a class. This allows an element to add
598
+ * values to `<form>` elements.
599
+ *
600
+ * Implementing classes should provide a `[formValue]` to return the current
601
+ * value of the element, as well as reset and restore callbacks.
602
+ *
603
+ * @example
604
+ * ```ts
605
+ * const base = mixinFormAssociated(mixinElementInternals(LitElement));
606
+ *
607
+ * class MyControl extends base {
608
+ * \@property()
609
+ * value = '';
610
+ *
611
+ * override [getFormValue]() {
612
+ * return this.value;
613
+ * }
614
+ *
615
+ * override formResetCallback() {
616
+ * const defaultValue = this.getAttribute('value');
617
+ * this.value = defaultValue;
618
+ * }
619
+ *
620
+ * override formStateRestoreCallback(state: string) {
621
+ * this.value = state;
622
+ * }
623
+ * }
624
+ * ```
625
+ *
626
+ * Elements may optionally provide a `[formState]` if their values do not
627
+ * represent the state of the component.
628
+ *
629
+ * @example
630
+ * ```ts
631
+ * const base = mixinFormAssociated(mixinElementInternals(LitElement));
632
+ *
633
+ * class MyCheckbox extends base {
634
+ * \@property()
635
+ * value = 'on';
636
+ *
637
+ * \@property({type: Boolean})
638
+ * checked = false;
639
+ *
640
+ * override [getFormValue]() {
641
+ * return this.checked ? this.value : null;
642
+ * }
643
+ *
644
+ * override [getFormState]() {
645
+ * return String(this.checked);
646
+ * }
647
+ *
648
+ * override formResetCallback() {
649
+ * const defaultValue = this.hasAttribute('checked');
650
+ * this.checked = defaultValue;
651
+ * }
652
+ *
653
+ * override formStateRestoreCallback(state: string) {
654
+ * this.checked = Boolean(state);
655
+ * }
656
+ * }
657
+ * ```
658
+ *
659
+ * IMPORTANT: Requires declares for lit-analyzer
660
+ * @example
661
+ * ```ts
662
+ * const base = mixinFormAssociated(mixinElementInternals(LitElement));
663
+ * class MyControl extends base {
664
+ * // Writable mixin properties for lit-html binding, needed for lit-analyzer
665
+ * declare disabled: boolean;
666
+ * declare name: string;
667
+ * }
668
+ * ```
669
+ *
670
+ * @param base The class to mix functionality into. The base class must use
671
+ * `mixinElementInternals()`.
672
+ * @return The provided class with `FormAssociated` mixed in.
673
+ */
674
+ function mixinFormAssociated(base) {
675
+ class FormAssociatedElement extends base {
676
+ get form() {
677
+ return this[internals].form;
678
+ }
679
+ get labels() {
680
+ return this[internals].labels;
681
+ }
682
+ // Use @property for the `name` and `disabled` properties to add them to the
683
+ // `observedAttributes` array and trigger `attributeChangedCallback()`.
684
+ //
685
+ // We don't use Lit's default getter/setter (`noAccessor: true`) because
686
+ // the attributes need to be updated synchronously to work with synchronous
687
+ // form APIs, and Lit updates attributes async by default.
688
+ get name() {
689
+ return this.getAttribute('name') ?? '';
690
+ }
691
+ set name(name) {
692
+ // Note: setting name to null or empty does not remove the attribute.
693
+ this.setAttribute('name', name);
694
+ // We don't need to call `requestUpdate()` since it's called synchronously
695
+ // in `attributeChangedCallback()`.
696
+ }
697
+ get disabled() {
698
+ return this.hasAttribute('disabled');
699
+ }
700
+ set disabled(disabled) {
701
+ this.toggleAttribute('disabled', disabled);
702
+ // We don't need to call `requestUpdate()` since it's called synchronously
703
+ // in `attributeChangedCallback()`.
704
+ }
705
+ attributeChangedCallback(name, old, value) {
706
+ // Manually `requestUpdate()` for `name` and `disabled` when their
707
+ // attribute or property changes.
708
+ // The properties update their attributes, so this callback is invoked
709
+ // immediately when the properties are set. We call `requestUpdate()` here
710
+ // instead of letting Lit set the properties from the attribute change.
711
+ // That would cause the properties to re-set the attribute and invoke this
712
+ // callback again in a loop. This leads to stale state when Lit tries to
713
+ // determine if a property changed or not.
714
+ if (name === 'name' || name === 'disabled') {
715
+ // Disabled's value is only false if the attribute is missing and null.
716
+ const oldValue = name === 'disabled' ? old !== null : old;
717
+ // Trigger a lit update when the attribute changes.
718
+ this.requestUpdate(name, oldValue);
719
+ return;
720
+ }
721
+ super.attributeChangedCallback(name, old, value);
722
+ }
723
+ requestUpdate(name, oldValue, options) {
724
+ super.requestUpdate(name, oldValue, options);
725
+ // If any properties change, update the form value, which may have changed
726
+ // as well.
727
+ // Update the form value synchronously in `requestUpdate()` rather than
728
+ // `update()` or `updated()`, which are async. This is necessary to ensure
729
+ // that form data is updated in time for synchronous event listeners.
730
+ this[internals].setFormValue(this[getFormValue](), this[getFormState]());
731
+ }
732
+ [getFormValue]() {
733
+ // Closure does not allow abstract symbol members, so a default
734
+ // implementation is needed.
735
+ throw new Error('Implement [getFormValue]');
736
+ }
737
+ [getFormState]() {
738
+ return this[getFormValue]();
739
+ }
740
+ formDisabledCallback(disabled) {
741
+ this.disabled = disabled;
742
+ }
743
+ }
744
+ /** @nocollapse */
745
+ FormAssociatedElement.formAssociated = true;
746
+ __decorate([n$1({
747
+ noAccessor: true
748
+ })], FormAssociatedElement.prototype, "name", null);
749
+ __decorate([n$1({
750
+ type: Boolean,
751
+ noAccessor: true
752
+ })], FormAssociatedElement.prototype, "disabled", null);
753
+ return FormAssociatedElement;
754
+ }
755
+
756
+ /**
757
+ * @license
758
+ * Copyright 2023 Google LLC
759
+ * SPDX-License-Identifier: Apache-2.0
760
+ */
761
+ /**
762
+ * A symbol property used for a callback when validity has been reported.
763
+ */
764
+ const onReportValidity = Symbol('onReportValidity');
765
+ // Private symbol members, used to avoid name clashing.
766
+ const privateCleanupFormListeners = Symbol('privateCleanupFormListeners');
767
+ const privateDoNotReportInvalid = Symbol('privateDoNotReportInvalid');
768
+ const privateIsSelfReportingValidity = Symbol('privateIsSelfReportingValidity');
769
+ const privateCallOnReportValidity = Symbol('privateCallOnReportValidity');
770
+ /**
771
+ * Mixes in a callback for constraint validation when validity should be
772
+ * styled and reported to the user.
773
+ *
774
+ * This is commonly used in text-field-like controls that display error styles
775
+ * and error messages.
776
+ *
777
+ * @example
778
+ * ```ts
779
+ * const baseClass = mixinOnReportValidity(
780
+ * mixinConstraintValidation(
781
+ * mixinFormAssociated(mixinElementInternals(LitElement)),
782
+ * ),
783
+ * );
784
+ *
785
+ * class MyField extends baseClass {
786
+ * \@property({type: Boolean}) error = false;
787
+ * \@property() errorMessage = '';
788
+ *
789
+ * [onReportValidity](invalidEvent: Event | null) {
790
+ * this.error = !!invalidEvent;
791
+ * this.errorMessage = this.validationMessage;
792
+ *
793
+ * // Optionally prevent platform popup from displaying
794
+ * invalidEvent?.preventDefault();
795
+ * }
796
+ * }
797
+ * ```
798
+ *
799
+ * @param base The class to mix functionality into.
800
+ * @return The provided class with `OnReportValidity` mixed in.
801
+ */
802
+ function mixinOnReportValidity(base) {
803
+ var _a, _b, _c;
804
+ class OnReportValidityElement extends base {
805
+ // Mixins must have a constructor with `...args: any[]`
806
+ // tslint:disable-next-line:no-any
807
+ constructor(...args) {
808
+ super(...args);
809
+ /**
810
+ * Used to clean up event listeners when a new form is associated.
811
+ */
812
+ this[_a] = new AbortController();
813
+ /**
814
+ * Used to determine if an invalid event should report validity. Invalid
815
+ * events from `checkValidity()` do not trigger reporting.
816
+ */
817
+ this[_b] = false;
818
+ /**
819
+ * Used to determine if the control is reporting validity from itself, or
820
+ * if a `<form>` is causing the validity report. Forms have different
821
+ * control focusing behavior.
822
+ */
823
+ this[_c] = false;
824
+ this.addEventListener('invalid', invalidEvent => {
825
+ // Listen for invalid events dispatched by a `<form>` when it tries to
826
+ // submit and the element is invalid. We ignore events dispatched when
827
+ // calling `checkValidity()` as well as untrusted events, since the
828
+ // `reportValidity()` and `<form>`-dispatched events are always
829
+ // trusted.
830
+ if (this[privateDoNotReportInvalid] || !invalidEvent.isTrusted) {
831
+ return;
832
+ }
833
+ this.addEventListener('invalid', () => {
834
+ // A normal bubbling phase event listener. By adding it here, we
835
+ // ensure it's the last event listener that is called during the
836
+ // bubbling phase.
837
+ this[privateCallOnReportValidity](invalidEvent);
838
+ }, {
839
+ once: true
840
+ });
841
+ }, {
842
+ // Listen during the capture phase, which will happen before the
843
+ // bubbling phase. That way, we can add a final event listener that
844
+ // will run after other event listeners, and we can check if it was
845
+ // default prevented. This works because invalid does not bubble.
846
+ capture: true
847
+ });
848
+ }
849
+ checkValidity() {
850
+ this[privateDoNotReportInvalid] = true;
851
+ const valid = super.checkValidity();
852
+ this[privateDoNotReportInvalid] = false;
853
+ return valid;
854
+ }
855
+ reportValidity() {
856
+ this[privateIsSelfReportingValidity] = true;
857
+ const valid = super.reportValidity();
858
+ // Constructor's invalid listener will handle reporting invalid events.
859
+ if (valid) {
860
+ this[privateCallOnReportValidity](null);
861
+ }
862
+ this[privateIsSelfReportingValidity] = false;
863
+ return valid;
864
+ }
865
+ [(_a = privateCleanupFormListeners, _b = privateDoNotReportInvalid, _c = privateIsSelfReportingValidity, privateCallOnReportValidity)](invalidEvent) {
866
+ // Since invalid events do not bubble to parent listeners, and because
867
+ // our invalid listeners are added lazily after other listeners, we can
868
+ // reliably read `defaultPrevented` synchronously without worrying
869
+ // about waiting for another listener that could cancel it.
870
+ const wasCanceled = invalidEvent === null || invalidEvent === void 0 ? void 0 : invalidEvent.defaultPrevented;
871
+ if (wasCanceled) {
872
+ return;
873
+ }
874
+ this[onReportValidity](invalidEvent);
875
+ // If an implementation calls invalidEvent.preventDefault() to stop the
876
+ // platform popup from displaying, focusing is also prevented, so we need
877
+ // to manually focus.
878
+ const implementationCanceledFocus = !wasCanceled && (invalidEvent === null || invalidEvent === void 0 ? void 0 : invalidEvent.defaultPrevented);
879
+ if (!implementationCanceledFocus) {
880
+ return;
881
+ }
882
+ // The control should be focused when:
883
+ // - `control.reportValidity()` is called (self-reporting).
884
+ // - a form is reporting validity for its controls and this is the first
885
+ // invalid control.
886
+ if (this[privateIsSelfReportingValidity] || isFirstInvalidControlInForm(this[internals].form, this)) {
887
+ this.focus();
888
+ }
889
+ }
890
+ [onReportValidity](invalidEvent) {
891
+ throw new Error('Implement [onReportValidity]');
892
+ }
893
+ formAssociatedCallback(form) {
894
+ // can't use super.formAssociatedCallback?.() due to closure
895
+ if (super.formAssociatedCallback) {
896
+ super.formAssociatedCallback(form);
897
+ }
898
+ // Clean up previous form listeners.
899
+ this[privateCleanupFormListeners].abort();
900
+ if (!form) {
901
+ return;
902
+ }
903
+ this[privateCleanupFormListeners] = new AbortController();
904
+ // Add a listener that fires when the form runs constraint validation and
905
+ // the control is valid, so that it may remove its error styles.
906
+ //
907
+ // This happens on `form.reportValidity()` and `form.requestSubmit()`
908
+ // (both when the submit fails and passes).
909
+ addFormReportValidListener(this, form, () => {
910
+ this[privateCallOnReportValidity](null);
911
+ }, this[privateCleanupFormListeners].signal);
912
+ }
913
+ }
914
+ return OnReportValidityElement;
915
+ }
916
+ /**
917
+ * Add a listener that fires when a form runs constraint validation on a control
918
+ * and it is valid. This is needed to clear previously invalid styles.
919
+ *
920
+ * @param control The control of the form to listen for valid events.
921
+ * @param form The control's form that can run constraint validation.
922
+ * @param onControlValid A listener that is called when the form runs constraint
923
+ * validation and the control is valid.
924
+ * @param cleanup A cleanup signal to remove the listener.
925
+ */
926
+ function addFormReportValidListener(control, form, onControlValid, cleanup) {
927
+ const validateHooks = getFormValidateHooks(form);
928
+ // When a form validates its controls, check if an invalid event is dispatched
929
+ // on the control. If it is not, then inform the control to report its valid
930
+ // state.
931
+ let controlFiredInvalid = false;
932
+ let cleanupInvalidListener;
933
+ let isNextSubmitFromHook = false;
934
+ validateHooks.addEventListener('before', () => {
935
+ isNextSubmitFromHook = true;
936
+ cleanupInvalidListener = new AbortController();
937
+ controlFiredInvalid = false;
938
+ control.addEventListener('invalid', () => {
939
+ controlFiredInvalid = true;
940
+ }, {
941
+ signal: cleanupInvalidListener.signal
942
+ });
943
+ }, {
944
+ signal: cleanup
945
+ });
946
+ validateHooks.addEventListener('after', () => {
947
+ var _cleanupInvalidListen;
948
+ isNextSubmitFromHook = false;
949
+ (_cleanupInvalidListen = cleanupInvalidListener) === null || _cleanupInvalidListen === void 0 || _cleanupInvalidListen.abort();
950
+ if (controlFiredInvalid) {
951
+ return;
952
+ }
953
+ onControlValid();
954
+ }, {
955
+ signal: cleanup
956
+ });
957
+ // The above hooks handle imperatively submitting the form, but not
958
+ // declaratively submitting the form. This happens when:
959
+ // 1. A non-custom element `<button type="submit">` is clicked.
960
+ // 2. Enter is pressed on a non-custom element text editable `<input>`.
961
+ form.addEventListener('submit', () => {
962
+ // This submit was from `form.requestSubmit()`, which already calls the
963
+ // listener.
964
+ if (isNextSubmitFromHook) {
965
+ return;
966
+ }
967
+ onControlValid();
968
+ }, {
969
+ signal: cleanup
970
+ });
971
+ // Note: it is a known limitation that we cannot detect if a form tries to
972
+ // submit declaratively, but fails to do so because an unrelated sibling
973
+ // control failed its constraint validation.
974
+ //
975
+ // Since we cannot detect when that happens, a previously invalid control may
976
+ // not clear its error styling when it becomes valid again.
977
+ //
978
+ // To work around this, call `form.reportValidity()` when submitting a form
979
+ // declaratively. This can be down on the `<button type="submit">`'s click or
980
+ // the text editable `<input>`'s 'Enter' keydown.
981
+ }
982
+ const FORM_VALIDATE_HOOKS = new WeakMap();
983
+ /**
984
+ * Get a hooks `EventTarget` that dispatches 'before' and 'after' events that
985
+ * fire before a form runs constraint validation and immediately after it
986
+ * finishes running constraint validation on its controls.
987
+ *
988
+ * This happens during `form.reportValidity()` and `form.requestSubmit()`.
989
+ *
990
+ * @param form The form to get or set up hooks for.
991
+ * @return A hooks `EventTarget` to add listeners to.
992
+ */
993
+ function getFormValidateHooks(form) {
994
+ if (!FORM_VALIDATE_HOOKS.has(form)) {
995
+ // Patch form methods to add event listener hooks. These are needed to react
996
+ // to form behaviors that do not dispatch events, such as a form asking its
997
+ // controls to report their validity.
998
+ //
999
+ // We should only patch the methods once, since multiple controls and other
1000
+ // forces may want to patch this method. We cannot reliably clean it up if
1001
+ // there are multiple patched and re-patched methods referring holding
1002
+ // references to each other.
1003
+ //
1004
+ // Instead, we never clean up the patch but add and clean up event listeners
1005
+ // added to the hooks after the patch.
1006
+ const hooks = new EventTarget();
1007
+ FORM_VALIDATE_HOOKS.set(form, hooks);
1008
+ // Add hooks to support notifying before and after a form has run constraint
1009
+ // validation on its controls.
1010
+ // Note: `form.submit()` does not run constraint validation per spec.
1011
+ for (const methodName of ['reportValidity', 'requestSubmit']) {
1012
+ const superMethod = form[methodName];
1013
+ form[methodName] = function () {
1014
+ hooks.dispatchEvent(new Event('before'));
1015
+ const result = Reflect.apply(superMethod, this, arguments);
1016
+ hooks.dispatchEvent(new Event('after'));
1017
+ return result;
1018
+ };
1019
+ }
1020
+ }
1021
+ return FORM_VALIDATE_HOOKS.get(form);
1022
+ }
1023
+ /**
1024
+ * Checks if a control is the first invalid control in a form.
1025
+ *
1026
+ * @param form The control's form. When `null`, the control doesn't have a form
1027
+ * and the method returns true.
1028
+ * @param control The control to check.
1029
+ * @return True if there is no form or if the control is the form's first
1030
+ * invalid control.
1031
+ */
1032
+ function isFirstInvalidControlInForm(form, control) {
1033
+ if (!form) {
1034
+ return true;
1035
+ }
1036
+ let firstInvalidControl;
1037
+ for (const element of form.elements) {
1038
+ if (element.matches(':invalid')) {
1039
+ firstInvalidControl = element;
1040
+ break;
1041
+ }
1042
+ }
1043
+ return firstInvalidControl === control;
1044
+ }
1045
+
1046
+ /**
1047
+ * @license
1048
+ * Copyright 2023 Google LLC
1049
+ * SPDX-License-Identifier: Apache-2.0
1050
+ */
1051
+ /**
1052
+ * A class that computes and caches `ValidityStateFlags` for a component with
1053
+ * a given `State` interface.
1054
+ *
1055
+ * Cached performance before computing validity is important since constraint
1056
+ * validation must be checked frequently and synchronously when properties
1057
+ * change.
1058
+ *
1059
+ * @template State The expected interface of properties relevant to constraint
1060
+ * validation.
1061
+ */
1062
+ class Validator {
1063
+ /**
1064
+ * Creates a new validator.
1065
+ *
1066
+ * @param getCurrentState A callback that returns the current state of
1067
+ * constraint validation-related properties.
1068
+ */
1069
+ constructor(getCurrentState) {
1070
+ this.getCurrentState = getCurrentState;
1071
+ /**
1072
+ * The current validity state and message. This is cached and returns if
1073
+ * constraint validation state does not change.
1074
+ */
1075
+ this.currentValidity = {
1076
+ validity: {},
1077
+ validationMessage: ''
1078
+ };
1079
+ }
1080
+ /**
1081
+ * Returns the current `ValidityStateFlags` and validation message for the
1082
+ * validator.
1083
+ *
1084
+ * If the constraint validation state has not changed, this will return a
1085
+ * cached result. This is important since `getValidity()` can be called
1086
+ * frequently in response to synchronous property changes.
1087
+ *
1088
+ * @return The current validity and validation message.
1089
+ */
1090
+ getValidity() {
1091
+ const state = this.getCurrentState();
1092
+ const hasStateChanged = !this.prevState || !this.equals(this.prevState, state);
1093
+ if (!hasStateChanged) {
1094
+ return this.currentValidity;
1095
+ }
1096
+ const {
1097
+ validity,
1098
+ validationMessage
1099
+ } = this.computeValidity(state);
1100
+ this.prevState = this.copy(state);
1101
+ this.currentValidity = {
1102
+ validationMessage,
1103
+ validity: {
1104
+ // Change any `ValidityState` instances into `ValidityStateFlags` since
1105
+ // `ValidityState` cannot be easily `{...spread}`.
1106
+ badInput: validity.badInput,
1107
+ customError: validity.customError,
1108
+ patternMismatch: validity.patternMismatch,
1109
+ rangeOverflow: validity.rangeOverflow,
1110
+ rangeUnderflow: validity.rangeUnderflow,
1111
+ stepMismatch: validity.stepMismatch,
1112
+ tooLong: validity.tooLong,
1113
+ tooShort: validity.tooShort,
1114
+ typeMismatch: validity.typeMismatch,
1115
+ valueMissing: validity.valueMissing
1116
+ }
1117
+ };
1118
+ return this.currentValidity;
1119
+ }
1120
+ }
1121
+
1122
+ export { Validator as V, mixinConstraintValidation as a, mixinFormAssociated as b, onReportValidity as c, createValidator as d, getValidityAnchor as e, getFormValue as g, mixinOnReportValidity as m, o };