With my basic coding skills and some ChatGPT talk, I made it work, I believe.
Created a custom component and put this in the CSS tab:
@media (max-width: 767px) {
#topic-progress-wrapper.sticky-bottom {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 1000;
}
}
and this in the JS tab
import { apiInitializer } from "discourse/lib/api";
export default apiInitializer((api) => {
api.onPageChange(() => {
const observer = new MutationObserver(() => {
const wrapper = document.getElementById("topic-progress-wrapper");
const tocButton = wrapper?.querySelector(".d-toc-mini button");
if (wrapper) {
if (tocButton) {
wrapper.classList.add("sticky-bottom");
} else {
wrapper.classList.remove("sticky-bottom");
}
}
});
observer.observe(document.body, {
childList: true,
subtree: true,
});
});
});
This seems to be working just fine even without a reply.
Again, I’m no expert, I’m just a good “asker” and after a little bit of “back and forth” with ChatGPT with the right questions and challenges, it seems to be working.
If anyone who is an expert in JavaScript and CSS wants to improve it, please share.
So, if you want:
- The text “Table of Contents” next to the icon
- Expanded headings
- Sticky button without relying on any replies, the full CSS is this:
/* expands all headings in table of content sidebar */
#d-toc li.d-toc-item > ul {
max-height: 500em !important;
overflow: visible !important;
opacity: 1 !important;
}
@media screen and (max-width: 767px) {
/* makes the wrapper including the table of contents button, sticky to the bottom */
#topic-progress-wrapper.sticky-bottom {
position: fixed;
bottom: 0;
left: 0;
right: 0;
z-index: 1000;
}
/* add "table ot contents" to the button after the icon */
.d-toc-mini button::after {
content: "Table of Contents";
margin-left: 5px;
font-size: 14px;
vertical-align: middle;
}
}
The JavaScript doesn’t change.