mirror of
https://github.com/discourse/DiscoTOC.git
synced 2026-09-17 16:02:12 -04:00
This commit adds a button at the top of the TOC headings list called "Expand all". This will expand all of the subheadings in the list for easier searching. Clicking the button again will hide all the subheadings except the currently active one.
89 lines
2.4 KiB
Plaintext
89 lines
2.4 KiB
Plaintext
import Component from "@glimmer/component";
|
|
import { concat } from "@ember/helper";
|
|
import { on } from "@ember/modifier";
|
|
import { action } from "@ember/object";
|
|
import { service } from "@ember/service";
|
|
import { headerOffset } from "discourse/lib/offset-calculator";
|
|
import { slugify } from "discourse/lib/utilities";
|
|
|
|
const SCROLL_BUFFER = 25;
|
|
|
|
export default class TocHeading extends Component {
|
|
@service tocProcessor;
|
|
|
|
get isActive() {
|
|
return this.args.activeHeadingId === this.args.item.id;
|
|
}
|
|
|
|
get isAncestorActive() {
|
|
return this.args.activeAncestorIds?.includes(this.args.item.id);
|
|
}
|
|
|
|
get classNames() {
|
|
const baseClass = "d-toc-item";
|
|
const typeClass = this.args.item.tagName
|
|
? ` d-toc-${this.args.item.tagName}`
|
|
: "";
|
|
let activeClass = "";
|
|
let expandAllClass = "";
|
|
if (this.isActive) {
|
|
activeClass = " direct-active active";
|
|
} else if (this.isAncestorActive) {
|
|
activeClass = " active";
|
|
}
|
|
if (this.args.expandAll) {
|
|
expandAllClass = " expand-all";
|
|
}
|
|
return `${baseClass}${typeClass}${activeClass}${expandAllClass}`;
|
|
}
|
|
|
|
@action
|
|
handleTocLinkClick(event) {
|
|
event.preventDefault();
|
|
|
|
const targetId = event.target.href?.split("#").pop();
|
|
if (!targetId) {
|
|
return;
|
|
}
|
|
|
|
const targetElement =
|
|
document.querySelector(`a[name="${targetId}"]`) ||
|
|
document.getElementById(targetId);
|
|
if (targetElement) {
|
|
const headerOffsetValue = headerOffset();
|
|
const elementPosition =
|
|
targetElement.getBoundingClientRect().top + window.pageYOffset;
|
|
const offsetPosition =
|
|
elementPosition - headerOffsetValue - SCROLL_BUFFER;
|
|
|
|
window.scrollTo({ top: offsetPosition, behavior: "smooth" });
|
|
|
|
// hide TOC overlay when navigating to link
|
|
this.tocProcessor.setOverlayVisible(false);
|
|
}
|
|
}
|
|
|
|
<template>
|
|
<li class={{this.classNames}}>
|
|
<a
|
|
href="#{{@item.id}}"
|
|
{{on "click" this.handleTocLinkClick}}
|
|
data-d-toc={{concat "toc-" @item.tagName "-" (slugify @item.text)}}
|
|
>
|
|
{{@item.text}}
|
|
</a>
|
|
{{#if @item.subItems}}
|
|
<ul class="d-toc-sublevel">
|
|
{{#each @item.subItems as |subItem|}}
|
|
<TocHeading
|
|
@item={{subItem}}
|
|
@activeHeadingId={{@activeHeadingId}}
|
|
@activeAncestorIds={{@activeAncestorIds}}
|
|
/>
|
|
{{/each}}
|
|
</ul>
|
|
{{/if}}
|
|
</li>
|
|
</template>
|
|
}
|