Skip to content

Commit 97586ab

Browse files
committed
docs: add angular aria banner (angular#32380)
* docs: add angular aria banner * Added a banner to the CDK Listbox, Menu, Tree, and Accordion to guide users to use the new Angular Aria components. * fixup! docs: add angular aria banner (cherry picked from commit 1a53671)
1 parent 5c82f69 commit 97586ab

File tree

5 files changed

+136
-3
lines changed

5 files changed

+136
-3
lines changed

docs/src/app/pages/component-viewer/component-overview.html

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
<h2 class="cdk-visually-hidden" tabindex="-1">
33
Overview for {{docItem.id}}
44
</h2>
5-
<doc-viewer [document]="getOverviewDocumentUrl(docItem)"
6-
class="docs-component-view-text-content docs-component-overview"
7-
(contentRendered)="updateTableOfContents('Overview Content', $event)" />
5+
<doc-viewer [name]="docItem.id"
6+
[document]="getOverviewDocumentUrl(docItem)"
7+
class="docs-component-view-text-content docs-component-overview"
8+
(contentRendered)="updateTableOfContents('Overview Content', $event)" />
89

910
@if (showToc | async) {
1011
<table-of-contents #toc container=".mat-drawer-content"/>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
.docs-angular-aria-banner {
2+
display: flex;
3+
align-items: flex-start;
4+
gap: 12px;
5+
padding: 16px;
6+
margin-bottom: 24px;
7+
background-color: color-mix(in srgb, var(--mat-sys-primary) 10%, transparent);
8+
border-left: 4px solid var(--mat-sys-primary);
9+
border-radius: 4px;
10+
font-size: 14px;
11+
line-height: 1.6;
12+
}
13+
14+
.docs-angular-aria-banner-icon {
15+
font-size: 20px;
16+
flex-shrink: 0;
17+
fill: var(--mat-sys-primary);
18+
}
19+
20+
.docs-angular-aria-banner-content {
21+
flex: 1;
22+
}
23+
24+
.docs-angular-aria-banner-content strong {
25+
color: var(--mat-sys-primary);
26+
}
27+
28+
.docs-angular-aria-banner-content a {
29+
color: var(--mat-sys-primary);
30+
text-decoration: underline;
31+
font-weight: 500;
32+
}
33+
34+
@media (max-width: 600px) {
35+
.docs-angular-aria-banner {
36+
padding: 12px;
37+
gap: 8px;
38+
}
39+
40+
.docs-angular-aria-banner-icon {
41+
font-size: 18px;
42+
}
43+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<div class="docs-angular-aria-banner">
2+
<svg class="docs-angular-aria-banner-icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24"
3+
width="24px">
4+
<path d="M0 0h24v24H0V0z" fill="none" />
5+
<path
6+
d="M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z" />
7+
</svg>
8+
<div class="docs-angular-aria-banner-content">
9+
<strong>Now Available in Angular Aria!</strong>
10+
<br />
11+
The Angular team has introduced a new low-level component library called Angular Aria.
12+
Consider using the
13+
<a [href]="ariaLink" target="_blank" rel="noopener">Angular Aria {{ componentName }}</a>
14+
component as an alternative to this CDK component.
15+
</div>
16+
</div>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
import {Component, Input} from '@angular/core';
10+
11+
/**
12+
* Mapping of CDK component names to their Angular Aria documentation URLs.
13+
*/
14+
const ANGULAR_ARIA_LINKS: Record<string, string> = {
15+
'listbox': 'https://angular.dev/guide/aria/listbox',
16+
'tree': 'https://angular.dev/guide/aria/tree',
17+
'accordion': 'https://angular.dev/guide/aria/accordion',
18+
'menu': 'https://angular.dev/guide/aria/menu',
19+
};
20+
21+
/**
22+
* Banner component that guides users to use the new Angular Aria components for CDK components
23+
* that have equivalent Angular Aria components.
24+
*/
25+
@Component({
26+
selector: 'angular-aria-banner',
27+
templateUrl: 'angular-aria-banner.html',
28+
styleUrl: 'angular-aria-banner.css',
29+
})
30+
export class AngularAriaBanner {
31+
@Input() componentName: string = '';
32+
33+
get ariaLink(): string {
34+
return ANGULAR_ARIA_LINKS[this.componentName.toLowerCase()] || '';
35+
}
36+
}

docs/src/app/shared/doc-viewer/doc-viewer.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import {ExampleViewer} from '../example-viewer/example-viewer';
3838
import {HeaderLink} from './header-link';
3939
import {DeprecatedFieldComponent} from './deprecated-tooltip';
4040
import {ModuleImportCopyButton} from './module-import-copy-button';
41+
import {AngularAriaBanner} from './angular-aria-banner/angular-aria-banner';
4142

4243
@Injectable({providedIn: 'root'})
4344
class DocFetcher {
@@ -154,6 +155,9 @@ export class DocViewer implements OnDestroy {
154155
this._loadComponents('material-docs-example', ExampleViewer);
155156
this._loadComponents('header-link', HeaderLink);
156157

158+
// Inject Angular Aria banner for specific CDK components
159+
this._injectAngularAriaBanner();
160+
157161
// Create tooltips for the deprecated fields
158162
this._createTooltipsForDeprecated();
159163

@@ -267,4 +271,37 @@ export class DocViewer implements OnDestroy {
267271
this._portalHosts.push(elementPortalOutlet);
268272
});
269273
}
274+
275+
/**
276+
* Injects the Angular Aria migration banner for specific CDK components.
277+
*/
278+
private _injectAngularAriaBanner() {
279+
const componentName = this.name();
280+
const componentsWithAriaBanner = ['listbox', 'tree', 'accordion', 'menu'];
281+
282+
if (!componentName || !componentsWithAriaBanner.includes(componentName.toLowerCase())) {
283+
return;
284+
}
285+
286+
// Create a container div for the banner at the beginning of the document
287+
const bannerContainer = document.createElement('div');
288+
bannerContainer.setAttribute('angular-aria-banner', '');
289+
bannerContainer.setAttribute('componentName', componentName);
290+
291+
// Insert the banner at the beginning of the document content
292+
const firstChild = this._elementRef.nativeElement.firstChild;
293+
if (firstChild) {
294+
this._elementRef.nativeElement.insertBefore(bannerContainer, firstChild);
295+
} else {
296+
this._elementRef.nativeElement.appendChild(bannerContainer);
297+
}
298+
299+
// Create and attach the banner component
300+
const portalHost = new DomPortalOutlet(bannerContainer, this._appRef, this._injector);
301+
const bannerPortal = new ComponentPortal(AngularAriaBanner, this._viewContainerRef);
302+
const bannerComponent = portalHost.attach(bannerPortal);
303+
bannerComponent.instance.componentName = componentName;
304+
305+
this._portalHosts.push(portalHost);
306+
}
270307
}

0 commit comments

Comments
 (0)