Skip to content

Commit eec0bf4

Browse files
committed
feat: add AutoCollapse component and use it for DeclDoc
1 parent 7733821 commit eec0bf4

2 files changed

Lines changed: 93 additions & 2 deletions

File tree

src/components/AutoCollapse.astro

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
---
2+
import { Icon } from "@astrojs/starlight/components";
3+
4+
interface Props {
5+
maxHeight?: number;
6+
}
7+
8+
const maxHeight = Astro.props.maxHeight ?? 200;
9+
const autoCollapseMaxHeight = maxHeight + "px";
10+
---
11+
12+
<div class="auto-collapse" data-max-height={maxHeight}>
13+
<div class="content">
14+
<slot />
15+
</div>
16+
<button class="expand-button">
17+
Expand
18+
<Icon class="expand-icon" name="down-caret" size="1em" />
19+
</button>
20+
</div>
21+
22+
<script>
23+
function initAutoCollapse() {
24+
const collapseWrappers = document.querySelectorAll(".auto-collapse");
25+
26+
collapseWrappers.forEach((wrapper) => {
27+
const contentElement = wrapper.querySelector(".content") as HTMLElement;
28+
const button = wrapper.querySelector(".expand-button") as HTMLElement;
29+
30+
if (!contentElement || !button) return;
31+
32+
const maxHeight = Number.parseInt(
33+
(wrapper as HTMLElement).dataset.maxHeight || "200",
34+
10
35+
);
36+
if (contentElement.scrollHeight <= maxHeight) {
37+
button.style.display = "none";
38+
return;
39+
}
40+
41+
// The document content is longer than the maximum height, collapse it.
42+
contentElement.classList.add("collapsed");
43+
44+
button.addEventListener("click", () => {
45+
contentElement.classList.remove("collapsed");
46+
button.style.display = "none";
47+
});
48+
});
49+
}
50+
51+
document.addEventListener("DOMContentLoaded", initAutoCollapse);
52+
document.addEventListener("astro:page-load", initAutoCollapse);
53+
</script>
54+
55+
<style define:vars={{ autoCollapseMaxHeight }}>
56+
.auto-collapse > .content.collapsed {
57+
max-height: var(--autoCollapseMaxHeight);
58+
overflow: hidden;
59+
position: relative;
60+
}
61+
62+
.auto-collapse > .content.collapsed::after {
63+
content: "";
64+
position: absolute;
65+
bottom: 0;
66+
left: 0;
67+
right: 0;
68+
height: 80px;
69+
background: linear-gradient(to bottom, transparent, var(--sl-color-bg));
70+
pointer-events: none;
71+
}
72+
73+
.auto-collapse > .expand-button {
74+
display: block;
75+
margin: 0 auto var(--sl-content-gap-y);
76+
padding: 0.25rem 1rem;
77+
background-color: var(--sl-color-text-accent);
78+
color: var(--sl-color-black);
79+
border: none;
80+
border-radius: 999rem;
81+
cursor: pointer;
82+
font-size: 0.9rem;
83+
}
84+
85+
.auto-collapse .expand-button .expand-icon {
86+
display: inline;
87+
vertical-align: middle;
88+
}
89+
</style>

src/components/DeclDoc.astro

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
---
2-
2+
import AutoCollapse from "./AutoCollapse.astro";
33
---
44

55
<div class="decl-doc">
66
<div class="decl">
77
<slot name="decl" />
88
</div>
99
<div class="doc">
10-
<slot name="doc" />
10+
<AutoCollapse maxHeight={200}>
11+
<slot name="doc" />
12+
</AutoCollapse>
1113
</div>
1214
</div>
1315

0 commit comments

Comments
 (0)