### Load all button harnesses and first button harness Source: https://v21.material.angular.dev/guide/using-component-harnesses Uses `getAllHarnesses` to get all MatButtonHarness instances (length 3) and `getHarness` to get the first one. All harness APIs are asynchronous and return Promises, so `async`/`await` is used. ```typescript import {MatButtonHarness} from '@angular/material/button/testing'; ... it('should work', async () => { const buttons = await loader.getAllHarnesses(MatButtonHarness); // length: 3 const firstButton = await loader.getHarness(MatButtonHarness); // === buttons[0] }); ``` -------------------------------- ### Flat tree structure example Source: https://v21.material.angular.dev/components/tree Shows the DOM structure of a flat tree where nodes are rendered as siblings. Use this when you need a simpler structure for styling or virtual scrolling. ```html parent node -- child node1 -- child node2 ``` -------------------------------- ### Example test using MyButtonComponentHarness Source: https://v21.material.angular.dev/cdk/testing Shows a unit test that uses a harness to load a button component and verify its text. The harness is obtained via `loader.getHarness` and the test asserts the button's text equals 'Confirm'. ```typescript // Example of test with a harness for a component called MyButtonComponent it('should load button with exact text', async () => { const button = await loader.getHarness(MyButtonComponentHarness); expect(await button.getText()).toBe('Confirm'); }); ``` -------------------------------- ### LiveAnnouncer example: inject and announce message Source: https://v21.material.angular.dev/cdk/a11y Inject `LiveAnnouncer` using Angular's `inject` function and call the `announce` method to communicate a message to screen-reader users. ```typescript @Component({...}) export class MyComponent { private liveAnnouncer = inject(LiveAnnouncer); announceMessage() { this.liveAnnouncer.announce("Hey Google"); } } ``` -------------------------------- ### Nested tree structure example Source: https://v21.material.angular.dev/components/tree Shows the DOM structure of a nested tree where children are placed inside their parent node. Use this when hierarchical relationships need visual representation. ```html parent node -- child node1 -- child node2 ``` -------------------------------- ### Focus region with cdkFocusRegionStart, cdkFocusInitial, cdkFocusRegionEnd Source: https://v21.material.angular.dev/cdk/a11y Example of declaring explicit focus regions using cdkFocusRegionStart, cdkFocusRegionEnd, and cdkFocusInitial. cdkFocusInitial specifies the initially focused element. Note that cdkFocusInitial requires cdkTrapFocusAutoCapture to work with CdkTrapFocus. ```html Focus region start Link Initially focused Focus region end ``` -------------------------------- ### Conditional tree node templates with when predicate Source: https://v21.material.angular.dev/components/tree The tree can include multiple node templates, selected by the when predicate of the matTreeNodeDef. This example shows a default template and a special template for nodes matching isSpecial. ```html {{node.value}} [ A special node {{node.value}} ] ``` -------------------------------- ### Load harness for button inside a child loader Source: https://v21.material.angular.dev/guide/using-component-harnesses Uses `getChildLoader` to scope the loader to a `.footer` div, then gets the MatButtonHarness within that sub-section. This avoids brittle tests that depend on button order. ```typescript it('should work', async () => { const footerLoader = await loader.getChildLoader('.footer'); const footerButton = await footerLoader.getHarness(MatButtonHarness); }); ``` -------------------------------- ### Filter harnesses with MatButtonHarness.with Source: https://v21.material.angular.dev/guide/using-component-harnesses Uses the static `with` method to create HarnessPredicate filters. Supports standard options `selector` and `ancestor`, plus `text` for MatButtonHarness. Examples filter by id, text, and a combination of class and regex text. ```typescript it('should work', async () => { // Harness for mat-button whose id is 'more-info'. const info = await loader.getHarness(MatButtonHarness.with({selector: '#more-info'})); // Harness for mat-button whose text is 'Cancel'. const cancel = await loader.getHarness(MatButtonHarness.with({text: 'Cancel'})); // Harness for mat-button with class 'confirm' and whose text is either 'Ok' or 'Okay'. const okButton = await loader.getHarness( MatButtonHarness.with({selector: '.confirm', text: /^(Ok|Okay)$/})); }); ``` -------------------------------- ### cdkTrapFocus directive example Source: https://v21.material.angular.dev/cdk/a11y Example of using the cdkTrapFocus directive to trap Tab key focus within an element. Note that it does not prevent focus from moving out due to mouse interaction. ```html
``` -------------------------------- ### Define high contrast styles with high-contrast mixin Source: https://v21.material.angular.dev/cdk/a11y Use the high-contrast mixin to define styles that only apply in high contrast mode. The mixin targets the forced-colors media query, and this example adds an outline to buttons in high contrast mode. ```scss @use '@angular/cdk'; button { @include cdk.high-contrast { outline: solid 1px; } } ``` -------------------------------- ### Customize tree with tree-overrides mixin Source: https://v21.material.angular.dev/components/tree/styling Use the `tree-overrides` mixin to customize tree styles. The example applies styles to the entire app by using the `:root` selector; change it to a specific selector to scope the styles. The mixin accepts a map of tokens such as `container-background-color` and `node-text-color`. ```scss @use '@angular/material' as mat; // Customize the entire app. Change :root to your selector if you want to scope the styles. :root { @include mat.tree-overrides(( container-background-color: orange, node-text-color: red, )); } ``` -------------------------------- ### Use cdk-visually-hidden class on a checkbox Source: https://v21.material.angular.dev/cdk/a11y Apply the .cdk-visually-hidden class to an input element to visually hide it while keeping it accessible to screen readers. This example shows a custom checkbox wrapper with a visually hidden native checkbox. ```html
``` -------------------------------- ### FocusKeyManager with withWrap Source: https://v21.material.angular.dev/cdk/a11y Shows how to enable wrapping navigation in a FocusKeyManager by calling the withWrap method. ```typescript this.keyManager = new FocusKeyManager(...).withWrap(); ``` -------------------------------- ### mat-tree-node activation event Source: https://v21.material.angular.dev/components/tree For trees with nodes that have actions upon activation or click, mat-tree-node emits (activation) events when the user activates a node via keyboard. $event contains the node's data and is equivalent to the implicit data passed in the matTreeNodeDef context. ```html ``` -------------------------------- ### Tree node with expand/collapse toggle Source: https://v21.material.angular.dev/components/tree Adds a matTreeNodeToggle button to expand/collapse the node. Setting [matTreeNodeToggleRecursive] to true expands/collapses recursively. Ensure aria-label is provided for icon buttons. ```html {{node.value}} ``` -------------------------------- ### Highlightable interface Source: https://v21.material.angular.dev/cdk/a11y Interface that items managed by an ActiveDescendantKeyManager must implement. Extends ListKeyManagerOption and requires setActiveStyles and setInactiveStyles methods. ```typescript interface Highlightable extends ListKeyManagerOption { setActiveStyles(): void; setInactiveStyles(): void; } ``` -------------------------------- ### Create HarnessLoader in unit test Source: https://v21.material.angular.dev/guide/using-component-harnesses Imports HarnessLoader and TestbedHarnessEnvironment, then creates a loader in the fixture. This is used to locate Angular Material components in the component under test. ```typescript import {HarnessLoader} from '@angular/cdk/testing'; import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed'; let loader: HarnessLoader; describe('my-component', () => { beforeEach(async () => { TestBed.configureTestingModule({imports: [MyModule], declarations: [UserProfile]}); fixture = TestBed.createComponent(UserProfile); loader = TestbedHarnessEnvironment.loader(fixture); }); } ``` -------------------------------- ### Test using MatButtonHarness to click a button Source: https://v21.material.angular.dev/guide/using-component-harnesses This test uses MatButtonHarness to find a button with selector '.confirm', checks it is not disabled, clicks it, and verifies the component's 'confirmed' property becomes true. The harness automatically invokes change detection and waits for the fixture to be stable, so no explicit 'fixture.detectChanges()' call is needed. ```typescript it('should mark confirmed when ok button clicked', async () => { const okButton = await loader.getHarness(MatButtonHarness.with({selector: '.confirm'}); expect(fixture.componentInstance.confirmed).toBe(false); expect(await okButton.isDisabled()).toBe(false); await okButton.click(); expect(fixture.componentInstance.confirmed).toBe(true); }); ``` -------------------------------- ### ListKeyManager Source: https://v21.material.angular.dev/cdk/a11y/overview Manages the active option in a list of items based on keyboard interaction. Intended for components with role="menu" or role="listbox" patterns. ```APIDOC ## ListKeyManager ### Description Manages the active option in a list of items based on keyboard interaction. Intended to be used with components that correspond to a `role="menu"` or `role="listbox"` pattern. ### Basic Usage Any component that uses a `ListKeyManager` will generally do three things: - Create a `@ViewChildren` query for the options being managed. - Initialize the `ListKeyManager`, passing in the options. - Forward keyboard events from the managed component to the `ListKeyManager`. Each option should implement the `ListKeyManagerOption` interface: ``` interface ListKeyManagerOption { disabled?: boolean; getLabel?(): string; } ``` ### Wrapping Navigation through options can be made to wrap via the `withWrap` method: ``` this.keyManager = new FocusKeyManager(...).withWrap(); ``` ### Types of List Key Managers There are two varieties of `ListKeyManager`: `FocusKeyManager` and `ActiveDescendantKeyManager`. #### FocusKeyManager Used when options will directly receive browser focus. Each item managed must implement the `FocusableOption` interface: ``` interface FocusableOption extends ListKeyManagerOption { focus(): void; } ``` #### ActiveDescendantKeyManager Used when options will be marked as active via `aria-activedescendant`. Each item managed must implement the `Highlightable` interface: ``` interface Highlightable extends ListKeyManagerOption { setActiveStyles(): void; setInactiveStyles(): void; } ``` Each item must also have an ID bound to the listbox's or menu's `aria-activedescendant`. ``` -------------------------------- ### Basic tree node definition with matTreeNodeDef Source: https://v21.material.angular.dev/components/tree Defines a tree node template using *matTreeNodeDef. The directive exports the node data for bindings in the template. ```html {{node.key}}: {{node.value}} ``` -------------------------------- ### Test with Angular Material component harnesses Source: https://v21.material.angular.dev/guide/using-component-harnesses Same test using MatSelectHarness and HarnessLoader. It uses the harness API to open the select and select an option by text, eliminating manual detectChanges and whenStable calls. ```typescript describe('issue-report-selector', () => { let fixture: ComponentFixture; let loader: HarnessLoader; beforeEach(async () => { TestBed.configureTestingModule({ imports: [IssueReportSelectorModule], declarations: [IssueReportSelector], }); fixture = TestBed.createComponent(IssueReportSelector); fixture.detectChanges(); loader = TestbedHarnessEnvironment.loader(fixture); }); it('should switch to bug report template', async () => { expect(fixture.debugElement.query('bug-report-form')).toBeNull(); const select = await loader.getHarness(MatSelectHarness); await select.open(); const bugOption = await select.getOption({text: 'Bug'}); await bugOption.click(); expect(fixture.debugElement.query('bug-report-form')).not.toBeNull(); }); }); ``` -------------------------------- ### Test without component harnesses Source: https://v21.material.angular.dev/guide/using-component-harnesses Traditional test using fixture.debugElement and CSS selectors to interact with the component. It requires manual detectChanges and whenStable calls and relies on internal DOM structure like .mat-select-trigger. ```typescript describe('issue-report-selector', () => { let fixture: ComponentFixture; beforeEach(async () => { TestBed.configureTestingModule({ imports: [IssueReportSelectorModule], declarations: [IssueReportSelector], }); fixture = TestBed.createComponent(IssueReportSelector); fixture.detectChanges(); }); it('should switch to bug report template', async () => { expect(fixture.debugElement.query('bug-report-form')).toBeNull(); const selectTrigger = fixture.debugElement.query(By.css('.mat-select-trigger')); selectTrigger.triggerEventHandler('click', {}); fixture.detectChanges(); await fixture.whenStable(); const options = document.querySelectorAll('.mat-select-panel mat-option'); options[1].click(); // Click the second option, "Bug". fixture.detectChanges(); await fixture.whenStable(); expect(fixture.debugElement.query('bug-report-form')).not.toBeNull(); }); }); ``` -------------------------------- ### Toolbar with title and actions Source: https://v21.material.angular.dev/components/toolbar A common pattern: place a title on the left and actions on the right using flexbox. The toolbar itself does not position content. ```html My App ``` -------------------------------- ### Toolbar with multiple rows Source: https://v21.material.angular.dev/components/toolbar Place `` elements inside a `` to create multiple rows. Placing content outside a `` when multiple rows are specified is not supported. ```html Custom Toolbar Second Row favorite delete ``` -------------------------------- ### ListKeyManagerOption interface Source: https://v21.material.angular.dev/cdk/a11y Defines the interface that each option managed by a ListKeyManager must implement. It includes an optional disabled property and an optional getLabel method. ```typescript interface ListKeyManagerOption { disabled?: boolean; getLabel?(): string; } ``` -------------------------------- ### Positioning toolbar content with flex Source: https://v21.material.angular.dev/components/toolbar Use `display: flex` to position toolbar content, such as a title on the left and actions on the right. The toolbar does not perform any positioning itself. ```css .example-toolbar { display: flex; align-items: center; justify-content: space-between; } ``` -------------------------------- ### Nested tree node template with matTreeNodeOutlet Source: https://v21.material.angular.dev/components/tree For nested trees, the node template must include a matTreeNodeOutlet to mark where children will be rendered. ```html {{node.value}} ``` -------------------------------- ### matTreeNodePadding in flat tree node template Source: https://v21.material.angular.dev/components/tree Use matTreeNodePadding on a mat-tree-node in a flat tree to display the level information of a flat tree node. This is unnecessary for nested trees because DOM hierarchy provides padding via CSS. ```html {{node.value}} ``` -------------------------------- ### FocusableOption interface Source: https://v21.material.angular.dev/cdk/a11y Interface that items managed by a FocusKeyManager must implement. Extends ListKeyManagerOption and requires a focus method. ```typescript interface FocusableOption extends ListKeyManagerOption { focus(): void; } ``` -------------------------------- ### InteractivityChecker Source: https://v21.material.angular.dev/cdk/a11y/overview Used to check the interactivity of an element, capturing disabled, visible, tabbable, and focusable states for accessibility purposes. ```APIDOC ## InteractivityChecker ### Description `InteractivityChecker` is used to check the interactivity of an element, capturing disabled, visible, tabbable, and focusable states for accessibility purposes. See the API docs for more details. ``` -------------------------------- ### TreeKeyManager Source: https://v21.material.angular.dev/cdk/a11y/overview Manages the active option in a tree view. Use for components that implement a role="tree" pattern. ```APIDOC ## TreeKeyManager ### Description Manages the active option in a tree view. Use this key manager for components that implement a `role="tree"` pattern. ### Basic Usage Any component that uses a `TreeKeyManager` should do three things: - Create a `@ViewChildren` query for the tree items being managed. - Initialize the `TreeKeyManager`, passing in the options. - Forward keyboard events from the managed component to the `TreeKeyManager` via `onKeydown`. Each tree item should implement the `TreeKeyManagerItem` interface. ### Focus Management The `TreeKeyManager` will handle focusing the appropriate item on keyboard interactions. `tabindex` should also be set by the component when the active item changes. This can be listened to via the `change` property on the `TreeKeyManager`. In particular, the tree should only have a `tabindex` set if there is no active item, and should not have a `tabindex` set if there is an active item. Only the HTML node corresponding to the active item should have a `tabindex` set to `0`, with all other items set to `-1`. ``` -------------------------------- ### mat-tree with trackBy for performance Source: https://v21.material.angular.dev/components/tree Provide a trackBy function to the tree to uniquely identify nodes, similar to Angular's ngFor trackBy, to improve performance when data changes. ```html ``` -------------------------------- ### cdkTrapFocus Source: https://v21.material.angular.dev/cdk/a11y/overview Directive that traps Tab key focus within an element. Intended for accessible experiences like modal dialogs. ```APIDOC ## cdkTrapFocus ### Description The `cdkTrapFocus` directive traps `Tab` key focus within an element. This is intended to be used to create accessible experience for components like modal dialogs, where focus must be constrained. Import `CdkTrapFocus` in your component to use this directive. ### Usage Example ```
``` This directive will not prevent focus from moving out of the trapped region due to mouse interaction. ### Regions Regions can be declared explicitly with an initial focus element by using the `cdkFocusRegionStart`, `cdkFocusRegionEnd` and `cdkFocusInitial` DOM attributes. `cdkFocusInitial` specifies the element that will receive focus upon initialization of the region. `cdkFocusRegionStart` and `cdkFocusRegionEnd` define the region within which focus will be trapped. When using the tab key, focus will move through this region and wrap around on either end. For example: ``` Focus region start Link Initially focused Focus region end ``` **Note:** If you're using `cdkFocusInitial` together with the `CdkTrapFocus` directive, nothing will happen unless you've enabled the `cdkTrapFocusAutoCapture` option as well. This is due to `CdkTrapFocus` not capturing focus on initialization by default. ``` -------------------------------- ### Include a11y-visually-hidden mixin Source: https://v21.material.angular.dev/cdk/a11y Use this Sass mixin to emit the .cdk-visually-hidden CSS class, which visually hides an element while keeping it available to assistive technology. Include it in a global stylesheet if you are not using Angular Material's theming system, which includes it automatically. ```scss @use '@angular/cdk'; @include cdk.a11y-visually-hidden(); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.