Skip to content

Commit

Permalink
fix(waku): link props (#360)
Browse files Browse the repository at this point in the history
* fix(waku): link props

* fix: code

* fix: improve code
  • Loading branch information
himself65 authored Jan 10, 2024
1 parent a756ba5 commit 59a2c60
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 32 deletions.
4 changes: 2 additions & 2 deletions e2e/fixtures/rsc-router/src/routes/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const HomeLayout = ({ children }: { children: ReactNode }) => (
<ul>
<li>
<Link
href="/"
to="/"
pending={<Pending isPending />}
notPending={<Pending isPending={false} />}
>
Expand All @@ -29,7 +29,7 @@ const HomeLayout = ({ children }: { children: ReactNode }) => (
</li>
<li>
<Link
href="/foo"
to="/foo"
pending={<Pending isPending />}
notPending={<Pending isPending={false} />}
>
Expand Down
2 changes: 1 addition & 1 deletion examples/07_router/src/components/Counter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const Counter = () => {
<p>Count: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>Increment</button>
<h3>This is a client component.</h3>
<Link href="/">Go to Home</Link>
<Link to="/">Go to Home</Link>
</div>
);
};
16 changes: 8 additions & 8 deletions examples/07_router/src/components/HomeLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const HomeLayout = ({ children }: { children: ReactNode }) => (
<ul>
<li>
<Link
href="/"
to="/"
pending={<Pending isPending />}
notPending={<Pending isPending={false} />}
>
Expand All @@ -29,32 +29,32 @@ const HomeLayout = ({ children }: { children: ReactNode }) => (
</li>
<li>
<Link
href="/foo"
to="/foo"
pending={<Pending isPending />}
notPending={<Pending isPending={false} />}
>
Foo
</Link>
</li>
<li>
<Link href="/bar" unstable_prefetchOnEnter>
<Link to="/bar" unstable_prefetchOnEnter>
Bar
</Link>
</li>
<li>
<Link href="/baz">Baz</Link>
<Link to="/baz">Baz</Link>
</li>
<li>
<Link href="/nested/foo">Nested / Foo</Link>
<Link to="/nested/foo">Nested / Foo</Link>
</li>
<li>
<Link href="/nested/bar">Nested / Bar</Link>
<Link to="/nested/bar">Nested / Bar</Link>
</li>
<li>
<Link href="/nested/baz">Nested / Baz</Link>
<Link to="/nested/baz">Nested / Baz</Link>
</li>
<li>
<Link href="/nested/qux">Nested / Qux</Link>
<Link to="/nested/qux">Nested / Qux</Link>
</li>
</ul>
{children}
Expand Down
2 changes: 1 addition & 1 deletion examples/10_dynamicroute/src/components/Counter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const Counter = () => {
<p>Count: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>Increment</button>
<h3>This is a client component.</h3>
<Link href="/">Go to Home</Link>
<Link to="/">Go to Home</Link>
</div>
);
};
10 changes: 5 additions & 5 deletions examples/10_dynamicroute/src/routes/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const HomeLayout = ({ children }: { children: ReactNode }) => (
<ul>
<li>
<Link
href="/"
to="/"
pending={<Pending isPending />}
notPending={<Pending isPending={false} />}
>
Expand All @@ -29,7 +29,7 @@ const HomeLayout = ({ children }: { children: ReactNode }) => (
</li>
<li>
<Link
href="/foo"
to="/foo"
pending={<Pending isPending />}
notPending={<Pending isPending={false} />}
>
Expand All @@ -38,7 +38,7 @@ const HomeLayout = ({ children }: { children: ReactNode }) => (
</li>
<li>
<Link
href="/bar"
to="/bar"
unstable_prefetchOnEnter
pending={<Pending isPending />}
notPending={<Pending isPending={false} />}
Expand All @@ -48,7 +48,7 @@ const HomeLayout = ({ children }: { children: ReactNode }) => (
</li>
<li>
<Link
href="/nested/baz"
to="/nested/baz"
pending={<Pending isPending />}
notPending={<Pending isPending={false} />}
>
Expand All @@ -57,7 +57,7 @@ const HomeLayout = ({ children }: { children: ReactNode }) => (
</li>
<li>
<Link
href="/nested/qux"
to="/nested/qux"
pending={<Pending isPending />}
notPending={<Pending isPending={false} />}
>
Expand Down
49 changes: 34 additions & 15 deletions packages/waku/src/router/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ import {
useTransition,
Fragment,
} from 'react';
import type { ComponentProps, FunctionComponent, ReactNode } from 'react';
import type {
ComponentProps,
FunctionComponent,
ReactNode,
AnchorHTMLAttributes,
ReactElement,
MouseEvent,
} from 'react';

import { prefetchRSC, Root, Slot, useRefetch } from '../client.js';
import {
Expand Down Expand Up @@ -69,19 +76,25 @@ export function useLocation() {
return value.loc;
}

export type LinkProps = {
to: string;
pending?: ReactNode;
notPending?: ReactNode;
children: ReactNode;
unstable_prefetchOnEnter?: boolean;
} & Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'>;

export function Link({
href,
to,
children,
pending,
notPending,
unstable_prefetchOnEnter,
}: {
href: string;
children: ReactNode;
pending?: ReactNode;
notPending?: ReactNode;
unstable_prefetchOnEnter?: boolean;
}) {
...props
}: LinkProps): ReactElement {
if (!to.startsWith('/')) {
throw new Error('Link must start with "/"');
}
const value = useContext(RouterContext);
const changeLocation = value
? value.changeLocation
Expand All @@ -94,25 +107,31 @@ export function Link({
throw new Error('Missing Router');
};
const [isPending, startTransition] = useTransition();
const onClick = (event: MouseEvent) => {
const onClick = (event: MouseEvent<HTMLAnchorElement>) => {
event.preventDefault();
const url = new URL(href, window.location.href);
const url = new URL(to, window.location.href);
if (url.href !== window.location.href) {
prefetchLocation(url.pathname, url.searchParams);
startTransition(() => {
changeLocation(url.pathname, url.searchParams);
});
}
props.onClick?.(event);
};
const onMouseEnter = unstable_prefetchOnEnter
? () => {
const url = new URL(href, window.location.href);
? (event: MouseEvent<HTMLAnchorElement>) => {
const url = new URL(to, window.location.href);
if (url.href !== window.location.href) {
prefetchLocation(url.pathname, url.searchParams);
}
props.onMouseEnter?.(event);
}
: undefined;
const ele = createElement('a', { href, onClick, onMouseEnter }, children);
: props.onMouseEnter;
const ele = createElement(
'a',
{ ...props, href: to, onClick, onMouseEnter },
children,
);
if (isPending && pending !== undefined) {
return createElement(Fragment, null, ele, pending);
}
Expand Down

1 comment on commit 59a2c60

@vercel
Copy link

@vercel vercel bot commented on 59a2c60 Jan 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

waku – ./

waku-git-main-daishi.vercel.app
waku.vercel.app
waku.gg
www.waku.gg
waku-daishi.vercel.app

Please sign in to comment.