Skip to content

Commit

Permalink
Remove useNavigationBlocker
Browse files Browse the repository at this point in the history
  • Loading branch information
zoontek committed Dec 19, 2023
1 parent 7900712 commit 8b3bd15
Show file tree
Hide file tree
Showing 9 changed files with 30 additions and 143 deletions.
19 changes: 0 additions & 19 deletions docs/docs/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,22 +72,3 @@ const App = () => {
//
};
```

## useNavigationBlocker

Block the navigation and ask user for confirmation. Useful to avoid loosing a form state.

```tsx
import { useNavigationBlocker } from "@swan-io/chicane";

const App = () => {
const { formStatus } = useForm(/**/);

useNavigationBlocker(
formStatus === "editing",
"Are you sure you want to stop editing this profile?",
);

//
};
```
26 changes: 4 additions & 22 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import {
Link,
useFocusReset,
useNavigationBlocker,
} from "@swan-io/chicane/src";
import { Link, useFocusReset } from "@swan-io/chicane/src";
import { useRef } from "react";
import { match } from "ts-pattern";
import { Router } from "./router";
Expand Down Expand Up @@ -110,22 +106,6 @@ const UsersArea = () => {
);
};

const Repository = ({
userId,
repositoryId,
}: {
userId: string;
repositoryId: string;
}) => {
useNavigationBlocker(true, "toto");

return (
<h2>
{userId}/{repositoryId}
</h2>
);
};

const RepositoriesArea = ({ userId }: { userId: string }) => {
const route = Router.useRoute(["Repositories", "Repository"]);
const containerRef = useRef(null);
Expand All @@ -151,7 +131,9 @@ const RepositoriesArea = ({ userId }: { userId: string }) => {
.with(
{ name: "Repository" },
({ params: { userId, repositoryId } }) => (
<Repository userId={userId} repositoryId={repositoryId} />
<h2>
{userId}/{repositoryId}
</h2>
),
)
.with(undefined, () => <div>404 - Repository not found</div>)
Expand Down
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,13 @@
"registry": "https://registry.npmjs.org"
},
"scripts": {
"build": "yarn clean && microbundle -f cjs,es",
"clean": "rm -rf dist",
"dev": "microbundle watch",
"format": "prettier '**/*' -u -w",
"format": "prettier '**/*' --ignore-unknown --write",
"lint": "eslint --ext ts,tsx ./src",
"test": "vitest --run",
"test:watch": "vitest --watch",
"typecheck": "tsc --noEmit",
"build": "yarn clean && microbundle -f cjs,es --tsconfig tsconfig.build.json",
"prepack": "yarn typecheck && yarn lint && yarn test && yarn build"
},
"browserslist": [
Expand Down
2 changes: 0 additions & 2 deletions src/history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const history: History =
? createBrowserHistory()
: {
location: parsePath("/"),
block: () => noop,
listen: () => noop, // TODO: rename this subscribe
push: noop,
replace: noop,
Expand Down Expand Up @@ -106,7 +105,6 @@ export const useLocation = (): Location => {
);
};

export const blockHistory = history.block;
export const pushUnsafe = history.push;
export const replaceUnsafe = history.replace;

Expand Down
93 changes: 17 additions & 76 deletions src/historyLite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,96 +7,52 @@ export type Location = {

export type Listener = (location: Location) => void;

type Retry = () => void;
type Unblock = () => void;
type Blocker = (retry: Retry) => void;

export type History = {
readonly location: Location;
push: (url: string) => void;
replace: (url: string) => void;
listen: (listener: Listener) => () => void;
block: (blocker: Blocker) => Unblock;
};

const promptBeforeUnload = (event: BeforeUnloadEvent) => {
// Cancel the event.
event.preventDefault();
// Chrome (and legacy IE) requires returnValue to be set.
event.returnValue = "";
};

export const createBrowserHistory = (): History => {
const globalHistory = window.history;
const globalLocation = window.location;

globalHistory.replaceState(0, ""); // TODO: Clean the url here too

const getStateIndex = () =>
typeof globalHistory.state === "number" ? globalHistory.state : 0;
// globalHistory.replaceState(0, ""); // TODO: Clean the url here too

const getLocation = (): Location => {
const { pathname, search } = globalLocation;
return { pathname, search };
};

const listeners = new Set<Listener>();
const blockers = new Set<Blocker>();

let location = getLocation();
let index = 0;
let blockDelta: number | undefined = undefined;

window.addEventListener("popstate", () => {
if (blockers.size > 0) {
if (typeof blockDelta === "undefined") {
console.log(index, getStateIndex());
blockDelta = index - getStateIndex();
globalHistory.go(blockDelta);
} else {
const delta = blockDelta * -1;
blockDelta = undefined;
const retry = () => globalHistory.go(delta);
blockers.forEach((blocker) => blocker(retry));
}
} else {
location = getLocation();
listeners.forEach((fn) => fn(location));
}
location = getLocation();
listeners.forEach((fn) => fn(location));
});

const push = (url: string): void => {
if (blockers.size > 0) {
blockers.forEach((blocker) => blocker(() => push(url)));
} else {
index = getStateIndex() + 1;
location = parsePath(url);

const url2 = createPath(location); // TODO: use location.toString()

try {
// iOS has a limit of 100 pushState calls / 30 secs
globalHistory.pushState(index, "", url2);
} catch {
globalLocation.assign(url2);
}

listeners.forEach((fn) => fn(location));
location = parsePath(url);
const url2 = createPath(location); // TODO: use location.toString()

try {
// iOS has a limit of 100 pushState calls / 30 secs
globalHistory.pushState(null, "", url2);
} catch {
globalLocation.assign(url2);
}

listeners.forEach((fn) => fn(location));
};

const replace = (url: string): void => {
if (blockers.size > 0) {
blockers.forEach((blocker) => blocker(() => replace(url)));
} else {
index = getStateIndex();
location = parsePath(url);

const url2 = createPath(location); // TODO: use location.toString()
location = parsePath(url);
const url2 = createPath(location); // TODO: use location.toString()

globalHistory.replaceState(index, "", url2);
listeners.forEach((fn) => fn(location));
}
globalHistory.replaceState(null, "", url2);
listeners.forEach((fn) => fn(location));
};

const history: History = {
Expand All @@ -112,21 +68,6 @@ export const createBrowserHistory = (): History => {
listeners.delete(listener);
};
},
block: (blocker: Blocker) => {
blockers.add(blocker);

if (blockers.size === 1) {
window.addEventListener("beforeunload", promptBeforeUnload);
}

return () => {
blockers.delete(blocker);

if (blockers.size === 0) {
window.removeEventListener("beforeunload", promptBeforeUnload);
}
};
},
};

return history;
Expand Down
1 change: 0 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,3 @@ export { ServerUrlProvider } from "./server";
export type { Location, Search } from "./types";
export { useFocusReset } from "./useFocusReset";
export { useLinkProps } from "./useLinkProps";
export { useNavigationBlocker } from "./useNavigationBlocker";
19 changes: 0 additions & 19 deletions src/useNavigationBlocker.ts

This file was deleted.

5 changes: 5 additions & 0 deletions tsconfig.build.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": "./tsconfig.json",
"include": ["src"],
"exclude": ["__tests__"]
}
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"include": ["./src"],
"include": ["src", "__tests__"],
"compilerOptions": {
"module": "ES2015",
"target": "ES2015",
Expand All @@ -13,6 +13,7 @@
"noEmit": true,
"sourceMap": true,
"strict": true,
"skipLibCheck": true,
"stripInternal": true,

// https://www.typescriptlang.org/tsconfig#Type_Checking_6248
Expand Down

0 comments on commit 8b3bd15

Please sign in to comment.