@material/web 2.2.0 → 2.2.1-nightly.045fe94.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 (190) hide show
  1. package/button/elevated-button.js +2 -1
  2. package/button/elevated-button.js.map +1 -1
  3. package/button/filled-button.js +2 -1
  4. package/button/filled-button.js.map +1 -1
  5. package/button/filled-tonal-button.js +2 -1
  6. package/button/filled-tonal-button.js.map +1 -1
  7. package/button/internal/button.js.map +1 -1
  8. package/button/outlined-button.js +2 -1
  9. package/button/outlined-button.js.map +1 -1
  10. package/button/text-button.js +2 -1
  11. package/button/text-button.js.map +1 -1
  12. package/checkbox/checkbox.js +2 -1
  13. package/checkbox/checkbox.js.map +1 -1
  14. package/checkbox/internal/checkbox.d.ts +1 -0
  15. package/checkbox/internal/checkbox.js.map +1 -1
  16. package/chips/assist-chip.js +2 -1
  17. package/chips/assist-chip.js.map +1 -1
  18. package/chips/chip-set.js +2 -1
  19. package/chips/chip-set.js.map +1 -1
  20. package/chips/filter-chip.js +2 -1
  21. package/chips/filter-chip.js.map +1 -1
  22. package/chips/harness.js.map +1 -1
  23. package/chips/input-chip.js +2 -1
  24. package/chips/input-chip.js.map +1 -1
  25. package/chips/internal/assist-chip.js.map +1 -1
  26. package/chips/internal/chip-set.js.map +1 -1
  27. package/chips/internal/chip.d.ts +1 -0
  28. package/chips/internal/chip.js.map +1 -1
  29. package/chips/internal/filter-chip.js.map +1 -1
  30. package/chips/internal/input-chip.js.map +1 -1
  31. package/chips/internal/multi-action-chip.js.map +1 -1
  32. package/chips/internal/trailing-icons.js.map +1 -1
  33. package/chips/suggestion-chip.js +2 -1
  34. package/chips/suggestion-chip.js.map +1 -1
  35. package/dialog/dialog.js +2 -1
  36. package/dialog/dialog.js.map +1 -1
  37. package/dialog/internal/dialog.js.map +1 -1
  38. package/divider/divider.js +2 -1
  39. package/divider/divider.js.map +1 -1
  40. package/elevation/elevation.js +2 -1
  41. package/elevation/elevation.js.map +1 -1
  42. package/fab/branded-fab.js +2 -1
  43. package/fab/branded-fab.js.map +1 -1
  44. package/fab/fab.js +2 -1
  45. package/fab/fab.js.map +1 -1
  46. package/field/filled-field.js +2 -1
  47. package/field/filled-field.js.map +1 -1
  48. package/field/internal/field.js.map +1 -1
  49. package/field/outlined-field.js +2 -1
  50. package/field/outlined-field.js.map +1 -1
  51. package/focus/internal/focus-ring.js.map +1 -1
  52. package/focus/md-focus-ring.js +2 -1
  53. package/focus/md-focus-ring.js.map +1 -1
  54. package/icon/icon.js +2 -1
  55. package/icon/icon.js.map +1 -1
  56. package/icon/internal/icon.js.map +1 -1
  57. package/iconbutton/filled-icon-button.js +2 -1
  58. package/iconbutton/filled-icon-button.js.map +1 -1
  59. package/iconbutton/filled-tonal-icon-button.js +2 -1
  60. package/iconbutton/filled-tonal-icon-button.js.map +1 -1
  61. package/iconbutton/harness.js.map +1 -1
  62. package/iconbutton/icon-button.js +2 -1
  63. package/iconbutton/icon-button.js.map +1 -1
  64. package/iconbutton/internal/icon-button.js.map +1 -1
  65. package/iconbutton/outlined-icon-button.js +2 -1
  66. package/iconbutton/outlined-icon-button.js.map +1 -1
  67. package/internal/aria/aria.d.ts +1 -1
  68. package/internal/aria/delegate.js.map +1 -1
  69. package/internal/controller/attachable-controller.js.map +1 -1
  70. package/internal/controller/form-submitter.js.map +1 -1
  71. package/internal/events/dispatch-hooks.js.map +1 -1
  72. package/internal/events/form-label-activation.js.map +1 -1
  73. package/internal/events/redispatch-event.js.map +1 -1
  74. package/internal/motion/animation.js.map +1 -1
  75. package/labs/badge/badge.js +2 -1
  76. package/labs/badge/badge.js.map +1 -1
  77. package/labs/behaviors/constraint-validation.js.map +1 -1
  78. package/labs/behaviors/custom-state-set.d.ts +107 -0
  79. package/labs/behaviors/custom-state-set.js +121 -0
  80. package/labs/behaviors/custom-state-set.js.map +1 -0
  81. package/labs/behaviors/element-internals.js.map +1 -1
  82. package/labs/behaviors/focusable.js.map +1 -1
  83. package/labs/behaviors/form-associated.js.map +1 -1
  84. package/labs/behaviors/on-report-validity.js.map +1 -1
  85. package/labs/behaviors/validators/checkbox-validator.js.map +1 -1
  86. package/labs/behaviors/validators/radio-validator.js.map +1 -1
  87. package/labs/behaviors/validators/select-validator.js.map +1 -1
  88. package/labs/behaviors/validators/text-field-validator.js.map +1 -1
  89. package/labs/behaviors/validators/validator.js.map +1 -1
  90. package/labs/card/elevated-card.js +2 -1
  91. package/labs/card/elevated-card.js.map +1 -1
  92. package/labs/card/filled-card.js +2 -1
  93. package/labs/card/filled-card.js.map +1 -1
  94. package/labs/card/outlined-card.js +2 -1
  95. package/labs/card/outlined-card.js.map +1 -1
  96. package/labs/item/internal/item.js.map +1 -1
  97. package/labs/item/item.js +2 -1
  98. package/labs/item/item.js.map +1 -1
  99. package/labs/navigationbar/internal/navigation-bar.js.map +1 -1
  100. package/labs/navigationbar/navigation-bar.js +2 -1
  101. package/labs/navigationbar/navigation-bar.js.map +1 -1
  102. package/labs/navigationdrawer/internal/navigation-drawer-modal.js.map +1 -1
  103. package/labs/navigationdrawer/internal/navigation-drawer.js.map +1 -1
  104. package/labs/navigationdrawer/navigation-drawer-modal.js +2 -1
  105. package/labs/navigationdrawer/navigation-drawer-modal.js.map +1 -1
  106. package/labs/navigationdrawer/navigation-drawer.js +2 -1
  107. package/labs/navigationdrawer/navigation-drawer.js.map +1 -1
  108. package/labs/navigationtab/internal/navigation-tab.js.map +1 -1
  109. package/labs/navigationtab/navigation-tab.js +2 -1
  110. package/labs/navigationtab/navigation-tab.js.map +1 -1
  111. package/labs/segmentedbutton/internal/segmented-button.js.map +1 -1
  112. package/labs/segmentedbutton/outlined-segmented-button.js +2 -1
  113. package/labs/segmentedbutton/outlined-segmented-button.js.map +1 -1
  114. package/labs/segmentedbuttonset/internal/segmented-button-set.js.map +1 -1
  115. package/labs/segmentedbuttonset/outlined-segmented-button-set.js +2 -1
  116. package/labs/segmentedbuttonset/outlined-segmented-button-set.js.map +1 -1
  117. package/list/internal/list-controller.js.map +1 -1
  118. package/list/internal/list-navigation-helpers.js.map +1 -1
  119. package/list/internal/list.js.map +1 -1
  120. package/list/internal/listitem/list-item.d.ts +1 -0
  121. package/list/internal/listitem/list-item.js.map +1 -1
  122. package/list/list-item.js +2 -1
  123. package/list/list-item.js.map +1 -1
  124. package/list/list.js +2 -1
  125. package/list/list.js.map +1 -1
  126. package/menu/harness.js.map +1 -1
  127. package/menu/internal/controllers/menuItemController.js.map +1 -1
  128. package/menu/internal/controllers/surfacePositionController.js.map +1 -1
  129. package/menu/internal/controllers/typeaheadController.js.map +1 -1
  130. package/menu/internal/menu.js.map +1 -1
  131. package/menu/internal/menuitem/menu-item.d.ts +1 -0
  132. package/menu/internal/menuitem/menu-item.js.map +1 -1
  133. package/menu/internal/submenu/sub-menu.js.map +1 -1
  134. package/menu/menu-item.js +2 -1
  135. package/menu/menu-item.js.map +1 -1
  136. package/menu/menu.js +2 -1
  137. package/menu/menu.js.map +1 -1
  138. package/menu/sub-menu.js +2 -1
  139. package/menu/sub-menu.js.map +1 -1
  140. package/migrations/v2/query-selector-aria.js.map +1 -1
  141. package/package.json +5 -3
  142. package/progress/circular-progress.js +2 -1
  143. package/progress/circular-progress.js.map +1 -1
  144. package/progress/internal/circular-progress.js.map +1 -1
  145. package/progress/linear-progress.js +2 -1
  146. package/progress/linear-progress.js.map +1 -1
  147. package/radio/internal/radio.js.map +1 -1
  148. package/radio/internal/single-selection-controller.js.map +1 -1
  149. package/radio/radio.js +2 -1
  150. package/radio/radio.js.map +1 -1
  151. package/ripple/internal/ripple.js.map +1 -1
  152. package/ripple/ripple.js +2 -1
  153. package/ripple/ripple.js.map +1 -1
  154. package/select/filled-select.js +2 -1
  155. package/select/filled-select.js.map +1 -1
  156. package/select/harness.js.map +1 -1
  157. package/select/internal/select.d.ts +1 -0
  158. package/select/internal/select.js +2 -1
  159. package/select/internal/select.js.map +1 -1
  160. package/select/internal/selectoption/select-option.d.ts +1 -0
  161. package/select/internal/selectoption/selectOptionController.js.map +1 -1
  162. package/select/internal/shared.js.map +1 -1
  163. package/select/outlined-select.js +2 -1
  164. package/select/outlined-select.js.map +1 -1
  165. package/select/select-option.js +2 -1
  166. package/select/select-option.js.map +1 -1
  167. package/slider/harness.js.map +1 -1
  168. package/slider/internal/slider.js.map +1 -1
  169. package/slider/slider.js +2 -1
  170. package/slider/slider.js.map +1 -1
  171. package/switch/internal/switch.js.map +1 -1
  172. package/switch/switch.js +2 -1
  173. package/switch/switch.js.map +1 -1
  174. package/tabs/harness.js.map +1 -1
  175. package/tabs/internal/tab.js.map +1 -1
  176. package/tabs/internal/tabs.js.map +1 -1
  177. package/tabs/primary-tab.js +2 -1
  178. package/tabs/primary-tab.js.map +1 -1
  179. package/tabs/secondary-tab.js +2 -1
  180. package/tabs/secondary-tab.js.map +1 -1
  181. package/tabs/tabs.js +2 -1
  182. package/tabs/tabs.js.map +1 -1
  183. package/testing/harness.js.map +1 -1
  184. package/testing/transform-pseudo-classes.js.map +1 -1
  185. package/textfield/filled-text-field.js +2 -1
  186. package/textfield/filled-text-field.js.map +1 -1
  187. package/textfield/harness.js.map +1 -1
  188. package/textfield/internal/text-field.js.map +1 -1
  189. package/textfield/outlined-text-field.js +2 -1
  190. package/textfield/outlined-text-field.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"constraint-validation.js","sourceRoot":"","sources":["constraint-validation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {isServer, LitElement, PropertyDeclaration, PropertyValues} from 'lit';\n\nimport {internals, WithElementInternals} from './element-internals.js';\nimport {FormAssociated} from './form-associated.js';\nimport {MixinBase, MixinReturn} from './mixin.js';\nimport {Validator} from './validators/validator.js';\n\n/**\n * A form associated element that provides constraint validation APIs.\n *\n * https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation\n */\nexport interface ConstraintValidation extends FormAssociated {\n /**\n * Returns a ValidityState object that represents the validity states of the\n * element.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/ValidityState\n */\n readonly validity: ValidityState;\n\n /**\n * Returns a validation error message or an empty string if the element is\n * valid.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/validationMessage\n */\n readonly validationMessage: string;\n\n /**\n * Returns whether an element will successfully validate based on forms\n * validation rules and constraints.\n *\n * Disabled and readonly elements will not validate.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/willValidate\n */\n readonly willValidate: boolean;\n\n /**\n * Checks the element's constraint validation and returns true if the element\n * is valid or false if not.\n *\n * If invalid, this method will dispatch an `invalid` event.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/checkValidity\n *\n * @return true if the element is valid, or false if not.\n */\n checkValidity(): boolean;\n\n /**\n * Checks the element's constraint validation and returns true if the element\n * is valid or false if not.\n *\n * If invalid, this method will dispatch a cancelable `invalid` event. If not\n * canceled, a the current `validationMessage` will be reported to the user.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/reportValidity\n *\n * @return true if the element is valid, or false if not.\n */\n reportValidity(): boolean;\n\n /**\n * Sets the element's constraint validation error message. When set to a\n * non-empty string, `validity.customError` will be true and\n * `validationMessage` will display the provided error.\n *\n * Use this method to customize error messages reported.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setCustomValidity\n *\n * @param error The error message to display, or an empty string.\n */\n setCustomValidity(error: string): void;\n\n /**\n * Creates and returns a `Validator` that is used to compute and cache\n * validity for the element.\n *\n * A validator that caches validity is important since constraint validation\n * must be computed synchronously and frequently in response to constraint\n * validation property changes.\n */\n [createValidator](): Validator<unknown>;\n\n /**\n * Returns shadow DOM child that is used as the anchor for the platform\n * `reportValidity()` popup. This is often the root element or the inner\n * focus-delegated element.\n */\n [getValidityAnchor](): HTMLElement | null;\n}\n\n/**\n * A symbol property used to create a constraint validation `Validator`.\n * Required for all `mixinConstraintValidation()` elements.\n */\nexport const createValidator = Symbol('createValidator');\n\n/**\n * A symbol property used to return an anchor for constraint validation popups.\n * Required for all `mixinConstraintValidation()` elements.\n */\nexport const getValidityAnchor = Symbol('getValidityAnchor');\n\n// Private symbol members, used to avoid name clashing.\nconst privateValidator = Symbol('privateValidator');\nconst privateSyncValidity = Symbol('privateSyncValidity');\nconst privateCustomValidationMessage = Symbol('privateCustomValidationMessage');\n\n/**\n * Mixes in constraint validation APIs for an element.\n *\n * See https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation\n * for more details.\n *\n * Implementations must provide a validator to cache and compute its validity,\n * along with a shadow root element to anchor validation popups to.\n *\n * @example\n * ```ts\n * const baseClass = mixinConstraintValidation(\n * mixinFormAssociated(mixinElementInternals(LitElement))\n * );\n *\n * class MyCheckbox extends baseClass {\n * \\@property({type: Boolean}) checked = false;\n * \\@property({type: Boolean}) required = false;\n *\n * [createValidator]() {\n * return new CheckboxValidator(() => this);\n * }\n *\n * [getValidityAnchor]() {\n * return this.renderRoot.querySelector('.root');\n * }\n * }\n * ```\n *\n * @param base The class to mix functionality into.\n * @return The provided class with `ConstraintValidation` mixed in.\n */\nexport function mixinConstraintValidation<\n T extends MixinBase<LitElement & FormAssociated & WithElementInternals>,\n>(base: T): MixinReturn<T, ConstraintValidation> {\n abstract class ConstraintValidationElement\n extends base\n implements ConstraintValidation\n {\n get validity() {\n this[privateSyncValidity]();\n return this[internals].validity;\n }\n\n get validationMessage() {\n this[privateSyncValidity]();\n return this[internals].validationMessage;\n }\n\n get willValidate() {\n this[privateSyncValidity]();\n return this[internals].willValidate;\n }\n\n /**\n * A validator instance created from `[createValidator]()`.\n */\n [privateValidator]?: Validator<unknown>;\n\n /**\n * Needed for Safari, see https://bugs.webkit.org/show_bug.cgi?id=261432\n * Replace with this[internals].validity.customError when resolved.\n */\n [privateCustomValidationMessage] = '';\n\n checkValidity() {\n this[privateSyncValidity]();\n return this[internals].checkValidity();\n }\n\n reportValidity() {\n this[privateSyncValidity]();\n return this[internals].reportValidity();\n }\n\n setCustomValidity(error: string) {\n this[privateCustomValidationMessage] = error;\n this[privateSyncValidity]();\n }\n\n override requestUpdate(\n name?: PropertyKey,\n oldValue?: unknown,\n options?: PropertyDeclaration,\n ) {\n super.requestUpdate(name, oldValue, options);\n this[privateSyncValidity]();\n }\n\n override firstUpdated(changed: PropertyValues) {\n super.firstUpdated(changed);\n // Sync the validity again when the element first renders, since the\n // validity anchor is now available.\n //\n // Elements that `delegatesFocus: true` to an `<input>` will throw an\n // error in Chrome and Safari when a form tries to submit or call\n // `form.reportValidity()`:\n // \"An invalid form control with name='' is not focusable\"\n //\n // The validity anchor MUST be provided in `internals.setValidity()` and\n // MUST be the `<input>` element rendered.\n //\n // See https://lit.dev/playground/#gist=6c26e418e0010f7a5aac15005cde8bde\n // for a reproduction.\n this[privateSyncValidity]();\n }\n\n [privateSyncValidity]() {\n if (isServer) {\n return;\n }\n\n if (!this[privateValidator]) {\n this[privateValidator] = this[createValidator]();\n }\n\n const {validity, validationMessage: nonCustomValidationMessage} =\n this[privateValidator].getValidity();\n\n const customError = !!this[privateCustomValidationMessage];\n const validationMessage =\n this[privateCustomValidationMessage] || nonCustomValidationMessage;\n\n this[internals].setValidity(\n {...validity, customError},\n validationMessage,\n this[getValidityAnchor]() ?? undefined,\n );\n }\n\n [createValidator](): Validator<unknown> {\n throw new Error('Implement [createValidator]');\n }\n\n [getValidityAnchor](): HTMLElement | null {\n throw new Error('Implement [getValidityAnchor]');\n }\n }\n\n return ConstraintValidationElement;\n}\n"]}
1
+ {"version":3,"file":"constraint-validation.js","sourceRoot":"","sources":["constraint-validation.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {isServer, LitElement, PropertyDeclaration, PropertyValues} from 'lit';\n\nimport {internals, WithElementInternals} from './element-internals.js';\nimport {FormAssociated} from './form-associated.js';\nimport {MixinBase, MixinReturn} from './mixin.js';\nimport {Validator} from './validators/validator.js';\n\n/**\n * A form associated element that provides constraint validation APIs.\n *\n * https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation\n */\nexport interface ConstraintValidation extends FormAssociated {\n /**\n * Returns a ValidityState object that represents the validity states of the\n * element.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/ValidityState\n */\n readonly validity: ValidityState;\n\n /**\n * Returns a validation error message or an empty string if the element is\n * valid.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/validationMessage\n */\n readonly validationMessage: string;\n\n /**\n * Returns whether an element will successfully validate based on forms\n * validation rules and constraints.\n *\n * Disabled and readonly elements will not validate.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/willValidate\n */\n readonly willValidate: boolean;\n\n /**\n * Checks the element's constraint validation and returns true if the element\n * is valid or false if not.\n *\n * If invalid, this method will dispatch an `invalid` event.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/checkValidity\n *\n * @return true if the element is valid, or false if not.\n */\n checkValidity(): boolean;\n\n /**\n * Checks the element's constraint validation and returns true if the element\n * is valid or false if not.\n *\n * If invalid, this method will dispatch a cancelable `invalid` event. If not\n * canceled, a the current `validationMessage` will be reported to the user.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/reportValidity\n *\n * @return true if the element is valid, or false if not.\n */\n reportValidity(): boolean;\n\n /**\n * Sets the element's constraint validation error message. When set to a\n * non-empty string, `validity.customError` will be true and\n * `validationMessage` will display the provided error.\n *\n * Use this method to customize error messages reported.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setCustomValidity\n *\n * @param error The error message to display, or an empty string.\n */\n setCustomValidity(error: string): void;\n\n /**\n * Creates and returns a `Validator` that is used to compute and cache\n * validity for the element.\n *\n * A validator that caches validity is important since constraint validation\n * must be computed synchronously and frequently in response to constraint\n * validation property changes.\n */\n [createValidator](): Validator<unknown>;\n\n /**\n * Returns shadow DOM child that is used as the anchor for the platform\n * `reportValidity()` popup. This is often the root element or the inner\n * focus-delegated element.\n */\n [getValidityAnchor](): HTMLElement | null;\n}\n\n/**\n * A symbol property used to create a constraint validation `Validator`.\n * Required for all `mixinConstraintValidation()` elements.\n */\nexport const createValidator = Symbol('createValidator');\n\n/**\n * A symbol property used to return an anchor for constraint validation popups.\n * Required for all `mixinConstraintValidation()` elements.\n */\nexport const getValidityAnchor = Symbol('getValidityAnchor');\n\n// Private symbol members, used to avoid name clashing.\nconst privateValidator = Symbol('privateValidator');\nconst privateSyncValidity = Symbol('privateSyncValidity');\nconst privateCustomValidationMessage = Symbol('privateCustomValidationMessage');\n\n/**\n * Mixes in constraint validation APIs for an element.\n *\n * See https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation\n * for more details.\n *\n * Implementations must provide a validator to cache and compute its validity,\n * along with a shadow root element to anchor validation popups to.\n *\n * @example\n * ```ts\n * const baseClass = mixinConstraintValidation(\n * mixinFormAssociated(mixinElementInternals(LitElement))\n * );\n *\n * class MyCheckbox extends baseClass {\n * \\@property({type: Boolean}) checked = false;\n * \\@property({type: Boolean}) required = false;\n *\n * [createValidator]() {\n * return new CheckboxValidator(() => this);\n * }\n *\n * [getValidityAnchor]() {\n * return this.renderRoot.querySelector('.root');\n * }\n * }\n * ```\n *\n * @param base The class to mix functionality into.\n * @return The provided class with `ConstraintValidation` mixed in.\n */\nexport function mixinConstraintValidation<\n T extends MixinBase<LitElement & FormAssociated & WithElementInternals>,\n>(base: T): MixinReturn<T, ConstraintValidation> {\n abstract class ConstraintValidationElement\n extends base\n implements ConstraintValidation\n {\n get validity() {\n this[privateSyncValidity]();\n return this[internals].validity;\n }\n\n get validationMessage() {\n this[privateSyncValidity]();\n return this[internals].validationMessage;\n }\n\n get willValidate() {\n this[privateSyncValidity]();\n return this[internals].willValidate;\n }\n\n /**\n * A validator instance created from `[createValidator]()`.\n */\n [privateValidator]?: Validator<unknown>;\n\n /**\n * Needed for Safari, see https://bugs.webkit.org/show_bug.cgi?id=261432\n * Replace with this[internals].validity.customError when resolved.\n */\n [privateCustomValidationMessage] = '';\n\n checkValidity() {\n this[privateSyncValidity]();\n return this[internals].checkValidity();\n }\n\n reportValidity() {\n this[privateSyncValidity]();\n return this[internals].reportValidity();\n }\n\n setCustomValidity(error: string) {\n this[privateCustomValidationMessage] = error;\n this[privateSyncValidity]();\n }\n\n override requestUpdate(\n name?: PropertyKey,\n oldValue?: unknown,\n options?: PropertyDeclaration,\n ) {\n super.requestUpdate(name, oldValue, options);\n this[privateSyncValidity]();\n }\n\n override firstUpdated(changed: PropertyValues) {\n super.firstUpdated(changed);\n // Sync the validity again when the element first renders, since the\n // validity anchor is now available.\n //\n // Elements that `delegatesFocus: true` to an `<input>` will throw an\n // error in Chrome and Safari when a form tries to submit or call\n // `form.reportValidity()`:\n // \"An invalid form control with name='' is not focusable\"\n //\n // The validity anchor MUST be provided in `internals.setValidity()` and\n // MUST be the `<input>` element rendered.\n //\n // See https://lit.dev/playground/#gist=6c26e418e0010f7a5aac15005cde8bde\n // for a reproduction.\n this[privateSyncValidity]();\n }\n\n [privateSyncValidity]() {\n if (isServer) {\n return;\n }\n\n if (!this[privateValidator]) {\n this[privateValidator] = this[createValidator]();\n }\n\n const {validity, validationMessage: nonCustomValidationMessage} =\n this[privateValidator].getValidity();\n\n const customError = !!this[privateCustomValidationMessage];\n const validationMessage =\n this[privateCustomValidationMessage] || nonCustomValidationMessage;\n\n this[internals].setValidity(\n {...validity, customError},\n validationMessage,\n this[getValidityAnchor]() ?? undefined,\n );\n }\n\n [createValidator](): Validator<unknown> {\n throw new Error('Implement [createValidator]');\n }\n\n [getValidityAnchor](): HTMLElement | null {\n throw new Error('Implement [getValidityAnchor]');\n }\n }\n\n return ConstraintValidationElement;\n}\n"]}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2024 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { LitElement } from 'lit';
7
+ import { WithElementInternals } from './element-internals.js';
8
+ import { MixinBase, MixinReturn } from './mixin.js';
9
+ /**
10
+ * A unique symbol used to check if an element's `CustomStateSet` has a state.
11
+ *
12
+ * Provides compatibility with legacy dashed identifier syntax (`:--state`) used
13
+ * by the element-internals-polyfill for Chrome extension support.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const baseClass = mixinCustomStateSet(mixinElementInternals(LitElement));
18
+ *
19
+ * class MyElement extends baseClass {
20
+ * get checked() {
21
+ * return this[hasState]('checked');
22
+ * }
23
+ * set checked(value: boolean) {
24
+ * this[toggleState]('checked', value);
25
+ * }
26
+ * }
27
+ * ```
28
+ */
29
+ export declare const hasState: unique symbol;
30
+ /**
31
+ * A unique symbol used to add or delete a state from an element's
32
+ * `CustomStateSet`.
33
+ *
34
+ * Provides compatibility with legacy dashed identifier syntax (`:--state`) used
35
+ * by the element-internals-polyfill for Chrome extension support.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * const baseClass = mixinCustomStateSet(mixinElementInternals(LitElement));
40
+ *
41
+ * class MyElement extends baseClass {
42
+ * get checked() {
43
+ * return this[hasState]('checked');
44
+ * }
45
+ * set checked(value: boolean) {
46
+ * this[toggleState]('checked', value);
47
+ * }
48
+ * }
49
+ * ```
50
+ */
51
+ export declare const toggleState: unique symbol;
52
+ /**
53
+ * An instance with `[hasState]()` and `[toggleState]()` symbol functions that
54
+ * provide compatibility with `CustomStateSet` legacy dashed identifier syntax,
55
+ * used by the element-internals-polyfill and needed for Chrome extension
56
+ * compatibility.
57
+ */
58
+ export interface WithCustomStateSet {
59
+ /**
60
+ * Checks if the state is active, returning true if the element matches
61
+ * `:state(customstate)`.
62
+ *
63
+ * @param customState the `CustomStateSet` state to check. Do not use the
64
+ * `--customstate` dashed identifier syntax.
65
+ * @return true if the custom state is active, or false if not.
66
+ */
67
+ [hasState](customState: string): boolean;
68
+ /**
69
+ * Toggles the state to be active or inactive based on the provided value.
70
+ * When active, the element matches `:state(customstate)`.
71
+ *
72
+ * @param customState the `CustomStateSet` state to check. Do not use the
73
+ * `--customstate` dashed identifier syntax.
74
+ * @param isActive true to add the state, or false to delete it.
75
+ */
76
+ [toggleState](customState: string, isActive: boolean): void;
77
+ }
78
+ /**
79
+ * Mixes in compatibility functions for access to an element's `CustomStateSet`.
80
+ *
81
+ * Use this mixin's `[hasState]()` and `[toggleState]()` symbol functions for
82
+ * compatibility with `CustomStateSet` legacy dashed identifier syntax.
83
+ *
84
+ * https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet#compatibility_with_dashed-ident_syntax.
85
+ *
86
+ * The dashed identifier syntax is needed for element-internals-polyfill, a
87
+ * requirement for Chome extension compatibility.
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * const baseClass = mixinCustomStateSet(mixinElementInternals(LitElement));
92
+ *
93
+ * class MyElement extends baseClass {
94
+ * get checked() {
95
+ * return this[hasState]('checked');
96
+ * }
97
+ * set checked(value: boolean) {
98
+ * this[toggleState]('checked', value);
99
+ * }
100
+ * }
101
+ * ```
102
+ *
103
+ * @param base The class to mix functionality into.
104
+ * @return The provided class with `[hasState]()` and `[toggleState]()`
105
+ * functions mixed in.
106
+ */
107
+ export declare function mixinCustomStateSet<T extends MixinBase<LitElement & WithElementInternals>>(base: T): MixinReturn<T, WithCustomStateSet>;
@@ -0,0 +1,121 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2024 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { internals } from './element-internals.js';
7
+ /**
8
+ * A unique symbol used to check if an element's `CustomStateSet` has a state.
9
+ *
10
+ * Provides compatibility with legacy dashed identifier syntax (`:--state`) used
11
+ * by the element-internals-polyfill for Chrome extension support.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const baseClass = mixinCustomStateSet(mixinElementInternals(LitElement));
16
+ *
17
+ * class MyElement extends baseClass {
18
+ * get checked() {
19
+ * return this[hasState]('checked');
20
+ * }
21
+ * set checked(value: boolean) {
22
+ * this[toggleState]('checked', value);
23
+ * }
24
+ * }
25
+ * ```
26
+ */
27
+ export const hasState = Symbol('hasState');
28
+ /**
29
+ * A unique symbol used to add or delete a state from an element's
30
+ * `CustomStateSet`.
31
+ *
32
+ * Provides compatibility with legacy dashed identifier syntax (`:--state`) used
33
+ * by the element-internals-polyfill for Chrome extension support.
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * const baseClass = mixinCustomStateSet(mixinElementInternals(LitElement));
38
+ *
39
+ * class MyElement extends baseClass {
40
+ * get checked() {
41
+ * return this[hasState]('checked');
42
+ * }
43
+ * set checked(value: boolean) {
44
+ * this[toggleState]('checked', value);
45
+ * }
46
+ * }
47
+ * ```
48
+ */
49
+ export const toggleState = Symbol('toggleState');
50
+ // Private symbols
51
+ const privateUseDashedIdentifier = Symbol('privateUseDashedIdentifier');
52
+ const privateGetStateIdentifier = Symbol('privateGetStateIdentifier');
53
+ /**
54
+ * Mixes in compatibility functions for access to an element's `CustomStateSet`.
55
+ *
56
+ * Use this mixin's `[hasState]()` and `[toggleState]()` symbol functions for
57
+ * compatibility with `CustomStateSet` legacy dashed identifier syntax.
58
+ *
59
+ * https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet#compatibility_with_dashed-ident_syntax.
60
+ *
61
+ * The dashed identifier syntax is needed for element-internals-polyfill, a
62
+ * requirement for Chome extension compatibility.
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * const baseClass = mixinCustomStateSet(mixinElementInternals(LitElement));
67
+ *
68
+ * class MyElement extends baseClass {
69
+ * get checked() {
70
+ * return this[hasState]('checked');
71
+ * }
72
+ * set checked(value: boolean) {
73
+ * this[toggleState]('checked', value);
74
+ * }
75
+ * }
76
+ * ```
77
+ *
78
+ * @param base The class to mix functionality into.
79
+ * @return The provided class with `[hasState]()` and `[toggleState]()`
80
+ * functions mixed in.
81
+ */
82
+ export function mixinCustomStateSet(base) {
83
+ var _a;
84
+ class WithCustomStateSetElement extends base {
85
+ constructor() {
86
+ super(...arguments);
87
+ this[_a] = null;
88
+ }
89
+ [hasState](state) {
90
+ state = this[privateGetStateIdentifier](state);
91
+ return this[internals].states.has(state);
92
+ }
93
+ [toggleState](state, isActive) {
94
+ state = this[privateGetStateIdentifier](state);
95
+ if (isActive) {
96
+ this[internals].states.add(state);
97
+ }
98
+ else {
99
+ this[internals].states.delete(state);
100
+ }
101
+ }
102
+ [(_a = privateUseDashedIdentifier, privateGetStateIdentifier)](state) {
103
+ if (this[privateUseDashedIdentifier] === null) {
104
+ // Check if `--state-string` needs to be used. See
105
+ // https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet#compatibility_with_dashed-ident_syntax
106
+ try {
107
+ const testState = '_test';
108
+ this[internals].states.add(testState);
109
+ this[internals].states.delete(testState);
110
+ this[privateUseDashedIdentifier] = false;
111
+ }
112
+ catch {
113
+ this[privateUseDashedIdentifier] = true;
114
+ }
115
+ }
116
+ return this[privateUseDashedIdentifier] ? `--${state}` : state;
117
+ }
118
+ }
119
+ return WithCustomStateSetElement;
120
+ }
121
+ //# sourceMappingURL=custom-state-set.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-state-set.js","sourceRoot":"","sources":["custom-state-set.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAC,SAAS,EAAuB,MAAM,wBAAwB,CAAC;AAGvE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;AA8BjD,kBAAkB;AAClB,MAAM,0BAA0B,GAAG,MAAM,CAAC,4BAA4B,CAAC,CAAC;AACxE,MAAM,yBAAyB,GAAG,MAAM,CAAC,2BAA2B,CAAC,CAAC;AAEtE;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,mBAAmB,CAEjC,IAAO;;IACP,MAAe,yBACb,SAAQ,IAAI;QADd;;YAkBE,QAA4B,GAAmB,IAAI,CAAC;QAkBtD,CAAC;QAhCC,CAAC,QAAQ,CAAC,CAAC,KAAa;YACtB,KAAK,GAAG,IAAI,CAAC,yBAAyB,CAAC,CAAC,KAAK,CAAC,CAAC;YAC/C,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3C,CAAC;QAED,CAAC,WAAW,CAAC,CAAC,KAAa,EAAE,QAAiB;YAC5C,KAAK,GAAG,IAAI,CAAC,yBAAyB,CAAC,CAAC,KAAK,CAAC,CAAC;YAC/C,IAAI,QAAQ,EAAE,CAAC;gBACb,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;QAID,OAFC,0BAA0B,EAE1B,yBAAyB,EAAC,CAAC,KAAa;YACvC,IAAI,IAAI,CAAC,0BAA0B,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC9C,kDAAkD;gBAClD,yGAAyG;gBACzG,IAAI,CAAC;oBACH,MAAM,SAAS,GAAG,OAAO,CAAC;oBAC1B,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;oBACtC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;oBACzC,IAAI,CAAC,0BAA0B,CAAC,GAAG,KAAK,CAAC;gBAC3C,CAAC;gBAAC,MAAM,CAAC;oBACP,IAAI,CAAC,0BAA0B,CAAC,GAAG,IAAI,CAAC;gBAC1C,CAAC;YACH,CAAC;YAED,OAAO,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QACjE,CAAC;KACF;IAED,OAAO,yBAAyB,CAAC;AACnC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2024 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {LitElement} from 'lit';\n\nimport {internals, WithElementInternals} from './element-internals.js';\nimport {MixinBase, MixinReturn} from './mixin.js';\n\n/**\n * A unique symbol used to check if an element's `CustomStateSet` has a state.\n *\n * Provides compatibility with legacy dashed identifier syntax (`:--state`) used\n * by the element-internals-polyfill for Chrome extension support.\n *\n * @example\n * ```ts\n * const baseClass = mixinCustomStateSet(mixinElementInternals(LitElement));\n *\n * class MyElement extends baseClass {\n * get checked() {\n * return this[hasState]('checked');\n * }\n * set checked(value: boolean) {\n * this[toggleState]('checked', value);\n * }\n * }\n * ```\n */\nexport const hasState = Symbol('hasState');\n\n/**\n * A unique symbol used to add or delete a state from an element's\n * `CustomStateSet`.\n *\n * Provides compatibility with legacy dashed identifier syntax (`:--state`) used\n * by the element-internals-polyfill for Chrome extension support.\n *\n * @example\n * ```ts\n * const baseClass = mixinCustomStateSet(mixinElementInternals(LitElement));\n *\n * class MyElement extends baseClass {\n * get checked() {\n * return this[hasState]('checked');\n * }\n * set checked(value: boolean) {\n * this[toggleState]('checked', value);\n * }\n * }\n * ```\n */\nexport const toggleState = Symbol('toggleState');\n\n/**\n * An instance with `[hasState]()` and `[toggleState]()` symbol functions that\n * provide compatibility with `CustomStateSet` legacy dashed identifier syntax,\n * used by the element-internals-polyfill and needed for Chrome extension\n * compatibility.\n */\nexport interface WithCustomStateSet {\n /**\n * Checks if the state is active, returning true if the element matches\n * `:state(customstate)`.\n *\n * @param customState the `CustomStateSet` state to check. Do not use the\n * `--customstate` dashed identifier syntax.\n * @return true if the custom state is active, or false if not.\n */\n [hasState](customState: string): boolean;\n\n /**\n * Toggles the state to be active or inactive based on the provided value.\n * When active, the element matches `:state(customstate)`.\n *\n * @param customState the `CustomStateSet` state to check. Do not use the\n * `--customstate` dashed identifier syntax.\n * @param isActive true to add the state, or false to delete it.\n */\n [toggleState](customState: string, isActive: boolean): void;\n}\n\n// Private symbols\nconst privateUseDashedIdentifier = Symbol('privateUseDashedIdentifier');\nconst privateGetStateIdentifier = Symbol('privateGetStateIdentifier');\n\n/**\n * Mixes in compatibility functions for access to an element's `CustomStateSet`.\n *\n * Use this mixin's `[hasState]()` and `[toggleState]()` symbol functions for\n * compatibility with `CustomStateSet` legacy dashed identifier syntax.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet#compatibility_with_dashed-ident_syntax.\n *\n * The dashed identifier syntax is needed for element-internals-polyfill, a\n * requirement for Chome extension compatibility.\n *\n * @example\n * ```ts\n * const baseClass = mixinCustomStateSet(mixinElementInternals(LitElement));\n *\n * class MyElement extends baseClass {\n * get checked() {\n * return this[hasState]('checked');\n * }\n * set checked(value: boolean) {\n * this[toggleState]('checked', value);\n * }\n * }\n * ```\n *\n * @param base The class to mix functionality into.\n * @return The provided class with `[hasState]()` and `[toggleState]()`\n * functions mixed in.\n */\nexport function mixinCustomStateSet<\n T extends MixinBase<LitElement & WithElementInternals>,\n>(base: T): MixinReturn<T, WithCustomStateSet> {\n abstract class WithCustomStateSetElement\n extends base\n implements WithCustomStateSet\n {\n [hasState](state: string) {\n state = this[privateGetStateIdentifier](state);\n return this[internals].states.has(state);\n }\n\n [toggleState](state: string, isActive: boolean) {\n state = this[privateGetStateIdentifier](state);\n if (isActive) {\n this[internals].states.add(state);\n } else {\n this[internals].states.delete(state);\n }\n }\n\n [privateUseDashedIdentifier]: boolean | null = null;\n\n [privateGetStateIdentifier](state: string) {\n if (this[privateUseDashedIdentifier] === null) {\n // Check if `--state-string` needs to be used. See\n // https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet#compatibility_with_dashed-ident_syntax\n try {\n const testState = '_test';\n this[internals].states.add(testState);\n this[internals].states.delete(testState);\n this[privateUseDashedIdentifier] = false;\n } catch {\n this[privateUseDashedIdentifier] = true;\n }\n }\n\n return this[privateUseDashedIdentifier] ? `--${state}` : state;\n }\n }\n\n return WithCustomStateSetElement;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"element-internals.js","sourceRoot":"","sources":["element-internals.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;AAgB7C,kBAAkB;AAClB,MAAM,gBAAgB,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAEpD;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAO;IAEP,MAAe,2BACb,SAAQ,IAAI;QAGZ,IAAI,CAAC,SAAS,CAAC;YACb,yEAAyE;YACzE,gEAAgE;YAChE,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE;gBAC3B,0BAA0B;gBAC1B,IAAI,CAAC,gBAAgB,CAAC,GAAI,IAAoB,CAAC,eAAe,EAAE,CAAC;aAClE;YAED,OAAO,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAChC,CAAC;KAGF;IAED,OAAO,2BAA2B,CAAC;AACrC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {LitElement} from 'lit';\n\nimport {MixinBase, MixinReturn} from './mixin.js';\n\n/**\n * A unique symbol used for protected access to an instance's\n * `ElementInternals`.\n *\n * @example\n * ```ts\n * class MyElement extends mixinElementInternals(LitElement) {\n * constructor() {\n * super();\n * this[internals].role = 'button';\n * }\n * }\n * ```\n */\nexport const internals = Symbol('internals');\n\n/**\n * An instance with an `internals` symbol property for the component's\n * `ElementInternals`.\n *\n * Use this when protected access is needed for an instance's `ElementInternals`\n * from other files. A unique symbol is used to access the internals.\n */\nexport interface WithElementInternals {\n /**\n * An instance's `ElementInternals`.\n */\n [internals]: ElementInternals;\n}\n\n// Private symbols\nconst privateInternals = Symbol('privateInternals');\n\n/**\n * Mixes in an attached `ElementInternals` instance.\n *\n * This mixin is only needed when other shared code needs access to a\n * component's `ElementInternals`, such as form-associated mixins.\n *\n * @param base The class to mix functionality into.\n * @return The provided class with `WithElementInternals` mixed in.\n */\nexport function mixinElementInternals<T extends MixinBase<LitElement>>(\n base: T,\n): MixinReturn<T, WithElementInternals> {\n abstract class WithElementInternalsElement\n extends base\n implements WithElementInternals\n {\n get [internals]() {\n // Create internals in getter so that it can be used in methods called on\n // construction in `ReactiveElement`, such as `requestUpdate()`.\n if (!this[privateInternals]) {\n // Cast needed for closure\n this[privateInternals] = (this as HTMLElement).attachInternals();\n }\n\n return this[privateInternals];\n }\n\n [privateInternals]?: ElementInternals;\n }\n\n return WithElementInternalsElement;\n}\n"]}
1
+ {"version":3,"file":"element-internals.js","sourceRoot":"","sources":["element-internals.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;AAgB7C,kBAAkB;AAClB,MAAM,gBAAgB,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAEpD;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAO;IAEP,MAAe,2BACb,SAAQ,IAAI;QAGZ,IAAI,CAAC,SAAS,CAAC;YACb,yEAAyE;YACzE,gEAAgE;YAChE,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBAC5B,0BAA0B;gBAC1B,IAAI,CAAC,gBAAgB,CAAC,GAAI,IAAoB,CAAC,eAAe,EAAE,CAAC;YACnE,CAAC;YAED,OAAO,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAChC,CAAC;KAGF;IAED,OAAO,2BAA2B,CAAC;AACrC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {LitElement} from 'lit';\n\nimport {MixinBase, MixinReturn} from './mixin.js';\n\n/**\n * A unique symbol used for protected access to an instance's\n * `ElementInternals`.\n *\n * @example\n * ```ts\n * class MyElement extends mixinElementInternals(LitElement) {\n * constructor() {\n * super();\n * this[internals].role = 'button';\n * }\n * }\n * ```\n */\nexport const internals = Symbol('internals');\n\n/**\n * An instance with an `internals` symbol property for the component's\n * `ElementInternals`.\n *\n * Use this when protected access is needed for an instance's `ElementInternals`\n * from other files. A unique symbol is used to access the internals.\n */\nexport interface WithElementInternals {\n /**\n * An instance's `ElementInternals`.\n */\n [internals]: ElementInternals;\n}\n\n// Private symbols\nconst privateInternals = Symbol('privateInternals');\n\n/**\n * Mixes in an attached `ElementInternals` instance.\n *\n * This mixin is only needed when other shared code needs access to a\n * component's `ElementInternals`, such as form-associated mixins.\n *\n * @param base The class to mix functionality into.\n * @return The provided class with `WithElementInternals` mixed in.\n */\nexport function mixinElementInternals<T extends MixinBase<LitElement>>(\n base: T,\n): MixinReturn<T, WithElementInternals> {\n abstract class WithElementInternalsElement\n extends base\n implements WithElementInternals\n {\n get [internals]() {\n // Create internals in getter so that it can be used in methods called on\n // construction in `ReactiveElement`, such as `requestUpdate()`.\n if (!this[privateInternals]) {\n // Cast needed for closure\n this[privateInternals] = (this as HTMLElement).attachInternals();\n }\n\n return this[privateInternals];\n }\n\n [privateInternals]?: ElementInternals;\n }\n\n return WithElementInternalsElement;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"focusable.js","sourceRoot":"","sources":["focusable.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAGH,OAAO,EAAC,QAAQ,EAAC,MAAM,mBAAmB,CAAC;AAe3C;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;AAEjD,MAAM,kBAAkB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AACxD,MAAM,gBAAgB,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;AACpD,MAAM,kBAAkB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AACxD,MAAM,cAAc,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAEhD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAO;;IAEP,MAAe,gBAAiB,SAAQ,IAAI;QAA5C;;YAiBE,QAAoB,GAAG,IAAI,CAAC;YAC5B,QAAkB,GAAkB,IAAI,CAAC;YACzC,QAAoB,GAAG,KAAK,CAAC;QAyC/B,CAAC;QAxDC,IAAI,CAAC,WAAW,CAAC;YACf,OAAO,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAClC,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,CAAC,KAAc;YAC9B,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,KAAK,EAAE;gBAC/B,OAAO;aACR;YAED,IAAI,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC;YACjC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;QACzB,CAAC;QAMQ,iBAAiB;YACxB,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC1B,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;QACzB,CAAC;QAEQ,wBAAwB,CAC/B,IAAY,EACZ,GAAkB,EAClB,KAAoB;YAEpB,IAAI,IAAI,KAAK,UAAU,EAAE;gBACvB,KAAK,CAAC,wBAAwB,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;gBACjD,OAAO;aACR;YAED,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAClD,IAAI,IAAI,CAAC,kBAAkB,CAAC,EAAE;gBAC5B,sCAAsC;gBACtC,OAAO;aACR;YAED,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE;gBAClC,4DAA4D;gBAC5D,IAAI,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC;gBAC9B,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;gBACvB,OAAO;aACR;YAED,IAAI,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;QACzC,CAAC;QAED,OAnCC,kBAAkB,OAClB,gBAAgB,OAChB,kBAAkB,EAiClB,cAAc,EAAC;YACd,MAAM,gBAAgB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACpD,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,gBAAgB,CAAC;YAEpE,IAAI,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC;YAChC,IAAI,CAAC,QAAQ,GAAG,gBAAgB,CAAC;YACjC,IAAI,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC;QACnC,CAAC;KACF;IA1DS;QADP,QAAQ,CAAC,EAAC,UAAU,EAAE,IAAI,EAAC,CAAC;sDACJ;IA4D3B,OAAO,gBAAgB,CAAC;AAC1B,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {LitElement} from 'lit';\nimport {property} from 'lit/decorators.js';\n\nimport {MixinBase, MixinReturn} from './mixin.js';\n\n/**\n * An element that can enable and disable `tabindex` focusability.\n */\nexport interface Focusable {\n /**\n * Whether or not the element can be focused. Defaults to true. Set to false\n * to disable focusing (unless a user has set a `tabindex`).\n */\n [isFocusable]: boolean;\n}\n\n/**\n * A property symbol that indicates whether or not a `Focusable` element can be\n * focused.\n */\nexport const isFocusable = Symbol('isFocusable');\n\nconst privateIsFocusable = Symbol('privateIsFocusable');\nconst externalTabIndex = Symbol('externalTabIndex');\nconst isUpdatingTabIndex = Symbol('isUpdatingTabIndex');\nconst updateTabIndex = Symbol('updateTabIndex');\n\n/**\n * Mixes in focusable functionality for a class.\n *\n * Elements can enable and disable their focusability with the `isFocusable`\n * symbol property. Changing `tabIndex` will trigger a lit render, meaning\n * `this.tabIndex` can be used in template expressions.\n *\n * This mixin will preserve externally-set tabindices. If an element turns off\n * focusability, but a user sets `tabindex=\"0\"`, it will still be focusable.\n *\n * To remove user overrides and restore focusability control to the element,\n * remove the `tabindex` attribute.\n *\n * @param base The class to mix functionality into.\n * @return The provided class with `Focusable` mixed in.\n */\nexport function mixinFocusable<T extends MixinBase<LitElement>>(\n base: T,\n): MixinReturn<T, Focusable> {\n abstract class FocusableElement extends base implements Focusable {\n @property({noAccessor: true})\n declare tabIndex: number;\n\n get [isFocusable]() {\n return this[privateIsFocusable];\n }\n\n set [isFocusable](value: boolean) {\n if (this[isFocusable] === value) {\n return;\n }\n\n this[privateIsFocusable] = value;\n this[updateTabIndex]();\n }\n\n [privateIsFocusable] = true;\n [externalTabIndex]: number | null = null;\n [isUpdatingTabIndex] = false;\n\n override connectedCallback() {\n super.connectedCallback();\n this[updateTabIndex]();\n }\n\n override attributeChangedCallback(\n name: string,\n old: string | null,\n value: string | null,\n ) {\n if (name !== 'tabindex') {\n super.attributeChangedCallback(name, old, value);\n return;\n }\n\n this.requestUpdate('tabIndex', Number(old ?? -1));\n if (this[isUpdatingTabIndex]) {\n // Not an externally-initiated update.\n return;\n }\n\n if (!this.hasAttribute('tabindex')) {\n // User removed the attribute, can now use internal tabIndex\n this[externalTabIndex] = null;\n this[updateTabIndex]();\n return;\n }\n\n this[externalTabIndex] = this.tabIndex;\n }\n\n [updateTabIndex]() {\n const internalTabIndex = this[isFocusable] ? 0 : -1;\n const computedTabIndex = this[externalTabIndex] ?? internalTabIndex;\n\n this[isUpdatingTabIndex] = true;\n this.tabIndex = computedTabIndex;\n this[isUpdatingTabIndex] = false;\n }\n }\n\n return FocusableElement;\n}\n"]}
1
+ {"version":3,"file":"focusable.js","sourceRoot":"","sources":["focusable.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAGH,OAAO,EAAC,QAAQ,EAAC,MAAM,mBAAmB,CAAC;AAe3C;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;AAEjD,MAAM,kBAAkB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AACxD,MAAM,gBAAgB,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;AACpD,MAAM,kBAAkB,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AACxD,MAAM,cAAc,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAEhD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAO;;IAEP,MAAe,gBAAiB,SAAQ,IAAI;QAA5C;;YAiBE,QAAoB,GAAG,IAAI,CAAC;YAC5B,QAAkB,GAAkB,IAAI,CAAC;YACzC,QAAoB,GAAG,KAAK,CAAC;QAyC/B,CAAC;QAxDC,IAAI,CAAC,WAAW,CAAC;YACf,OAAO,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAClC,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,CAAC,KAAc;YAC9B,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,KAAK,EAAE,CAAC;gBAChC,OAAO;YACT,CAAC;YAED,IAAI,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC;YACjC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;QACzB,CAAC;QAMQ,iBAAiB;YACxB,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC1B,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;QACzB,CAAC;QAEQ,wBAAwB,CAC/B,IAAY,EACZ,GAAkB,EAClB,KAAoB;YAEpB,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;gBACxB,KAAK,CAAC,wBAAwB,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;gBACjD,OAAO;YACT,CAAC;YAED,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAClD,IAAI,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBAC7B,sCAAsC;gBACtC,OAAO;YACT,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC;gBACnC,4DAA4D;gBAC5D,IAAI,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC;gBAC9B,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;gBACvB,OAAO;YACT,CAAC;YAED,IAAI,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;QACzC,CAAC;QAED,OAnCC,kBAAkB,OAClB,gBAAgB,OAChB,kBAAkB,EAiClB,cAAc,EAAC;YACd,MAAM,gBAAgB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACpD,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,gBAAgB,CAAC;YAEpE,IAAI,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC;YAChC,IAAI,CAAC,QAAQ,GAAG,gBAAgB,CAAC;YACjC,IAAI,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC;QACnC,CAAC;KACF;IA1DS;QADP,QAAQ,CAAC,EAAC,UAAU,EAAE,IAAI,EAAC,CAAC;sDACJ;IA4D3B,OAAO,gBAAgB,CAAC;AAC1B,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {LitElement} from 'lit';\nimport {property} from 'lit/decorators.js';\n\nimport {MixinBase, MixinReturn} from './mixin.js';\n\n/**\n * An element that can enable and disable `tabindex` focusability.\n */\nexport interface Focusable {\n /**\n * Whether or not the element can be focused. Defaults to true. Set to false\n * to disable focusing (unless a user has set a `tabindex`).\n */\n [isFocusable]: boolean;\n}\n\n/**\n * A property symbol that indicates whether or not a `Focusable` element can be\n * focused.\n */\nexport const isFocusable = Symbol('isFocusable');\n\nconst privateIsFocusable = Symbol('privateIsFocusable');\nconst externalTabIndex = Symbol('externalTabIndex');\nconst isUpdatingTabIndex = Symbol('isUpdatingTabIndex');\nconst updateTabIndex = Symbol('updateTabIndex');\n\n/**\n * Mixes in focusable functionality for a class.\n *\n * Elements can enable and disable their focusability with the `isFocusable`\n * symbol property. Changing `tabIndex` will trigger a lit render, meaning\n * `this.tabIndex` can be used in template expressions.\n *\n * This mixin will preserve externally-set tabindices. If an element turns off\n * focusability, but a user sets `tabindex=\"0\"`, it will still be focusable.\n *\n * To remove user overrides and restore focusability control to the element,\n * remove the `tabindex` attribute.\n *\n * @param base The class to mix functionality into.\n * @return The provided class with `Focusable` mixed in.\n */\nexport function mixinFocusable<T extends MixinBase<LitElement>>(\n base: T,\n): MixinReturn<T, Focusable> {\n abstract class FocusableElement extends base implements Focusable {\n @property({noAccessor: true})\n declare tabIndex: number;\n\n get [isFocusable]() {\n return this[privateIsFocusable];\n }\n\n set [isFocusable](value: boolean) {\n if (this[isFocusable] === value) {\n return;\n }\n\n this[privateIsFocusable] = value;\n this[updateTabIndex]();\n }\n\n [privateIsFocusable] = true;\n [externalTabIndex]: number | null = null;\n [isUpdatingTabIndex] = false;\n\n override connectedCallback() {\n super.connectedCallback();\n this[updateTabIndex]();\n }\n\n override attributeChangedCallback(\n name: string,\n old: string | null,\n value: string | null,\n ) {\n if (name !== 'tabindex') {\n super.attributeChangedCallback(name, old, value);\n return;\n }\n\n this.requestUpdate('tabIndex', Number(old ?? -1));\n if (this[isUpdatingTabIndex]) {\n // Not an externally-initiated update.\n return;\n }\n\n if (!this.hasAttribute('tabindex')) {\n // User removed the attribute, can now use internal tabIndex\n this[externalTabIndex] = null;\n this[updateTabIndex]();\n return;\n }\n\n this[externalTabIndex] = this.tabIndex;\n }\n\n [updateTabIndex]() {\n const internalTabIndex = this[isFocusable] ? 0 : -1;\n const computedTabIndex = this[externalTabIndex] ?? internalTabIndex;\n\n this[isUpdatingTabIndex] = true;\n this.tabIndex = computedTabIndex;\n this[isUpdatingTabIndex] = false;\n }\n }\n\n return FocusableElement;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"form-associated.js","sourceRoot":"","sources":["form-associated.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {LitElement, PropertyDeclaration} from 'lit';\nimport {property} from 'lit/decorators.js';\n\nimport {internals, WithElementInternals} from './element-internals.js';\nimport {MixinBase, MixinReturn} from './mixin.js';\n\n/**\n * A form-associated element.\n *\n * IMPORTANT: Requires declares for lit-analyzer\n * @example\n * ```ts\n * const base = mixinFormAssociated(mixinElementInternals(LitElement));\n * class MyControl extends base {\n * // Writable mixin properties for lit-html binding, needed for lit-analyzer\n * declare disabled: boolean;\n * declare name: string;\n * }\n * ```\n */\nexport interface FormAssociated {\n /**\n * The associated form element with which this element's value will submit.\n */\n readonly form: HTMLFormElement | null;\n\n /**\n * The labels this element is associated with.\n */\n readonly labels: NodeList;\n\n /**\n * The HTML name to use in form submission.\n */\n name: string;\n\n /**\n * Whether or not the element is disabled.\n */\n disabled: boolean;\n\n /**\n * Gets the current form value of a component.\n *\n * @return The current form value.\n */\n [getFormValue](): FormValue | null;\n\n /**\n * Gets the current form state of a component. Defaults to the component's\n * `[formValue]`.\n *\n * Use this when the state of an element is different from its value, such as\n * checkboxes (internal boolean state and a user string value).\n *\n * @return The current form state, defaults to the form value.\n */\n [getFormState](): FormValue | null;\n\n /**\n * A callback for when a form component should be disabled or enabled. This\n * can be called in a variety of situations, such as disabled `<fieldset>`s.\n *\n * @param disabled Whether or not the form control should be disabled.\n */\n formDisabledCallback(disabled: boolean): void;\n\n /**\n * A callback for when the form requests to reset its value. Typically, the\n * default value that is reset is represented in the attribute of an element.\n *\n * This means the attribute used for the value should not update as the value\n * changes. For example, a checkbox should not change its default `checked`\n * attribute when selected. Ensure form values do not reflect.\n */\n formResetCallback(): void;\n\n /**\n * A callback for when the form restores the state of a component. For\n * example, when a page is reloaded or forms are autofilled.\n *\n * @param state The state to restore, or null to reset the form control's\n * value.\n * @param reason The reason state was restored, either `'restore'` or\n * `'autocomplete'`.\n */\n formStateRestoreCallback(\n state: FormRestoreState | null,\n reason: FormRestoreReason,\n ): void;\n\n /**\n * An optional callback for when the associated form changes.\n *\n * @param form The new associated form, or `null` if there is none.\n */\n formAssociatedCallback?(form: HTMLFormElement | null): void;\n}\n\n/**\n * The constructor of a `FormAssociated` element.\n */\nexport interface FormAssociatedConstructor {\n /**\n * Indicates that an element is participating in form association.\n */\n readonly formAssociated: true;\n}\n\n/**\n * A symbol property to retrieve the form value for an element.\n */\nexport const getFormValue = Symbol('getFormValue');\n\n/**\n * A symbol property to retrieve the form state for an element.\n */\nexport const getFormState = Symbol('getFormState');\n\n/**\n * Mixes in form-associated behavior for a class. This allows an element to add\n * values to `<form>` elements.\n *\n * Implementing classes should provide a `[formValue]` to return the current\n * value of the element, as well as reset and restore callbacks.\n *\n * @example\n * ```ts\n * const base = mixinFormAssociated(mixinElementInternals(LitElement));\n *\n * class MyControl extends base {\n * \\@property()\n * value = '';\n *\n * override [getFormValue]() {\n * return this.value;\n * }\n *\n * override formResetCallback() {\n * const defaultValue = this.getAttribute('value');\n * this.value = defaultValue;\n * }\n *\n * override formStateRestoreCallback(state: string) {\n * this.value = state;\n * }\n * }\n * ```\n *\n * Elements may optionally provide a `[formState]` if their values do not\n * represent the state of the component.\n *\n * @example\n * ```ts\n * const base = mixinFormAssociated(mixinElementInternals(LitElement));\n *\n * class MyCheckbox extends base {\n * \\@property()\n * value = 'on';\n *\n * \\@property({type: Boolean})\n * checked = false;\n *\n * override [getFormValue]() {\n * return this.checked ? this.value : null;\n * }\n *\n * override [getFormState]() {\n * return String(this.checked);\n * }\n *\n * override formResetCallback() {\n * const defaultValue = this.hasAttribute('checked');\n * this.checked = defaultValue;\n * }\n *\n * override formStateRestoreCallback(state: string) {\n * this.checked = Boolean(state);\n * }\n * }\n * ```\n *\n * IMPORTANT: Requires declares for lit-analyzer\n * @example\n * ```ts\n * const base = mixinFormAssociated(mixinElementInternals(LitElement));\n * class MyControl extends base {\n * // Writable mixin properties for lit-html binding, needed for lit-analyzer\n * declare disabled: boolean;\n * declare name: string;\n * }\n * ```\n *\n * @param base The class to mix functionality into. The base class must use\n * `mixinElementInternals()`.\n * @return The provided class with `FormAssociated` mixed in.\n */\nexport function mixinFormAssociated<\n T extends MixinBase<LitElement & WithElementInternals>,\n>(base: T): MixinReturn<T & FormAssociatedConstructor, FormAssociated> {\n abstract class FormAssociatedElement extends base implements FormAssociated {\n /** @nocollapse */\n static readonly formAssociated = true;\n\n get form() {\n return this[internals].form;\n }\n\n get labels() {\n return this[internals].labels;\n }\n\n // Use @property for the `name` and `disabled` properties to add them to the\n // `observedAttributes` array and trigger `attributeChangedCallback()`.\n //\n // We don't use Lit's default getter/setter (`noAccessor: true`) because\n // the attributes need to be updated synchronously to work with synchronous\n // form APIs, and Lit updates attributes async by default.\n @property({noAccessor: true})\n get name() {\n return this.getAttribute('name') ?? '';\n }\n set name(name: string) {\n // Note: setting name to null or empty does not remove the attribute.\n this.setAttribute('name', name);\n // We don't need to call `requestUpdate()` since it's called synchronously\n // in `attributeChangedCallback()`.\n }\n\n @property({type: Boolean, noAccessor: true})\n get disabled() {\n return this.hasAttribute('disabled');\n }\n set disabled(disabled: boolean) {\n this.toggleAttribute('disabled', disabled);\n // We don't need to call `requestUpdate()` since it's called synchronously\n // in `attributeChangedCallback()`.\n }\n\n override attributeChangedCallback(\n name: string,\n old: string | null,\n value: string | null,\n ) {\n // Manually `requestUpdate()` for `name` and `disabled` when their\n // attribute or property changes.\n // The properties update their attributes, so this callback is invoked\n // immediately when the properties are set. We call `requestUpdate()` here\n // instead of letting Lit set the properties from the attribute change.\n // That would cause the properties to re-set the attribute and invoke this\n // callback again in a loop. This leads to stale state when Lit tries to\n // determine if a property changed or not.\n if (name === 'name' || name === 'disabled') {\n // Disabled's value is only false if the attribute is missing and null.\n const oldValue = name === 'disabled' ? old !== null : old;\n // Trigger a lit update when the attribute changes.\n this.requestUpdate(name, oldValue);\n return;\n }\n\n super.attributeChangedCallback(name, old, value);\n }\n\n override requestUpdate(\n name?: PropertyKey,\n oldValue?: unknown,\n options?: PropertyDeclaration,\n ) {\n super.requestUpdate(name, oldValue, options);\n // If any properties change, update the form value, which may have changed\n // as well.\n // Update the form value synchronously in `requestUpdate()` rather than\n // `update()` or `updated()`, which are async. This is necessary to ensure\n // that form data is updated in time for synchronous event listeners.\n this[internals].setFormValue(this[getFormValue](), this[getFormState]());\n }\n\n [getFormValue](): FormValue | null {\n // Closure does not allow abstract symbol members, so a default\n // implementation is needed.\n throw new Error('Implement [getFormValue]');\n }\n\n [getFormState](): FormValue | null {\n return this[getFormValue]();\n }\n\n formDisabledCallback(disabled: boolean) {\n this.disabled = disabled;\n }\n\n abstract formResetCallback(): void;\n\n abstract formStateRestoreCallback(\n state: FormRestoreState | null,\n reason: FormRestoreReason,\n ): void;\n }\n\n return FormAssociatedElement;\n}\n\n/**\n * A value that can be provided for form submission and state.\n */\nexport type FormValue = File | string | FormData;\n\n/**\n * A value to be restored for a component's form value. If a component's form\n * state is a `FormData` object, its entry list of name and values will be\n * provided.\n */\nexport type FormRestoreState =\n | File\n | string\n | Array<[string, FormDataEntryValue]>;\n\n/**\n * The reason a form component is being restored for, either `'restore'` for\n * browser restoration or `'autocomplete'` for restoring user values.\n */\nexport type FormRestoreReason = 'restore' | 'autocomplete';\n"]}
1
+ {"version":3,"file":"form-associated.js","sourceRoot":"","sources":["form-associated.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {LitElement, PropertyDeclaration} from 'lit';\nimport {property} from 'lit/decorators.js';\n\nimport {internals, WithElementInternals} from './element-internals.js';\nimport {MixinBase, MixinReturn} from './mixin.js';\n\n/**\n * A form-associated element.\n *\n * IMPORTANT: Requires declares for lit-analyzer\n * @example\n * ```ts\n * const base = mixinFormAssociated(mixinElementInternals(LitElement));\n * class MyControl extends base {\n * // Writable mixin properties for lit-html binding, needed for lit-analyzer\n * declare disabled: boolean;\n * declare name: string;\n * }\n * ```\n */\nexport interface FormAssociated {\n /**\n * The associated form element with which this element's value will submit.\n */\n readonly form: HTMLFormElement | null;\n\n /**\n * The labels this element is associated with.\n */\n readonly labels: NodeList;\n\n /**\n * The HTML name to use in form submission.\n */\n name: string;\n\n /**\n * Whether or not the element is disabled.\n */\n disabled: boolean;\n\n /**\n * Gets the current form value of a component.\n *\n * @return The current form value.\n */\n [getFormValue](): FormValue | null;\n\n /**\n * Gets the current form state of a component. Defaults to the component's\n * `[formValue]`.\n *\n * Use this when the state of an element is different from its value, such as\n * checkboxes (internal boolean state and a user string value).\n *\n * @return The current form state, defaults to the form value.\n */\n [getFormState](): FormValue | null;\n\n /**\n * A callback for when a form component should be disabled or enabled. This\n * can be called in a variety of situations, such as disabled `<fieldset>`s.\n *\n * @param disabled Whether or not the form control should be disabled.\n */\n formDisabledCallback(disabled: boolean): void;\n\n /**\n * A callback for when the form requests to reset its value. Typically, the\n * default value that is reset is represented in the attribute of an element.\n *\n * This means the attribute used for the value should not update as the value\n * changes. For example, a checkbox should not change its default `checked`\n * attribute when selected. Ensure form values do not reflect.\n */\n formResetCallback(): void;\n\n /**\n * A callback for when the form restores the state of a component. For\n * example, when a page is reloaded or forms are autofilled.\n *\n * @param state The state to restore, or null to reset the form control's\n * value.\n * @param reason The reason state was restored, either `'restore'` or\n * `'autocomplete'`.\n */\n formStateRestoreCallback(\n state: FormRestoreState | null,\n reason: FormRestoreReason,\n ): void;\n\n /**\n * An optional callback for when the associated form changes.\n *\n * @param form The new associated form, or `null` if there is none.\n */\n formAssociatedCallback?(form: HTMLFormElement | null): void;\n}\n\n/**\n * The constructor of a `FormAssociated` element.\n */\nexport interface FormAssociatedConstructor {\n /**\n * Indicates that an element is participating in form association.\n */\n readonly formAssociated: true;\n}\n\n/**\n * A symbol property to retrieve the form value for an element.\n */\nexport const getFormValue = Symbol('getFormValue');\n\n/**\n * A symbol property to retrieve the form state for an element.\n */\nexport const getFormState = Symbol('getFormState');\n\n/**\n * Mixes in form-associated behavior for a class. This allows an element to add\n * values to `<form>` elements.\n *\n * Implementing classes should provide a `[formValue]` to return the current\n * value of the element, as well as reset and restore callbacks.\n *\n * @example\n * ```ts\n * const base = mixinFormAssociated(mixinElementInternals(LitElement));\n *\n * class MyControl extends base {\n * \\@property()\n * value = '';\n *\n * override [getFormValue]() {\n * return this.value;\n * }\n *\n * override formResetCallback() {\n * const defaultValue = this.getAttribute('value');\n * this.value = defaultValue;\n * }\n *\n * override formStateRestoreCallback(state: string) {\n * this.value = state;\n * }\n * }\n * ```\n *\n * Elements may optionally provide a `[formState]` if their values do not\n * represent the state of the component.\n *\n * @example\n * ```ts\n * const base = mixinFormAssociated(mixinElementInternals(LitElement));\n *\n * class MyCheckbox extends base {\n * \\@property()\n * value = 'on';\n *\n * \\@property({type: Boolean})\n * checked = false;\n *\n * override [getFormValue]() {\n * return this.checked ? this.value : null;\n * }\n *\n * override [getFormState]() {\n * return String(this.checked);\n * }\n *\n * override formResetCallback() {\n * const defaultValue = this.hasAttribute('checked');\n * this.checked = defaultValue;\n * }\n *\n * override formStateRestoreCallback(state: string) {\n * this.checked = Boolean(state);\n * }\n * }\n * ```\n *\n * IMPORTANT: Requires declares for lit-analyzer\n * @example\n * ```ts\n * const base = mixinFormAssociated(mixinElementInternals(LitElement));\n * class MyControl extends base {\n * // Writable mixin properties for lit-html binding, needed for lit-analyzer\n * declare disabled: boolean;\n * declare name: string;\n * }\n * ```\n *\n * @param base The class to mix functionality into. The base class must use\n * `mixinElementInternals()`.\n * @return The provided class with `FormAssociated` mixed in.\n */\nexport function mixinFormAssociated<\n T extends MixinBase<LitElement & WithElementInternals>,\n>(base: T): MixinReturn<T & FormAssociatedConstructor, FormAssociated> {\n abstract class FormAssociatedElement extends base implements FormAssociated {\n /** @nocollapse */\n static readonly formAssociated = true;\n\n get form() {\n return this[internals].form;\n }\n\n get labels() {\n return this[internals].labels;\n }\n\n // Use @property for the `name` and `disabled` properties to add them to the\n // `observedAttributes` array and trigger `attributeChangedCallback()`.\n //\n // We don't use Lit's default getter/setter (`noAccessor: true`) because\n // the attributes need to be updated synchronously to work with synchronous\n // form APIs, and Lit updates attributes async by default.\n @property({noAccessor: true})\n get name() {\n return this.getAttribute('name') ?? '';\n }\n set name(name: string) {\n // Note: setting name to null or empty does not remove the attribute.\n this.setAttribute('name', name);\n // We don't need to call `requestUpdate()` since it's called synchronously\n // in `attributeChangedCallback()`.\n }\n\n @property({type: Boolean, noAccessor: true})\n get disabled() {\n return this.hasAttribute('disabled');\n }\n set disabled(disabled: boolean) {\n this.toggleAttribute('disabled', disabled);\n // We don't need to call `requestUpdate()` since it's called synchronously\n // in `attributeChangedCallback()`.\n }\n\n override attributeChangedCallback(\n name: string,\n old: string | null,\n value: string | null,\n ) {\n // Manually `requestUpdate()` for `name` and `disabled` when their\n // attribute or property changes.\n // The properties update their attributes, so this callback is invoked\n // immediately when the properties are set. We call `requestUpdate()` here\n // instead of letting Lit set the properties from the attribute change.\n // That would cause the properties to re-set the attribute and invoke this\n // callback again in a loop. This leads to stale state when Lit tries to\n // determine if a property changed or not.\n if (name === 'name' || name === 'disabled') {\n // Disabled's value is only false if the attribute is missing and null.\n const oldValue = name === 'disabled' ? old !== null : old;\n // Trigger a lit update when the attribute changes.\n this.requestUpdate(name, oldValue);\n return;\n }\n\n super.attributeChangedCallback(name, old, value);\n }\n\n override requestUpdate(\n name?: PropertyKey,\n oldValue?: unknown,\n options?: PropertyDeclaration,\n ) {\n super.requestUpdate(name, oldValue, options);\n // If any properties change, update the form value, which may have changed\n // as well.\n // Update the form value synchronously in `requestUpdate()` rather than\n // `update()` or `updated()`, which are async. This is necessary to ensure\n // that form data is updated in time for synchronous event listeners.\n this[internals].setFormValue(this[getFormValue](), this[getFormState]());\n }\n\n [getFormValue](): FormValue | null {\n // Closure does not allow abstract symbol members, so a default\n // implementation is needed.\n throw new Error('Implement [getFormValue]');\n }\n\n [getFormState](): FormValue | null {\n return this[getFormValue]();\n }\n\n formDisabledCallback(disabled: boolean) {\n this.disabled = disabled;\n }\n\n abstract formResetCallback(): void;\n\n abstract formStateRestoreCallback(\n state: FormRestoreState | null,\n reason: FormRestoreReason,\n ): void;\n }\n\n return FormAssociatedElement;\n}\n\n/**\n * A value that can be provided for form submission and state.\n */\nexport type FormValue = File | string | FormData;\n\n/**\n * A value to be restored for a component's form value. If a component's form\n * state is a `FormData` object, its entry list of name and values will be\n * provided.\n */\nexport type FormRestoreState =\n | File\n | string\n | Array<[string, FormDataEntryValue]>;\n\n/**\n * The reason a form component is being restored for, either `'restore'` for\n * browser restoration or `'autocomplete'` for restoring user values.\n */\nexport type FormRestoreReason = 'restore' | 'autocomplete';\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"on-report-validity.js","sourceRoot":"","sources":["on-report-validity.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {LitElement, isServer} from 'lit';\n\nimport {ConstraintValidation} from './constraint-validation.js';\nimport {WithElementInternals, internals} from './element-internals.js';\nimport {MixinBase, MixinReturn} from './mixin.js';\n\n/**\n * A constraint validation element that has a callback for when the element\n * should report validity styles and error messages to the user.\n *\n * This is commonly used in text-field-like controls that display error styles\n * and error messages.\n */\nexport interface OnReportValidity extends ConstraintValidation {\n /**\n * A callback that is invoked when validity should be reported. Components\n * that can display their own error state can use this and update their\n * styles.\n *\n * If an invalid event is provided, the element is invalid. If `null`, the\n * element is valid.\n *\n * The invalid event's `preventDefault()` may be called to stop the platform\n * popup from displaying.\n *\n * @param invalidEvent The `invalid` event dispatched when an element is\n * invalid, or `null` if the element is valid.\n */\n [onReportValidity](invalidEvent: Event | null): void;\n\n // `mixinOnReportValidity()` implements this optional method. If overriden,\n // call `super.formAssociatedCallback(form)`.\n // (inherit jsdoc from `FormAssociated`)\n formAssociatedCallback(form: HTMLFormElement | null): void;\n}\n\n/**\n * A symbol property used for a callback when validity has been reported.\n */\nexport const onReportValidity = Symbol('onReportValidity');\n\n// Private symbol members, used to avoid name clashing.\nconst privateCleanupFormListeners = Symbol('privateCleanupFormListeners');\nconst privateDoNotReportInvalid = Symbol('privateDoNotReportInvalid');\nconst privateIsSelfReportingValidity = Symbol('privateIsSelfReportingValidity');\nconst privateCallOnReportValidity = Symbol('privateCallOnReportValidity');\n\n/**\n * Mixes in a callback for constraint validation when validity should be\n * styled and reported to the user.\n *\n * This is commonly used in text-field-like controls that display error styles\n * and error messages.\n *\n * @example\n * ```ts\n * const baseClass = mixinOnReportValidity(\n * mixinConstraintValidation(\n * mixinFormAssociated(mixinElementInternals(LitElement)),\n * ),\n * );\n *\n * class MyField extends baseClass {\n * \\@property({type: Boolean}) error = false;\n * \\@property() errorMessage = '';\n *\n * [onReportValidity](invalidEvent: Event | null) {\n * this.error = !!invalidEvent;\n * this.errorMessage = this.validationMessage;\n *\n * // Optionally prevent platform popup from displaying\n * invalidEvent?.preventDefault();\n * }\n * }\n * ```\n *\n * @param base The class to mix functionality into.\n * @return The provided class with `OnReportValidity` mixed in.\n */\nexport function mixinOnReportValidity<\n T extends MixinBase<LitElement & ConstraintValidation & WithElementInternals>,\n>(base: T): MixinReturn<T, OnReportValidity> {\n abstract class OnReportValidityElement\n extends base\n implements OnReportValidity\n {\n /**\n * Used to clean up event listeners when a new form is associated.\n */\n [privateCleanupFormListeners] = new AbortController();\n\n /**\n * Used to determine if an invalid event should report validity. Invalid\n * events from `checkValidity()` do not trigger reporting.\n */\n [privateDoNotReportInvalid] = false;\n\n /**\n * Used to determine if the control is reporting validity from itself, or\n * if a `<form>` is causing the validity report. Forms have different\n * control focusing behavior.\n */\n [privateIsSelfReportingValidity] = false;\n\n // Mixins must have a constructor with `...args: any[]`\n // tslint:disable-next-line:no-any\n constructor(...args: any[]) {\n super(...args);\n if (isServer) {\n return;\n }\n\n this.addEventListener(\n 'invalid',\n (invalidEvent) => {\n // Listen for invalid events dispatched by a `<form>` when it tries to\n // submit and the element is invalid. We ignore events dispatched when\n // calling `checkValidity()` as well as untrusted events, since the\n // `reportValidity()` and `<form>`-dispatched events are always\n // trusted.\n if (this[privateDoNotReportInvalid] || !invalidEvent.isTrusted) {\n return;\n }\n\n this.addEventListener(\n 'invalid',\n () => {\n // A normal bubbling phase event listener. By adding it here, we\n // ensure it's the last event listener that is called during the\n // bubbling phase.\n this[privateCallOnReportValidity](invalidEvent);\n },\n {once: true},\n );\n },\n {\n // Listen during the capture phase, which will happen before the\n // bubbling phase. That way, we can add a final event listener that\n // will run after other event listeners, and we can check if it was\n // default prevented. This works because invalid does not bubble.\n capture: true,\n },\n );\n }\n\n override checkValidity() {\n this[privateDoNotReportInvalid] = true;\n const valid = super.checkValidity();\n this[privateDoNotReportInvalid] = false;\n return valid;\n }\n\n override reportValidity() {\n this[privateIsSelfReportingValidity] = true;\n const valid = super.reportValidity();\n // Constructor's invalid listener will handle reporting invalid events.\n if (valid) {\n this[privateCallOnReportValidity](null);\n }\n\n this[privateIsSelfReportingValidity] = false;\n return valid;\n }\n\n [privateCallOnReportValidity](invalidEvent: Event | null) {\n // Since invalid events do not bubble to parent listeners, and because\n // our invalid listeners are added lazily after other listeners, we can\n // reliably read `defaultPrevented` synchronously without worrying\n // about waiting for another listener that could cancel it.\n const wasCanceled = invalidEvent?.defaultPrevented;\n if (wasCanceled) {\n return;\n }\n\n this[onReportValidity](invalidEvent);\n\n // If an implementation calls invalidEvent.preventDefault() to stop the\n // platform popup from displaying, focusing is also prevented, so we need\n // to manually focus.\n const implementationCanceledFocus =\n !wasCanceled && invalidEvent?.defaultPrevented;\n if (!implementationCanceledFocus) {\n return;\n }\n\n // The control should be focused when:\n // - `control.reportValidity()` is called (self-reporting).\n // - a form is reporting validity for its controls and this is the first\n // invalid control.\n if (\n this[privateIsSelfReportingValidity] ||\n isFirstInvalidControlInForm(this[internals].form, this)\n ) {\n this.focus();\n }\n }\n\n [onReportValidity](invalidEvent: Event | null) {\n throw new Error('Implement [onReportValidity]');\n }\n\n override formAssociatedCallback(form: HTMLFormElement | null) {\n // can't use super.formAssociatedCallback?.() due to closure\n if (super.formAssociatedCallback) {\n super.formAssociatedCallback(form);\n }\n\n // Clean up previous form listeners.\n this[privateCleanupFormListeners].abort();\n if (!form) {\n return;\n }\n\n this[privateCleanupFormListeners] = new AbortController();\n\n // Add a listener that fires when the form runs constraint validation and\n // the control is valid, so that it may remove its error styles.\n //\n // This happens on `form.reportValidity()` and `form.requestSubmit()`\n // (both when the submit fails and passes).\n addFormReportValidListener(\n this,\n form,\n () => {\n this[privateCallOnReportValidity](null);\n },\n this[privateCleanupFormListeners].signal,\n );\n }\n }\n\n return OnReportValidityElement;\n}\n\n/**\n * Add a listener that fires when a form runs constraint validation on a control\n * and it is valid. This is needed to clear previously invalid styles.\n *\n * @param control The control of the form to listen for valid events.\n * @param form The control's form that can run constraint validation.\n * @param onControlValid A listener that is called when the form runs constraint\n * validation and the control is valid.\n * @param cleanup A cleanup signal to remove the listener.\n */\nfunction addFormReportValidListener(\n control: Element,\n form: HTMLFormElement,\n onControlValid: () => void,\n cleanup: AbortSignal,\n) {\n const validateHooks = getFormValidateHooks(form);\n\n // When a form validates its controls, check if an invalid event is dispatched\n // on the control. If it is not, then inform the control to report its valid\n // state.\n let controlFiredInvalid = false;\n let cleanupInvalidListener: AbortController | undefined;\n let isNextSubmitFromHook = false;\n validateHooks.addEventListener(\n 'before',\n () => {\n isNextSubmitFromHook = true;\n cleanupInvalidListener = new AbortController();\n controlFiredInvalid = false;\n control.addEventListener(\n 'invalid',\n () => {\n controlFiredInvalid = true;\n },\n {\n signal: cleanupInvalidListener.signal,\n },\n );\n },\n {signal: cleanup},\n );\n\n validateHooks.addEventListener(\n 'after',\n () => {\n isNextSubmitFromHook = false;\n cleanupInvalidListener?.abort();\n if (controlFiredInvalid) {\n return;\n }\n\n onControlValid();\n },\n {signal: cleanup},\n );\n\n // The above hooks handle imperatively submitting the form, but not\n // declaratively submitting the form. This happens when:\n // 1. A non-custom element `<button type=\"submit\">` is clicked.\n // 2. Enter is pressed on a non-custom element text editable `<input>`.\n form.addEventListener(\n 'submit',\n () => {\n // This submit was from `form.requestSubmit()`, which already calls the\n // listener.\n if (isNextSubmitFromHook) {\n return;\n }\n\n onControlValid();\n },\n {\n signal: cleanup,\n },\n );\n\n // Note: it is a known limitation that we cannot detect if a form tries to\n // submit declaratively, but fails to do so because an unrelated sibling\n // control failed its constraint validation.\n //\n // Since we cannot detect when that happens, a previously invalid control may\n // not clear its error styling when it becomes valid again.\n //\n // To work around this, call `form.reportValidity()` when submitting a form\n // declaratively. This can be down on the `<button type=\"submit\">`'s click or\n // the text editable `<input>`'s 'Enter' keydown.\n}\n\nconst FORM_VALIDATE_HOOKS = new WeakMap<HTMLFormElement, EventTarget>();\n\n/**\n * Get a hooks `EventTarget` that dispatches 'before' and 'after' events that\n * fire before a form runs constraint validation and immediately after it\n * finishes running constraint validation on its controls.\n *\n * This happens during `form.reportValidity()` and `form.requestSubmit()`.\n *\n * @param form The form to get or set up hooks for.\n * @return A hooks `EventTarget` to add listeners to.\n */\nfunction getFormValidateHooks(form: HTMLFormElement) {\n if (!FORM_VALIDATE_HOOKS.has(form)) {\n // Patch form methods to add event listener hooks. These are needed to react\n // to form behaviors that do not dispatch events, such as a form asking its\n // controls to report their validity.\n //\n // We should only patch the methods once, since multiple controls and other\n // forces may want to patch this method. We cannot reliably clean it up if\n // there are multiple patched and re-patched methods referring holding\n // references to each other.\n //\n // Instead, we never clean up the patch but add and clean up event listeners\n // added to the hooks after the patch.\n const hooks = new EventTarget();\n FORM_VALIDATE_HOOKS.set(form, hooks);\n\n // Add hooks to support notifying before and after a form has run constraint\n // validation on its controls.\n // Note: `form.submit()` does not run constraint validation per spec.\n for (const methodName of ['reportValidity', 'requestSubmit'] as const) {\n const superMethod = form[methodName];\n form[methodName] = function (this: HTMLFormElement) {\n hooks.dispatchEvent(new Event('before'));\n const result = Reflect.apply(superMethod, this, arguments);\n hooks.dispatchEvent(new Event('after'));\n return result;\n };\n }\n }\n\n return FORM_VALIDATE_HOOKS.get(form)!;\n}\n\n/**\n * Checks if a control is the first invalid control in a form.\n *\n * @param form The control's form. When `null`, the control doesn't have a form\n * and the method returns true.\n * @param control The control to check.\n * @return True if there is no form or if the control is the form's first\n * invalid control.\n */\nfunction isFirstInvalidControlInForm(\n form: HTMLFormElement | null,\n control: HTMLElement,\n) {\n if (!form) {\n return true;\n }\n\n let firstInvalidControl: Element | undefined;\n for (const element of form.elements) {\n if (element.matches(':invalid')) {\n firstInvalidControl = element;\n break;\n }\n }\n\n return firstInvalidControl === control;\n}\n"]}
1
+ {"version":3,"file":"on-report-validity.js","sourceRoot":"","sources":["on-report-validity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAa,QAAQ,EAAC,MAAM,KAAK,CAAC;AAGzC,OAAO,EAAuB,SAAS,EAAC,MAAM,wBAAwB,CAAC;AAiCvE;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAE3D,uDAAuD;AACvD,MAAM,2BAA2B,GAAG,MAAM,CAAC,6BAA6B,CAAC,CAAC;AAC1E,MAAM,yBAAyB,GAAG,MAAM,CAAC,2BAA2B,CAAC,CAAC;AACtE,MAAM,8BAA8B,GAAG,MAAM,CAAC,gCAAgC,CAAC,CAAC;AAChF,MAAM,2BAA2B,GAAG,MAAM,CAAC,6BAA6B,CAAC,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,qBAAqB,CAEnC,IAAO;;IACP,MAAe,uBACb,SAAQ,IAAI;QAqBZ,uDAAuD;QACvD,kCAAkC;QAClC,YAAY,GAAG,IAAW;YACxB,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;YArBjB;;eAEG;YACH,QAA6B,GAAG,IAAI,eAAe,EAAE,CAAC;YAEtD;;;eAGG;YACH,QAA2B,GAAG,KAAK,CAAC;YAEpC;;;;eAIG;YACH,QAAgC,GAAG,KAAK,CAAC;YAMvC,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO;YACT,CAAC;YAED,IAAI,CAAC,gBAAgB,CACnB,SAAS,EACT,CAAC,YAAY,EAAE,EAAE;gBACf,sEAAsE;gBACtE,sEAAsE;gBACtE,mEAAmE;gBACnE,+DAA+D;gBAC/D,WAAW;gBACX,IAAI,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC;oBAC/D,OAAO;gBACT,CAAC;gBAED,IAAI,CAAC,gBAAgB,CACnB,SAAS,EACT,GAAG,EAAE;oBACH,gEAAgE;oBAChE,gEAAgE;oBAChE,kBAAkB;oBAClB,IAAI,CAAC,2BAA2B,CAAC,CAAC,YAAY,CAAC,CAAC;gBAClD,CAAC,EACD,EAAC,IAAI,EAAE,IAAI,EAAC,CACb,CAAC;YACJ,CAAC,EACD;gBACE,gEAAgE;gBAChE,mEAAmE;gBACnE,mEAAmE;gBACnE,iEAAiE;gBACjE,OAAO,EAAE,IAAI;aACd,CACF,CAAC;QACJ,CAAC;QAEQ,aAAa;YACpB,IAAI,CAAC,yBAAyB,CAAC,GAAG,IAAI,CAAC;YACvC,MAAM,KAAK,GAAG,KAAK,CAAC,aAAa,EAAE,CAAC;YACpC,IAAI,CAAC,yBAAyB,CAAC,GAAG,KAAK,CAAC;YACxC,OAAO,KAAK,CAAC;QACf,CAAC;QAEQ,cAAc;YACrB,IAAI,CAAC,8BAA8B,CAAC,GAAG,IAAI,CAAC;YAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC;YACrC,uEAAuE;YACvE,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,CAAC;YAC1C,CAAC;YAED,IAAI,CAAC,8BAA8B,CAAC,GAAG,KAAK,CAAC;YAC7C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OA3EC,2BAA2B,OAM3B,yBAAyB,OAOzB,8BAA8B,EA8D9B,2BAA2B,EAAC,CAAC,YAA0B;YACtD,sEAAsE;YACtE,uEAAuE;YACvE,kEAAkE;YAClE,2DAA2D;YAC3D,MAAM,WAAW,GAAG,YAAY,EAAE,gBAAgB,CAAC;YACnD,IAAI,WAAW,EAAE,CAAC;gBAChB,OAAO;YACT,CAAC;YAED,IAAI,CAAC,gBAAgB,CAAC,CAAC,YAAY,CAAC,CAAC;YAErC,uEAAuE;YACvE,yEAAyE;YACzE,qBAAqB;YACrB,MAAM,2BAA2B,GAC/B,CAAC,WAAW,IAAI,YAAY,EAAE,gBAAgB,CAAC;YACjD,IAAI,CAAC,2BAA2B,EAAE,CAAC;gBACjC,OAAO;YACT,CAAC;YAED,sCAAsC;YACtC,2DAA2D;YAC3D,wEAAwE;YACxE,qBAAqB;YACrB,IACE,IAAI,CAAC,8BAA8B,CAAC;gBACpC,2BAA2B,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EACvD,CAAC;gBACD,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,CAAC;QACH,CAAC;QAED,CAAC,gBAAgB,CAAC,CAAC,YAA0B;YAC3C,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAClD,CAAC;QAEQ,sBAAsB,CAAC,IAA4B;YAC1D,4DAA4D;YAC5D,IAAI,KAAK,CAAC,sBAAsB,EAAE,CAAC;gBACjC,KAAK,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;YACrC,CAAC;YAED,oCAAoC;YACpC,IAAI,CAAC,2BAA2B,CAAC,CAAC,KAAK,EAAE,CAAC;YAC1C,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO;YACT,CAAC;YAED,IAAI,CAAC,2BAA2B,CAAC,GAAG,IAAI,eAAe,EAAE,CAAC;YAE1D,yEAAyE;YACzE,gEAAgE;YAChE,EAAE;YACF,qEAAqE;YACrE,2CAA2C;YAC3C,0BAA0B,CACxB,IAAI,EACJ,IAAI,EACJ,GAAG,EAAE;gBACH,IAAI,CAAC,2BAA2B,CAAC,CAAC,IAAI,CAAC,CAAC;YAC1C,CAAC,EACD,IAAI,CAAC,2BAA2B,CAAC,CAAC,MAAM,CACzC,CAAC;QACJ,CAAC;KACF;IAED,OAAO,uBAAuB,CAAC;AACjC,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,0BAA0B,CACjC,OAAgB,EAChB,IAAqB,EACrB,cAA0B,EAC1B,OAAoB;IAEpB,MAAM,aAAa,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAEjD,8EAA8E;IAC9E,4EAA4E;IAC5E,SAAS;IACT,IAAI,mBAAmB,GAAG,KAAK,CAAC;IAChC,IAAI,sBAAmD,CAAC;IACxD,IAAI,oBAAoB,GAAG,KAAK,CAAC;IACjC,aAAa,CAAC,gBAAgB,CAC5B,QAAQ,EACR,GAAG,EAAE;QACH,oBAAoB,GAAG,IAAI,CAAC;QAC5B,sBAAsB,GAAG,IAAI,eAAe,EAAE,CAAC;QAC/C,mBAAmB,GAAG,KAAK,CAAC;QAC5B,OAAO,CAAC,gBAAgB,CACtB,SAAS,EACT,GAAG,EAAE;YACH,mBAAmB,GAAG,IAAI,CAAC;QAC7B,CAAC,EACD;YACE,MAAM,EAAE,sBAAsB,CAAC,MAAM;SACtC,CACF,CAAC;IACJ,CAAC,EACD,EAAC,MAAM,EAAE,OAAO,EAAC,CAClB,CAAC;IAEF,aAAa,CAAC,gBAAgB,CAC5B,OAAO,EACP,GAAG,EAAE;QACH,oBAAoB,GAAG,KAAK,CAAC;QAC7B,sBAAsB,EAAE,KAAK,EAAE,CAAC;QAChC,IAAI,mBAAmB,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,cAAc,EAAE,CAAC;IACnB,CAAC,EACD,EAAC,MAAM,EAAE,OAAO,EAAC,CAClB,CAAC;IAEF,mEAAmE;IACnE,wDAAwD;IACxD,+DAA+D;IAC/D,uEAAuE;IACvE,IAAI,CAAC,gBAAgB,CACnB,QAAQ,EACR,GAAG,EAAE;QACH,uEAAuE;QACvE,YAAY;QACZ,IAAI,oBAAoB,EAAE,CAAC;YACzB,OAAO;QACT,CAAC;QAED,cAAc,EAAE,CAAC;IACnB,CAAC,EACD;QACE,MAAM,EAAE,OAAO;KAChB,CACF,CAAC;IAEF,0EAA0E;IAC1E,wEAAwE;IACxE,4CAA4C;IAC5C,EAAE;IACF,6EAA6E;IAC7E,2DAA2D;IAC3D,EAAE;IACF,2EAA2E;IAC3E,6EAA6E;IAC7E,iDAAiD;AACnD,CAAC;AAED,MAAM,mBAAmB,GAAG,IAAI,OAAO,EAAgC,CAAC;AAExE;;;;;;;;;GASG;AACH,SAAS,oBAAoB,CAAC,IAAqB;IACjD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,4EAA4E;QAC5E,2EAA2E;QAC3E,qCAAqC;QACrC,EAAE;QACF,2EAA2E;QAC3E,0EAA0E;QAC1E,sEAAsE;QACtE,4BAA4B;QAC5B,EAAE;QACF,4EAA4E;QAC5E,sCAAsC;QACtC,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC;QAChC,mBAAmB,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAErC,4EAA4E;QAC5E,8BAA8B;QAC9B,qEAAqE;QACrE,KAAK,MAAM,UAAU,IAAI,CAAC,gBAAgB,EAAE,eAAe,CAAU,EAAE,CAAC;YACtE,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;YACrC,IAAI,CAAC,UAAU,CAAC,GAAG;gBACjB,KAAK,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACzC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;gBAC3D,KAAK,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;gBACxC,OAAO,MAAM,CAAC;YAChB,CAAC,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;AACxC,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,2BAA2B,CAClC,IAA4B,EAC5B,OAAoB;IAEpB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,mBAAwC,CAAC;IAC7C,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACpC,IAAI,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YAChC,mBAAmB,GAAG,OAAO,CAAC;YAC9B,MAAM;QACR,CAAC;IACH,CAAC;IAED,OAAO,mBAAmB,KAAK,OAAO,CAAC;AACzC,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {LitElement, isServer} from 'lit';\n\nimport {ConstraintValidation} from './constraint-validation.js';\nimport {WithElementInternals, internals} from './element-internals.js';\nimport {MixinBase, MixinReturn} from './mixin.js';\n\n/**\n * A constraint validation element that has a callback for when the element\n * should report validity styles and error messages to the user.\n *\n * This is commonly used in text-field-like controls that display error styles\n * and error messages.\n */\nexport interface OnReportValidity extends ConstraintValidation {\n /**\n * A callback that is invoked when validity should be reported. Components\n * that can display their own error state can use this and update their\n * styles.\n *\n * If an invalid event is provided, the element is invalid. If `null`, the\n * element is valid.\n *\n * The invalid event's `preventDefault()` may be called to stop the platform\n * popup from displaying.\n *\n * @param invalidEvent The `invalid` event dispatched when an element is\n * invalid, or `null` if the element is valid.\n */\n [onReportValidity](invalidEvent: Event | null): void;\n\n // `mixinOnReportValidity()` implements this optional method. If overriden,\n // call `super.formAssociatedCallback(form)`.\n // (inherit jsdoc from `FormAssociated`)\n formAssociatedCallback(form: HTMLFormElement | null): void;\n}\n\n/**\n * A symbol property used for a callback when validity has been reported.\n */\nexport const onReportValidity = Symbol('onReportValidity');\n\n// Private symbol members, used to avoid name clashing.\nconst privateCleanupFormListeners = Symbol('privateCleanupFormListeners');\nconst privateDoNotReportInvalid = Symbol('privateDoNotReportInvalid');\nconst privateIsSelfReportingValidity = Symbol('privateIsSelfReportingValidity');\nconst privateCallOnReportValidity = Symbol('privateCallOnReportValidity');\n\n/**\n * Mixes in a callback for constraint validation when validity should be\n * styled and reported to the user.\n *\n * This is commonly used in text-field-like controls that display error styles\n * and error messages.\n *\n * @example\n * ```ts\n * const baseClass = mixinOnReportValidity(\n * mixinConstraintValidation(\n * mixinFormAssociated(mixinElementInternals(LitElement)),\n * ),\n * );\n *\n * class MyField extends baseClass {\n * \\@property({type: Boolean}) error = false;\n * \\@property() errorMessage = '';\n *\n * [onReportValidity](invalidEvent: Event | null) {\n * this.error = !!invalidEvent;\n * this.errorMessage = this.validationMessage;\n *\n * // Optionally prevent platform popup from displaying\n * invalidEvent?.preventDefault();\n * }\n * }\n * ```\n *\n * @param base The class to mix functionality into.\n * @return The provided class with `OnReportValidity` mixed in.\n */\nexport function mixinOnReportValidity<\n T extends MixinBase<LitElement & ConstraintValidation & WithElementInternals>,\n>(base: T): MixinReturn<T, OnReportValidity> {\n abstract class OnReportValidityElement\n extends base\n implements OnReportValidity\n {\n /**\n * Used to clean up event listeners when a new form is associated.\n */\n [privateCleanupFormListeners] = new AbortController();\n\n /**\n * Used to determine if an invalid event should report validity. Invalid\n * events from `checkValidity()` do not trigger reporting.\n */\n [privateDoNotReportInvalid] = false;\n\n /**\n * Used to determine if the control is reporting validity from itself, or\n * if a `<form>` is causing the validity report. Forms have different\n * control focusing behavior.\n */\n [privateIsSelfReportingValidity] = false;\n\n // Mixins must have a constructor with `...args: any[]`\n // tslint:disable-next-line:no-any\n constructor(...args: any[]) {\n super(...args);\n if (isServer) {\n return;\n }\n\n this.addEventListener(\n 'invalid',\n (invalidEvent) => {\n // Listen for invalid events dispatched by a `<form>` when it tries to\n // submit and the element is invalid. We ignore events dispatched when\n // calling `checkValidity()` as well as untrusted events, since the\n // `reportValidity()` and `<form>`-dispatched events are always\n // trusted.\n if (this[privateDoNotReportInvalid] || !invalidEvent.isTrusted) {\n return;\n }\n\n this.addEventListener(\n 'invalid',\n () => {\n // A normal bubbling phase event listener. By adding it here, we\n // ensure it's the last event listener that is called during the\n // bubbling phase.\n this[privateCallOnReportValidity](invalidEvent);\n },\n {once: true},\n );\n },\n {\n // Listen during the capture phase, which will happen before the\n // bubbling phase. That way, we can add a final event listener that\n // will run after other event listeners, and we can check if it was\n // default prevented. This works because invalid does not bubble.\n capture: true,\n },\n );\n }\n\n override checkValidity() {\n this[privateDoNotReportInvalid] = true;\n const valid = super.checkValidity();\n this[privateDoNotReportInvalid] = false;\n return valid;\n }\n\n override reportValidity() {\n this[privateIsSelfReportingValidity] = true;\n const valid = super.reportValidity();\n // Constructor's invalid listener will handle reporting invalid events.\n if (valid) {\n this[privateCallOnReportValidity](null);\n }\n\n this[privateIsSelfReportingValidity] = false;\n return valid;\n }\n\n [privateCallOnReportValidity](invalidEvent: Event | null) {\n // Since invalid events do not bubble to parent listeners, and because\n // our invalid listeners are added lazily after other listeners, we can\n // reliably read `defaultPrevented` synchronously without worrying\n // about waiting for another listener that could cancel it.\n const wasCanceled = invalidEvent?.defaultPrevented;\n if (wasCanceled) {\n return;\n }\n\n this[onReportValidity](invalidEvent);\n\n // If an implementation calls invalidEvent.preventDefault() to stop the\n // platform popup from displaying, focusing is also prevented, so we need\n // to manually focus.\n const implementationCanceledFocus =\n !wasCanceled && invalidEvent?.defaultPrevented;\n if (!implementationCanceledFocus) {\n return;\n }\n\n // The control should be focused when:\n // - `control.reportValidity()` is called (self-reporting).\n // - a form is reporting validity for its controls and this is the first\n // invalid control.\n if (\n this[privateIsSelfReportingValidity] ||\n isFirstInvalidControlInForm(this[internals].form, this)\n ) {\n this.focus();\n }\n }\n\n [onReportValidity](invalidEvent: Event | null) {\n throw new Error('Implement [onReportValidity]');\n }\n\n override formAssociatedCallback(form: HTMLFormElement | null) {\n // can't use super.formAssociatedCallback?.() due to closure\n if (super.formAssociatedCallback) {\n super.formAssociatedCallback(form);\n }\n\n // Clean up previous form listeners.\n this[privateCleanupFormListeners].abort();\n if (!form) {\n return;\n }\n\n this[privateCleanupFormListeners] = new AbortController();\n\n // Add a listener that fires when the form runs constraint validation and\n // the control is valid, so that it may remove its error styles.\n //\n // This happens on `form.reportValidity()` and `form.requestSubmit()`\n // (both when the submit fails and passes).\n addFormReportValidListener(\n this,\n form,\n () => {\n this[privateCallOnReportValidity](null);\n },\n this[privateCleanupFormListeners].signal,\n );\n }\n }\n\n return OnReportValidityElement;\n}\n\n/**\n * Add a listener that fires when a form runs constraint validation on a control\n * and it is valid. This is needed to clear previously invalid styles.\n *\n * @param control The control of the form to listen for valid events.\n * @param form The control's form that can run constraint validation.\n * @param onControlValid A listener that is called when the form runs constraint\n * validation and the control is valid.\n * @param cleanup A cleanup signal to remove the listener.\n */\nfunction addFormReportValidListener(\n control: Element,\n form: HTMLFormElement,\n onControlValid: () => void,\n cleanup: AbortSignal,\n) {\n const validateHooks = getFormValidateHooks(form);\n\n // When a form validates its controls, check if an invalid event is dispatched\n // on the control. If it is not, then inform the control to report its valid\n // state.\n let controlFiredInvalid = false;\n let cleanupInvalidListener: AbortController | undefined;\n let isNextSubmitFromHook = false;\n validateHooks.addEventListener(\n 'before',\n () => {\n isNextSubmitFromHook = true;\n cleanupInvalidListener = new AbortController();\n controlFiredInvalid = false;\n control.addEventListener(\n 'invalid',\n () => {\n controlFiredInvalid = true;\n },\n {\n signal: cleanupInvalidListener.signal,\n },\n );\n },\n {signal: cleanup},\n );\n\n validateHooks.addEventListener(\n 'after',\n () => {\n isNextSubmitFromHook = false;\n cleanupInvalidListener?.abort();\n if (controlFiredInvalid) {\n return;\n }\n\n onControlValid();\n },\n {signal: cleanup},\n );\n\n // The above hooks handle imperatively submitting the form, but not\n // declaratively submitting the form. This happens when:\n // 1. A non-custom element `<button type=\"submit\">` is clicked.\n // 2. Enter is pressed on a non-custom element text editable `<input>`.\n form.addEventListener(\n 'submit',\n () => {\n // This submit was from `form.requestSubmit()`, which already calls the\n // listener.\n if (isNextSubmitFromHook) {\n return;\n }\n\n onControlValid();\n },\n {\n signal: cleanup,\n },\n );\n\n // Note: it is a known limitation that we cannot detect if a form tries to\n // submit declaratively, but fails to do so because an unrelated sibling\n // control failed its constraint validation.\n //\n // Since we cannot detect when that happens, a previously invalid control may\n // not clear its error styling when it becomes valid again.\n //\n // To work around this, call `form.reportValidity()` when submitting a form\n // declaratively. This can be down on the `<button type=\"submit\">`'s click or\n // the text editable `<input>`'s 'Enter' keydown.\n}\n\nconst FORM_VALIDATE_HOOKS = new WeakMap<HTMLFormElement, EventTarget>();\n\n/**\n * Get a hooks `EventTarget` that dispatches 'before' and 'after' events that\n * fire before a form runs constraint validation and immediately after it\n * finishes running constraint validation on its controls.\n *\n * This happens during `form.reportValidity()` and `form.requestSubmit()`.\n *\n * @param form The form to get or set up hooks for.\n * @return A hooks `EventTarget` to add listeners to.\n */\nfunction getFormValidateHooks(form: HTMLFormElement) {\n if (!FORM_VALIDATE_HOOKS.has(form)) {\n // Patch form methods to add event listener hooks. These are needed to react\n // to form behaviors that do not dispatch events, such as a form asking its\n // controls to report their validity.\n //\n // We should only patch the methods once, since multiple controls and other\n // forces may want to patch this method. We cannot reliably clean it up if\n // there are multiple patched and re-patched methods referring holding\n // references to each other.\n //\n // Instead, we never clean up the patch but add and clean up event listeners\n // added to the hooks after the patch.\n const hooks = new EventTarget();\n FORM_VALIDATE_HOOKS.set(form, hooks);\n\n // Add hooks to support notifying before and after a form has run constraint\n // validation on its controls.\n // Note: `form.submit()` does not run constraint validation per spec.\n for (const methodName of ['reportValidity', 'requestSubmit'] as const) {\n const superMethod = form[methodName];\n form[methodName] = function (this: HTMLFormElement) {\n hooks.dispatchEvent(new Event('before'));\n const result = Reflect.apply(superMethod, this, arguments);\n hooks.dispatchEvent(new Event('after'));\n return result;\n };\n }\n }\n\n return FORM_VALIDATE_HOOKS.get(form)!;\n}\n\n/**\n * Checks if a control is the first invalid control in a form.\n *\n * @param form The control's form. When `null`, the control doesn't have a form\n * and the method returns true.\n * @param control The control to check.\n * @return True if there is no form or if the control is the form's first\n * invalid control.\n */\nfunction isFirstInvalidControlInForm(\n form: HTMLFormElement | null,\n control: HTMLElement,\n) {\n if (!form) {\n return true;\n }\n\n let firstInvalidControl: Element | undefined;\n for (const element of form.elements) {\n if (element.matches(':invalid')) {\n firstInvalidControl = element;\n break;\n }\n }\n\n return firstInvalidControl === control;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"checkbox-validator.js","sourceRoot":"","sources":["checkbox-validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAiBzC;;;GAGG;AACH,MAAM,OAAO,iBAAkB,SAAQ,SAAwB;IAG1C,eAAe,CAAC,KAAoB;QACrD,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE;YACzB,mCAAmC;YACnC,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YACvD,IAAI,CAAC,eAAe,CAAC,IAAI,GAAG,UAAU,CAAC;SACxC;QAED,IAAI,CAAC,eAAe,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC7C,IAAI,CAAC,eAAe,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QAC/C,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,eAAe,CAAC,QAAQ;YACvC,iBAAiB,EAAE,IAAI,CAAC,eAAe,CAAC,iBAAiB;SAC1D,CAAC;IACJ,CAAC;IAEkB,MAAM,CAAC,IAAmB,EAAE,IAAmB;QAChE,OAAO,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,CAAC;IAC1E,CAAC;IAEkB,IAAI,CAAC,EAAC,OAAO,EAAE,QAAQ,EAAgB;QACxD,OAAO,EAAC,OAAO,EAAE,QAAQ,EAAC,CAAC;IAC7B,CAAC;CACF","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Validator} from './validator.js';\n\n/**\n * Constraint validation properties for a checkbox.\n */\nexport interface CheckboxState {\n /**\n * Whether the checkbox is checked.\n */\n readonly checked: boolean;\n\n /**\n * Whether the checkbox is required.\n */\n readonly required: boolean;\n}\n\n/**\n * A validator that provides constraint validation that emulates\n * `<input type=\"checkbox\">` validation.\n */\nexport class CheckboxValidator extends Validator<CheckboxState> {\n private checkboxControl?: HTMLInputElement;\n\n protected override computeValidity(state: CheckboxState) {\n if (!this.checkboxControl) {\n // Lazily create the platform input\n this.checkboxControl = document.createElement('input');\n this.checkboxControl.type = 'checkbox';\n }\n\n this.checkboxControl.checked = state.checked;\n this.checkboxControl.required = state.required;\n return {\n validity: this.checkboxControl.validity,\n validationMessage: this.checkboxControl.validationMessage,\n };\n }\n\n protected override equals(prev: CheckboxState, next: CheckboxState) {\n return prev.checked === next.checked && prev.required === next.required;\n }\n\n protected override copy({checked, required}: CheckboxState) {\n return {checked, required};\n }\n}\n"]}
1
+ {"version":3,"file":"checkbox-validator.js","sourceRoot":"","sources":["checkbox-validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAiBzC;;;GAGG;AACH,MAAM,OAAO,iBAAkB,SAAQ,SAAwB;IAG1C,eAAe,CAAC,KAAoB;QACrD,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YAC1B,mCAAmC;YACnC,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YACvD,IAAI,CAAC,eAAe,CAAC,IAAI,GAAG,UAAU,CAAC;QACzC,CAAC;QAED,IAAI,CAAC,eAAe,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC7C,IAAI,CAAC,eAAe,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QAC/C,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,eAAe,CAAC,QAAQ;YACvC,iBAAiB,EAAE,IAAI,CAAC,eAAe,CAAC,iBAAiB;SAC1D,CAAC;IACJ,CAAC;IAEkB,MAAM,CAAC,IAAmB,EAAE,IAAmB;QAChE,OAAO,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,CAAC;IAC1E,CAAC;IAEkB,IAAI,CAAC,EAAC,OAAO,EAAE,QAAQ,EAAgB;QACxD,OAAO,EAAC,OAAO,EAAE,QAAQ,EAAC,CAAC;IAC7B,CAAC;CACF","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Validator} from './validator.js';\n\n/**\n * Constraint validation properties for a checkbox.\n */\nexport interface CheckboxState {\n /**\n * Whether the checkbox is checked.\n */\n readonly checked: boolean;\n\n /**\n * Whether the checkbox is required.\n */\n readonly required: boolean;\n}\n\n/**\n * A validator that provides constraint validation that emulates\n * `<input type=\"checkbox\">` validation.\n */\nexport class CheckboxValidator extends Validator<CheckboxState> {\n private checkboxControl?: HTMLInputElement;\n\n protected override computeValidity(state: CheckboxState) {\n if (!this.checkboxControl) {\n // Lazily create the platform input\n this.checkboxControl = document.createElement('input');\n this.checkboxControl.type = 'checkbox';\n }\n\n this.checkboxControl.checked = state.checked;\n this.checkboxControl.required = state.required;\n return {\n validity: this.checkboxControl.validity,\n validationMessage: this.checkboxControl.validationMessage,\n };\n }\n\n protected override equals(prev: CheckboxState, next: CheckboxState) {\n return prev.checked === next.checked && prev.required === next.required;\n }\n\n protected override copy({checked, required}: CheckboxState) {\n return {checked, required};\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"radio-validator.js","sourceRoot":"","sources":["radio-validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAsBzC;;;GAGG;AACH,MAAM,OAAO,cAAe,SAAQ,SAA0B;IAGzC,eAAe,CAAC,MAAuB;QACxD,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;YACtB,kCAAkC;YAClC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YACpD,IAAI,CAAC,YAAY,CAAC,IAAI,GAAG,OAAO,CAAC;YACjC,2CAA2C;YAC3C,IAAI,CAAC,YAAY,CAAC,IAAI,GAAG,OAAO,CAAC;SAClC;QAED,IAAI,UAAU,GAAG,KAAK,CAAC;QACvB,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,KAAK,MAAM,EAAC,OAAO,EAAE,QAAQ,EAAC,IAAI,MAAM,EAAE;YACxC,IAAI,QAAQ,EAAE;gBACZ,UAAU,GAAG,IAAI,CAAC;aACnB;YAED,IAAI,OAAO,EAAE;gBACX,SAAS,GAAG,IAAI,CAAC;aAClB;SACF;QAED,wEAAwE;QACxE,wEAAwE;QACxE,0EAA0E;QAC1E,8DAA8D;QAC9D,IAAI,CAAC,YAAY,CAAC,OAAO,GAAG,SAAS,CAAC;QACtC,IAAI,CAAC,YAAY,CAAC,QAAQ,GAAG,UAAU,CAAC;QACxC,OAAO;YACL,QAAQ,EAAE;gBACR,YAAY,EAAE,UAAU,IAAI,CAAC,SAAS;aACvC;YACD,iBAAiB,EAAE,IAAI,CAAC,YAAY,CAAC,iBAAiB;SACvD,CAAC;IACJ,CAAC;IAEkB,MAAM,CACvB,SAA0B,EAC1B,SAA0B;QAE1B,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,EAAE;YACzC,OAAO,KAAK,CAAC;SACd;QAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACzC,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YAC1B,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YAC1B,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,EAAE;gBACpE,OAAO,KAAK,CAAC;aACd;SACF;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAEkB,IAAI,CAAC,MAAuB;QAC7C,uEAAuE;QACvE,wDAAwD;QACxD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,EAAC,OAAO,EAAE,QAAQ,EAAC,EAAE,EAAE,CAAC,CAAC;YAC1C,OAAO;YACP,QAAQ;SACT,CAAC,CAA+B,CAAC;IACpC,CAAC;CACF","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Validator} from './validator.js';\n\n/**\n * Constraint validation properties for a radio.\n */\nexport interface RadioState {\n /**\n * Whether the radio is checked.\n */\n readonly checked: boolean;\n\n /**\n * Whether the radio is required.\n */\n readonly required: boolean;\n}\n\n/**\n * Radio constraint validation properties for a single radio and its siblings.\n */\nexport type RadioGroupState = readonly [RadioState, ...RadioState[]];\n\n/**\n * A validator that provides constraint validation that emulates\n * `<input type=\"radio\">` validation.\n */\nexport class RadioValidator extends Validator<RadioGroupState> {\n private radioElement?: HTMLInputElement;\n\n protected override computeValidity(states: RadioGroupState) {\n if (!this.radioElement) {\n // Lazily create the radio element\n this.radioElement = document.createElement('input');\n this.radioElement.type = 'radio';\n // A name is required for validation to run\n this.radioElement.name = 'group';\n }\n\n let isRequired = false;\n let isChecked = false;\n for (const {checked, required} of states) {\n if (required) {\n isRequired = true;\n }\n\n if (checked) {\n isChecked = true;\n }\n }\n\n // Firefox v119 doesn't compute grouped radio validation correctly while\n // they are detached from the DOM, which is why we don't render multiple\n // virtual <input>s. Instead, we can check the required/checked states and\n // grab the i18n'd validation message if the value is missing.\n this.radioElement.checked = isChecked;\n this.radioElement.required = isRequired;\n return {\n validity: {\n valueMissing: isRequired && !isChecked,\n },\n validationMessage: this.radioElement.validationMessage,\n };\n }\n\n protected override equals(\n prevGroup: RadioGroupState,\n nextGroup: RadioGroupState,\n ) {\n if (prevGroup.length !== nextGroup.length) {\n return false;\n }\n\n for (let i = 0; i < prevGroup.length; i++) {\n const prev = prevGroup[i];\n const next = nextGroup[i];\n if (prev.checked !== next.checked || prev.required !== next.required) {\n return false;\n }\n }\n\n return true;\n }\n\n protected override copy(states: RadioGroupState): RadioGroupState {\n // Cast as unknown since typescript does not have enough information to\n // infer that the array always has at least one element.\n return states.map(({checked, required}) => ({\n checked,\n required,\n })) as unknown as RadioGroupState;\n }\n}\n"]}
1
+ {"version":3,"file":"radio-validator.js","sourceRoot":"","sources":["radio-validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAsBzC;;;GAGG;AACH,MAAM,OAAO,cAAe,SAAQ,SAA0B;IAGzC,eAAe,CAAC,MAAuB;QACxD,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,kCAAkC;YAClC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YACpD,IAAI,CAAC,YAAY,CAAC,IAAI,GAAG,OAAO,CAAC;YACjC,2CAA2C;YAC3C,IAAI,CAAC,YAAY,CAAC,IAAI,GAAG,OAAO,CAAC;QACnC,CAAC;QAED,IAAI,UAAU,GAAG,KAAK,CAAC;QACvB,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,KAAK,MAAM,EAAC,OAAO,EAAE,QAAQ,EAAC,IAAI,MAAM,EAAE,CAAC;YACzC,IAAI,QAAQ,EAAE,CAAC;gBACb,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;YAED,IAAI,OAAO,EAAE,CAAC;gBACZ,SAAS,GAAG,IAAI,CAAC;YACnB,CAAC;QACH,CAAC;QAED,wEAAwE;QACxE,wEAAwE;QACxE,0EAA0E;QAC1E,8DAA8D;QAC9D,IAAI,CAAC,YAAY,CAAC,OAAO,GAAG,SAAS,CAAC;QACtC,IAAI,CAAC,YAAY,CAAC,QAAQ,GAAG,UAAU,CAAC;QACxC,OAAO;YACL,QAAQ,EAAE;gBACR,YAAY,EAAE,UAAU,IAAI,CAAC,SAAS;aACvC;YACD,iBAAiB,EAAE,IAAI,CAAC,YAAY,CAAC,iBAAiB;SACvD,CAAC;IACJ,CAAC;IAEkB,MAAM,CACvB,SAA0B,EAC1B,SAA0B;QAE1B,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC;YAC1C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YAC1B,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YAC1B,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACrE,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAEkB,IAAI,CAAC,MAAuB;QAC7C,uEAAuE;QACvE,wDAAwD;QACxD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,EAAC,OAAO,EAAE,QAAQ,EAAC,EAAE,EAAE,CAAC,CAAC;YAC1C,OAAO;YACP,QAAQ;SACT,CAAC,CAA+B,CAAC;IACpC,CAAC;CACF","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {Validator} from './validator.js';\n\n/**\n * Constraint validation properties for a radio.\n */\nexport interface RadioState {\n /**\n * Whether the radio is checked.\n */\n readonly checked: boolean;\n\n /**\n * Whether the radio is required.\n */\n readonly required: boolean;\n}\n\n/**\n * Radio constraint validation properties for a single radio and its siblings.\n */\nexport type RadioGroupState = readonly [RadioState, ...RadioState[]];\n\n/**\n * A validator that provides constraint validation that emulates\n * `<input type=\"radio\">` validation.\n */\nexport class RadioValidator extends Validator<RadioGroupState> {\n private radioElement?: HTMLInputElement;\n\n protected override computeValidity(states: RadioGroupState) {\n if (!this.radioElement) {\n // Lazily create the radio element\n this.radioElement = document.createElement('input');\n this.radioElement.type = 'radio';\n // A name is required for validation to run\n this.radioElement.name = 'group';\n }\n\n let isRequired = false;\n let isChecked = false;\n for (const {checked, required} of states) {\n if (required) {\n isRequired = true;\n }\n\n if (checked) {\n isChecked = true;\n }\n }\n\n // Firefox v119 doesn't compute grouped radio validation correctly while\n // they are detached from the DOM, which is why we don't render multiple\n // virtual <input>s. Instead, we can check the required/checked states and\n // grab the i18n'd validation message if the value is missing.\n this.radioElement.checked = isChecked;\n this.radioElement.required = isRequired;\n return {\n validity: {\n valueMissing: isRequired && !isChecked,\n },\n validationMessage: this.radioElement.validationMessage,\n };\n }\n\n protected override equals(\n prevGroup: RadioGroupState,\n nextGroup: RadioGroupState,\n ) {\n if (prevGroup.length !== nextGroup.length) {\n return false;\n }\n\n for (let i = 0; i < prevGroup.length; i++) {\n const prev = prevGroup[i];\n const next = nextGroup[i];\n if (prev.checked !== next.checked || prev.required !== next.required) {\n return false;\n }\n }\n\n return true;\n }\n\n protected override copy(states: RadioGroupState): RadioGroupState {\n // Cast as unknown since typescript does not have enough information to\n // infer that the array always has at least one element.\n return states.map(({checked, required}) => ({\n checked,\n required,\n })) as unknown as RadioGroupState;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"select-validator.js","sourceRoot":"","sources":["select-validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,IAAI,EAAE,MAAM,EAAC,MAAM,KAAK,CAAC;AAEjC,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAiBzC;;;GAGG;AACH,MAAM,OAAO,eAAgB,SAAQ,SAAsB;IAGtC,eAAe,CAAC,KAAkB;QACnD,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE;YACvB,oCAAoC;YACpC,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;SACvD;QAED,MAAM,CAAC,IAAI,CAAA,iBAAiB,KAAK,CAAC,KAAK,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAEzE,IAAI,CAAC,aAAa,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACvC,IAAI,CAAC,aAAa,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QAC7C,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ;YACrC,iBAAiB,EAAE,IAAI,CAAC,aAAa,CAAC,iBAAiB;SACxD,CAAC;IACJ,CAAC;IAEkB,MAAM,CAAC,IAAiB,EAAE,IAAiB;QAC5D,OAAO,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,CAAC;IACtE,CAAC;IAEkB,IAAI,CAAC,EAAC,KAAK,EAAE,QAAQ,EAAc;QACpD,OAAO,EAAC,KAAK,EAAE,QAAQ,EAAC,CAAC;IAC3B,CAAC;CACF","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {html, render} from 'lit';\n\nimport {Validator} from './validator.js';\n\n/**\n * Constraint validation properties for a select dropdown.\n */\nexport interface SelectState {\n /**\n * The current selected value.\n */\n readonly value: string;\n\n /**\n * Whether the select is required.\n */\n readonly required: boolean;\n}\n\n/**\n * A validator that provides constraint validation that emulates `<select>`\n * validation.\n */\nexport class SelectValidator extends Validator<SelectState> {\n private selectControl?: HTMLSelectElement;\n\n protected override computeValidity(state: SelectState) {\n if (!this.selectControl) {\n // Lazily create the platform select\n this.selectControl = document.createElement('select');\n }\n\n render(html`<option value=${state.value}></option>`, this.selectControl);\n\n this.selectControl.value = state.value;\n this.selectControl.required = state.required;\n return {\n validity: this.selectControl.validity,\n validationMessage: this.selectControl.validationMessage,\n };\n }\n\n protected override equals(prev: SelectState, next: SelectState) {\n return prev.value === next.value && prev.required === next.required;\n }\n\n protected override copy({value, required}: SelectState) {\n return {value, required};\n }\n}\n"]}
1
+ {"version":3,"file":"select-validator.js","sourceRoot":"","sources":["select-validator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAC,IAAI,EAAE,MAAM,EAAC,MAAM,KAAK,CAAC;AAEjC,OAAO,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAiBzC;;;GAGG;AACH,MAAM,OAAO,eAAgB,SAAQ,SAAsB;IAGtC,eAAe,CAAC,KAAkB;QACnD,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,oCAAoC;YACpC,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QACxD,CAAC;QAED,MAAM,CAAC,IAAI,CAAA,iBAAiB,KAAK,CAAC,KAAK,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAEzE,IAAI,CAAC,aAAa,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACvC,IAAI,CAAC,aAAa,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QAC7C,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,QAAQ;YACrC,iBAAiB,EAAE,IAAI,CAAC,aAAa,CAAC,iBAAiB;SACxD,CAAC;IACJ,CAAC;IAEkB,MAAM,CAAC,IAAiB,EAAE,IAAiB;QAC5D,OAAO,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,CAAC;IACtE,CAAC;IAEkB,IAAI,CAAC,EAAC,KAAK,EAAE,QAAQ,EAAc;QACpD,OAAO,EAAC,KAAK,EAAE,QAAQ,EAAC,CAAC;IAC3B,CAAC;CACF","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {html, render} from 'lit';\n\nimport {Validator} from './validator.js';\n\n/**\n * Constraint validation properties for a select dropdown.\n */\nexport interface SelectState {\n /**\n * The current selected value.\n */\n readonly value: string;\n\n /**\n * Whether the select is required.\n */\n readonly required: boolean;\n}\n\n/**\n * A validator that provides constraint validation that emulates `<select>`\n * validation.\n */\nexport class SelectValidator extends Validator<SelectState> {\n private selectControl?: HTMLSelectElement;\n\n protected override computeValidity(state: SelectState) {\n if (!this.selectControl) {\n // Lazily create the platform select\n this.selectControl = document.createElement('select');\n }\n\n render(html`<option value=${state.value}></option>`, this.selectControl);\n\n this.selectControl.value = state.value;\n this.selectControl.required = state.required;\n return {\n validity: this.selectControl.validity,\n validationMessage: this.selectControl.validationMessage,\n };\n }\n\n protected override equals(prev: SelectState, next: SelectState) {\n return prev.value === next.value && prev.required === next.required;\n }\n\n protected override copy({value, required}: SelectState) {\n return {value, required};\n }\n}\n"]}