Closed Klynger closed 2 years ago
Hi @Klynger, thanks for bringing this up.
There was a regression introduced in v2.1.2
that removed default support for common props like className
, onClick
, etc.
While the change technically is more correct (<PrismicLink>
can render any component, including ones that don't support className
or onClick
), it is not practically usable.
I see where you're going with suggesting a hook since it gives you the PrismicLink-specific props needed to pass to your own component. That being said, I don't think a hook is the best solution for this issue. Assuming we fix the type issue and now have <PrismicLink>
and usePrismicLink()
, the hook would almost always be less ergonomic. You effectively would need to use the hook and then manually pass that data to some other component.
If I'm misunderstanding the request, please let me know. 🙂
Here is what I think we can do to remedy this issue:
<a>
. This includes props like className
, onClick
, and anything provided by React.AnchorHTMLAttributes
. This would solve type issues for most users.<PrismicLink>
is configured to use something that works differently than <a>
(for example, it does not accept className
), there should be a standard way to override it.<PrismicLink>
implementation built off <PrismicLink>
provided by @prismicio/react
.Rather than import <PrismicLink>
from @prismicio/react
, you would import your custom component instead.
<PrismicLink>
using global configuration and TypeScript 4.7 Instantiation Expressions(Note: This assumes PrismicLink is configured globally via <PrismicProvider>
to render <Link>
for internal links.)
You can take advantage of TypeScript 4.7's Instantiation Expressions feature to define a custom instance of <PrismicLink>
specific to your internal and external link React components.
react-router-dom
's <Link>
is used as an example below, but this could be any component.
// src/components/PrismicLink.tsx
import { PrismicLink as PrismicLinkBase } from "@prismicio/react";
import { Link } from "react-router-dom";
export const PrismicLink = PrismicLinkBase<typeof Link>;
TypeScript 4.7 is currently in beta, and we cannot expect users to always be using the latest version of TypeScript. As such, this solution will not apply to everyone.
<PrismicLink>
using global configuration and type parameters in JSX(Note: This assumes PrismicLink is configured globally via <PrismicProvider>
to render <Link>
for internal links.)
Similar to the above solution, a custom instance of <PrismicLink>
can be created with the correct generic. This does not rely on bleeding-edge TypeScript features.
// src/components/PrismicLink.tsx
import {
PrismicLink as PrismicLinkBase,
PrismicLinkProps,
} from "@prismicio/react";
import { Link } from "react-router-dom";
export const PrismicLink = (props: PrismicLinkProps<typeof Link>) => (
<PrismicLinkBase<typeof Link> {...props} />
);
<PrismicLink>
using non-global configuration(Note: This assumes PrismicLink is not configured globally via <PrismicProvider>
to render <Link>
for internal links.)
Alternatively, a custom PrismicLink instance could be configured by passing the internal/external React components directly. This ignores any global configuration provided to <PrismicProvider>
.
// src/components/PrismicLink.tsx
import {
PrismicLink as PrismicLinkBase,
PrismicLinkProps,
} from "@prismicio/react";
import { Link } from "react-router-dom";
export const PrismicLink = (props: PrismicLinkProps<typeof Link>) => (
<PrismicLinkBase internalComponent={Link} {...props} />
);
If you have any questions or suggestions, please feel free to reply here. Thanks! 🙂
I'm going to close this issue since we won't be adding a usePrismicLink()
hook at this time. I recommend using one of the three strategies shown above when using TypeScript with a link component that diverges from <a>
's inherit props.
If anyone feels strongly about creating a usePrismicLink()
hook here, please feel free to comment here and we can discuss further. Thanks!
Is your feature request related to a problem? Please describe.
PrismicLink
doesn't work very well on Typescript. Given the complexity of the type, you can't even pass aclassName
to the component without having to disable Typescript. But at the same time, it is a handy component. So it would be nice to have a way to re-use its logic.Describe the solution you'd like
We could have a hook like
const anchorProps = usePrismicLink({ field, document, href, ... })
Describe alternatives you've considered
PrismicLink
type and remove the@ts-expect-error
(MaterialUI has some solutions in their components to fix this issue. But yet, it is very complex)Additional context
Even if we find a way to fix the
PrismicLInk
type, I think that we should have a hook with the logic of this component