-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FEAT] @refinedev/nextjs-router
and others should allow configuration
#6308
Comments
Hey @datner, Refine expects provider props to be objects with certain properties. Simply by overriding the I think having something like |
import { Url } from "next/dist/shared/lib/router/router";
import NextLink, { type LinkProps } from "next/link";
import React, { forwardRef } from "react";
type Destination = { to: string; href: never } | { href: Url; to?: string };
export const Link = forwardRef(function Link(
props: Omit<LinkProps, "href"> & Destination & React.ComponentPropsWithoutRef<"a">,
ref: React.ForwardedRef<HTMLAnchorElement>,
) {
return (
<NextLink {...props} href={props.to ?? props.href} ref={ref} />
);
}); This obviously is not a 1:1 to my component, which has other stuff included. But the point is that the |
@alicanerdurmaz Hey, the issue was not solved. It persists in the same manner and can be recreated as described above The error has changed, but the narrowing issue persists. I don't think it's possible without a |
Hey @datner I think it looks like a type issue, not an issue with Refine. You are providing |
@BatuhanW Thank you. But I am well aware of the error. Please read the rest of the issue 🥲 Solving the type error is not a problem. I'm saying that it shouldn't exist because the error is incorrect. Or, more specifically, the type is too strict. But I don't want to widen the type. I suggested a way to configure the router without hacking it in, which would solve the issue. To quote:
My component allows a Unless you feel like my use-case of using the |
Hello @datner, In the November release, we improved the types of the import { Link } from "@refinedev/core";
import React, {
type CSSProperties,
forwardRef,
type PropsWithChildren,
type Ref,
} from "react";
type MyCustomLinkProps = PropsWithChildren<{
href: string;
style?: CSSProperties;
}>;
const MyCustomLink = forwardRef(
(
{ children, style, ...props }: MyCustomLinkProps,
ref: Ref<HTMLAnchorElement>,
) => {
return (
<Link<MyCustomLinkProps>
{...props}
ref={ref}
style={{ color: "red", ...style }}
to={props.href}
>
{children}
</Link>
);
},
);
export const PostList: React.FC = () => {
return <MyCustomLink href="/posts">Go to posts</MyCustomLink>;
}; I didn’t fully understand what you want to do or the problem you’re facing. Sorry about that. If you’re still having trouble, could you please explain it in more detail? |
Hi @alicanerdurmaz , You're "looking" in the wrong end here. You're using the existing import routerProvider from "@refinedev/nextjs-router";
routerProvider.Link = MyCustomLink as any
function RootLayout() {
return <Refine routerProvider={routerProvider} ...></Refine>
} What am I suggesting? import makeProvider from "@refinedev/nextjs-router";
const routerProvider = makeProvider({ Link: MyCustomLink }) // no `any` casting required
function RootLayout() {
return <Refine routerProvider={routerProvider} ...></Refine>
} There are many many reasons why you would want this:
And most importantly, leveraging what refinedev has and provides.. This difficulty in customization is prevalent throughout the project, and since I've opened this issue I had to drop refinedev from my project because I found myself just reimplementing the lib in its entirety, benefitting only from the hooks. (which are great!, but they complete the refine suite, they don't make it) I want to use refine, I see the value and I believe that it's fit and ready and miles ahead of the ecosystem. |
Hello again @datner, This is my implementation; please let me know if I'm missing anything. 1. Custom Router ProviderInstead of manipulating the "use client";
import baseRouterProvider from "@refinedev/nextjs-router";
import { forwardRef, type PropsWithChildren } from "react";
export type MyCustomLinkProps = PropsWithChildren<{
to: string;
color: "red" | "green";
[prop: string]: any;
}>;
const MyCustomLink = forwardRef<HTMLAnchorElement, MyCustomLinkProps>(
({ to, color, children, ...props }, ref) => {
return (
<a
{...props}
href={to}
style={{
color,
...props.style,
}}
ref={ref}
>
{children}
</a>
);
},
);
export const routerProvider = {
...baseRouterProvider,
Link: MyCustomLink,
}; 2. Usage of custom routerProvider.LinkWe can use it by importing from "@refinedev/core". "use client";
import { Link } from "@refinedev/core";
export default function IndexPage() {
return (
<div
style={{
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
height: "100vh",
gap: "24px",
}}
>
<Link to="/page-1" color="red">
To Page 1
</Link>
<Link to="/page-2" color="green">
To Page 2
</Link>
</div>
);
} 3. TypeScript support.Since we're using the "use client";
import { Link } from "@refinedev/core";
import type { MyCustomLinkProps } from "./router-provider";
export default function IndexPage() {
return (
<Link<MyCustomLinkProps> to="/page-2" color="pink">
To Page 2
</Link>
);
} Adding a generic type to every |
Hey @datner your desire is acceptable, using your custom link for analytics and all other features. What we can't clarify is, it's already possible currently. What we call router provider is just a simple object. That returns some methods inside it. So you can already implement
Refine is already designed in a way, that it will use router provider's Link method when possible internally. You don't need to change anything else. Closing the issue, feel free to re-open it if you see fit. |
Not sure if the error was related to an earlier bug or not. I've just tested an implementation with a custom Implementation can be something like below: "use client";
import React from "react";
import Link from "next/link";
import routerProviderBase from "@refinedev/nextjs-router";
import type { RouterProvider } from "@refinedev/core";
import type { Url } from "next/dist/shared/lib/router/router";
type Destination = { to: string; href: never } | { href: Url; to?: string };
type LinkProps = React.ComponentProps<NonNullable<RouterProvider["Link"]>> &
Destination;
const MyLink: RouterProvider["Link"] = React.forwardRef<
HTMLAnchorElement,
LinkProps
>(({ to, children, href, ...props }, ref) => {
// any custom requirements can be handled here and will be shared with all `<Link />` usages.
return <Link href={href ?? to} {...props} ref={ref} />;
});
export const routerProvider: RouterProvider = {
...routerProviderBase,
Link: MyLink,
}; Then for the usage in custom made pages, |
Is your feature request related to a problem? Please describe.
Trying to use refine without material ui or antd or anything of the sort for personal taste reasons (and a big reason why I adopted refine).
But I found it quite difficult to actually develop a proper customized solution on the most surface level.. For example it is impossible to sufficiently customize the
AuthPage
without swizzling, but doing the same for theLink
of therouterProvider
is plain impossible in conventional methods 🤷🏻♂️Describe alternatives you've considered
Additional context
No response
Describe the thing to improve
The text was updated successfully, but these errors were encountered: