@angular/material 21.0.0-next.3 → 21.0.0-next.5

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.
@@ -18,6 +18,8 @@ interface ButtonHarnessFilters extends BaseHarnessFilters {
18
18
  disabled?: boolean;
19
19
  /** Only find instances with the specified type. */
20
20
  buttonType?: ButtonType;
21
+ /** Only find instances that contain an icon whose name matches the given value. */
22
+ iconName?: string | RegExp;
21
23
  }
22
24
 
23
25
  /** Harness for interacting with a mat-button in tests. */
@@ -86,6 +86,10 @@ $default-border-radius: 4px;
86
86
  $config: map.merge($default-config, $config);
87
87
 
88
88
  @include _customize-focus-indicators($config);
89
+
90
+ // Strong focus indicators currently need chip labels to have overflow visible.
91
+ // TODO(b/446709063) revisit the structure to find a way to remove this dependency.
92
+ @include _chip-label-overflow-visible();
89
93
  }
90
94
 
91
95
  @mixin strong-focus-indicators-color($theme-or-color) {
@@ -108,3 +112,15 @@ $default-border-radius: 4px;
108
112
  }
109
113
  }
110
114
  }
115
+
116
+ @mixin _chip-label-overflow-visible {
117
+ .mat-mdc-standard-chip {
118
+ // MDC sets `overflow: hidden` on these elements in order to truncate the text. This conflicts
119
+ // with how we structure and style the strong focus indicators so we need to override it.
120
+ .mdc-evolution-chip__cell--primary,
121
+ .mdc-evolution-chip__action--primary,
122
+ .mat-mdc-chip-action-label {
123
+ overflow: visible;
124
+ }
125
+ }
126
+ }
@@ -3,134 +3,109 @@
3
3
  @mixin system-classes() {
4
4
 
5
5
  // ***********************************************************************************************
6
- // Background - Apply background color and a contrastful corresponding text color
7
- // See https://m3.material.io/styles/color/roles for guidance.
6
+ // Background - Applies background colors defined by Material Design.
7
+ // See https://m3.material.io/styles/color/roles for detailed guidance.
8
8
  // ***********************************************************************************************
9
9
 
10
- // Styles an element with a primary color background and applies an accessible contrasting
11
- // color for text and icons. Use for key components across the UI, such as buttons that
12
- // have greater importance on the page. In Angular Material, this is used for the selected
13
- // date in a datepicker, the handle of a slider, and the background of a checkbox.
10
+ // Styles an element with a primary color background. Use for key components across the UI, such
11
+ // as buttons that have greater importance on the page. In Angular Material, this is used for the
12
+ // selected date in a datepicker, the handle of a slider, and the background of a checkbox.
14
13
  .mat-bg-primary {
15
14
  background-color: var(--mat-sys-primary);
16
- color: var(--mat-sys-on-primary);
17
15
  }
18
16
 
19
- // Styles an element with a primary container color background and applies an accessible
20
- // contrasting color for text and icons. Use for filling components that should stand out
21
- // on a surface. In Angular Material, this is used for
22
- // the container of a floating action button.
17
+ // Styles an element with a primary container color background. Use for filling components that
18
+ // should stand out on a surface. In Angular Material, this is used for the container of a
19
+ // floating action button.
23
20
  .mat-bg-primary-container {
24
21
  background-color: var(--mat-sys-primary-container);
25
- color: var(--mat-sys-on-primary-container);
26
22
  }
27
23
 
28
- // Styles an element with a secondary color background and applies an accessible contrasting
29
- // color for text and icons. Use for less prominent components in the UI that have a different
30
- // color scheme than the primary.
24
+ // Styles an element with a secondary color background. Use for less prominent components in the
25
+ // UI that have a different color scheme than the primary.
31
26
  .mat-bg-secondary {
32
27
  background-color: var(--mat-sys-secondary);
33
- color: var(--mat-sys-on-secondary);
34
28
  }
35
29
 
36
- // Styles an element with a secondary container color background and applies an accessible
37
- // contrasting color for text and icons. Use for components that need less emphasis than
38
- // secondary, such as filter chips. In Angular Material, this is used for selected items
39
- // in a list and the container of a tonal button.
30
+ // Styles an element with a secondary container color background. Use for components that need
31
+ // less emphasis than secondary, such as filter chips. In Angular Material, this is used for
32
+ // selected items in a list and the container of a tonal button.
40
33
  .mat-bg-secondary-container {
41
34
  background-color: var(--mat-sys-secondary-container);
42
- color: var(--mat-sys-on-secondary-container);
43
35
  }
44
36
 
45
- // Styles an element with an error color background and applies an accessible contrasting
46
- // color for text and icons. Use for indicating an error state, such as an invalid text field, or
47
- // for the background of an important notification. In Angular Material, this is used for the
48
- // background of a badge.
37
+ // Styles an element with an error color background. Use for indicating an error state, such as
38
+ // an invalid text field, or for the background of an important notification. In Angular
39
+ // Material, this is used for the background of a badge.
49
40
  .mat-bg-error {
50
41
  background-color: var(--mat-sys-error);
51
- color: var(--mat-sys-on-error);
52
42
  }
53
43
 
54
- // Styles an element with an error container color background and applies an accessible
55
- // contrasting color for text and icons. Use for components that need less emphasis than
56
- // error, such as a container for error text.
44
+ // Styles an element with an error container color background. Use for components that need less
45
+ // emphasis than error, such as a container for error text.
57
46
  .mat-bg-error-container {
58
47
  background-color: var(--mat-sys-error-container);
59
- color: var(--mat-sys-on-error-container);
60
48
  }
61
49
 
62
- // Styles an element with a surface color background and applies an accessible contrasting
63
- // color for text and icons. Use for general surfaces of components. In Angular Material, this is
64
- // used for the background of many components, like tables, dialogs, menus, and toolbars.
50
+ // Styles an element with a surface color background. Use for general surfaces of components. In
51
+ // Angular Material, this is used for the background of many components, like tables, dialogs,
52
+ // menus, and toolbars.
65
53
  .mat-bg-surface {
66
54
  background-color: var(--mat-sys-surface);
67
- color: var(--mat-sys-on-surface);
68
55
  }
69
56
 
70
- // Styles an element with a surface variant color background and applies an accessible
71
- // contrasting color for text and icons. Use for surfaces that need to stand out from the
72
- // main surface color. In Angular Material, this is used for the background of a filled
73
- // form field and the track of a progress bar.
57
+ // Styles an element with a surface variant color background. Use for surfaces that need to stand
58
+ // out from the main surface color. In Angular Material, this is used for the background of a
59
+ // filled form field and the track of a progress bar.
74
60
  .mat-bg-surface-variant {
75
61
  background-color: var(--mat-sys-surface-variant);
76
- color: var(--mat-sys-on-surface-variant);
77
62
  }
78
63
 
79
- // Styles an element with the "highest" surface container color background and applies an
80
- // accessible contrasting color for text and icons. Use for surfaces that need the most
81
- // emphasis against the main surface color. In Angular Material, this is used for the
82
- // background of a filled card.
64
+ // Styles an element with the "highest" surface container color background. Use for surfaces that
65
+ // need the most emphasis against the main surface color. In Angular Material, this is used for
66
+ // the background of a filled card.
83
67
  .mat-bg-surface-container-highest {
84
68
  background-color: var(--mat-sys-surface-container-highest);
85
- color: var(--mat-sys-on-surface);
86
69
  }
87
70
 
88
- // Styles an element with a "high" surface container color background and applies an accessible
89
- // contrasting color for text and icons. Use for surfaces that need more emphasis against
90
- // the main surface color. In Angular Material, this is used for the background of a datepicker.
71
+ // Styles an element with a "high" surface container color background. Use for surfaces that need
72
+ // more emphasis against the main surface color. In Angular Material, this is used for the
73
+ // background of a datepicker.
91
74
  .mat-bg-surface-container-high {
92
75
  background-color: var(--mat-sys-surface-container-high);
93
- color: var(--mat-sys-on-surface);
94
76
  }
95
77
 
96
- // Styles an element with a surface container color background and applies an accessible
97
- // contrasting color for text and icons. Use for surfaces that need to stand out from the
98
- // main surface color. In Angular Material, this is used for the background of a menu.
78
+ // Styles an element with a surface container color background. Use for surfaces that need to
79
+ // stand out from the main surface color. In Angular Material, this is used for the background
80
+ // of a menu.
99
81
  .mat-bg-surface-container {
100
82
  background-color: var(--mat-sys-surface-container);
101
- color: var(--mat-sys-on-surface);
102
83
  }
103
84
 
104
- // Styles an element with a "low" surface container color background and applies an accessible
105
- // contrasting color for text and icons. Use for surfaces that need less emphasis against
106
- // the main surface color. In Angular Material, this is used for the background of a bottom sheet.
85
+ // Styles an element with a "low" surface container color background. Use for surfaces that need
86
+ // less emphasis against the main surface color. In Angular Material, this is used for the
87
+ // background of a bottom sheet.
107
88
  .mat-bg-surface-container-low {
108
89
  background-color: var(--mat-sys-surface-container-low);
109
- color: var(--mat-sys-on-surface);
110
90
  }
111
91
 
112
- // Styles an element with the "lowest" surface container color background and applies an
113
- // accessible contrasting color for text and icons. Use for surfaces that need the least
114
- // emphasis against the main surface color.
92
+ // Styles an element with the "lowest" surface container color background. Use for surfaces that
93
+ // need the least emphasis against the main surface color.
115
94
  .mat-bg-surface-container-lowest {
116
95
  background-color: var(--mat-sys-surface-container-lowest);
117
- color: var(--mat-sys-on-surface);
118
96
  }
119
97
 
120
- // Styles an element with an inverse surface color background and applies an accessible
121
- // contrasting color for text and icons. Use for making elements stand out against the
122
- // default color scheme. Good for temporary notifications. In Angular Material, this is used for
123
- // the background of a snackbar and a tooltip.
98
+ // Styles an element with an inverse surface color background. Use for making elements stand out
99
+ // against the default color scheme. Good for temporary notifications. In Angular Material, this
100
+ // is used for the background of a snackbar and a tooltip.
124
101
  .mat-bg-inverse-surface {
125
102
  background-color: var(--mat-sys-inverse-surface);
126
- color: var(--mat-sys-inverse-on-surface);
127
103
  }
128
104
 
129
- // Styles an element with a disabled color background and applies an accessible contrasting
130
- // color for text and icons. Use for disabled components. In Angular Material, this is used
131
- // for components generally filled with the primary color but are currently disabled.
105
+ // Styles an element with a disabled color background. Use for disabled components. In Angular
106
+ // Material, this is used for components generally filled with the primary color but are
107
+ // currently disabled.
132
108
  .mat-bg-disabled {
133
- color: color-mix(in srgb, var(--mat-sys-on-surface) 38%, transparent);
134
109
  background-color: color-mix(in srgb, var(--mat-sys-on-surface) 12%, transparent);
135
110
  }
136
111
 
@@ -145,8 +120,7 @@
145
120
  color: var(--mat-sys-primary);
146
121
  }
147
122
 
148
- // Styles the text of an element with the secondary color. Use for text that needs less emphasis
149
- // than primary text.
123
+ // Styles the text of an element with the secondary color. Use for text that needs to stand out.
150
124
  .mat-text-secondary {
151
125
  color: var(--mat-sys-secondary);
152
126
  }
@@ -158,11 +132,60 @@
158
132
  }
159
133
 
160
134
  // Styles the text of an element with the disabled color. Use for text in disabled components.
161
- // In Angular Material this is used to show text is disabled, generally on a "surface" background.
162
135
  .mat-text-disabled {
163
136
  color: color-mix(in srgb, var(--mat-sys-on-surface) 38%, transparent);
164
137
  }
165
138
 
139
+ // Styles the text of an element with the on-surface-variant color. Use for text that should have
140
+ // a lower emphasis than the surrounding text. This can include subheading, captions, and hint
141
+ // text.
142
+ .mat-text-on-surface-variant {
143
+ color: var(--mat-sys-on-surface-variant);
144
+ }
145
+
146
+ // Styles the text of an element with a color that contrasts well against a primary background.
147
+ .mat-text-on-primary {
148
+ color: var(--mat-sys-on-primary);
149
+ }
150
+
151
+ // Styles the text of an element with a color that contrasts well against a primary-container
152
+ // background.
153
+ .mat-text-on-primary-container {
154
+ color: var(--mat-sys-on-primary-container);
155
+ }
156
+
157
+ // Styles the text of an element with a color that contrasts well against a secondary background.
158
+ .mat-text-on-secondary {
159
+ color: var(--mat-sys-on-secondary);
160
+ }
161
+
162
+ // Styles the text of an element with a color that contrasts well against a secondary-container
163
+ // background.
164
+ .mat-text-on-secondary-container {
165
+ color: var(--mat-sys-on-secondary-container);
166
+ }
167
+
168
+ // Styles the text of an element with a color that contrasts well against an error background.
169
+ .mat-text-on-error {
170
+ color: var(--mat-sys-on-error);
171
+ }
172
+
173
+ // Styles the text of an element with a color that contrasts well against an error-container
174
+ // background.
175
+ .mat-text-on-error-container {
176
+ color: var(--mat-sys-on-error-container);
177
+ }
178
+
179
+ // Styles the text of an element with a color that contrasts well against a surface background.
180
+ .mat-text-on-surface {
181
+ color: var(--mat-sys-on-surface);
182
+ }
183
+
184
+ // Styles the text of an element with a color that contrasts well against an inverse-surface
185
+ // background.
186
+ .mat-text-inverse-on-surface {
187
+ color: var(--mat-sys-inverse-on-surface);
188
+ }
166
189
 
167
190
  // ***********************************************************************************************
168
191
  // Font - Apply typography styles
@@ -232,6 +255,26 @@
232
255
  letter-spacing: var(--mat-sys-headline-large-tracking);
233
256
  }
234
257
 
258
+ // Sets the font to the label small typeface. Use for small labels, such as text in a badge.
259
+ .mat-font-label-sm {
260
+ font: var(--mat-sys-label-small);
261
+ letter-spacing: var(--mat-sys-label-small-tracking);
262
+ }
263
+
264
+ // Sets the font to the label medium typeface. Use for medium labels. In Angular Material, this
265
+ // is used for the slider label.
266
+ .mat-font-label-md {
267
+ font: var(--mat-sys-label-medium);
268
+ letter-spacing: var(--mat-sys-label-medium-tracking);
269
+ }
270
+
271
+ // Sets the font to the label large typeface. Use for large labels. In Angular Material, this is
272
+ // used for buttons, chips, and menu labels.
273
+ .mat-font-label-lg {
274
+ font: var(--mat-sys-label-large);
275
+ letter-spacing: var(--mat-sys-label-large-tracking);
276
+ }
277
+
235
278
  // Sets the font to the title small typeface. Use for small titles, such as a card title. In
236
279
  // Angular Material, this is used for the header of a table and the label of an option group.
237
280
  .mat-font-title-sm {
@@ -317,68 +360,6 @@
317
360
  border: 1px solid var(--mat-sys-outline-variant);
318
361
  }
319
362
 
320
-
321
- // ***********************************************************************************************
322
- // Interactive - Adds interaction colors for hover, active, and focus
323
- // ***********************************************************************************************
324
-
325
- // Adds hover, focus, and active states to an element by applying varying shades of the surface
326
- // color. Use for interactive components that are not based on a primary color.
327
- .mat-interactive {
328
- &:hover {
329
- background: color-mix(
330
- in srgb,
331
- var(--mat-sys-on-surface) calc(var(--mat-sys-hover-state-layer-opacity) * 100%),
332
- transparent
333
- );
334
- }
335
-
336
- &:focus {
337
- background: color-mix(
338
- in srgb,
339
- var(--mat-sys-on-surface) calc(var(--mat-sys-focus-state-layer-opacity) * 100%),
340
- transparent
341
- );
342
- }
343
-
344
- &:active {
345
- background: color-mix(
346
- in srgb,
347
- var(--mat-sys-on-surface) calc(var(--mat-sys-pressed-state-layer-opacity) * 100%),
348
- transparent
349
- );
350
- }
351
- }
352
-
353
- // Adds hover, focus, and active states to an element by applying varying shades of the primary
354
- // color. Use for interactive components that are not based on a primary color.
355
- .mat-interactive-primary {
356
- &:hover {
357
- background: color-mix(
358
- in srgb,
359
- var(--mat-sys-primary) calc(var(--mat-sys-hover-state-layer-opacity) * 100%),
360
- transparent
361
- );
362
- }
363
-
364
- &:focus {
365
- background: color-mix(
366
- in srgb,
367
- var(--mat-sys-primary) calc(var(--mat-sys-focus-state-layer-opacity) * 100%),
368
- transparent
369
- );
370
- }
371
-
372
- &:active {
373
- background: color-mix(
374
- in srgb,
375
- var(--mat-sys-primary) calc(var(--mat-sys-pressed-state-layer-opacity) * 100%),
376
- transparent
377
- );
378
- }
379
- }
380
-
381
-
382
363
  // ***********************************************************************************************
383
364
  // Shadow - Applies elevation levels through box-shadow
384
365
  // See https://m3.material.io/styles/elevation/applying-elevation for guidance.
@@ -0,0 +1,11 @@
1
+ // Dark system color values that are google3-internal and diverge from the
2
+ // external Material Design spec.
3
+ @function values-dark($palettes) {
4
+ @return ();
5
+ }
6
+
7
+ // Light system color values that are google3-internal and diverge from the
8
+ // external Material Design spec.
9
+ @function values-light($palettes) {
10
+ @return ();
11
+ }
@@ -1,8 +1,9 @@
1
1
  @use 'sass:map';
2
2
  @use '../../m2/palette';
3
+ @use './md-sys-color-internal';
3
4
 
4
5
  @function md-sys-color-values-dark($palettes) {
5
- @return (
6
+ $values: (
6
7
  primary: map.get($palettes, primary, default),
7
8
  on-primary: map.get($palettes, primary, default-contrast),
8
9
  inverse-primary: map.get($palettes, primary, 600),
@@ -55,10 +56,14 @@
55
56
  tertiary-fixed: map.get($palettes, accent, default),
56
57
  tertiary-fixed-dim: map.get($palettes, accent, default),
57
58
  );
59
+
60
+ $values: map.merge($values, md-sys-color-internal.values-dark($palettes));
61
+
62
+ @return $values;
58
63
  }
59
64
 
60
65
  @function md-sys-color-values-light($palettes) {
61
- @return (
66
+ $values: (
62
67
  primary: map.get($palettes, primary, default),
63
68
  on-primary: map.get($palettes, primary, default-contrast),
64
69
  inverse-primary: map.get($palettes, primary, 300),
@@ -111,4 +116,8 @@
111
116
  tertiary-fixed: map.get($palettes, accent, default),
112
117
  tertiary-fixed-dim: map.get($palettes, accent, default),
113
118
  );
119
+
120
+ $values: map.merge($values, md-sys-color-internal.values-light($palettes));
121
+
122
+ @return $values;
114
123
  }
@@ -0,0 +1,11 @@
1
+ // Dark system color values that are internal-only and diverge from the
2
+ // external Material Design spec.
3
+ @function values-dark($palettes) {
4
+ @return ();
5
+ }
6
+
7
+ // Light system color values that are internal-only and diverge from the
8
+ // external Material Design spec.
9
+ @function values-light($palettes) {
10
+ @return ();
11
+ }
@@ -1,7 +1,5 @@
1
1
  @use 'sass:map';
2
-
3
- // Indicates whether alternative tokens should be used
4
- $_alternate-tokens: false;
2
+ @use './md-sys-color-internal';
5
3
 
6
4
  @function md-sys-color-values-dark($palettes: ()) {
7
5
  $values: (
@@ -53,22 +51,10 @@ $_alternate-tokens: false;
53
51
  tertiary: map.get($palettes, tertiary, 80),
54
52
  tertiary-container: map.get($palettes, tertiary, 30),
55
53
  tertiary-fixed: map.get($palettes, tertiary, 90),
56
- tertiary-fixed-dim: map.get($palettes, tertiary, 80)
54
+ tertiary-fixed-dim: map.get($palettes, tertiary, 80),
57
55
  );
58
56
 
59
- @if ($_alternate-tokens) {
60
- $values: map.merge($values, (
61
- on-surface-variant: map.get($palettes, neutral-variant, 80),
62
- surface-bright: #37393b,
63
- surface-container: #1e1f20,
64
- surface-container-high: #282a2c,
65
- surface-container-highest: #333537,
66
- surface-container-low: #1b1b1b,
67
- surface-container-lowest: #0e0e0e,
68
- surface-dim: #131313,
69
- surface-tint: #d1e1ff,
70
- ));
71
- }
57
+ $values: map.merge($values, md-sys-color-internal.values-dark($palettes));
72
58
 
73
59
  @return $values;
74
60
  }
@@ -123,22 +109,10 @@ $_alternate-tokens: false;
123
109
  tertiary: map.get($palettes, tertiary, 40),
124
110
  tertiary-container: map.get($palettes, tertiary, 90),
125
111
  tertiary-fixed: map.get($palettes, tertiary, 90),
126
- tertiary-fixed-dim: map.get($palettes, tertiary, 80)
112
+ tertiary-fixed-dim: map.get($palettes, tertiary, 80),
127
113
  );
128
114
 
129
- @if ($_alternate-tokens) {
130
- $values: map.merge($values, (
131
- background: map.get($palettes, neutral, 100),
132
- surface: map.get($palettes, neutral, 100),
133
- surface-bright: map.get($palettes, neutral, 100),
134
- surface-container: #f0f4f9,
135
- surface-container-high: #e9eef6,
136
- surface-container-highest: #dde3ea,
137
- surface-container-low: #f8fafd,
138
- surface-dim: #d3dbe5,
139
- surface-tint: #6991d6,
140
- ));
141
- }
115
+ $values: map.merge($values, md-sys-color-internal.values-light($palettes));
142
116
 
143
117
  @return $values;
144
118
  }
@@ -0,0 +1,5 @@
1
+ // System typescale values that are internal-only and diverge from the
2
+ // external Material Design spec.
3
+ @function values($typography) {
4
+ @return ();
5
+ }
@@ -4,9 +4,7 @@
4
4
  //
5
5
 
6
6
  @use 'sass:map';
7
-
8
- // Indicates whether alternative tokens should be used
9
- $_alternate-tokens: false;
7
+ @use './md-sys-typescale-internal';
10
8
 
11
9
  @function md-sys-typescale-values($typography: ()) {
12
10
  $plain: map.get($typography, plain);
@@ -110,19 +108,7 @@ $_alternate-tokens: false;
110
108
  title-small-weight: $medium
111
109
  );
112
110
 
113
- @if ($_alternate-tokens) {
114
- $values: map.merge($values, (
115
- body-large-tracking: 0,
116
- body-medium-tracking: 0,
117
- body-small-tracking: 0.006rem,
118
- display-large-tracking: 0,
119
- label-large-tracking: 0,
120
- label-medium-tracking: 0.006rem,
121
- label-small-tracking: 0.006rem,
122
- title-medium-tracking: 0,
123
- title-small-tracking: 0,
124
- ));
125
- }
111
+ $values: map.merge($values, md-sys-typescale-internal.values($typography));
126
112
 
127
113
  @return $values;
128
114
  }
@@ -1,5 +1,6 @@
1
1
  import { booleanAttribute } from '@angular/core';
2
2
  import { ContentContainerComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
3
+ import { MatIconHarness } from '@angular/material/icon/testing';
3
4
 
4
5
  /** Harness for interacting with a mat-button in tests. */
5
6
  class MatButtonHarness extends ContentContainerComponentHarness {
@@ -27,7 +28,10 @@ class MatButtonHarness extends ContentContainerComponentHarness {
27
28
  .addOption('disabled', options.disabled, async (harness, disabled) => {
28
29
  return (await harness.isDisabled()) === disabled;
29
30
  })
30
- .addOption('buttonType', options.buttonType, (harness, buttonType) => HarnessPredicate.stringMatches(harness.getType(), buttonType));
31
+ .addOption('buttonType', options.buttonType, (harness, buttonType) => HarnessPredicate.stringMatches(harness.getType(), buttonType))
32
+ .addOption('iconName', options.iconName, (harness, iconName) => {
33
+ return harness.hasHarness(MatIconHarness.with({ name: iconName }));
34
+ });
31
35
  }
32
36
  async click(...args) {
33
37
  return (await this.host()).click(...args);
@@ -1 +1 @@
1
- {"version":3,"file":"testing.mjs","sources":["../../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/src/material/button/testing/button-harness.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {booleanAttribute} from '@angular/core';\nimport {\n ComponentHarnessConstructor,\n ContentContainerComponentHarness,\n HarnessPredicate,\n} from '@angular/cdk/testing';\nimport {\n ButtonAppearance,\n ButtonHarnessFilters,\n ButtonType,\n ButtonVariant,\n} from './button-harness-filters';\n\n/** Harness for interacting with a mat-button in tests. */\nexport class MatButtonHarness extends ContentContainerComponentHarness {\n // Note: `.mat-mdc-button-base` should be enough for all buttons, however some apps are using\n // the harness without actually having an applied button. Keep the attributes for backwards\n // compatibility.\n\n /** Selector for the harness. */\n static hostSelector = `.mat-mdc-button-base, [matButton], [mat-button], [matIconButton],\n [matFab], [matMiniFab], [mat-raised-button], [mat-flat-button], [mat-icon-button],\n [mat-stroked-button], [mat-fab], [mat-mini-fab]`;\n\n /**\n * Gets a `HarnessPredicate` that can be used to search for a button with specific attributes.\n * @param options Options for narrowing the search:\n * - `selector` finds a button whose host element matches the given selector.\n * - `text` finds a button with specific text content.\n * - `variant` finds buttons matching a specific variant.\n * - `appearance` finds buttons matching a specific appearance.\n * @return a `HarnessPredicate` configured with the given options.\n */\n static with<T extends MatButtonHarness>(\n this: ComponentHarnessConstructor<T>,\n options: ButtonHarnessFilters = {},\n ): HarnessPredicate<T> {\n return new HarnessPredicate(this, options)\n .addOption('text', options.text, (harness, text) =>\n HarnessPredicate.stringMatches(harness.getText(), text),\n )\n .addOption('variant', options.variant, (harness, variant) =>\n HarnessPredicate.stringMatches(harness.getVariant(), variant),\n )\n .addOption('appearance', options.appearance, (harness, appearance) =>\n HarnessPredicate.stringMatches(harness.getAppearance(), appearance),\n )\n .addOption('disabled', options.disabled, async (harness, disabled) => {\n return (await harness.isDisabled()) === disabled;\n })\n .addOption('buttonType', options.buttonType, (harness, buttonType) =>\n HarnessPredicate.stringMatches(harness.getType(), buttonType),\n );\n }\n\n /**\n * Clicks the button at the given position relative to its top-left.\n * @param relativeX The relative x position of the click.\n * @param relativeY The relative y position of the click.\n */\n click(relativeX: number, relativeY: number): Promise<void>;\n /** Clicks the button at its center. */\n click(location: 'center'): Promise<void>;\n /** Clicks the button. */\n click(): Promise<void>;\n async click(...args: [] | ['center'] | [number, number]): Promise<void> {\n return (await this.host()).click(...(args as []));\n }\n\n /** Gets a boolean promise indicating if the button is disabled. */\n async isDisabled(): Promise<boolean> {\n const host = await this.host();\n return (\n booleanAttribute(await host.getAttribute('disabled')) ||\n (await host.hasClass('mat-mdc-button-disabled'))\n );\n }\n\n /** Gets a promise for the button's label text. */\n async getText(): Promise<string> {\n return (await this.host()).text();\n }\n\n /** Focuses the button and returns a void promise that indicates when the action is complete. */\n async focus(): Promise<void> {\n return (await this.host()).focus();\n }\n\n /** Blurs the button and returns a void promise that indicates when the action is complete. */\n async blur(): Promise<void> {\n return (await this.host()).blur();\n }\n\n /** Whether the button is focused. */\n async isFocused(): Promise<boolean> {\n return (await this.host()).isFocused();\n }\n\n /** Gets the variant of the button. */\n async getVariant(): Promise<ButtonVariant> {\n const host = await this.host();\n\n // TODO(crisbeto): we're checking both classes and attributes for backwards compatibility\n // with some internal apps that were applying the attribute without importing the directive.\n // Really we should be only targeting the classes.\n if (\n (await host.hasClass('mat-mdc-icon-button')) ||\n (await host.getAttribute('mat-icon-button')) != null\n ) {\n return 'icon';\n }\n\n if (\n (await host.hasClass('mat-mdc-mini-fab')) ||\n (await host.getAttribute('mat-mini-fab')) != null\n ) {\n return 'mini-fab';\n }\n\n if ((await host.hasClass('mat-mdc-fab')) || (await host.getAttribute('mat-fab')) != null) {\n return 'fab';\n }\n\n return 'basic';\n }\n\n /** Gets the appearance of the button. */\n async getAppearance(): Promise<ButtonAppearance | null> {\n const host = await this.host();\n\n if (await host.hasClass('mat-mdc-outlined-button')) {\n return 'outlined';\n }\n\n if (await host.hasClass('mat-mdc-raised-button')) {\n return 'elevated';\n }\n\n if (await host.hasClass('mat-mdc-unelevated-button')) {\n return 'filled';\n }\n\n if (await host.hasClass('mat-mdc-button')) {\n return 'text';\n }\n\n if (await host.hasClass('mat-tonal-button')) {\n return 'tonal';\n }\n\n return null;\n }\n\n /**\n * Gets the type of the button. Supported values are 'button', 'submit', and 'reset'.\n */\n async getType(): Promise<ButtonType | null> {\n const host = await this.host();\n const buttonType = await host.getAttribute('type');\n if (buttonType === 'button' || buttonType === 'submit' || buttonType === 'reset') {\n return buttonType;\n }\n return null;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"testing.mjs","sources":["../../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/src/material/button/testing/button-harness.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport {booleanAttribute} from '@angular/core';\nimport {\n ComponentHarnessConstructor,\n ContentContainerComponentHarness,\n HarnessPredicate,\n} from '@angular/cdk/testing';\nimport {MatIconHarness} from '@angular/material/icon/testing';\nimport {\n ButtonAppearance,\n ButtonHarnessFilters,\n ButtonType,\n ButtonVariant,\n} from './button-harness-filters';\n\n/** Harness for interacting with a mat-button in tests. */\nexport class MatButtonHarness extends ContentContainerComponentHarness {\n // Note: `.mat-mdc-button-base` should be enough for all buttons, however some apps are using\n // the harness without actually having an applied button. Keep the attributes for backwards\n // compatibility.\n\n /** Selector for the harness. */\n static hostSelector = `.mat-mdc-button-base, [matButton], [mat-button], [matIconButton],\n [matFab], [matMiniFab], [mat-raised-button], [mat-flat-button], [mat-icon-button],\n [mat-stroked-button], [mat-fab], [mat-mini-fab]`;\n\n /**\n * Gets a `HarnessPredicate` that can be used to search for a button with specific attributes.\n * @param options Options for narrowing the search:\n * - `selector` finds a button whose host element matches the given selector.\n * - `text` finds a button with specific text content.\n * - `variant` finds buttons matching a specific variant.\n * - `appearance` finds buttons matching a specific appearance.\n * @return a `HarnessPredicate` configured with the given options.\n */\n static with<T extends MatButtonHarness>(\n this: ComponentHarnessConstructor<T>,\n options: ButtonHarnessFilters = {},\n ): HarnessPredicate<T> {\n return new HarnessPredicate(this, options)\n .addOption('text', options.text, (harness, text) =>\n HarnessPredicate.stringMatches(harness.getText(), text),\n )\n .addOption('variant', options.variant, (harness, variant) =>\n HarnessPredicate.stringMatches(harness.getVariant(), variant),\n )\n .addOption('appearance', options.appearance, (harness, appearance) =>\n HarnessPredicate.stringMatches(harness.getAppearance(), appearance),\n )\n .addOption('disabled', options.disabled, async (harness, disabled) => {\n return (await harness.isDisabled()) === disabled;\n })\n .addOption('buttonType', options.buttonType, (harness, buttonType) =>\n HarnessPredicate.stringMatches(harness.getType(), buttonType),\n )\n .addOption('iconName', options.iconName, (harness, iconName) => {\n return harness.hasHarness(MatIconHarness.with({name: iconName}));\n });\n }\n\n /**\n * Clicks the button at the given position relative to its top-left.\n * @param relativeX The relative x position of the click.\n * @param relativeY The relative y position of the click.\n */\n click(relativeX: number, relativeY: number): Promise<void>;\n /** Clicks the button at its center. */\n click(location: 'center'): Promise<void>;\n /** Clicks the button. */\n click(): Promise<void>;\n async click(...args: [] | ['center'] | [number, number]): Promise<void> {\n return (await this.host()).click(...(args as []));\n }\n\n /** Gets a boolean promise indicating if the button is disabled. */\n async isDisabled(): Promise<boolean> {\n const host = await this.host();\n return (\n booleanAttribute(await host.getAttribute('disabled')) ||\n (await host.hasClass('mat-mdc-button-disabled'))\n );\n }\n\n /** Gets a promise for the button's label text. */\n async getText(): Promise<string> {\n return (await this.host()).text();\n }\n\n /** Focuses the button and returns a void promise that indicates when the action is complete. */\n async focus(): Promise<void> {\n return (await this.host()).focus();\n }\n\n /** Blurs the button and returns a void promise that indicates when the action is complete. */\n async blur(): Promise<void> {\n return (await this.host()).blur();\n }\n\n /** Whether the button is focused. */\n async isFocused(): Promise<boolean> {\n return (await this.host()).isFocused();\n }\n\n /** Gets the variant of the button. */\n async getVariant(): Promise<ButtonVariant> {\n const host = await this.host();\n\n // TODO(crisbeto): we're checking both classes and attributes for backwards compatibility\n // with some internal apps that were applying the attribute without importing the directive.\n // Really we should be only targeting the classes.\n if (\n (await host.hasClass('mat-mdc-icon-button')) ||\n (await host.getAttribute('mat-icon-button')) != null\n ) {\n return 'icon';\n }\n\n if (\n (await host.hasClass('mat-mdc-mini-fab')) ||\n (await host.getAttribute('mat-mini-fab')) != null\n ) {\n return 'mini-fab';\n }\n\n if ((await host.hasClass('mat-mdc-fab')) || (await host.getAttribute('mat-fab')) != null) {\n return 'fab';\n }\n\n return 'basic';\n }\n\n /** Gets the appearance of the button. */\n async getAppearance(): Promise<ButtonAppearance | null> {\n const host = await this.host();\n\n if (await host.hasClass('mat-mdc-outlined-button')) {\n return 'outlined';\n }\n\n if (await host.hasClass('mat-mdc-raised-button')) {\n return 'elevated';\n }\n\n if (await host.hasClass('mat-mdc-unelevated-button')) {\n return 'filled';\n }\n\n if (await host.hasClass('mat-mdc-button')) {\n return 'text';\n }\n\n if (await host.hasClass('mat-tonal-button')) {\n return 'tonal';\n }\n\n return null;\n }\n\n /**\n * Gets the type of the button. Supported values are 'button', 'submit', and 'reset'.\n */\n async getType(): Promise<ButtonType | null> {\n const host = await this.host();\n const buttonType = await host.getAttribute('type');\n if (buttonType === 'button' || buttonType === 'submit' || buttonType === 'reset') {\n return buttonType;\n }\n return null;\n }\n}\n"],"names":[],"mappings":"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"}