Skip to content

Commit

Permalink
Add prop blurParams: BlurParams | null = { duration: 200 } (#47)
Browse files Browse the repository at this point in the history
* add prop blurParams: BlurParams | null = { duration: 200 }

* test blurParams

* readme.md document blurParams
  • Loading branch information
janosh committed Sep 10, 2023
1 parent 8f3b9fe commit 2ed78d0
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 17 deletions.
6 changes: 6 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ Full list of props and bindable variables for this component (all of them option

The DOM node of the currently active (highlighted) ToC item (based on user's scroll position on the page).

1. ```ts
blurParams: BlurParams | null = { duration: 200 }
```

Parameters to pass to `transition:blur` from `svelte/transition`. Set to `null` or `{ duration: 0 }` to disable blurring.

1. ```ts
breakpoint: number = 1000
```
Expand Down
7 changes: 4 additions & 3 deletions src/lib/Toc.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import { onMount } from 'svelte'
import { blur } from 'svelte/transition'
import { blur, type BlurParams } from 'svelte/transition'
import { MenuIcon } from '.'
export let activeHeading: HTMLHeadingElement | null = null
Expand All @@ -14,6 +14,7 @@
Number(node.nodeName[1]) // get the number from H1, H2, ...
export let getHeadingTitles = (node: HTMLHeadingElement): string =>
node.textContent ?? ``
// the result of document.querySelectorAll(headingSelector). can be useful for binding
export let headings: HTMLHeadingElement[] = []
export let headingSelector: string = `:is(h2, h3, h4):not(.toc-exclude)`
export let hide: boolean = false
Expand All @@ -26,9 +27,9 @@
export let scrollBehavior: 'auto' | 'smooth' = `smooth`
export let title: string = `On this page`
export let titleTag: string = `h2`
// the result of document.querySelectorAll(headingSelector). can be useful for binding
export let tocItems: HTMLLIElement[] = []
export let warnOnEmpty: boolean = true
export let blurParams: BlurParams | null = { duration: 200 }
let window_width: number
Expand Down Expand Up @@ -146,7 +147,7 @@
</button>
{/if}
{#if open || (desktop && headings.length >= minItems)}
<nav transition:blur bind:this={nav}>
<nav transition:blur={blurParams} bind:this={nav}>
{#if title}
<slot name="title">
<svelte:element this={titleTag} class="toc-title toc-exclude">
Expand Down
2 changes: 1 addition & 1 deletion src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
</main>

{#if [`/`, `/long-page`, `/changelog`, `/contributing`].includes($page.url.pathname)}
<Toc {headingSelector} activeHeadingScrollOffset={200} />
<Toc {headingSelector} activeHeadingScrollOffset={200} blurParams={{ duration: 400 }} />
{/if}

<style>
Expand Down
33 changes: 20 additions & 13 deletions tests/unit/toc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ describe(`Toc`, () => {
})

test.each([
[null, 3, [...Array(3).keys()].map((idx) => `Heading ${idx + 2}`)],
[null, 3, [0, 1, 2].map((lvl) => `Heading ${lvl + 2}`)],
[
`body > :is(h1, h2, h3, h4, h5, h6)`,
6,
[...Array(6).keys()].map((idx) => `Heading ${idx + 1}`),
[...Array(6).keys()].map((lvl) => `Heading ${lvl + 1}`),
],
[`h1:not(.toc-exclude)`, 0, []],
])(
Expand Down Expand Up @@ -132,17 +132,12 @@ describe(`Toc`, () => {
expect(lis[2].style.marginLeft).toBe(`2em`)
})

describe.each([
[
[1, 2, 3, 4],
[1, 5, 6],
],
])(`minItems`, (headings) => {
describe.each([[[1, 2, 3, 4]], [[1, 5, 6]]])(`minItems`, (heading_levels) => {
test.each([[1], [2], [3], [4]])(
`only renders TOC when there are more than minItems headings matching the selector`,
`only renders TOC when there are more than minItems=%s headings matching the selector`,
async (minItems) => {
document.body.innerHTML = headings
.map((h) => `<h${h}>Heading ${h}</h${h}>`)
document.body.innerHTML = heading_levels
.map((lvl) => `<h${lvl}>Heading ${lvl}</h${lvl}>`)
.join(``)

new Toc({
Expand All @@ -152,12 +147,15 @@ describe(`Toc`, () => {
await tick()

// count the number of headings that match the selector
const matches = headings.filter((h) => h >= 2 && h <= 4).length
const matches = heading_levels.filter(
(lvl) => lvl >= 2 && lvl <= 4,
).length
if (matches >= minItems) {
const toc_ul = doc_query(`aside.toc ol`)

expect(
toc_ul.children.length,
`headings=${headings}, minItems=${minItems}`,
`heading_levels=${heading_levels}, minItems=${minItems}`,
).toBe(matches)
} else {
const nav = document.querySelector(`aside.toc nav`)
Expand Down Expand Up @@ -199,3 +197,12 @@ test.each([
expect(node.className).toContain(`mobile`)
},
)

test(`ToC should have blur effect with duration of 400ms`, async () => {
const blurParams = { duration: 400 }
const toc = new Toc({
target: document.body,
props: { blurParams },
})
expect(toc.blurParams).toEqual(blurParams)
})

0 comments on commit 2ed78d0

Please sign in to comment.