Skip to content
This repository was archived by the owner on Dec 18, 2024. It is now read-only.

Commit c032e7e

Browse files
committed
feat: show deprecated related information in material/tooltip
previously we weren't showing any other information other than `breaking-change` for deprecated fields, this commit adds a component that protrays information regarding deprecation in tooltips rather than `title` attribute closes angular/component#29873
1 parent 6a6db1c commit c032e7e

File tree

4 files changed

+89
-4
lines changed

4 files changed

+89
-4
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import {Component, Input} from '@angular/core';
2+
import {MatTooltipModule} from '@angular/material/tooltip';
3+
4+
/**
5+
* This component is responsible for showing the
6+
* deprecated fields throughout API from material repo,
7+
*
8+
* When deprecated docs content is generated like:
9+
*
10+
* <div class="docs-api-class-deprecated-marker"
11+
* title="Will be removed in v21.0.0 or later">
12+
* Deprecated
13+
* </div>
14+
*
15+
* It uses `title` attribute to show information regarding
16+
* depreciation and other information regarding depreciation
17+
* isnt shown either.
18+
*
19+
* We are gonna use this component to show deprecation
20+
* information using the `material/tooltip`, the information
21+
* would contain when the field is being deprecated and what
22+
* are the alternatives to it which both are extracted from
23+
* `deprecated` and `breaking-change`.
24+
*/
25+
@Component({
26+
selector: 'deprecated-field',
27+
template: `<div class="deprecated-content"
28+
[attr.aria-label]="message"
29+
[matTooltip]="message">
30+
{{ htmlContent }}
31+
</div>`,
32+
standalone: true,
33+
imports: [MatTooltipModule],
34+
})
35+
export class DeprecatedFieldComponent {
36+
/** Message regarding the deprecation */
37+
@Input() message!: string;
38+
/** Inner content for our element, it could be either
39+
* `Deprecated` which is shown mostly in most of the case
40+
* but we can not show class names with just `Deprecated` label
41+
* so otherwise the value is going to be name of whatever
42+
* is being deprecated, so we can show the deprecation alternative
43+
* description on hover */
44+
@Input() htmlContent!: string;
45+
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {PortalModule} from '@angular/cdk/portal';
99
import {NgModule} from '@angular/core';
1010
import {HeaderLink} from './header-link';
1111
import {CodeSnippet} from '../example-viewer/code-snippet';
12+
import {DeprecatedFieldComponent} from './deprecated-tooltip';
1213

1314

1415
// ExampleViewer is included in the DocViewerModule because they have a circular dependency.
@@ -23,8 +24,9 @@ import {CodeSnippet} from '../example-viewer/code-snippet';
2324
DocViewer,
2425
ExampleViewer,
2526
HeaderLink,
26-
CodeSnippet
27+
CodeSnippet,
28+
DeprecatedFieldComponent
2729
],
28-
exports: [DocViewer, ExampleViewer, HeaderLink]
30+
exports: [DocViewer, ExampleViewer, HeaderLink, DeprecatedFieldComponent]
2931
})
3032
export class DocViewerModule { }

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {Observable, Subscription} from 'rxjs';
2121
import {shareReplay, take, tap} from 'rxjs/operators';
2222
import {ExampleViewer} from '../example-viewer/example-viewer';
2323
import {HeaderLink} from './header-link';
24+
import {DeprecatedFieldComponent} from './deprecated-tooltip';
2425

2526
@Injectable({providedIn: 'root'})
2627
class DocFetcher {
@@ -121,6 +122,9 @@ export class DocViewer implements OnDestroy {
121122
this._loadComponents('material-docs-example', ExampleViewer);
122123
this._loadComponents('header-link', HeaderLink);
123124

125+
// Create tooltips for the deprecated fields
126+
this._createTooltipsForDeprecated();
127+
124128
// Resolving and creating components dynamically in Angular happens synchronously, but since
125129
// we want to emit the output if the components are actually rendered completely, we wait
126130
// until the Angular zone becomes stable.
@@ -166,4 +170,37 @@ export class DocViewer implements OnDestroy {
166170
this._clearLiveExamples();
167171
this._documentFetchSubscription?.unsubscribe();
168172
}
173+
174+
_createTooltipsForDeprecated() {
175+
// all of the deprecated markers end with `deprecated-marker`
176+
// in their class name
177+
const deprecatedElements =
178+
this._elementRef.nativeElement.querySelectorAll(`[class$=deprecated-marker]`);
179+
180+
[...deprecatedElements].forEach((element: Element) => {
181+
// the deprecation message, it will include alternative to deprecated item
182+
// and breaking change if there is one included.
183+
const deprecationTitle = element.getAttribute('depreciation-title');
184+
// In case of a class being deprecated we can not just show `Deprecated`
185+
// text, this attribute contains the text we need to show tooltip against.
186+
const innerText = element.getAttribute('inner-text');
187+
188+
const elementPortalOutlet = new DomPortalOutlet(
189+
element, this._componentFactoryResolver, this._appRef, this._injector);
190+
191+
const tooltipPortal = new ComponentPortal(DeprecatedFieldComponent, this._viewContainerRef);
192+
const tooltipOutlet = elementPortalOutlet.attach(tooltipPortal);
193+
194+
195+
if (deprecationTitle) {
196+
tooltipOutlet.instance.message = deprecationTitle;
197+
}
198+
199+
if (innerText) {
200+
tooltipOutlet.instance.htmlContent = innerText;
201+
}
202+
203+
this._portalHosts.push(elementPortalOutlet);
204+
});
205+
}
169206
}

src/styles/_api.scss

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,13 @@
101101
display: inline-block;
102102
font-weight: bold;
103103

104-
&[title] {
104+
& .deprecated-content {
105105
border-bottom: 1px dotted grey;
106106
cursor: help;
107107
}
108108
}
109109

110-
.docs-api-deprecated-marker + .docs-api-property-name {
110+
.docs-api-deprecated-marker + .docs-api-property-name,
111+
.docs-api-class-deprecated-marker {
111112
text-decoration: line-through;
112113
}

0 commit comments

Comments
 (0)