Skip to content

Commit fb04603

Browse files
committed
Label icon SVGs
Resolves #2832
1 parent 8f64b47 commit fb04603

File tree

10 files changed

+243
-191
lines changed

10 files changed

+243
-191
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ title: Changelog
1111
### Bug Fixes
1212

1313
- Fixed an issue where TypeDoc would incorrectly ignore type arguments in references, #2823.
14+
- Improved narrator support for labeling icons, #2832.
1415

1516
## v0.27.6 (2024-12-26)
1617

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ export type {
6363
NavigationElement,
6464
RendererEvents,
6565
PageHeading,
66+
Icons,
6667
} from "./lib/output/index.js";
6768

6869
export { Outputs } from "./lib/output/output.js";

src/lib/internationalization/locales/en.cts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,10 +512,12 @@ export = {
512512
theme_search: "Search",
513513
theme_menu: "Menu",
514514
theme_permalink: "Permalink",
515+
theme_folder: "Folder",
515516

516517
// Used by the frontend JS
517518
// For the English translations only, these should also be added to
518519
// src/lib/output/themes/default/assets/typedoc/Application.ts
520+
// Also uses theme_folder and singular kinds
519521
theme_copy: "Copy",
520522
theme_copied: "Copied!",
521523
theme_normally_hidden:

src/lib/output/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ export {
1616
} from "./themes/default/DefaultTheme.js";
1717
export { Slugger } from "./themes/default/Slugger.js";
1818
export { DefaultThemeRenderContext } from "./themes/default/DefaultThemeRenderContext.js";
19+
export type { Icons } from "./themes/default/partials/icon.js";

src/lib/output/plugins/AssetsPlugin.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ import { RendererEvent } from "../events.js";
33
import { copySync, readFile, writeFileSync } from "../../utils/fs.js";
44
import { DefaultTheme } from "../themes/default/DefaultTheme.js";
55
import { getStyles } from "../../utils/highlighter.js";
6-
import { Option } from "../../utils/index.js";
6+
import { getEnumKeys, Option, type EnumKeys } from "../../utils/index.js";
77
import { existsSync } from "fs";
88
import { extname, join } from "path";
99
import { fileURLToPath } from "url";
1010
import type { Renderer } from "../index.js";
11+
import { ReflectionKind } from "../../models/index.js";
1112

1213
/**
1314
* A plugin that copies the subdirectory ´assets´ from the current themes
@@ -30,14 +31,24 @@ export class AssetsPlugin extends RendererComponent {
3031
}
3132

3233
getTranslatedStrings() {
33-
return {
34-
copy: this.application.i18n.theme_copy(),
35-
copied: this.application.i18n.theme_copied(),
36-
normally_hidden: this.application.i18n.theme_normally_hidden(),
37-
hierarchy_expand: this.application.i18n.theme_hierarchy_expand(),
38-
hierarchy_collapse:
39-
this.application.i18n.theme_hierarchy_collapse(),
34+
const inter = this.application.internationalization;
35+
const i18n = this.application.i18n;
36+
37+
const translations: Record<string, string> = {
38+
copy: i18n.theme_copy(),
39+
copied: i18n.theme_copied(),
40+
normally_hidden: i18n.theme_normally_hidden(),
41+
hierarchy_expand: i18n.theme_hierarchy_expand(),
42+
hierarchy_collapse: i18n.theme_hierarchy_collapse(),
43+
folder: i18n.theme_folder(),
4044
};
45+
46+
for (const key of getEnumKeys(ReflectionKind)) {
47+
const kind = ReflectionKind[key as EnumKeys<typeof ReflectionKind>];
48+
translations[`kind_${kind}`] = inter.kindSingularString(kind);
49+
}
50+
51+
return translations;
4152
}
4253

4354
private onRenderBegin(event: RendererEvent) {

src/lib/output/themes/default/DefaultTheme.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import type { MarkedPlugin } from "../../plugins/index.js";
1919
import { DefaultThemeRenderContext } from "./DefaultThemeRenderContext.js";
2020
import { filterMap, JSX, Option, type TypeDocOptionMap } from "../../../utils/index.js";
2121
import { classNames, getDisplayName, getHierarchyRoots, toStyleClass } from "../lib.js";
22-
import { icons } from "./partials/icon.js";
22+
import { getIcons, type Icons } from "./partials/icon.js";
2323
import { Slugger } from "./Slugger.js";
2424
import { createNormalizedUrl } from "../../../utils/html.js";
2525

@@ -77,7 +77,7 @@ export class DefaultTheme extends Theme {
7777
* the icons used within the page, however TypeDoc currently assumes that all icons are svg
7878
* elements, so custom themes must also use svg elements.
7979
*/
80-
icons = { ...icons };
80+
icons: Icons;
8181

8282
getRenderContext(pageEvent: PageEvent<Reflection>) {
8383
return new DefaultThemeRenderContext(this, pageEvent, this.application.options);
@@ -159,6 +159,7 @@ export class DefaultTheme extends Theme {
159159
*/
160160
constructor(renderer: Renderer) {
161161
super(renderer);
162+
this.icons = getIcons(renderer.application.i18n);
162163
this.markedPlugin = renderer.markedPlugin;
163164
}
164165

src/lib/output/themes/default/DefaultThemeRenderContext.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {
2424
import { footer } from "./partials/footer.js";
2525
import { header } from "./partials/header.js";
2626
import { hierarchy } from "./partials/hierarchy.js";
27-
import { buildRefIcons, type icons } from "./partials/icon.js";
27+
import { buildRefIcons, type Icons } from "./partials/icon.js";
2828
import { member } from "./partials/member.js";
2929
import { memberDeclaration } from "./partials/member.declaration.js";
3030
import { memberGetterSetter } from "./partials/member.getterSetter.js";
@@ -65,7 +65,7 @@ function bind<F, L extends any[], R>(fn: (f: F, ...a: L) => R, first: F) {
6565
}
6666

6767
export class DefaultThemeRenderContext {
68-
private _refIcons: typeof icons;
68+
private _refIcons: Icons;
6969
options: Options;
7070
internationalization: Internationalization;
7171
i18n: TranslationProxy;
@@ -87,7 +87,7 @@ export class DefaultThemeRenderContext {
8787
* Note: This creates a reference to icons declared by {@link DefaultTheme.icons},
8888
* to customize icons, that object must be modified instead.
8989
*/
90-
get icons(): Readonly<typeof icons> {
90+
get icons(): Readonly<Icons> {
9191
return this._refIcons;
9292
}
9393

src/lib/output/themes/default/assets/typedoc/Application.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ declare global {
88
normally_hidden: string;
99
hierarchy_expand: string;
1010
hierarchy_collapse: string;
11+
12+
// Kind strings for icons
13+
folder: string;
14+
[k: `kind_${number}`]: string;
1115
};
1216
}
1317
}
@@ -20,6 +24,32 @@ window.translations ||= {
2024
"This member is normally hidden due to your filter settings.",
2125
hierarchy_expand: "Expand",
2226
hierarchy_collapse: "Collapse",
27+
28+
folder: "Folder",
29+
kind_1: "Project",
30+
kind_2: "Module",
31+
kind_4: "Namespace",
32+
kind_8: "Enumeration",
33+
kind_16: "Enumeration Member",
34+
kind_32: "Variable",
35+
kind_64: "Function",
36+
kind_128: "Class",
37+
kind_256: "Interface",
38+
kind_512: "Constructor",
39+
kind_1024: "Property",
40+
kind_2048: "Method",
41+
kind_4096: "Call Signature",
42+
kind_8192: "Index Signature",
43+
kind_16384: "Constructor Signature",
44+
kind_32768: "Parameter",
45+
kind_65536: "Type Literal",
46+
kind_131072: "Type Parameter",
47+
kind_262144: "Accessor",
48+
kind_524288: "Get Signature",
49+
kind_1048576: "Set Signature",
50+
kind_2097152: "Type Alias",
51+
kind_4194304: "Reference",
52+
kind_8388608: "Document",
2353
};
2454

2555
/**

src/lib/output/themes/default/assets/typedoc/Navigation.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,17 @@ function addNavText(
9898
a.classList.add("current");
9999
}
100100
if (el.kind) {
101-
a.innerHTML = `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" class="tsd-kind-icon"><use href="#icon-${el.kind}"></use></svg>`;
101+
const label = window.translations[`kind_${el.kind}`].replaceAll(
102+
'"',
103+
"&quot;",
104+
);
105+
a.innerHTML = `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" class="tsd-kind-icon" aria-label="${label}"><use href="#icon-${el.kind}"></use></svg>`;
102106
}
103107
a.appendChild(document.createElement("span")).textContent = el.text;
104108
} else {
105109
const span = parent.appendChild(document.createElement("span"));
106-
span.innerHTML = `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" class="tsd-kind-icon"><use href="#icon-folder"></use></svg>`;
110+
const label = window.translations.folder.replaceAll('"', "&quot;");
111+
span.innerHTML = `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" class="tsd-kind-icon" aria-label="${label}"><use href="#icon-folder"></use></svg>`;
107112
span.appendChild(document.createElement("span")).textContent = el.text;
108113
}
109114
}

0 commit comments

Comments
 (0)