react-slips-hook
Version:
Display and layer pages as slips in Gatsby
126 lines (105 loc) • 2.98 kB
Markdown
# react-slips-hook
Treats pages as slips in Gatsby, allowing multiple pages to slip over and under each other in the viewport.
Incidentally "[zettel](https://www.wikiwand.com/en/Zettel_(Wittgenstein_book))" as in zettelkasten can refer to slips of paper.
## Installation
```bash
npm install react-slips-hook
```
## Usage
In your layout component:
```js
import React, { useEffect, useRef, useCallback } from "react";
import Page from "../components/Page";
import {
useSlipsProvider,
LinkToSlip,
useSlip,
PageIndexProvider,
SlipsProvider,
} from "react-slips-hook";
const PageContainer = ({ children, slug }) => {
const [, { overlay, obstructed, highlighted }, i] = useSlip();
return (
<div
className={`page-container ${overlay ? "page-container-overlay" : ""} ${
obstructed ? "page-container-obstructed" : ""
} ${highlighted ? "page-container-highlighted" : ""}`}
style={{ left: 40 * i, right: -585 }}
>
<div className="page-content">{children}</div>
<LinkToSlip to={slug} className="obstructed-label">
{slug}
</LinkToSlip>
</div>
);
};
// A wrapper component to render the content of layered slips
const SlipWrapper = ({ children, slug, i }) => (
<PageIndexProvider value={i}>
<PageContainer slug={slug}>{children}</PageContainer>
</PageIndexProvider>
);
const SlipLayout = ({ data, location, slug }) => {
// Use this callback to update what you want to stack.
// `pageQuery` will be similar to the data prop you get in a Page component.
// You can return `null` to filter out the page
const processPageQuery = useCallback((pageQuery) => pageQuery, []);
const [state, scrollContainer] = useSlipNotesProvider({
firstPage: { data, slug },
location,
processPageQuery,
pageWidth: 625,
});
return (
<div className="slip-layout">
<div className="page-columns-scrolling-container" ref={scrollContainer}>
<div
className="page-columns-container"
style={{ width: 625 * (state.slips.length + 1) }}
>
<SlipsProvider value={state}>
{/* Render the layered slips */}
{state.slips.map((page, i) => (
<SlipWrapper i={i} key={page.slug} slug={page.slug}>
<Page {...page} />
</SlipWrapper>
))}
</SlipsProvider>
</div>
</div>
</div>
);
};
export default SlipLayout;
```
Somewhere in your slip, you can use
```js
import {
useSlips,
useSlip,
LinkToSlip,
} from "react-slips-hook";
const Component = () => {
const [
slips,
slipStates,
hookedNavigateToSlip,
highlightSlip,
] = useSlips();
const [
currentPage,
currentPageState,
pageIndex,
navigateToSlip,
highlightSlip,
] = useSlip();
return null;
};
const AnotherComponent = () => {
return (
<LinkToSlip to={"/slips"}>
Magic link that will stack a page
</LinkToSlip>
);
};
```