react-slips-hook
v0.7.0
Published
Display and layer pages as slips in Gatsby
Downloads
4
Maintainers
Readme
react-slips-hook
Treats pages as slips in Gatsby, allowing multiple pages to slip over and under each other in the viewport.
Incidentally "zettel" as in zettelkasten can refer to slips of paper.
Installation
npm install react-slips-hook
Usage
In your layout component:
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
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>
);
};