@material/web 1.1.2-nightly.cef1b74.0 → 1.2.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 (120) hide show
  1. package/button/internal/button.d.ts +9 -1
  2. package/button/internal/button.js +9 -1
  3. package/button/internal/button.js.map +1 -1
  4. package/checkbox/internal/_checkbox.scss +69 -63
  5. package/checkbox/internal/checkbox-styles.css.js +1 -1
  6. package/checkbox/internal/checkbox-styles.css.js.map +1 -1
  7. package/dialog/internal/_dialog.scss +50 -42
  8. package/dialog/internal/dialog-styles.css.js +1 -1
  9. package/dialog/internal/dialog-styles.css.js.map +1 -1
  10. package/divider/internal/_divider.scss +6 -6
  11. package/divider/internal/divider-styles.css.js +1 -1
  12. package/divider/internal/divider-styles.css.js.map +1 -1
  13. package/elevation/internal/_elevation.scss +10 -4
  14. package/elevation/internal/elevation-styles.css.js +1 -1
  15. package/elevation/internal/elevation-styles.css.js.map +1 -1
  16. package/fab/branded-fab.d.ts +1 -1
  17. package/fab/branded-fab.js.map +1 -1
  18. package/fab/fab.d.ts +2 -2
  19. package/fab/fab.js.map +1 -1
  20. package/iconbutton/internal/icon-button.d.ts +9 -1
  21. package/iconbutton/internal/icon-button.js +9 -1
  22. package/iconbutton/internal/icon-button.js.map +1 -1
  23. package/labs/behaviors/on-report-validity.d.ts +2 -1
  24. package/labs/behaviors/on-report-validity.js +171 -67
  25. package/labs/behaviors/on-report-validity.js.map +1 -1
  26. package/list/list-item.d.ts +1 -1
  27. package/list/list-item.js.map +1 -1
  28. package/menu/internal/menuitem/_menu-item.scss +31 -52
  29. package/menu/internal/menuitem/menu-item-styles.css.js +1 -1
  30. package/menu/internal/menuitem/menu-item-styles.css.js.map +1 -1
  31. package/menu/internal/menuitem/menu-item.d.ts +1 -1
  32. package/menu/internal/menuitem/menu-item.js.map +1 -1
  33. package/menu/menu-item.d.ts +2 -2
  34. package/menu/menu-item.js.map +1 -1
  35. package/menu/menu.d.ts +3 -3
  36. package/menu/menu.js.map +1 -1
  37. package/package.json +5 -3
  38. package/radio/internal/_radio.scss +34 -34
  39. package/radio/internal/radio-styles.css.js +1 -1
  40. package/radio/internal/radio-styles.css.js.map +1 -1
  41. package/ripple/internal/_ripple.scss +8 -9
  42. package/ripple/internal/ripple-styles.css.js +1 -1
  43. package/ripple/internal/ripple-styles.css.js.map +1 -1
  44. package/select/internal/select.js +3 -10
  45. package/select/internal/select.js.map +1 -1
  46. package/select/select-option.d.ts +1 -1
  47. package/select/select-option.js.map +1 -1
  48. package/switch/internal/_handle.scss +42 -37
  49. package/switch/internal/_icon.scss +17 -17
  50. package/switch/internal/_switch.scss +52 -52
  51. package/switch/internal/_track.scss +18 -18
  52. package/switch/internal/switch-styles.css.js +1 -1
  53. package/switch/internal/switch-styles.css.js.map +1 -1
  54. package/tabs/internal/tabs.d.ts +1 -0
  55. package/tabs/internal/tabs.js +7 -2
  56. package/tabs/internal/tabs.js.map +1 -1
  57. package/testing/harness.d.ts +371 -0
  58. package/testing/harness.js +737 -0
  59. package/testing/harness.js.map +1 -0
  60. package/testing/transform-pseudo-classes.d.ts +39 -0
  61. package/testing/transform-pseudo-classes.js +172 -0
  62. package/testing/transform-pseudo-classes.js.map +1 -0
  63. package/textfield/filled-text-field.d.ts +1 -1
  64. package/textfield/filled-text-field.js.map +1 -1
  65. package/textfield/internal/text-field.d.ts +1 -2
  66. package/textfield/internal/text-field.js +12 -18
  67. package/textfield/internal/text-field.js.map +1 -1
  68. package/textfield/outlined-text-field.d.ts +1 -1
  69. package/textfield/outlined-text-field.js.map +1 -1
  70. package/tokens/_index.scss +0 -1
  71. package/tokens/_md-comp-assist-chip.scss +2 -2
  72. package/tokens/_md-comp-checkbox.scss +2 -2
  73. package/tokens/_md-comp-circular-progress.scss +2 -2
  74. package/tokens/_md-comp-dialog.scss +2 -2
  75. package/tokens/_md-comp-divider.scss +2 -2
  76. package/tokens/_md-comp-elevated-button.scss +2 -2
  77. package/tokens/_md-comp-elevated-card.scss +2 -2
  78. package/tokens/_md-comp-elevation.scss +2 -2
  79. package/tokens/_md-comp-fab-branded.scss +2 -2
  80. package/tokens/_md-comp-fab.scss +2 -2
  81. package/tokens/_md-comp-filled-button.scss +2 -2
  82. package/tokens/_md-comp-filled-card.scss +2 -2
  83. package/tokens/_md-comp-filled-field.scss +2 -2
  84. package/tokens/_md-comp-filled-icon-button.scss +2 -2
  85. package/tokens/_md-comp-filled-select.scss +2 -2
  86. package/tokens/_md-comp-filled-text-field.scss +2 -2
  87. package/tokens/_md-comp-filled-tonal-button.scss +2 -2
  88. package/tokens/_md-comp-filled-tonal-icon-button.scss +2 -2
  89. package/tokens/_md-comp-filter-chip.scss +2 -2
  90. package/tokens/_md-comp-focus-ring.scss +2 -2
  91. package/tokens/_md-comp-icon-button.scss +2 -2
  92. package/tokens/_md-comp-icon.scss +2 -2
  93. package/tokens/_md-comp-input-chip.scss +2 -2
  94. package/tokens/_md-comp-item.scss +2 -2
  95. package/tokens/_md-comp-linear-progress.scss +2 -2
  96. package/tokens/_md-comp-list-item.scss +4 -4
  97. package/tokens/_md-comp-list.scss +2 -2
  98. package/tokens/_md-comp-menu-item.scss +65 -9
  99. package/tokens/_md-comp-menu.scss +2 -2
  100. package/tokens/_md-comp-outlined-button.scss +2 -2
  101. package/tokens/_md-comp-outlined-card.scss +2 -2
  102. package/tokens/_md-comp-outlined-field.scss +2 -2
  103. package/tokens/_md-comp-outlined-icon-button.scss +2 -2
  104. package/tokens/_md-comp-outlined-segmented-button.scss +2 -2
  105. package/tokens/_md-comp-outlined-select.scss +2 -2
  106. package/tokens/_md-comp-outlined-text-field.scss +2 -2
  107. package/tokens/_md-comp-primary-tab.scss +2 -2
  108. package/tokens/_md-comp-radio.scss +2 -2
  109. package/tokens/_md-comp-ripple.scss +2 -2
  110. package/tokens/_md-comp-secondary-tab.scss +2 -2
  111. package/tokens/_md-comp-slider.scss +2 -2
  112. package/tokens/_md-comp-suggestion-chip.scss +2 -2
  113. package/tokens/_md-comp-switch.scss +2 -2
  114. package/tokens/_md-comp-text-button.scss +2 -2
  115. package/tokens/_md-ref-palette.scss +2 -2
  116. package/tokens/_md-ref-typeface.scss +2 -2
  117. package/tokens/_md-sys-color.scss +3 -3
  118. package/tokens/_md-sys-typescale.scss +2 -2
  119. package/tokens/{_values.scss → internal/_validate.scss} +10 -10
  120. package/tokens/_md-comp-menu-list-item.scss +0 -162
@@ -5,6 +5,7 @@
5
5
 
6
6
  // go/keep-sorted start
7
7
  @use 'sass:list';
8
+ @use 'sass:map';
8
9
  // go/keep-sorted end
9
10
  // go/keep-sorted start
10
11
  @use '../../tokens';
@@ -26,16 +27,15 @@
26
27
 
27
28
  @mixin styles() {
28
29
  $tokens: tokens.md-comp-divider-values();
30
+ @each $token, $value in $tokens {
31
+ $tokens: map.set($tokens, $token, var(--md-divider-#{$token}, #{$value}));
32
+ }
29
33
 
30
34
  :host {
31
- @each $token, $value in $tokens {
32
- --_#{$token}: var(--md-divider-#{$token}, #{$value});
33
- }
34
-
35
35
  box-sizing: border-box;
36
- color: var(--_color);
36
+ color: map.get($tokens, 'color');
37
37
  display: flex;
38
- height: var(--_thickness);
38
+ height: map.get($tokens, 'thickness');
39
39
  width: 100%;
40
40
  }
41
41
 
@@ -4,6 +4,6 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { css } from 'lit';
7
- export const styles = css `:host{--_color: var(--md-divider-color, var(--md-sys-color-outline-variant, #cac4d0));--_thickness: var(--md-divider-thickness, 1px);box-sizing:border-box;color:var(--_color);display:flex;height:var(--_thickness);width:100%}:host([inset]),:host([inset-start]){padding-inline-start:16px}:host([inset]),:host([inset-end]){padding-inline-end:16px}:host::before{background:currentColor;content:"";height:100%;width:100%}@media(forced-colors: active){:host::before{background:CanvasText}}/*# sourceMappingURL=divider-styles.css.map */
7
+ export const styles = css `:host{box-sizing:border-box;color:var(--md-divider-color, var(--md-sys-color-outline-variant, #cac4d0));display:flex;height:var(--md-divider-thickness, 1px);width:100%}:host([inset]),:host([inset-start]){padding-inline-start:16px}:host([inset]),:host([inset-end]){padding-inline-end:16px}:host::before{background:currentColor;content:"";height:100%;width:100%}@media(forced-colors: active){:host::before{background:CanvasText}}/*# sourceMappingURL=divider-styles.css.map */
8
8
  `;
9
9
  //# sourceMappingURL=divider-styles.css.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"divider-styles.css.js","sourceRoot":"","sources":["divider-styles.css.ts"],"names":[],"mappings":"AAAA;;;;IAII;AACH,OAAO,EAAC,GAAG,EAAC,MAAM,KAAK,CAAC;AACxB,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;CACzB,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n import {css} from 'lit';\n export const styles = css`:host{--_color: var(--md-divider-color, var(--md-sys-color-outline-variant, #cac4d0));--_thickness: var(--md-divider-thickness, 1px);box-sizing:border-box;color:var(--_color);display:flex;height:var(--_thickness);width:100%}:host([inset]),:host([inset-start]){padding-inline-start:16px}:host([inset]),:host([inset-end]){padding-inline-end:16px}:host::before{background:currentColor;content:\"\";height:100%;width:100%}@media(forced-colors: active){:host::before{background:CanvasText}}/*# sourceMappingURL=divider-styles.css.map */\n`;\n "]}
1
+ {"version":3,"file":"divider-styles.css.js","sourceRoot":"","sources":["divider-styles.css.ts"],"names":[],"mappings":"AAAA;;;;IAII;AACH,OAAO,EAAC,GAAG,EAAC,MAAM,KAAK,CAAC;AACxB,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;CACzB,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n import {css} from 'lit';\n export const styles = css`:host{box-sizing:border-box;color:var(--md-divider-color, var(--md-sys-color-outline-variant, #cac4d0));display:flex;height:var(--md-divider-thickness, 1px);width:100%}:host([inset]),:host([inset-start]){padding-inline-start:16px}:host([inset]),:host([inset-end]){padding-inline-end:16px}:host::before{background:currentColor;content:\"\";height:100%;width:100%}@media(forced-colors: active){:host::before{background:CanvasText}}/*# sourceMappingURL=divider-styles.css.map */\n`;\n "]}
@@ -27,12 +27,11 @@
27
27
 
28
28
  @mixin styles() {
29
29
  $tokens: tokens.md-comp-elevation-values();
30
+ @each $token, $value in $tokens {
31
+ $tokens: map.set($tokens, $token, var(--md-elevation-#{$token}, #{$value}));
32
+ }
30
33
 
31
34
  :host {
32
- @each $token, $value in $tokens {
33
- --_#{$token}: var(--md-elevation-#{$token}, #{$value});
34
- }
35
-
36
35
  display: flex;
37
36
  pointer-events: none;
38
37
  }
@@ -53,6 +52,13 @@
53
52
  .shadow::after {
54
53
  content: '';
55
54
  transition-property: box-shadow, opacity;
55
+
56
+ // Elevation doesn't share styles with multiple variants, so we normally
57
+ // would not use private custom properties. However, these variables are
58
+ // repeated several times in the styles below, and a shorter custom property
59
+ // reduces the CSS size, minified and gzip.
60
+ --_level: #{map.get($tokens, 'level')};
61
+ --_shadow-color: #{map.get($tokens, 'shadow-color')};
56
62
  }
57
63
 
58
64
  // Key box shadow
@@ -4,6 +4,6 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { css } from 'lit';
7
- export const styles = css `:host{--_level: var(--md-elevation-level, 0);--_shadow-color: var(--md-elevation-shadow-color, var(--md-sys-color-shadow, #000));display:flex;pointer-events:none}:host,.shadow,.shadow::before,.shadow::after{border-radius:inherit;inset:0;position:absolute;transition-duration:inherit;transition-property:inherit;transition-timing-function:inherit}.shadow::before,.shadow::after{content:"";transition-property:box-shadow,opacity}.shadow::before{box-shadow:0px calc(1px*(clamp(0,var(--_level),1) + clamp(0,var(--_level) - 3,1) + 2*clamp(0,var(--_level) - 4,1))) calc(1px*(2*clamp(0,var(--_level),1) + clamp(0,var(--_level) - 2,1) + clamp(0,var(--_level) - 4,1))) 0px var(--_shadow-color);opacity:.3}.shadow::after{box-shadow:0px calc(1px*(clamp(0,var(--_level),1) + clamp(0,var(--_level) - 1,1) + 2*clamp(0,var(--_level) - 2,3))) calc(1px*(3*clamp(0,var(--_level),2) + 2*clamp(0,var(--_level) - 2,3))) calc(1px*(clamp(0,var(--_level),4) + 2*clamp(0,var(--_level) - 4,1))) var(--_shadow-color);opacity:.15}/*# sourceMappingURL=elevation-styles.css.map */
7
+ export const styles = css `:host{display:flex;pointer-events:none}:host,.shadow,.shadow::before,.shadow::after{border-radius:inherit;inset:0;position:absolute;transition-duration:inherit;transition-property:inherit;transition-timing-function:inherit}.shadow::before,.shadow::after{content:"";transition-property:box-shadow,opacity;--_level: var(--md-elevation-level, 0);--_shadow-color: var(--md-elevation-shadow-color, var(--md-sys-color-shadow, #000))}.shadow::before{box-shadow:0px calc(1px*(clamp(0,var(--_level),1) + clamp(0,var(--_level) - 3,1) + 2*clamp(0,var(--_level) - 4,1))) calc(1px*(2*clamp(0,var(--_level),1) + clamp(0,var(--_level) - 2,1) + clamp(0,var(--_level) - 4,1))) 0px var(--_shadow-color);opacity:.3}.shadow::after{box-shadow:0px calc(1px*(clamp(0,var(--_level),1) + clamp(0,var(--_level) - 1,1) + 2*clamp(0,var(--_level) - 2,3))) calc(1px*(3*clamp(0,var(--_level),2) + 2*clamp(0,var(--_level) - 2,3))) calc(1px*(clamp(0,var(--_level),4) + 2*clamp(0,var(--_level) - 4,1))) var(--_shadow-color);opacity:.15}/*# sourceMappingURL=elevation-styles.css.map */
8
8
  `;
9
9
  //# sourceMappingURL=elevation-styles.css.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"elevation-styles.css.js","sourceRoot":"","sources":["elevation-styles.css.ts"],"names":[],"mappings":"AAAA;;;;IAII;AACH,OAAO,EAAC,GAAG,EAAC,MAAM,KAAK,CAAC;AACxB,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;CACzB,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n import {css} from 'lit';\n export const styles = css`:host{--_level: var(--md-elevation-level, 0);--_shadow-color: var(--md-elevation-shadow-color, var(--md-sys-color-shadow, #000));display:flex;pointer-events:none}:host,.shadow,.shadow::before,.shadow::after{border-radius:inherit;inset:0;position:absolute;transition-duration:inherit;transition-property:inherit;transition-timing-function:inherit}.shadow::before,.shadow::after{content:\"\";transition-property:box-shadow,opacity}.shadow::before{box-shadow:0px calc(1px*(clamp(0,var(--_level),1) + clamp(0,var(--_level) - 3,1) + 2*clamp(0,var(--_level) - 4,1))) calc(1px*(2*clamp(0,var(--_level),1) + clamp(0,var(--_level) - 2,1) + clamp(0,var(--_level) - 4,1))) 0px var(--_shadow-color);opacity:.3}.shadow::after{box-shadow:0px calc(1px*(clamp(0,var(--_level),1) + clamp(0,var(--_level) - 1,1) + 2*clamp(0,var(--_level) - 2,3))) calc(1px*(3*clamp(0,var(--_level),2) + 2*clamp(0,var(--_level) - 2,3))) calc(1px*(clamp(0,var(--_level),4) + 2*clamp(0,var(--_level) - 4,1))) var(--_shadow-color);opacity:.15}/*# sourceMappingURL=elevation-styles.css.map */\n`;\n "]}
1
+ {"version":3,"file":"elevation-styles.css.js","sourceRoot":"","sources":["elevation-styles.css.ts"],"names":[],"mappings":"AAAA;;;;IAII;AACH,OAAO,EAAC,GAAG,EAAC,MAAM,KAAK,CAAC;AACxB,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;CACzB,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n import {css} from 'lit';\n export const styles = css`:host{display:flex;pointer-events:none}:host,.shadow,.shadow::before,.shadow::after{border-radius:inherit;inset:0;position:absolute;transition-duration:inherit;transition-property:inherit;transition-timing-function:inherit}.shadow::before,.shadow::after{content:\"\";transition-property:box-shadow,opacity;--_level: var(--md-elevation-level, 0);--_shadow-color: var(--md-elevation-shadow-color, var(--md-sys-color-shadow, #000))}.shadow::before{box-shadow:0px calc(1px*(clamp(0,var(--_level),1) + clamp(0,var(--_level) - 3,1) + 2*clamp(0,var(--_level) - 4,1))) calc(1px*(2*clamp(0,var(--_level),1) + clamp(0,var(--_level) - 2,1) + clamp(0,var(--_level) - 4,1))) 0px var(--_shadow-color);opacity:.3}.shadow::after{box-shadow:0px calc(1px*(clamp(0,var(--_level),1) + clamp(0,var(--_level) - 1,1) + 2*clamp(0,var(--_level) - 2,3))) calc(1px*(3*clamp(0,var(--_level),2) + 2*clamp(0,var(--_level) - 2,3))) calc(1px*(clamp(0,var(--_level),4) + 2*clamp(0,var(--_level) - 4,1))) var(--_shadow-color);opacity:.15}/*# sourceMappingURL=elevation-styles.css.map */\n`;\n "]}
@@ -4,7 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { Fab, FabVariant } from './internal/fab.js';
7
- export { FabSize } from './internal/shared.js';
7
+ export { type FabSize } from './internal/shared.js';
8
8
  declare global {
9
9
  interface HTMLElementTagNameMap {
10
10
  'md-branded-fab': MdBrandedFab;
@@ -1 +1 @@
1
- {"version":3,"file":"branded-fab.js","sourceRoot":"","sources":["branded-fab.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAEH,OAAO,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAC,GAAG,EAAa,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,MAAM,EAAC,MAAM,sCAAsC,CAAC;AAC5D,OAAO,EAAC,MAAM,IAAI,YAAY,EAAC,MAAM,wCAAwC,CAAC;AAC9E,OAAO,EAAC,MAAM,IAAI,YAAY,EAAC,MAAM,iCAAiC,CAAC;AAUvE;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEI,WAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,GAAG;IAM1B,gBAAgB;QACvB,OAAO;YACL,GAAG,KAAK,CAAC,gBAAgB,EAAE;YAC3B,SAAS,EAAE,KAAK;YAChB,WAAW,EAAE,KAAK;YAClB,UAAU,EAAE,KAAK;YACjB,OAAO,EAAE,KAAK;SACf,CAAC;IACJ,CAAC;;AACe,mBAAM,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,CAAC,AAAvC,CAAwC;AAfnD,YAAY;IADxB,aAAa,CAAC,gBAAgB,CAAC;GACnB,YAAY,CAgBxB","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {customElement} from 'lit/decorators.js';\n\nimport {Fab, FabVariant} from './internal/fab.js';\nimport {styles} from './internal/fab-branded-styles.css.js';\nimport {styles as forcedColors} from './internal/forced-colors-styles.css.js';\nimport {styles as sharedStyles} from './internal/shared-styles.css.js';\n\nexport {FabSize} from './internal/shared.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'md-branded-fab': MdBrandedFab;\n }\n}\n\n/**\n * @summary Floating action buttons (FABs) help people take primary actions.\n * They’re used to represent the most important action on a screen, such as\n * Create or Reply.\n *\n * @description\n * __Emphasis:__ High emphasis – For the primary, most important, or most common\n * action on a screen\n *\n * __Rationale:__ The FAB remains the default component for a screen’s primary\n * action. It comes in three sizes: small FAB, FAB, and large FAB. The extended\n * FAB’s wider format and text label give it more visual prominence than a FAB.\n * It’s often used on larger screens where a FAB would seem too small. Branded\n * FABs are used to specifically call attention to branded logo icons.\n *\n * __Example usages:__\n * - FAB\n * - Create\n * - Compose\n * - Extended FAB\n * - Create\n * - Compose\n * - New Thread\n * - New File\n *\n * @final\n * @suppress {visibility}\n */\n@customElement('md-branded-fab')\nexport class MdBrandedFab extends Fab {\n /**\n * Branded FABs have no variants\n */\n override variant!: FabVariant;\n\n override getRenderClasses() {\n return {\n ...super.getRenderClasses(),\n 'primary': false,\n 'secondary': false,\n 'tertiary': false,\n 'small': false,\n };\n }\n static override styles = [sharedStyles, styles, forcedColors];\n}\n"]}
1
+ {"version":3,"file":"branded-fab.js","sourceRoot":"","sources":["branded-fab.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAEH,OAAO,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAC,GAAG,EAAa,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,MAAM,EAAC,MAAM,sCAAsC,CAAC;AAC5D,OAAO,EAAC,MAAM,IAAI,YAAY,EAAC,MAAM,wCAAwC,CAAC;AAC9E,OAAO,EAAC,MAAM,IAAI,YAAY,EAAC,MAAM,iCAAiC,CAAC;AAUvE;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEI,WAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,GAAG;IAM1B,gBAAgB;QACvB,OAAO;YACL,GAAG,KAAK,CAAC,gBAAgB,EAAE;YAC3B,SAAS,EAAE,KAAK;YAChB,WAAW,EAAE,KAAK;YAClB,UAAU,EAAE,KAAK;YACjB,OAAO,EAAE,KAAK;SACf,CAAC;IACJ,CAAC;;AACe,mBAAM,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,CAAC,AAAvC,CAAwC;AAfnD,YAAY;IADxB,aAAa,CAAC,gBAAgB,CAAC;GACnB,YAAY,CAgBxB","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {customElement} from 'lit/decorators.js';\n\nimport {Fab, FabVariant} from './internal/fab.js';\nimport {styles} from './internal/fab-branded-styles.css.js';\nimport {styles as forcedColors} from './internal/forced-colors-styles.css.js';\nimport {styles as sharedStyles} from './internal/shared-styles.css.js';\n\nexport {type FabSize} from './internal/shared.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'md-branded-fab': MdBrandedFab;\n }\n}\n\n/**\n * @summary Floating action buttons (FABs) help people take primary actions.\n * They’re used to represent the most important action on a screen, such as\n * Create or Reply.\n *\n * @description\n * __Emphasis:__ High emphasis – For the primary, most important, or most common\n * action on a screen\n *\n * __Rationale:__ The FAB remains the default component for a screen’s primary\n * action. It comes in three sizes: small FAB, FAB, and large FAB. The extended\n * FAB’s wider format and text label give it more visual prominence than a FAB.\n * It’s often used on larger screens where a FAB would seem too small. Branded\n * FABs are used to specifically call attention to branded logo icons.\n *\n * __Example usages:__\n * - FAB\n * - Create\n * - Compose\n * - Extended FAB\n * - Create\n * - Compose\n * - New Thread\n * - New File\n *\n * @final\n * @suppress {visibility}\n */\n@customElement('md-branded-fab')\nexport class MdBrandedFab extends Fab {\n /**\n * Branded FABs have no variants\n */\n override variant!: FabVariant;\n\n override getRenderClasses() {\n return {\n ...super.getRenderClasses(),\n 'primary': false,\n 'secondary': false,\n 'tertiary': false,\n 'small': false,\n };\n }\n static override styles = [sharedStyles, styles, forcedColors];\n}\n"]}
package/fab/fab.d.ts CHANGED
@@ -4,8 +4,8 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { Fab } from './internal/fab.js';
7
- export { FabVariant } from './internal/fab.js';
8
- export { FabSize } from './internal/shared.js';
7
+ export { type FabVariant } from './internal/fab.js';
8
+ export { type FabSize } from './internal/shared.js';
9
9
  declare global {
10
10
  interface HTMLElementTagNameMap {
11
11
  'md-fab': MdFab;
package/fab/fab.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"fab.js","sourceRoot":"","sources":["fab.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAEH,OAAO,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAC,GAAG,EAAC,MAAM,mBAAmB,CAAC;AACtC,OAAO,EAAC,MAAM,EAAC,MAAM,8BAA8B,CAAC;AACpD,OAAO,EAAC,MAAM,IAAI,YAAY,EAAC,MAAM,wCAAwC,CAAC;AAC9E,OAAO,EAAC,MAAM,IAAI,YAAY,EAAC,MAAM,iCAAiC,CAAC;AAWvE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEI,WAAM,KAAK,GAAX,MAAM,KAAM,SAAQ,GAAG;;AACZ,YAAM,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,CAAC,AAAvC,CAAwC;AADnD,KAAK;IADjB,aAAa,CAAC,QAAQ,CAAC;GACX,KAAK,CAEjB","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {customElement} from 'lit/decorators.js';\n\nimport {Fab} from './internal/fab.js';\nimport {styles} from './internal/fab-styles.css.js';\nimport {styles as forcedColors} from './internal/forced-colors-styles.css.js';\nimport {styles as sharedStyles} from './internal/shared-styles.css.js';\n\nexport {FabVariant} from './internal/fab.js';\nexport {FabSize} from './internal/shared.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'md-fab': MdFab;\n }\n}\n\n/**\n * @summary Floating action buttons (FABs) help people take primary actions.\n * They’re used to represent the most important action on a screen, such as\n * Create or Reply.\n *\n * @description\n * __Emphasis:__ High emphasis – For the primary, most important, or most common\n * action on a screen\n *\n * __Rationale:__ The FAB remains the default component for a screen’s primary\n * action. It comes in three sizes: small FAB, FAB, and large FAB. The extended\n * FAB’s wider format and text label give it more visual prominence than a FAB.\n * It’s often used on larger screens where a FAB would seem too small.\n *\n * __Example usages:__\n * - FAB\n * - Create\n * - Compose\n * - Extended FAB\n * - Create\n * - Compose\n * - New Thread\n * - New File\n *\n * @final\n * @suppress {visibility}\n */\n@customElement('md-fab')\nexport class MdFab extends Fab {\n static override styles = [sharedStyles, styles, forcedColors];\n}\n"]}
1
+ {"version":3,"file":"fab.js","sourceRoot":"","sources":["fab.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAEH,OAAO,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAC,GAAG,EAAC,MAAM,mBAAmB,CAAC;AACtC,OAAO,EAAC,MAAM,EAAC,MAAM,8BAA8B,CAAC;AACpD,OAAO,EAAC,MAAM,IAAI,YAAY,EAAC,MAAM,wCAAwC,CAAC;AAC9E,OAAO,EAAC,MAAM,IAAI,YAAY,EAAC,MAAM,iCAAiC,CAAC;AAWvE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEI,WAAM,KAAK,GAAX,MAAM,KAAM,SAAQ,GAAG;;AACZ,YAAM,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,CAAC,AAAvC,CAAwC;AADnD,KAAK;IADjB,aAAa,CAAC,QAAQ,CAAC;GACX,KAAK,CAEjB","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {customElement} from 'lit/decorators.js';\n\nimport {Fab} from './internal/fab.js';\nimport {styles} from './internal/fab-styles.css.js';\nimport {styles as forcedColors} from './internal/forced-colors-styles.css.js';\nimport {styles as sharedStyles} from './internal/shared-styles.css.js';\n\nexport {type FabVariant} from './internal/fab.js';\nexport {type FabSize} from './internal/shared.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'md-fab': MdFab;\n }\n}\n\n/**\n * @summary Floating action buttons (FABs) help people take primary actions.\n * They’re used to represent the most important action on a screen, such as\n * Create or Reply.\n *\n * @description\n * __Emphasis:__ High emphasis – For the primary, most important, or most common\n * action on a screen\n *\n * __Rationale:__ The FAB remains the default component for a screen’s primary\n * action. It comes in three sizes: small FAB, FAB, and large FAB. The extended\n * FAB’s wider format and text label give it more visual prominence than a FAB.\n * It’s often used on larger screens where a FAB would seem too small.\n *\n * __Example usages:__\n * - FAB\n * - Create\n * - Compose\n * - Extended FAB\n * - Create\n * - Compose\n * - New Thread\n * - New File\n *\n * @final\n * @suppress {visibility}\n */\n@customElement('md-fab')\nexport class MdFab extends Fab {\n static override styles = [sharedStyles, styles, forcedColors];\n}\n"]}
@@ -6,7 +6,7 @@
6
6
  import '../../focus/md-focus-ring.js';
7
7
  import '../../ripple/ripple.js';
8
8
  import { LitElement } from 'lit';
9
- import { FormSubmitter, FormSubmitterType } from '../../internal/controller/form-submitter.js';
9
+ import { FormSubmitter, type FormSubmitterType } from '../../internal/controller/form-submitter.js';
10
10
  type LinkTarget = '_blank' | '_parent' | '_self' | '_top';
11
11
  declare const iconButtonBaseClass: import("../../labs/behaviors/mixin.js").MixinReturn<typeof LitElement, import("../../labs/behaviors/element-internals.js").WithElementInternals>;
12
12
  /**
@@ -52,7 +52,15 @@ export declare class IconButton extends iconButtonBaseClass implements FormSubmi
52
52
  * icon is provided.
53
53
  */
54
54
  selected: boolean;
55
+ /**
56
+ * The default behavior of the button. May be "text", "reset", or "submit"
57
+ * (default).
58
+ */
55
59
  type: FormSubmitterType;
60
+ /**
61
+ * The value added to a form with the button's name when the button submits a
62
+ * form.
63
+ */
56
64
  value: string;
57
65
  get name(): string;
58
66
  set name(name: string);
@@ -57,7 +57,15 @@ export class IconButton extends iconButtonBaseClass {
57
57
  * icon is provided.
58
58
  */
59
59
  this.selected = false;
60
+ /**
61
+ * The default behavior of the button. May be "text", "reset", or "submit"
62
+ * (default).
63
+ */
60
64
  this.type = 'submit';
65
+ /**
66
+ * The value added to a form with the button's name when the button submits a
67
+ * form.
68
+ */
61
69
  this.value = '';
62
70
  this.flipIcon = isRtl(this, this.flipIconInRtl);
63
71
  }
@@ -212,7 +220,7 @@ __decorate([
212
220
  property()
213
221
  ], IconButton.prototype, "type", void 0);
214
222
  __decorate([
215
- property()
223
+ property({ reflect: true })
216
224
  ], IconButton.prototype, "value", void 0);
217
225
  __decorate([
218
226
  state()
@@ -1 +1 @@
1
- {"version":3,"file":"icon-button.js","sourceRoot":"","sources":["icon-button.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport '../../focus/md-focus-ring.js';\nimport '../../ripple/ripple.js';\n\nimport {html, LitElement, nothing} from 'lit';\nimport {property, state} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport {literal, html as staticHtml} from 'lit/static-html.js';\n\nimport {ARIAMixinStrict} from '../../internal/aria/aria.js';\nimport {requestUpdateOnAriaChange} from '../../internal/aria/delegate.js';\nimport {\n FormSubmitter,\n FormSubmitterType,\n setupFormSubmitter,\n} from '../../internal/controller/form-submitter.js';\nimport {isRtl} from '../../internal/controller/is-rtl.js';\nimport {\n internals,\n mixinElementInternals,\n} from '../../labs/behaviors/element-internals.js';\n\ntype LinkTarget = '_blank' | '_parent' | '_self' | '_top';\n\n// Separate variable needed for closure.\nconst iconButtonBaseClass = mixinElementInternals(LitElement);\n\n/**\n * A button for rendering icons.\n *\n * @fires input {InputEvent} Dispatched when a toggle button toggles --bubbles\n * --composed\n * @fires change {Event} Dispatched when a toggle button toggles --bubbles\n */\nexport class IconButton extends iconButtonBaseClass implements FormSubmitter {\n static {\n requestUpdateOnAriaChange(IconButton);\n setupFormSubmitter(IconButton);\n }\n\n /** @nocollapse */\n static readonly formAssociated = true;\n\n /** @nocollapse */\n static override shadowRootOptions: ShadowRootInit = {\n mode: 'open',\n delegatesFocus: true,\n };\n\n /**\n * Disables the icon button and makes it non-interactive.\n */\n @property({type: Boolean, reflect: true}) disabled = false;\n\n /**\n * Flips the icon if it is in an RTL context at startup.\n */\n @property({type: Boolean, attribute: 'flip-icon-in-rtl'})\n flipIconInRtl = false;\n\n /**\n * Sets the underlying `HTMLAnchorElement`'s `href` resource attribute.\n */\n @property() href = '';\n\n /**\n * Sets the underlying `HTMLAnchorElement`'s `target` attribute.\n */\n @property() target: LinkTarget | '' = '';\n\n /**\n * The `aria-label` of the button when the button is toggleable and selected.\n */\n @property({attribute: 'aria-label-selected'}) ariaLabelSelected = '';\n\n /**\n * When true, the button will toggle between selected and unselected\n * states\n */\n @property({type: Boolean}) toggle = false;\n\n /**\n * Sets the selected state. When false, displays the default icon. When true,\n * displays the selected icon, or the default icon If no `slot=\"selected\"`\n * icon is provided.\n */\n @property({type: Boolean, reflect: true}) selected = false;\n\n @property() type: FormSubmitterType = 'submit';\n\n @property() value = '';\n\n get name() {\n return this.getAttribute('name') ?? '';\n }\n set name(name: string) {\n this.setAttribute('name', name);\n }\n\n /**\n * The associated form element with which this element's value will submit.\n */\n get form() {\n return this[internals].form;\n }\n\n /**\n * The labels this element is associated with.\n */\n get labels() {\n return this[internals].labels;\n }\n\n @state() private flipIcon = isRtl(this, this.flipIconInRtl);\n\n /**\n * Link buttons cannot be disabled.\n */\n protected override willUpdate() {\n if (this.href) {\n this.disabled = false;\n }\n }\n\n protected override render() {\n const tag = this.href ? literal`div` : literal`button`;\n // Needed for closure conformance\n const {ariaLabel, ariaHasPopup, ariaExpanded} = this as ARIAMixinStrict;\n const hasToggledAriaLabel = ariaLabel && this.ariaLabelSelected;\n const ariaPressedValue = !this.toggle ? nothing : this.selected;\n let ariaLabelValue: string | null | typeof nothing = nothing;\n if (!this.href) {\n ariaLabelValue =\n hasToggledAriaLabel && this.selected\n ? this.ariaLabelSelected\n : ariaLabel;\n }\n return staticHtml`<${tag}\n class=\"icon-button ${classMap(this.getRenderClasses())}\"\n id=\"button\"\n aria-label=\"${ariaLabelValue || nothing}\"\n aria-haspopup=\"${(!this.href && ariaHasPopup) || nothing}\"\n aria-expanded=\"${(!this.href && ariaExpanded) || nothing}\"\n aria-pressed=\"${ariaPressedValue}\"\n ?disabled=\"${!this.href && this.disabled}\"\n @click=\"${this.handleClick}\">\n ${this.renderFocusRing()}\n ${this.renderRipple()}\n ${!this.selected ? this.renderIcon() : nothing}\n ${this.selected ? this.renderSelectedIcon() : nothing}\n ${this.renderTouchTarget()}\n ${this.href && this.renderLink()}\n </${tag}>`;\n }\n\n private renderLink() {\n // Needed for closure conformance\n const {ariaLabel} = this as ARIAMixinStrict;\n return html`\n <a\n class=\"link\"\n id=\"link\"\n href=\"${this.href}\"\n target=\"${this.target || nothing}\"\n aria-label=\"${ariaLabel || nothing}\"></a>\n `;\n }\n\n protected getRenderClasses() {\n return {\n 'flip-icon': this.flipIcon,\n 'selected': this.toggle && this.selected,\n };\n }\n\n private renderIcon() {\n return html`<span class=\"icon\"><slot></slot></span>`;\n }\n\n private renderSelectedIcon() {\n // Use default slot as fallback to not require specifying multiple icons\n return html`<span class=\"icon icon--selected\"\n ><slot name=\"selected\"><slot></slot></slot\n ></span>`;\n }\n\n private renderTouchTarget() {\n return html`<span class=\"touch\"></span>`;\n }\n\n private renderFocusRing() {\n // TODO(b/310046938): use the same id for both elements\n return html`<md-focus-ring\n part=\"focus-ring\"\n for=${this.href ? 'link' : 'button'}></md-focus-ring>`;\n }\n\n private renderRipple() {\n // TODO(b/310046938): use the same id for both elements\n return html`<md-ripple\n for=${this.href ? 'link' : nothing}\n ?disabled=\"${!this.href && this.disabled}\"></md-ripple>`;\n }\n\n override connectedCallback() {\n this.flipIcon = isRtl(this, this.flipIconInRtl);\n super.connectedCallback();\n }\n\n private async handleClick(event: Event) {\n // Allow the event to propagate\n await 0;\n if (!this.toggle || this.disabled || event.defaultPrevented) {\n return;\n }\n\n this.selected = !this.selected;\n this.dispatchEvent(\n new InputEvent('input', {bubbles: true, composed: true}),\n );\n // Bubbles but does not compose to mimic native browser <input> & <select>\n // Additionally, native change event is not an InputEvent.\n this.dispatchEvent(new Event('change', {bubbles: true}));\n }\n}\n"]}
1
+ {"version":3,"file":"icon-button.js","sourceRoot":"","sources":["icon-button.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAEH,OAAO,8BAA8B,CAAC;AACtC,OAAO,wBAAwB,CAAC;AAEhC,OAAO,EAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAC,MAAM,KAAK,CAAC;AAC9C,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAC,QAAQ,EAAC,MAAM,6BAA6B,CAAC;AACrD,OAAO,EAAC,OAAO,EAAE,IAAI,IAAI,UAAU,EAAC,MAAM,oBAAoB,CAAC;AAG/D,OAAO,EAAC,yBAAyB,EAAC,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAEL,kBAAkB,GAEnB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAAC,KAAK,EAAC,MAAM,qCAAqC,CAAC;AAC1D,OAAO,EACL,SAAS,EACT,qBAAqB,GACtB,MAAM,2CAA2C,CAAC;AAInD,wCAAwC;AACxC,MAAM,mBAAmB,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;AAE9D;;;;;;GAMG;AACH,MAAM,OAAO,UAAW,SAAQ,mBAAmB;IAAnD;;QAeE;;WAEG;QACuC,aAAQ,GAAG,KAAK,CAAC;QAE3D;;WAEG;QAEH,kBAAa,GAAG,KAAK,CAAC;QAEtB;;WAEG;QACS,SAAI,GAAG,EAAE,CAAC;QAEtB;;WAEG;QACS,WAAM,GAAoB,EAAE,CAAC;QAEzC;;WAEG;QAC2C,sBAAiB,GAAG,EAAE,CAAC;QAErE;;;WAGG;QACwB,WAAM,GAAG,KAAK,CAAC;QAE1C;;;;WAIG;QACuC,aAAQ,GAAG,KAAK,CAAC;QAE3D;;;WAGG;QACS,SAAI,GAAsB,QAAQ,CAAC;QAE/C;;;WAGG;QACwB,UAAK,GAAG,EAAE,CAAC;QAuBrB,aAAQ,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IA+G9D,CAAC;IApIC,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACzC,CAAC;IACD,IAAI,IAAI,CAAC,IAAY;QACnB,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC;IAChC,CAAC;IAID;;OAEG;IACgB,UAAU;QAC3B,IAAI,IAAI,CAAC,IAAI,EAAE;YACb,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;SACvB;IACH,CAAC;IAEkB,MAAM;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAA,KAAK,CAAC,CAAC,CAAC,OAAO,CAAA,QAAQ,CAAC;QACvD,iCAAiC;QACjC,MAAM,EAAC,SAAS,EAAE,YAAY,EAAE,YAAY,EAAC,GAAG,IAAuB,CAAC;QACxE,MAAM,mBAAmB,GAAG,SAAS,IAAI,IAAI,CAAC,iBAAiB,CAAC;QAChE,MAAM,gBAAgB,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;QAChE,IAAI,cAAc,GAAmC,OAAO,CAAC;QAC7D,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YACd,cAAc;gBACZ,mBAAmB,IAAI,IAAI,CAAC,QAAQ;oBAClC,CAAC,CAAC,IAAI,CAAC,iBAAiB;oBACxB,CAAC,CAAC,SAAS,CAAC;SACjB;QACD,OAAO,UAAU,CAAA,IAAI,GAAG;6BACC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;;sBAExC,cAAc,IAAI,OAAO;yBACtB,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,YAAY,CAAC,IAAI,OAAO;yBACvC,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,YAAY,CAAC,IAAI,OAAO;wBACxC,gBAAgB;qBACnB,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ;kBAC9B,IAAI,CAAC,WAAW;UACxB,IAAI,CAAC,eAAe,EAAE;UACtB,IAAI,CAAC,YAAY,EAAE;UACnB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,OAAO;UAC5C,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,OAAO;UACnD,IAAI,CAAC,iBAAiB,EAAE;UACxB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE;MAClC,GAAG,GAAG,CAAC;IACX,CAAC;IAEO,UAAU;QAChB,iCAAiC;QACjC,MAAM,EAAC,SAAS,EAAC,GAAG,IAAuB,CAAC;QAC5C,OAAO,IAAI,CAAA;;;;gBAIC,IAAI,CAAC,IAAI;kBACP,IAAI,CAAC,MAAM,IAAI,OAAO;sBAClB,SAAS,IAAI,OAAO;KACrC,CAAC;IACJ,CAAC;IAES,gBAAgB;QACxB,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,QAAQ;YAC1B,UAAU,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ;SACzC,CAAC;IACJ,CAAC;IAEO,UAAU;QAChB,OAAO,IAAI,CAAA,yCAAyC,CAAC;IACvD,CAAC;IAEO,kBAAkB;QACxB,wEAAwE;QACxE,OAAO,IAAI,CAAA;;aAEF,CAAC;IACZ,CAAC;IAEO,iBAAiB;QACvB,OAAO,IAAI,CAAA,6BAA6B,CAAC;IAC3C,CAAC;IAEO,eAAe;QACrB,uDAAuD;QACvD,OAAO,IAAI,CAAA;;YAEH,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,mBAAmB,CAAC;IAC3D,CAAC;IAEO,YAAY;QAClB,uDAAuD;QACvD,OAAO,IAAI,CAAA;YACH,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;mBACrB,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,gBAAgB,CAAC;IAC7D,CAAC;IAEQ,iBAAiB;QACxB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAChD,KAAK,CAAC,iBAAiB,EAAE,CAAC;IAC5B,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,KAAY;QACpC,+BAA+B;QAC/B,MAAM,CAAC,CAAC;QACR,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,gBAAgB,EAAE;YAC3D,OAAO;SACR;QAED,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC/B,IAAI,CAAC,aAAa,CAChB,IAAI,UAAU,CAAC,OAAO,EAAE,EAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC,CACzD,CAAC;QACF,0EAA0E;QAC1E,0DAA0D;QAC1D,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAC,OAAO,EAAE,IAAI,EAAC,CAAC,CAAC,CAAC;IAC3D,CAAC;;AApMD;IACE,yBAAyB,CAAC,UAAU,CAAC,CAAC;IACtC,kBAAkB,CAAC,UAAU,CAAC,CAAC;AACjC,CAAC,GAAA,CAAA;AAED,kBAAkB;AACF,yBAAc,GAAG,IAAI,AAAP,CAAQ;AAEtC,kBAAkB;AACF,4BAAiB,GAAmB;IAClD,IAAI,EAAE,MAAM;IACZ,cAAc,EAAE,IAAI;CACrB,AAHgC,CAG/B;AAKwC;IAAzC,QAAQ,CAAC,EAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAC,CAAC;4CAAkB;AAM3D;IADC,QAAQ,CAAC,EAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAC,CAAC;iDACnC;AAKV;IAAX,QAAQ,EAAE;wCAAW;AAKV;IAAX,QAAQ,EAAE;0CAA8B;AAKK;IAA7C,QAAQ,CAAC,EAAC,SAAS,EAAE,qBAAqB,EAAC,CAAC;qDAAwB;AAM1C;IAA1B,QAAQ,CAAC,EAAC,IAAI,EAAE,OAAO,EAAC,CAAC;0CAAgB;AAOA;IAAzC,QAAQ,CAAC,EAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAC,CAAC;4CAAkB;AAM/C;IAAX,QAAQ,EAAE;wCAAoC;AAMpB;IAA1B,QAAQ,CAAC,EAAC,OAAO,EAAE,IAAI,EAAC,CAAC;yCAAY;AAuBrB;IAAhB,KAAK,EAAE;4CAAoD","sourcesContent":["/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport '../../focus/md-focus-ring.js';\nimport '../../ripple/ripple.js';\n\nimport {html, LitElement, nothing} from 'lit';\nimport {property, state} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\nimport {literal, html as staticHtml} from 'lit/static-html.js';\n\nimport {ARIAMixinStrict} from '../../internal/aria/aria.js';\nimport {requestUpdateOnAriaChange} from '../../internal/aria/delegate.js';\nimport {\n FormSubmitter,\n setupFormSubmitter,\n type FormSubmitterType,\n} from '../../internal/controller/form-submitter.js';\nimport {isRtl} from '../../internal/controller/is-rtl.js';\nimport {\n internals,\n mixinElementInternals,\n} from '../../labs/behaviors/element-internals.js';\n\ntype LinkTarget = '_blank' | '_parent' | '_self' | '_top';\n\n// Separate variable needed for closure.\nconst iconButtonBaseClass = mixinElementInternals(LitElement);\n\n/**\n * A button for rendering icons.\n *\n * @fires input {InputEvent} Dispatched when a toggle button toggles --bubbles\n * --composed\n * @fires change {Event} Dispatched when a toggle button toggles --bubbles\n */\nexport class IconButton extends iconButtonBaseClass implements FormSubmitter {\n static {\n requestUpdateOnAriaChange(IconButton);\n setupFormSubmitter(IconButton);\n }\n\n /** @nocollapse */\n static readonly formAssociated = true;\n\n /** @nocollapse */\n static override shadowRootOptions: ShadowRootInit = {\n mode: 'open',\n delegatesFocus: true,\n };\n\n /**\n * Disables the icon button and makes it non-interactive.\n */\n @property({type: Boolean, reflect: true}) disabled = false;\n\n /**\n * Flips the icon if it is in an RTL context at startup.\n */\n @property({type: Boolean, attribute: 'flip-icon-in-rtl'})\n flipIconInRtl = false;\n\n /**\n * Sets the underlying `HTMLAnchorElement`'s `href` resource attribute.\n */\n @property() href = '';\n\n /**\n * Sets the underlying `HTMLAnchorElement`'s `target` attribute.\n */\n @property() target: LinkTarget | '' = '';\n\n /**\n * The `aria-label` of the button when the button is toggleable and selected.\n */\n @property({attribute: 'aria-label-selected'}) ariaLabelSelected = '';\n\n /**\n * When true, the button will toggle between selected and unselected\n * states\n */\n @property({type: Boolean}) toggle = false;\n\n /**\n * Sets the selected state. When false, displays the default icon. When true,\n * displays the selected icon, or the default icon If no `slot=\"selected\"`\n * icon is provided.\n */\n @property({type: Boolean, reflect: true}) selected = false;\n\n /**\n * The default behavior of the button. May be \"text\", \"reset\", or \"submit\"\n * (default).\n */\n @property() type: FormSubmitterType = 'submit';\n\n /**\n * The value added to a form with the button's name when the button submits a\n * form.\n */\n @property({reflect: true}) value = '';\n\n get name() {\n return this.getAttribute('name') ?? '';\n }\n set name(name: string) {\n this.setAttribute('name', name);\n }\n\n /**\n * The associated form element with which this element's value will submit.\n */\n get form() {\n return this[internals].form;\n }\n\n /**\n * The labels this element is associated with.\n */\n get labels() {\n return this[internals].labels;\n }\n\n @state() private flipIcon = isRtl(this, this.flipIconInRtl);\n\n /**\n * Link buttons cannot be disabled.\n */\n protected override willUpdate() {\n if (this.href) {\n this.disabled = false;\n }\n }\n\n protected override render() {\n const tag = this.href ? literal`div` : literal`button`;\n // Needed for closure conformance\n const {ariaLabel, ariaHasPopup, ariaExpanded} = this as ARIAMixinStrict;\n const hasToggledAriaLabel = ariaLabel && this.ariaLabelSelected;\n const ariaPressedValue = !this.toggle ? nothing : this.selected;\n let ariaLabelValue: string | null | typeof nothing = nothing;\n if (!this.href) {\n ariaLabelValue =\n hasToggledAriaLabel && this.selected\n ? this.ariaLabelSelected\n : ariaLabel;\n }\n return staticHtml`<${tag}\n class=\"icon-button ${classMap(this.getRenderClasses())}\"\n id=\"button\"\n aria-label=\"${ariaLabelValue || nothing}\"\n aria-haspopup=\"${(!this.href && ariaHasPopup) || nothing}\"\n aria-expanded=\"${(!this.href && ariaExpanded) || nothing}\"\n aria-pressed=\"${ariaPressedValue}\"\n ?disabled=\"${!this.href && this.disabled}\"\n @click=\"${this.handleClick}\">\n ${this.renderFocusRing()}\n ${this.renderRipple()}\n ${!this.selected ? this.renderIcon() : nothing}\n ${this.selected ? this.renderSelectedIcon() : nothing}\n ${this.renderTouchTarget()}\n ${this.href && this.renderLink()}\n </${tag}>`;\n }\n\n private renderLink() {\n // Needed for closure conformance\n const {ariaLabel} = this as ARIAMixinStrict;\n return html`\n <a\n class=\"link\"\n id=\"link\"\n href=\"${this.href}\"\n target=\"${this.target || nothing}\"\n aria-label=\"${ariaLabel || nothing}\"></a>\n `;\n }\n\n protected getRenderClasses() {\n return {\n 'flip-icon': this.flipIcon,\n 'selected': this.toggle && this.selected,\n };\n }\n\n private renderIcon() {\n return html`<span class=\"icon\"><slot></slot></span>`;\n }\n\n private renderSelectedIcon() {\n // Use default slot as fallback to not require specifying multiple icons\n return html`<span class=\"icon icon--selected\"\n ><slot name=\"selected\"><slot></slot></slot\n ></span>`;\n }\n\n private renderTouchTarget() {\n return html`<span class=\"touch\"></span>`;\n }\n\n private renderFocusRing() {\n // TODO(b/310046938): use the same id for both elements\n return html`<md-focus-ring\n part=\"focus-ring\"\n for=${this.href ? 'link' : 'button'}></md-focus-ring>`;\n }\n\n private renderRipple() {\n // TODO(b/310046938): use the same id for both elements\n return html`<md-ripple\n for=${this.href ? 'link' : nothing}\n ?disabled=\"${!this.href && this.disabled}\"></md-ripple>`;\n }\n\n override connectedCallback() {\n this.flipIcon = isRtl(this, this.flipIconInRtl);\n super.connectedCallback();\n }\n\n private async handleClick(event: Event) {\n // Allow the event to propagate\n await 0;\n if (!this.toggle || this.disabled || event.defaultPrevented) {\n return;\n }\n\n this.selected = !this.selected;\n this.dispatchEvent(\n new InputEvent('input', {bubbles: true, composed: true}),\n );\n // Bubbles but does not compose to mimic native browser <input> & <select>\n // Additionally, native change event is not an InputEvent.\n this.dispatchEvent(new Event('change', {bubbles: true}));\n }\n}\n"]}
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import { LitElement } from 'lit';
7
7
  import { ConstraintValidation } from './constraint-validation.js';
8
+ import { WithElementInternals } from './element-internals.js';
8
9
  import { MixinBase, MixinReturn } from './mixin.js';
9
10
  /**
10
11
  * A constraint validation element that has a callback for when the element
@@ -67,4 +68,4 @@ export declare const onReportValidity: unique symbol;
67
68
  * @param base The class to mix functionality into.
68
69
  * @return The provided class with `OnReportValidity` mixed in.
69
70
  */
70
- export declare function mixinOnReportValidity<T extends MixinBase<LitElement & ConstraintValidation>>(base: T): MixinReturn<T, OnReportValidity>;
71
+ export declare function mixinOnReportValidity<T extends MixinBase<LitElement & ConstraintValidation & WithElementInternals>>(base: T): MixinReturn<T, OnReportValidity>;
@@ -4,6 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { isServer } from 'lit';
7
+ import { internals } from './element-internals.js';
7
8
  /**
8
9
  * A symbol property used for a callback when validity has been reported.
9
10
  */
@@ -11,6 +12,8 @@ export const onReportValidity = Symbol('onReportValidity');
11
12
  // Private symbol members, used to avoid name clashing.
12
13
  const privateCleanupFormListeners = Symbol('privateCleanupFormListeners');
13
14
  const privateDoNotReportInvalid = Symbol('privateDoNotReportInvalid');
15
+ const privateIsSelfReportingValidity = Symbol('privateIsSelfReportingValidity');
16
+ const privateCallOnReportValidity = Symbol('privateCallOnReportValidity');
14
17
  /**
15
18
  * Mixes in a callback for constraint validation when validity should be
16
19
  * styled and reported to the user.
@@ -44,7 +47,7 @@ const privateDoNotReportInvalid = Symbol('privateDoNotReportInvalid');
44
47
  * @return The provided class with `OnReportValidity` mixed in.
45
48
  */
46
49
  export function mixinOnReportValidity(base) {
47
- var _a, _b;
50
+ var _a, _b, _c;
48
51
  class OnReportValidityElement extends base {
49
52
  // Mixins must have a constructor with `...args: any[]`
50
53
  // tslint:disable-next-line:no-any
@@ -59,6 +62,12 @@ export function mixinOnReportValidity(base) {
59
62
  * events from `checkValidity()` do not trigger reporting.
60
63
  */
61
64
  this[_b] = false;
65
+ /**
66
+ * Used to determine if the control is reporting validity from itself, or
67
+ * if a `<form>` is causing the validity report. Forms have different
68
+ * control focusing behavior.
69
+ */
70
+ this[_c] = false;
62
71
  if (isServer) {
63
72
  return;
64
73
  }
@@ -75,9 +84,7 @@ export function mixinOnReportValidity(base) {
75
84
  // A normal bubbling phase event listener. By adding it here, we
76
85
  // ensure it's the last event listener that is called during the
77
86
  // bubbling phase.
78
- if (!invalidEvent.defaultPrevented) {
79
- this[onReportValidity](invalidEvent);
80
- }
87
+ this[privateCallOnReportValidity](invalidEvent);
81
88
  }, { once: true });
82
89
  }, {
83
90
  // Listen during the capture phase, which will happen before the
@@ -94,14 +101,42 @@ export function mixinOnReportValidity(base) {
94
101
  return valid;
95
102
  }
96
103
  reportValidity() {
104
+ this[privateIsSelfReportingValidity] = true;
97
105
  const valid = super.reportValidity();
98
106
  // Constructor's invalid listener will handle reporting invalid events.
99
107
  if (valid) {
100
- this[onReportValidity](null);
108
+ this[privateCallOnReportValidity](null);
101
109
  }
110
+ this[privateIsSelfReportingValidity] = false;
102
111
  return valid;
103
112
  }
104
- [(_a = privateCleanupFormListeners, _b = privateDoNotReportInvalid, onReportValidity)](invalidEvent) {
113
+ [(_a = privateCleanupFormListeners, _b = privateDoNotReportInvalid, _c = privateIsSelfReportingValidity, privateCallOnReportValidity)](invalidEvent) {
114
+ // Since invalid events do not bubble to parent listeners, and because
115
+ // our invalid listeners are added lazily after other listeners, we can
116
+ // reliably read `defaultPrevented` synchronously without worrying
117
+ // about waiting for another listener that could cancel it.
118
+ const wasCanceled = invalidEvent?.defaultPrevented;
119
+ if (wasCanceled) {
120
+ return;
121
+ }
122
+ this[onReportValidity](invalidEvent);
123
+ // If an implementation calls invalidEvent.preventDefault() to stop the
124
+ // platform popup from displaying, focusing is also prevented, so we need
125
+ // to manually focus.
126
+ const implementationCanceledFocus = !wasCanceled && invalidEvent?.defaultPrevented;
127
+ if (!implementationCanceledFocus) {
128
+ return;
129
+ }
130
+ // The control should be focused when:
131
+ // - `control.reportValidity()` is called (self-reporting).
132
+ // - a form is reporting validity for its controls and this is the first
133
+ // invalid control.
134
+ if (this[privateIsSelfReportingValidity] ||
135
+ isFirstInvalidControlInForm(this[internals].form, this)) {
136
+ this.focus();
137
+ }
138
+ }
139
+ [onReportValidity](invalidEvent) {
105
140
  throw new Error('Implement [onReportValidity]');
106
141
  }
107
142
  formAssociatedCallback(form) {
@@ -109,77 +144,146 @@ export function mixinOnReportValidity(base) {
109
144
  if (super.formAssociatedCallback) {
110
145
  super.formAssociatedCallback(form);
111
146
  }
112
- // Clean up previous submit listener
147
+ // Clean up previous form listeners.
113
148
  this[privateCleanupFormListeners].abort();
114
149
  if (!form) {
115
150
  return;
116
151
  }
117
152
  this[privateCleanupFormListeners] = new AbortController();
118
- // If the element's form submits, then all controls are valid. This lets
119
- // the element remove its error styles that may have been set when
120
- // `reportValidity()` was called.
121
- form.addEventListener('submit', () => {
122
- this[onReportValidity](null);
123
- }, {
124
- signal: this[privateCleanupFormListeners].signal,
125
- });
126
- // Inject a callback when `form.reportValidity()` is called and the form
127
- // is valid. There isn't an event that is dispatched to alert us (unlike
128
- // the 'invalid' event), and we need to remove error styles when
129
- // `form.reportValidity()` is called and returns true.
130
- let reportedInvalidEventFromForm = false;
131
- let formReportValidityCleanup = new AbortController();
132
- injectFormReportValidityHooks({
133
- form,
134
- cleanup: this[privateCleanupFormListeners].signal,
135
- beforeReportValidity: () => {
136
- reportedInvalidEventFromForm = false;
137
- this.addEventListener('invalid', (invalidEvent) => {
138
- reportedInvalidEventFromForm = true;
139
- if (!invalidEvent.defaultPrevented) {
140
- this[onReportValidity](invalidEvent);
141
- }
142
- }, { signal: formReportValidityCleanup.signal });
143
- },
144
- afterReportValidity: () => {
145
- formReportValidityCleanup.abort();
146
- formReportValidityCleanup = new AbortController();
147
- if (reportedInvalidEventFromForm) {
148
- reportedInvalidEventFromForm = false;
149
- return;
150
- }
151
- // Report successful form validation if an invalid event wasn't
152
- // fired.
153
- this[onReportValidity](null);
154
- },
155
- });
153
+ // Add a listener that fires when the form runs constraint validation and
154
+ // the control is valid, so that it may remove its error styles.
155
+ //
156
+ // This happens on `form.reportValidity()` and `form.requestSubmit()`
157
+ // (both when the submit fails and passes).
158
+ addFormReportValidListener(this, form, () => {
159
+ this[privateCallOnReportValidity](null);
160
+ }, this[privateCleanupFormListeners].signal);
156
161
  }
157
162
  }
158
163
  return OnReportValidityElement;
159
164
  }
160
- const FORM_REPORT_VALIDITY_HOOKS = new WeakMap();
161
- function injectFormReportValidityHooks({ form, beforeReportValidity, afterReportValidity, cleanup, }) {
162
- if (!FORM_REPORT_VALIDITY_HOOKS.has(form)) {
163
- // Patch form.reportValidity() to add an event target that can be used to
164
- // react when the method is called.
165
- // We should only patch this method once, since multiple controls and other
166
- // forces may want to patch this method. We cannot reliably clean it up by
167
- // resetting the method to "superReportValidity", which may be a patched
168
- // function.
169
- // Instead, we never clean up the patch but add and clean up event listener
170
- // hooks once it's patched.
165
+ /**
166
+ * Add a listener that fires when a form runs constraint validation on a control
167
+ * and it is valid. This is needed to clear previously invalid styles.
168
+ *
169
+ * @param control The control of the form to listen for valid events.
170
+ * @param form The control's form that can run constraint validation.
171
+ * @param onControlValid A listener that is called when the form runs constraint
172
+ * validation and the control is valid.
173
+ * @param cleanup A cleanup signal to remove the listener.
174
+ */
175
+ function addFormReportValidListener(control, form, onControlValid, cleanup) {
176
+ const validateHooks = getFormValidateHooks(form);
177
+ // When a form validates its controls, check if an invalid event is dispatched
178
+ // on the control. If it is not, then inform the control to report its valid
179
+ // state.
180
+ let controlFiredInvalid = false;
181
+ let cleanupInvalidListener;
182
+ let isNextSubmitFromHook = false;
183
+ validateHooks.addEventListener('before', () => {
184
+ isNextSubmitFromHook = true;
185
+ cleanupInvalidListener = new AbortController();
186
+ controlFiredInvalid = false;
187
+ control.addEventListener('invalid', () => {
188
+ controlFiredInvalid = true;
189
+ }, {
190
+ signal: cleanupInvalidListener.signal,
191
+ });
192
+ }, { signal: cleanup });
193
+ validateHooks.addEventListener('after', () => {
194
+ isNextSubmitFromHook = false;
195
+ cleanupInvalidListener?.abort();
196
+ if (controlFiredInvalid) {
197
+ return;
198
+ }
199
+ onControlValid();
200
+ }, { signal: cleanup });
201
+ // The above hooks handle imperatively submitting the form, but not
202
+ // declaratively submitting the form. This happens when:
203
+ // 1. A non-custom element `<button type="submit">` is clicked.
204
+ // 2. Enter is pressed on a non-custom element text editable `<input>`.
205
+ form.addEventListener('submit', () => {
206
+ // This submit was from `form.requestSubmit()`, which already calls the
207
+ // listener.
208
+ if (isNextSubmitFromHook) {
209
+ return;
210
+ }
211
+ onControlValid();
212
+ }, {
213
+ signal: cleanup,
214
+ });
215
+ // Note: it is a known limitation that we cannot detect if a form tries to
216
+ // submit declaratively, but fails to do so because an unrelated sibling
217
+ // control failed its constraint validation.
218
+ //
219
+ // Since we cannot detect when that happens, a previously invalid control may
220
+ // not clear its error styling when it becomes valid again.
221
+ //
222
+ // To work around this, call `form.reportValidity()` when submitting a form
223
+ // declaratively. This can be down on the `<button type="submit">`'s click or
224
+ // the text editable `<input>`'s 'Enter' keydown.
225
+ }
226
+ const FORM_VALIDATE_HOOKS = new WeakMap();
227
+ /**
228
+ * Get a hooks `EventTarget` that dispatches 'before' and 'after' events that
229
+ * fire before a form runs constraint validation and immediately after it
230
+ * finishes running constraint validation on its controls.
231
+ *
232
+ * This happens during `form.reportValidity()` and `form.requestSubmit()`.
233
+ *
234
+ * @param form The form to get or set up hooks for.
235
+ * @return A hooks `EventTarget` to add listeners to.
236
+ */
237
+ function getFormValidateHooks(form) {
238
+ if (!FORM_VALIDATE_HOOKS.has(form)) {
239
+ // Patch form methods to add event listener hooks. These are needed to react
240
+ // to form behaviors that do not dispatch events, such as a form asking its
241
+ // controls to report their validity.
242
+ //
243
+ // We should only patch the methods once, since multiple controls and other
244
+ // forces may want to patch this method. We cannot reliably clean it up if
245
+ // there are multiple patched and re-patched methods referring holding
246
+ // references to each other.
247
+ //
248
+ // Instead, we never clean up the patch but add and clean up event listeners
249
+ // added to the hooks after the patch.
171
250
  const hooks = new EventTarget();
172
- const superReportValidity = form.reportValidity;
173
- form.reportValidity = function () {
174
- hooks.dispatchEvent(new Event('before'));
175
- const valid = superReportValidity.call(this);
176
- hooks.dispatchEvent(new Event('after'));
177
- return valid;
178
- };
179
- FORM_REPORT_VALIDITY_HOOKS.set(form, hooks);
251
+ FORM_VALIDATE_HOOKS.set(form, hooks);
252
+ // Add hooks to support notifying before and after a form has run constraint
253
+ // validation on its controls.
254
+ // Note: `form.submit()` does not run constraint validation per spec.
255
+ for (const methodName of ['reportValidity', 'requestSubmit']) {
256
+ const superMethod = form[methodName];
257
+ form[methodName] = function () {
258
+ hooks.dispatchEvent(new Event('before'));
259
+ const result = Reflect.apply(superMethod, this, arguments);
260
+ hooks.dispatchEvent(new Event('after'));
261
+ return result;
262
+ };
263
+ }
264
+ }
265
+ return FORM_VALIDATE_HOOKS.get(form);
266
+ }
267
+ /**
268
+ * Checks if a control is the first invalid control in a form.
269
+ *
270
+ * @param form The control's form. When `null`, the control doesn't have a form
271
+ * and the method returns true.
272
+ * @param control The control to check.
273
+ * @return True if there is no form or if the control is the form's first
274
+ * invalid control.
275
+ */
276
+ function isFirstInvalidControlInForm(form, control) {
277
+ if (!form) {
278
+ return true;
279
+ }
280
+ let firstInvalidControl;
281
+ for (const element of form.elements) {
282
+ if (element.matches(':invalid')) {
283
+ firstInvalidControl = element;
284
+ break;
285
+ }
180
286
  }
181
- const hooks = FORM_REPORT_VALIDITY_HOOKS.get(form);
182
- hooks.addEventListener('before', beforeReportValidity, { signal: cleanup });
183
- hooks.addEventListener('after', afterReportValidity, { signal: cleanup });
287
+ return firstInvalidControl === control;
184
288
  }
185
289
  //# sourceMappingURL=on-report-validity.js.map