Skip to content

Commit

Permalink
Add index drawer using lion
Browse files Browse the repository at this point in the history
Closes: 

#3

See here for more information:

#13
  • Loading branch information
rg-wood authored Jul 23, 2024
1 parent 6e435f9 commit 726cc8f
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 30 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ A custom element to turn plain HTML into rich documents, inspired by
[Docsify](https://docsify.js.org). Features include:

- Document index pane
- Stow index pane in application drawer on mobile devices
- Anchor links (optional)

**[Demo](https://grislyeye.github.io/vellum-doc/)** |
Expand Down
10 changes: 7 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,18 @@

<script type="module" src="./vellum-doc.js"></script>
<style>
body {
margin: 0;
}

vellum-doc {
padding-left: 10px;
padding-right: 10px;
padding: 0;
}

vellum-doc::part(index) {
border-right: dashed red;
padding-right: 10px;
padding-left: 1em;
margin-right: 10px;
}

vellum-doc::part(index-h1) {
Expand Down
90 changes: 90 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@
"lit": "^3.1.4"
},
"devDependencies": {
"@custom-elements-manifest/analyzer": "^0.10.2",
"@lion/ui": "^0.7.4",
"@typescript-eslint/eslint-plugin": "^7.7.1",
"@typescript-eslint/parser": "^7.7.1",
"@custom-elements-manifest/analyzer": "^0.10.2",
"esbuild": "^0.21.5",
"lit-analyzer": "^2.0.3",
"prettier": "^3.3.2",
Expand Down
109 changes: 83 additions & 26 deletions src/vellum-doc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { LitElement, html, css } from 'lit'
import { customElement, property } from 'lit/decorators.js'
import { slugifyWithCounter } from '@sindresorhus/slugify'

import '@lion/ui/define/lion-drawer.js'

@customElement('vellum-doc')
export class VellumDocument extends LitElement {
static override styles = css`
Expand All @@ -14,27 +16,36 @@ export class VellumDocument extends LitElement {
--default-index-width: 300px;
}
#sidebar {
float: left;
min-width: var(--index-width, var(--default-index-width));
font-size: 15px;
#drawer {
position: sticky;
top: 0;
--min-width: 0;
}
.scrollable {
width: var(--index-width, var(--default-index-width));
min-height: 100vh;
max-height: 100vh;
#toggle {
position: fixed;
top: 0;
overflow-y: auto;
bottom: 1.5em;
left: 1.5em;
padding: 20px;
background-color: lightgray;
border-radius: 50%;
height: 20px;
width: 20px;
}
#index {
min-height: 100vh;
width: var(--index-width, var(--default-index-width));
border-right: 1px solid;
padding-bottom: 1em;
}
.scrollable {
min-height: 100vh;
max-height: 100vh;
overflow-y: scroll;
position: sticky;
}
#index h1 {
font: bold 1.3em inherit;
margin: 0;
Expand Down Expand Up @@ -62,16 +73,6 @@ export class VellumDocument extends LitElement {
color: inherit;
text-decoration: inherit;
}
@media (max-width: 700px) {
#document {
margin-left: 0;
}
#sidebar {
display: none;
}
}
`

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

// eslint-disable-next-line @typescript-eslint/no-explicit-any
get drawer(): any | null {
return this.renderRoot.querySelector('#drawer')
}

get toggle(): HTMLElement | null {
return this.renderRoot.querySelector('#toggle')
}

override connectedCallback() {
super.connectedCallback()
this.labelHeaders()
this.exportIndexHeadingParts()
this.enableMobileIndexVisibility()
}

override firstUpdated(): void {
this.checkIndexVisibility()
}

labelHeaders() {
Expand Down Expand Up @@ -122,16 +137,58 @@ export class VellumDocument extends LitElement {
})
}

enableMobileIndexVisibility() {
const checkIndexVisibility = this.checkIndexVisibility.bind(this)
window.addEventListener('resize', checkIndexVisibility)
}

toggleIndex() {
if (this.drawer) this.drawer.toggle()
}

checkIndexVisibility() {
if (window.innerWidth < 700 && this.toggle) {
this.toggle!.style.visibility = 'visible'
}

if (window.innerWidth < 700 && this.drawer && this.drawer.opened) {
this.toggleIndex()
}

if (window.innerWidth >= 700 && this.toggle) {
this.toggle.style.visibility = 'hidden'
}

if (window.innerWidth >= 700 && this.drawer && !this.drawer.opened) {
this.toggleIndex()
}
}

override render() {
return html`
<div id="sidebar">
<div class="scrollable">
<div id="index" part="index">${this.renderIndex()}</div>
<lion-drawer
id="drawer"
@click="${this.checkIndexVisibility}"
opened
hide>
<div slot="content">
<div id="index" class="scrollable" part="index">
${this.renderIndex()}
</div>
</div>
</div>
</lion-drawer>
<article id="document">
<slot></slot>
<div id="toggle" @click="${this.toggleIndex}">
<svg class="icon" viewBox="0 0 100 80" width="20" height="20">
<rect width="100" height="15"></rect>
<rect y="30" width="100" height="15"></rect>
<rect y="60" width="100" height="15"></rect>
</svg>
</div>
<div id="content" @click="${this.checkIndexVisibility}">
<slot></slot>
</div>
</article>
`
}
Expand Down

0 comments on commit 726cc8f

Please sign in to comment.