Skip to content

feat: introduce header default filter options #307 #1816

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export {
TSConfigReader,
TypeDocReader,
EntryPointStrategy,
VisibilityFilter,
EventHooks,
} from "./lib/utils";

Expand Down
24 changes: 14 additions & 10 deletions src/lib/output/themes/default/assets/typedoc/components/Filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ abstract class FilterItem<T> {

protected defaultValue: T;

constructor(key: string, value: T) {
constructor(key: string) {
this.key = key;
this.value = value;
this.defaultValue = value;
this.value;
this.defaultValue;

this.initialize();

Expand Down Expand Up @@ -50,6 +50,8 @@ class FilterItemCheckbox extends FilterItem<boolean> {
if (!checkbox) return;

this.checkbox = checkbox;
this.value = !!checkbox.checked;
this.defaultValue = this.value;
this.checkbox.addEventListener("change", () => {
this.setValue(this.checkbox.checked);
});
Expand Down Expand Up @@ -77,16 +79,18 @@ class FilterItemSelect extends FilterItem<string> {
private select!: HTMLElement;

protected override initialize() {
document.documentElement.classList.add(
"toggle-" + this.key + this.value
);

const select = document.querySelector<HTMLElement>(
"#tsd-filter-" + this.key
);
if (!select) return;

const selectedEl = select.querySelector("li.selected");
this.select = select;
this.value = selectedEl.getAttribute("data-value");
this.defaultValue = this.value;
document.documentElement.classList.add(
"toggle-" + this.key + this.value
);
const onActivate = () => {
this.select.classList.add("active");
};
Expand Down Expand Up @@ -151,9 +155,9 @@ export class Filter extends Component {
constructor(options: IComponentOptions) {
super(options);

this.optionVisibility = new FilterItemSelect("visibility", "private");
this.optionInherited = new FilterItemCheckbox("inherited", true);
this.optionExternals = new FilterItemCheckbox("externals", true);
this.optionVisibility = new FilterItemSelect("visibility");
this.optionInherited = new FilterItemCheckbox("inherited");
this.optionExternals = new FilterItemCheckbox("externals");
}

static isSupported(): boolean {
Expand Down
168 changes: 98 additions & 70 deletions src/lib/output/themes/default/partials/header.tsx
Original file line number Diff line number Diff line change
@@ -1,85 +1,113 @@
import type { Reflection } from "../../../../models";
import { JSX } from "../../../../utils";
import { JSX, VisibilityFilter } from "../../../../utils";
import type { PageEvent } from "../../../events";
import { hasTypeParameters, join } from "../../lib";
import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext";

export const header = (context: DefaultThemeRenderContext, props: PageEvent<Reflection>) => (
<header>
<div class="tsd-page-toolbar">
<div class="container">
<div class="table-wrap">
<div class="table-cell" id="tsd-search" data-base={context.relativeURL("./")}>
<div class="field">
<label for="tsd-search-field" class="tsd-widget search no-caption">
Search
</label>
<input type="text" id="tsd-search-field" />
</div>

<ul class="results">
<li class="state loading">Preparing search index...</li>
<li class="state failure">The search index is not available</li>
</ul>
const visibilityFilterLabels = {
[VisibilityFilter.all]: "All",
[VisibilityFilter.public]: "Public",
[VisibilityFilter.protected]: "Public/Protected",
};

<a href={context.relativeURL("index.html")} class="title">
{props.project.name}
</a>
</div>
export const header = (context: DefaultThemeRenderContext, props: PageEvent<Reflection>) => {
const defaultSelectedVisibility = context.options.getValue("visibility");
const selectedVisibility = Object.keys(visibilityFilterLabels).includes(defaultSelectedVisibility)
? (defaultSelectedVisibility as VisibilityFilter)
: VisibilityFilter.all;
const defaultInheritedChecked = context.options.getValue("showInherited");
const defaultExternalsChecked = context.options.getValue("showExternals");

<div class="table-cell" id="tsd-widgets">
<div id="tsd-filter">
<a href="#" class="tsd-widget options no-caption" data-toggle="options">
Options
</a>
<div class="tsd-filter-group">
<div class="tsd-select" id="tsd-filter-visibility">
<span class="tsd-select-label">All</span>
<ul class="tsd-select-list">
<li data-value="public">Public</li>
<li data-value="protected">Public/Protected</li>
<li data-value="private" class="selected">
All
</li>
</ul>
</div>{" "}
<input type="checkbox" id="tsd-filter-inherited" checked={true} />
<label class="tsd-widget" for="tsd-filter-inherited">
Inherited
return (
<header>
<div class="tsd-page-toolbar">
<div class="container">
<div class="table-wrap">
<div class="table-cell" id="tsd-search" data-base={context.relativeURL("./")}>
<div class="field">
<label for="tsd-search-field" class="tsd-widget search no-caption">
Search
</label>
{!context.options.getValue("excludeExternals") && (
<>
<input type="checkbox" id="tsd-filter-externals" checked={true} />
<label class="tsd-widget" for="tsd-filter-externals">
Externals
</label>
</>
)}
<input type="text" id="tsd-search-field" />
</div>

<ul class="results">
<li class="state loading">Preparing search index...</li>
<li class="state failure">The search index is not available</li>
</ul>

<a href={context.relativeURL("index.html")} class="title">
{props.project.name}
</a>
</div>

<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">
Menu
</a>
<div class="table-cell" id="tsd-widgets">
<div id="tsd-filter">
<a href="#" class="tsd-widget options no-caption" data-toggle="options">
Options
</a>
<div class="tsd-filter-group">
<div class="tsd-select" id="tsd-filter-visibility">
<span class="tsd-select-label">
{visibilityFilterLabels[selectedVisibility]}
</span>
<ul class="tsd-select-list">
{Object.entries(visibilityFilterLabels).map(([value, label]) => (
<li
data-value={value}
class={value === selectedVisibility ? "selected" : ""}
>
{label}
</li>
))}
</ul>
</div>{" "}
<input
type="checkbox"
id="tsd-filter-inherited"
checked={!!defaultInheritedChecked}
/>
<label class="tsd-widget" for="tsd-filter-inherited">
Inherited
</label>
{!context.options.getValue("excludeExternals") && (
<>
<input
type="checkbox"
id="tsd-filter-externals"
checked={!!defaultExternalsChecked}
/>
<label class="tsd-widget" for="tsd-filter-externals">
Externals
</label>
</>
)}
</div>
</div>

<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">
Menu
</a>
</div>
</div>
</div>
</div>
</div>
<div class="tsd-page-title">
<div class="container">
{!!props.model.parent && <ul class="tsd-breadcrumb">{context.breadcrumb(props.model)}</ul>}
<h1>
{props.model.kindString !== "Project" && `${props.model.kindString ?? ""} `}
{props.model.name}
{hasTypeParameters(props.model) && (
<>
{"<"}
{join(", ", props.model.typeParameters, (item) => item.name)}
{">"}
</>
)}
</h1>
<div class="tsd-page-title">
<div class="container">
{!!props.model.parent && <ul class="tsd-breadcrumb">{context.breadcrumb(props.model)}</ul>}
<h1>
{props.model.kindString !== "Project" && `${props.model.kindString ?? ""} `}
{props.model.name}
{hasTypeParameters(props.model) && (
<>
{"<"}
{join(", ", props.model.typeParameters, (item) => item.name)}
{">"}
</>
)}
</h1>
</div>
</div>
</div>
</header>
);
</header>
);
};
1 change: 1 addition & 0 deletions src/lib/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export {
ParameterType,
TSConfigReader,
TypeDocReader,
VisibilityFilter,
} from "./options";
export type {
ArrayDeclarationOption,
Expand Down
11 changes: 11 additions & 0 deletions src/lib/utils/options/declaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ export type TypeDocOptionValues = {
: TypeDocOptionMap[K][keyof TypeDocOptionMap[K]];
};

export enum VisibilityFilter {
all = "private",
public = "public",
protected = "protected",
}

/**
* Describes all TypeDoc options. Used internally to provide better types when fetching options.
* External consumers should likely use {@link TypeDocOptions} instead.
Expand All @@ -60,6 +66,11 @@ export interface TypeDocOptionMap {
entryPoints: string[];
entryPointStrategy: typeof EntryPointStrategy;

// typedoc header filters
visibility: string;
showInherited: boolean;
showExternals: boolean;

exclude: string[];
externalPattern: string[];
excludeExternals: boolean;
Expand Down
7 changes: 6 additions & 1 deletion src/lib/utils/options/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
export { Options, BindOption } from "./options";
export type { OptionsReader } from "./options";
export { ArgumentsReader, TypeDocReader, TSConfigReader } from "./readers";
export { EmitStrategy, ParameterType, ParameterHint } from "./declaration";
export {
EmitStrategy,
ParameterType,
ParameterHint,
VisibilityFilter,
} from "./declaration";

export type {
TypeDocOptions,
Expand Down
19 changes: 19 additions & 0 deletions src/lib/utils/options/sources/typedoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,25 @@ export function addTypeDocOptions(options: Pick<Options, "addDeclaration">) {
defaultValue: EntryPointStrategy.Resolve,
});

options.addDeclaration({
name: "visibility",
help: 'Specify the default visibility for methods, possible values: "private" | "public" | "protected"',
type: ParameterType.String,
defaultValue: "private",
});
options.addDeclaration({
name: "showInherited",
help: "Specify the default inherited checkbox value",
type: ParameterType.Boolean,
defaultValue: true,
});
options.addDeclaration({
name: "showExternals",
help: "Specify the default externals checkbox value",
type: ParameterType.Boolean,
defaultValue: true,
});

options.addDeclaration({
name: "exclude",
help: "Define patterns to be excluded when expanding a directory that was specified as an entry point.",
Expand Down