Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(www): useActiveHash hook for highlighting links in Docs' table of contents #21762

Merged
merged 31 commits into from
Mar 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c4b122a
Create useActiveHash hook
jlkiri Feb 26, 2020
dceb3d5
Change hashlist to idlist
jlkiri Feb 26, 2020
8bef0e7
Remove console.log
jlkiri Feb 26, 2020
1bedc8b
Hook cleanup
jlkiri Feb 26, 2020
ca9761d
Style link based on hash
jlkiri Feb 26, 2020
e85d299
Add traversal option
jlkiri Feb 26, 2020
bd9aa2c
Move hooks to its own file
jlkiri Feb 26, 2020
7f302b1
Merge remote-tracking branch 'upstream/master' into use-active-hash
jlkiri Feb 26, 2020
7b924e4
Improve hook
jlkiri Feb 26, 2020
28b9403
Add comments, remove console.log
jlkiri Feb 26, 2020
036fcfd
Revert hash remove logic
jlkiri Feb 26, 2020
8160ad8
Remove unused colors
jlkiri Feb 26, 2020
b804b4d
Revert "Remove unused colors"
jlkiri Feb 26, 2020
b522004
Remove unused colors
jlkiri Feb 26, 2020
0a6f3aa
Refactor getHeadingIds
jlkiri Feb 26, 2020
89c4ef5
Switch to getElementById
jlkiri Feb 27, 2020
4763d30
Merge remote-tracking branch 'upstream/master' into use-active-hash
jlkiri Feb 27, 2020
1376382
Handle cases where url is absent
jlkiri Feb 28, 2020
53399bb
Do not update URL hash
jlkiri Feb 28, 2020
78632a9
Disable active link behavior on mobile
jlkiri Feb 28, 2020
e350ada
Handle mobile with media query
jlkiri Feb 28, 2020
fbd2248
Merge remote-tracking branch 'upstream/master' into use-active-hash
jlkiri Feb 28, 2020
e567fe2
Move function
Feb 29, 2020
a7dac40
Rename toc to items, add depth prop
jlkiri Mar 3, 2020
c7f8110
Merge remote-tracking branch 'upstream/master' into use-active-hash
jlkiri Mar 3, 2020
3cf10d2
Merge remote-tracking branch 'upstream/master' into use-active-hash
jlkiri Mar 10, 2020
5f051fd
Highlight subheadings
jlkiri Mar 10, 2020
63373b8
Add tests
jlkiri Mar 19, 2020
41661fd
Fix merge conflict
jlkiri Mar 19, 2020
c2ed59a
update recursion so tableOfContentsDepth is respected and something i…
gillkyle Mar 20, 2020
291850c
Merge branch 'master' into use-active-hash
gillkyle Mar 20, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions www/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@
"lingui:build": "yarn lingui:extract && yarn lingui:compile"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.1.1",
"@lingui/cli": "^2.9.1",
"@lingui/macro": "^2.9.1",
"@testing-library/react": "^8.0.9",
Expand Down
221 changes: 221 additions & 0 deletions www/src/components/__tests__/table-of-contents.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
import React from "react"
import { render } from "@testing-library/react"
import "@testing-library/jest-dom/extend-expect"
import { ThemeProvider } from "theme-ui"

import theme from "../../../src/gatsby-plugin-theme-ui"
import TableOfContents from "../docs-table-of-contents"

const tableOfContentsNoUrl = {
location: {
pathname: "",
},
depth: 2,
items: [
{
title: "API commands",
items: [
{
url: "#new",
title: "new",
items: [
{
title: "Arguments",
},
{
url: "#examples",
title: "Examples",
},
],
},
],
},
],
}

const tableOfContentsSimple = {
location: {
pathname: "",
},
depth: null,
items: [
{
url: "#how-to-use-gatsby-cli",
title: "How to use gatsby-cli",
},
],
}

const tableOfContentsDeep = {
location: {
pathname: "",
},
depth: 2,
items: [
{
url: "#how-to-use-gatsby-cli",
title: "How to use gatsby-cli",
},
{
url: "#api-commands",
title: "API commands",
items: [
{
url: "#new",
title: "new",
items: [
{
url: "#arguments",
title: "Arguments",
},
{
url: "#examples",
title: "Examples",
},
],
},
{
url: "#develop",
title: "develop",
items: [
{
url: "#options",
title: "Options",
},
{
url: "#preview-changes-on-other-devices",
title: "Preview changes on other devices",
},
],
},
{
url: "#build",
title: "build",
items: [
{
url: "#options-1",
title: "Options",
},
],
},
{
url: "#serve",
title: "serve",
items: [
{
url: "#options-2",
title: "Options",
},
],
},
{
url: "#info",
title: "info",
items: [
{
url: "#options-3",
title: "Options",
},
],
},
{
url: "#clean",
title: "clean",
},
{
url: "#plugin",
title: "plugin",
items: [
{
url: "#docs",
title: "docs",
},
],
},
{
url: "#repl",
title: "Repl",
},
{
url: "#disabling-colored-output",
title: "Disabling colored output",
},
],
},
{
url: "#how-to-change-your-default-package-manager-for-your-next-project",
title:
"How to change your default package manager for your next project?",
},
],
}

Object.defineProperty(window, "IntersectionObserver", {
writable: true,
value: jest.fn().mockImplementation(() => {
return {
observe: jest.fn(),
unobserve: jest.fn(),
}
}),
})

Object.defineProperty(window, "matchMedia", {
writable: true,
value: jest.fn().mockImplementation(query => ({
matches: false,
addListener: jest.fn(),
removeListener: jest.fn(),
})),
})

const testHeadingsRecursively = (getByTestId, items, depth) => {
if (depth === 0) return

for (const item of items) {
if (item.url) {
expect(getByTestId(item.url)).toHaveTextContent(item.title)
}

if (item.items) {
testHeadingsRecursively(getByTestId, item.items, depth - 1)
}
}
}

test("Table of contents (depth == 0)", () => {
const { items, depth, location } = tableOfContentsSimple
const { getByTestId } = render(
<ThemeProvider theme={theme}>
<TableOfContents items={items} depth={depth} location={location} />
</ThemeProvider>
)

for (const item of items) {
if (item.url) {
expect(getByTestId(item.url)).toHaveTextContent(item.title)
}
}
})

test("Table of contents (depth >= 1)", () => {
const { items, depth, location } = tableOfContentsDeep
const { getByTestId } = render(
<ThemeProvider theme={theme}>
<TableOfContents items={items} depth={depth} location={location} />
</ThemeProvider>
)

testHeadingsRecursively(getByTestId, items, depth - 1)
})

test("Table of contents (missing URLs)", () => {
const { items, depth, location } = tableOfContentsNoUrl
const { getByTestId } = render(
<ThemeProvider theme={theme}>
<TableOfContents items={items} depth={depth} location={location} />
</ThemeProvider>
)

testHeadingsRecursively(getByTestId, items, depth - 1)
})
Loading