Skip to content

Commit 726cc8f

Browse files
authored
Add index drawer using lion
Closes: #3 See here for more information: #13
1 parent 6e435f9 commit 726cc8f

File tree

5 files changed

+183
-30
lines changed

5 files changed

+183
-30
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ A custom element to turn plain HTML into rich documents, inspired by
44
[Docsify](https://docsify.js.org). Features include:
55

66
- Document index pane
7+
- Stow index pane in application drawer on mobile devices
78
- Anchor links (optional)
89

910
**[Demo](https://grislyeye.github.io/vellum-doc/)** |

index.html

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,18 @@
99

1010
<script type="module" src="./vellum-doc.js"></script>
1111
<style>
12+
body {
13+
margin: 0;
14+
}
15+
1216
vellum-doc {
13-
padding-left: 10px;
14-
padding-right: 10px;
17+
padding: 0;
1518
}
1619

1720
vellum-doc::part(index) {
1821
border-right: dashed red;
19-
padding-right: 10px;
22+
padding-left: 1em;
23+
margin-right: 10px;
2024
}
2125

2226
vellum-doc::part(index-h1) {

package-lock.json

Lines changed: 90 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,10 @@
3232
"lit": "^3.1.4"
3333
},
3434
"devDependencies": {
35+
"@custom-elements-manifest/analyzer": "^0.10.2",
36+
"@lion/ui": "^0.7.4",
3537
"@typescript-eslint/eslint-plugin": "^7.7.1",
3638
"@typescript-eslint/parser": "^7.7.1",
37-
"@custom-elements-manifest/analyzer": "^0.10.2",
3839
"esbuild": "^0.21.5",
3940
"lit-analyzer": "^2.0.3",
4041
"prettier": "^3.3.2",

src/vellum-doc.ts

Lines changed: 83 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { LitElement, html, css } from 'lit'
22
import { customElement, property } from 'lit/decorators.js'
33
import { slugifyWithCounter } from '@sindresorhus/slugify'
44

5+
import '@lion/ui/define/lion-drawer.js'
6+
57
@customElement('vellum-doc')
68
export class VellumDocument extends LitElement {
79
static override styles = css`
@@ -14,27 +16,36 @@ export class VellumDocument extends LitElement {
1416
--default-index-width: 300px;
1517
}
1618
17-
#sidebar {
18-
float: left;
19-
min-width: var(--index-width, var(--default-index-width));
20-
font-size: 15px;
19+
#drawer {
20+
position: sticky;
21+
top: 0;
22+
--min-width: 0;
2123
}
2224
23-
.scrollable {
24-
width: var(--index-width, var(--default-index-width));
25-
min-height: 100vh;
26-
max-height: 100vh;
25+
#toggle {
2726
position: fixed;
28-
top: 0;
29-
overflow-y: auto;
27+
bottom: 1.5em;
28+
left: 1.5em;
29+
padding: 20px;
30+
background-color: lightgray;
31+
border-radius: 50%;
32+
height: 20px;
33+
width: 20px;
3034
}
3135
3236
#index {
33-
min-height: 100vh;
37+
width: var(--index-width, var(--default-index-width));
3438
border-right: 1px solid;
3539
padding-bottom: 1em;
3640
}
3741
42+
.scrollable {
43+
min-height: 100vh;
44+
max-height: 100vh;
45+
overflow-y: scroll;
46+
position: sticky;
47+
}
48+
3849
#index h1 {
3950
font: bold 1.3em inherit;
4051
margin: 0;
@@ -62,16 +73,6 @@ export class VellumDocument extends LitElement {
6273
color: inherit;
6374
text-decoration: inherit;
6475
}
65-
66-
@media (max-width: 700px) {
67-
#document {
68-
margin-left: 0;
69-
}
70-
71-
#sidebar {
72-
display: none;
73-
}
74-
}
7576
`
7677

7778
@property({ type: Boolean })
@@ -83,10 +84,24 @@ export class VellumDocument extends LitElement {
8384
return Array.from(this.querySelectorAll('h1, h2, h3, h4'))
8485
}
8586

87+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
88+
get drawer(): any | null {
89+
return this.renderRoot.querySelector('#drawer')
90+
}
91+
92+
get toggle(): HTMLElement | null {
93+
return this.renderRoot.querySelector('#toggle')
94+
}
95+
8696
override connectedCallback() {
8797
super.connectedCallback()
8898
this.labelHeaders()
8999
this.exportIndexHeadingParts()
100+
this.enableMobileIndexVisibility()
101+
}
102+
103+
override firstUpdated(): void {
104+
this.checkIndexVisibility()
90105
}
91106

92107
labelHeaders() {
@@ -122,16 +137,58 @@ export class VellumDocument extends LitElement {
122137
})
123138
}
124139

140+
enableMobileIndexVisibility() {
141+
const checkIndexVisibility = this.checkIndexVisibility.bind(this)
142+
window.addEventListener('resize', checkIndexVisibility)
143+
}
144+
145+
toggleIndex() {
146+
if (this.drawer) this.drawer.toggle()
147+
}
148+
149+
checkIndexVisibility() {
150+
if (window.innerWidth < 700 && this.toggle) {
151+
this.toggle!.style.visibility = 'visible'
152+
}
153+
154+
if (window.innerWidth < 700 && this.drawer && this.drawer.opened) {
155+
this.toggleIndex()
156+
}
157+
158+
if (window.innerWidth >= 700 && this.toggle) {
159+
this.toggle.style.visibility = 'hidden'
160+
}
161+
162+
if (window.innerWidth >= 700 && this.drawer && !this.drawer.opened) {
163+
this.toggleIndex()
164+
}
165+
}
166+
125167
override render() {
126168
return html`
127-
<div id="sidebar">
128-
<div class="scrollable">
129-
<div id="index" part="index">${this.renderIndex()}</div>
169+
<lion-drawer
170+
id="drawer"
171+
@click="${this.checkIndexVisibility}"
172+
opened
173+
hide>
174+
<div slot="content">
175+
<div id="index" class="scrollable" part="index">
176+
${this.renderIndex()}
177+
</div>
130178
</div>
131-
</div>
179+
</lion-drawer>
132180
133181
<article id="document">
134-
<slot></slot>
182+
<div id="toggle" @click="${this.toggleIndex}">
183+
<svg class="icon" viewBox="0 0 100 80" width="20" height="20">
184+
<rect width="100" height="15"></rect>
185+
<rect y="30" width="100" height="15"></rect>
186+
<rect y="60" width="100" height="15"></rect>
187+
</svg>
188+
</div>
189+
<div id="content" @click="${this.checkIndexVisibility}">
190+
<slot></slot>
191+
</div>
135192
</article>
136193
`
137194
}

0 commit comments

Comments
 (0)