Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/funtechinc/mekuri
📕 Page transition animation for React
https://github.com/funtechinc/mekuri
hooks nextjs pagetransition react remix remix-run
Last synced: 2 months ago
JSON representation
📕 Page transition animation for React
- Host: GitHub
- URL: https://github.com/funtechinc/mekuri
- Owner: FunTechInc
- License: mit
- Created: 2023-06-15T07:57:32.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-05-24T08:04:32.000Z (9 months ago)
- Last Synced: 2024-10-15T11:33:03.769Z (4 months ago)
- Topics: hooks, nextjs, pagetransition, react, remix, remix-run
- Language: TypeScript
- Homepage: https://mekuri.vercel.app
- Size: 24.7 MB
- Stars: 60
- Watchers: 3
- Forks: 3
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# mekuri
![mekuri](public/app-head.jpg)
`mekuri` is React package for page transition animations with `wait` and `sync` modes, supporting `popstate` and `scroll restoration`.
Customize animations per component with the `useMekuri` hook and use with libraries like `GSAP`. It integrates with Next.js and Remix; can also be integrated with Next.js `App Router`, but for stable operation it is recommended to use Pages Router rather than App Router. [Next.js Pages Router demo](https://github.com/FunTechInc/mekuri-demo-pages)
```bash
$ npm i @funtech-inc/mekuri
```### Features 📕
- `wait` and `sync` modes
- `scrollRestoration` in popstate.
- When in `sync` mode, routing is possible in `wait` mode when in popstate.
- Supports frameworks such as `Next.js` and `Remix`. Can also integrate with `Next.js App Router`.
- `useMekuri` hook for each component.
- Integration into smooth scrolling libraries such as [lenis](https://github.com/darkroomengineering/lenis) is also possible.# Usage
```tsx
export default function App({ Component, pageProps }: AppProps) {
const { pathname } = useRouter();
return (
);
}
```## MekuriContext
The context to wrap the whole thing in. Set the `trigger` to a `state` to switch content. You can use `pathname` if you want to use it as a page transition.
## Mekuri
Unmounting of children can be delayed by wrapping them in a `Mekuri` component.
## useMekuri
Hooks that can be called within `MekuriContext`. Callbacks include `onOnce`, `onLeave`, `onEnter`, `onAfterSyncEnter`, `onEveryLeave` and `onEveryEnter`.
```tsx
const SomeAnimationComponent = ({
children,
}: {
children: React.ReactNode;
}) => {
const ref = useRef(null);
useMekuri({
onLeave: (props: MekuriCallbackProps) => {
gsap.to(ref.current, {
opacity: 0,
});
},
onEnter: (props: MekuriCallbackProps) => {
gsap.to(ref.current, {
opacity: 1,
});
},
});
return{children};
};
```Each callback has `MekuriCallbackProps` as an argument.
```ts
type MekuriCallbackProps = {
prevTrigger: Trigger | null | undefined;
currentTrigger: Trigger | null | undefined;
nextTrigger: Trigger | null | undefined;
/** Returns the Y position before leaving the page */
yPosBeforeLeave: number;
/** If # is attached to the URL when transitioning, the distance to that ID is returned. */
getHashPos: ReturnHashPosReturn;
/** intersectionObserver (
targetRef: React.RefObject,
callback: (isIntersecting: boolean) => void
) => void
* */
intersectionObserver: HandleIntersectionObserver;
/** mekuri renders based on timeout. Therefore, there are cases where the next component is rendered before the chunked Stylesheet updated by Next.js is loaded. `onStylesheetLoad` ensures that functions are executed after the Stylesheet is loaded. `onStylesheetLoad` ensures that the function is executed after the Stylesheet is loaded */
onStylesheetLoad: (callback: () => void) => void;
/** Whether the transition is by popstate */
isPopstate: boolean;
};
```## useMekuriDuration
It is possible to receive the `duration` set in the `MekuriContext`.
```tsx
const { millisecond, second } = useMekuriDuration();
```## useMekuriTrigger
`phase` : `enter` | `leave` , Specify the phase to subscribe to trigger updates
```tsx
const trigger = useMekuriTrigger(phase);
```# integrate with Next.js App Router
Since the key cannot be obtained by changing children during app router page transition, it is necessary to import `LayoutRouterContext` from next and pass the context to `MekuriFreezer`.
For more information on `App Router` page transition animations, see the following issue.
[See this issue](https://github.com/vercel/next.js/issues/49279#issuecomment-1675782002)## MekuriFreezer
```tsx
"use client";
import { MekuriFreezer, Mekuri } from "@/packages/mekuri/src";
// import { LayoutRouterContext } from "next/dist/shared/lib/app-router-context";
// Next.js ^13.5.2
import { LayoutRouterContext } from "next/dist/shared/lib/app-router-context.shared-runtime";
import { usePathname } from "next/navigation";export const PageTransitionLayout = ({
children,
}: {
children: React.ReactNode;
}) => {
const pathname = usePathname();
return (
{children}
);
};
```# integrate with Remix
```tsx
export default function App() {
const location = useLocation();
const outlet = useOutlet();
return (
{outlet}
);
}
```