mirror of
https://github.com/cupcakearmy/nicco.io.git
synced 2024-12-22 08:06:29 +00:00
sidepanel
This commit is contained in:
parent
31fc15118b
commit
0c79aff77b
55
src/lib/components/ArticleOverview.svelte
Normal file
55
src/lib/components/ArticleOverview.svelte
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<script lang="ts" context="module">
|
||||||
|
export type ArticleHeading = {
|
||||||
|
text: string
|
||||||
|
hash: string
|
||||||
|
href: string
|
||||||
|
level: number
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
export let headings: ArticleHeading[]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<b>Outline</b>
|
||||||
|
{#each headings as { text, level, href }}
|
||||||
|
<div style="margin-left: {level - 2}rem;">
|
||||||
|
<span>▶</span>
|
||||||
|
<a {href}>
|
||||||
|
{text}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.wrapper {
|
||||||
|
margin: 2rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 75rem) {
|
||||||
|
.wrapper {
|
||||||
|
margin: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 40rem;
|
||||||
|
width: max-content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 0.5em;
|
||||||
|
transform: translateY(-0.8em);
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
height: 1.4em;
|
||||||
|
display: inline-block;
|
||||||
|
max-width: 20rem;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,14 +1,16 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import hljs from 'highlight.js/lib/core'
|
import hljs from 'highlight.js/lib/core'
|
||||||
import javascript from 'highlight.js/lib/languages/javascript'
|
|
||||||
import python from 'highlight.js/lib/languages/python'
|
|
||||||
import yaml from 'highlight.js/lib/languages/yaml'
|
|
||||||
import json from 'highlight.js/lib/languages/json'
|
|
||||||
import bash from 'highlight.js/lib/languages/bash'
|
import bash from 'highlight.js/lib/languages/bash'
|
||||||
import docker from 'highlight.js/lib/languages/dockerfile'
|
|
||||||
import rust from 'highlight.js/lib/languages/rust'
|
|
||||||
import css from 'highlight.js/lib/languages/css'
|
import css from 'highlight.js/lib/languages/css'
|
||||||
|
import docker from 'highlight.js/lib/languages/dockerfile'
|
||||||
|
import javascript from 'highlight.js/lib/languages/javascript'
|
||||||
|
import json from 'highlight.js/lib/languages/json'
|
||||||
|
import python from 'highlight.js/lib/languages/python'
|
||||||
|
import rust from 'highlight.js/lib/languages/rust'
|
||||||
import typescript from 'highlight.js/lib/languages/typescript'
|
import typescript from 'highlight.js/lib/languages/typescript'
|
||||||
|
import yaml from 'highlight.js/lib/languages/yaml'
|
||||||
|
import { onMount } from 'svelte'
|
||||||
|
import ArticleOverview, { ArticleHeading } from './ArticleOverview.svelte'
|
||||||
|
|
||||||
hljs.registerLanguage('javascript', javascript)
|
hljs.registerLanguage('javascript', javascript)
|
||||||
hljs.registerLanguage('python', python)
|
hljs.registerLanguage('python', python)
|
||||||
@ -20,15 +22,18 @@
|
|||||||
hljs.registerLanguage('css', css)
|
hljs.registerLanguage('css', css)
|
||||||
hljs.registerLanguage('typescript', typescript)
|
hljs.registerLanguage('typescript', typescript)
|
||||||
|
|
||||||
import { onMount } from 'svelte'
|
|
||||||
|
|
||||||
export let content: string
|
export let content: string
|
||||||
|
let headings: ArticleHeading[] | null = null
|
||||||
|
|
||||||
function encodeTextToUrl(text: string): string {
|
function encodeTextToUrl(text: string): string {
|
||||||
return text
|
return text
|
||||||
.replace(/[^A-Za-z ]/, '')
|
.toLowerCase()
|
||||||
.replace('/ +/', ' ')
|
.replace(/[^A-Za-z ]/g, '')
|
||||||
.replace(' ', '-')
|
.replace(/ +/g, '-')
|
||||||
|
}
|
||||||
|
|
||||||
|
async function update(isDark: boolean) {
|
||||||
|
isDark ? await import('highlight.js/styles/github-dark.css') : await import('highlight.js/styles/github.css')
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
@ -37,16 +42,15 @@
|
|||||||
// Add anchor links to headers
|
// Add anchor links to headers
|
||||||
const selector = [1, 2, 3, 4, 5, 6].map((i) => `div.adapter h${i}`).join(', ')
|
const selector = [1, 2, 3, 4, 5, 6].map((i) => `div.adapter h${i}`).join(', ')
|
||||||
const elements = window.document.querySelectorAll(selector)
|
const elements = window.document.querySelectorAll(selector)
|
||||||
elements.forEach((el) => {
|
headings = Array.from(elements).map((element) => {
|
||||||
if (el.textContent) {
|
const text = element.textContent || ''
|
||||||
const hash = encodeTextToUrl(el.textContent)
|
const hash = encodeTextToUrl(text)
|
||||||
el.innerHTML = `<a class="target-link" name="${hash}" href="${window.location.pathname}#${hash}">${el.innerHTML}</a>`
|
const href = `${window.location.pathname}#${hash}`
|
||||||
}
|
const level = parseInt(element.tagName.slice(1))
|
||||||
})
|
|
||||||
|
|
||||||
async function update(isDark: boolean) {
|
element.innerHTML = `<a class="target-link" id="${hash}" href="${href}">${text}</a>`
|
||||||
isDark ? await import('highlight.js/styles/github-dark.css') : await import('highlight.js/styles/github.css')
|
return { text, hash, level, href }
|
||||||
}
|
})
|
||||||
|
|
||||||
const match = window.matchMedia('(prefers-color-scheme: dark)')
|
const match = window.matchMedia('(prefers-color-scheme: dark)')
|
||||||
match.addEventListener('change', (e) => update(e.matches))
|
match.addEventListener('change', (e) => update(e.matches))
|
||||||
@ -55,10 +59,16 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="adapter">
|
<div class="adapter">
|
||||||
|
{#if headings}
|
||||||
|
<ArticleOverview {headings} />
|
||||||
|
{/if}
|
||||||
{@html content}
|
{@html content}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.adapter {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
div :global(.alignfull) {
|
div :global(.alignfull) {
|
||||||
width: calc(100vw - 6em);
|
width: calc(100vw - 6em);
|
||||||
margin-left: -2em;
|
margin-left: -2em;
|
||||||
|
Loading…
Reference in New Issue
Block a user