Skip to content

Commit 99fc7ca

Browse files
Tim-Obertlinawolf
authored andcommitted
[TASK] Add Expandable and collapsible headings
1 parent 66ab040 commit 99fc7ca

File tree

6 files changed

+137
-1
lines changed

6 files changed

+137
-1
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
class ToggleSection {
2+
TOGGLE_CLASS = 'toggle-section';
3+
TOGGLE_ICON_SHOW = ['fa-solid', 'fa-eye'];
4+
TOGGLE_ICON_HIDE = ['fa-solid', 'fa-eye-slash'];
5+
TOGGLE_TITLE_SHOW = 'Show Section';
6+
TOGGLE_TITLE_HIDE = 'Hide section';
7+
TOGGLE_ALL_SECTIONS_SELECTOR = '.toggle-all-sections';
8+
TOGGLE_ALL_SECTIONS_TITLE_SHOW = 'Expand all sections';
9+
TOGGLE_ALL_SECTIONS_TITLE_HIDE = 'Collapse all sections';
10+
sections = [];
11+
12+
13+
constructor() {
14+
this.sectionHeadings = document.querySelectorAll('section > h2,h3,h4,h5,h6');
15+
this.sectionHeadings.forEach(heading => {
16+
const toggleSectionButton = this.createToggleSectionButton()
17+
const headerLink = heading.querySelector('a.headerlink');
18+
const section = heading.parentElement;
19+
this.sections.push(section)
20+
heading.insertBefore(toggleSectionButton, headerLink);
21+
toggleSectionButton.addEventListener('click', (e) => {
22+
e.preventDefault()
23+
this.toggleSection(section)
24+
})
25+
})
26+
if (this.sectionHeadings) {
27+
const links = document.querySelectorAll('a')
28+
links.forEach(link => {
29+
if (link.hash) {
30+
link.addEventListener('click', (e) => {
31+
const section = document.querySelector(link.hash)
32+
if (section) {
33+
this.changeSection(section, false)
34+
}
35+
})
36+
}
37+
})
38+
}
39+
const toggleAllSectionsButton = document.querySelector(this.TOGGLE_ALL_SECTIONS_SELECTOR)
40+
if (toggleAllSectionsButton) {
41+
toggleAllSectionsButton.addEventListener('click', () => {
42+
toggleAllSectionsButton.classList.toggle('hide-all')
43+
const hideAll = toggleAllSectionsButton.classList.contains('hide-all')
44+
toggleAllSectionsButton.setAttribute('title', hideAll ? this.TOGGLE_ALL_SECTIONS_TITLE_SHOW : this.TOGGLE_ALL_SECTIONS_TITLE_HIDE);
45+
toggleAllSectionsButton.textContent = hideAll ? this.TOGGLE_ALL_SECTIONS_TITLE_SHOW : this.TOGGLE_ALL_SECTIONS_TITLE_HIDE;
46+
this.sections.forEach(section => {
47+
this.changeSection(section, hideAll)
48+
})
49+
})
50+
}
51+
}
52+
53+
createToggleSectionButton() {
54+
const toggleButton = document.createElement('a')
55+
toggleButton.classList.add(this.TOGGLE_CLASS);
56+
toggleButton.setAttribute('href', '#');
57+
toggleButton.setAttribute('title', this.TOGGLE_TITLE_HIDE);
58+
const icon = document.createElement('i');
59+
icon.classList.add(...this.TOGGLE_ICON_HIDE);
60+
toggleButton.appendChild(icon);
61+
return toggleButton;
62+
}
63+
64+
toggleSection(section) {
65+
const isCollapsed = section.classList.contains('section-collapsed');
66+
this.changeSection(section, !isCollapsed)
67+
}
68+
69+
changeSection(section, hide) {
70+
if (hide) {
71+
section.classList.add('section-collapsed');
72+
} else {
73+
section.classList.remove('section-collapsed');
74+
}
75+
const headings = ['H2', 'H3', 'H4', 'H5', 'H6'];
76+
section.querySelectorAll(':scope > *').forEach(sectionEl => {
77+
if (headings.includes(sectionEl.nodeName)) {
78+
const toggle = sectionEl.querySelector('.' + this.TOGGLE_CLASS);
79+
const icon = toggle.querySelector(':scope > i');
80+
toggle.setAttribute('title', hide ? this.TOGGLE_TITLE_SHOW : this.TOGGLE_TITLE_HIDE);
81+
icon.classList.remove(...icon.classList);
82+
const classesToAdd = hide ? this.TOGGLE_ICON_SHOW : this.TOGGLE_ICON_HIDE;
83+
icon.classList.add(...classesToAdd);
84+
} else {
85+
if (hide) {
86+
sectionEl.classList.add('collapsed-section-content');
87+
} else {
88+
sectionEl.classList.remove('collapsed-section-content');
89+
}
90+
}
91+
})
92+
}
93+
}
94+
95+
96+
new ToggleSection()
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
.collapsed-section-content {
2+
display: none !important;
3+
}
4+
5+
article {
6+
a.toggle-section {
7+
position: relative;
8+
font-size: .65em;
9+
top: -.15em;
10+
text-decoration: none;
11+
color: $gray-700;
12+
visibility: hidden;
13+
}
14+
*:hover {
15+
& > a.toggle-section {
16+
visibility: visible;
17+
}
18+
}
19+
20+
}
21+

packages/typo3-docs-theme/assets/sass/theme.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
@import 'components/table';
4444
@import 'components/tabs';
4545
@import 'components/textroles';
46+
@import 'components/toggleSelection';
4647
@import 'components/uml';
4748
@import 'components/allDocumentationMenu';
4849

packages/typo3-docs-theme/resources/public/css/theme.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24938,6 +24938,22 @@ article a.composer-link {
2493824938
text-decoration: underline dotted;
2493924939
}
2494024940

24941+
.collapsed-section-content {
24942+
display: none !important;
24943+
}
24944+
24945+
article a.toggle-section {
24946+
position: relative;
24947+
font-size: 0.65em;
24948+
top: -0.15em;
24949+
text-decoration: none;
24950+
color: rgb(127.5, 127.5, 127.5);
24951+
visibility: hidden;
24952+
}
24953+
article *:hover > a.toggle-section {
24954+
visibility: visible;
24955+
}
24956+
2494124957
figure.uml-diagram {
2494224958
max-width: 100%;
2494324959
overflow: scroll;

0 commit comments

Comments
 (0)