-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
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
[Link] component expects ref of type HTMLSpanElement #24901
Comments
@qlonik Do you have a reproduction? |
edited the original comment to add the example with the type error |
I meant something we could run locally. Here we go: https://codesandbox.io/s/strange-wright-083td?file=/src/App.tsx. Maybe a fix like this? diff --git a/packages/material-ui/src/Link/Link.d.ts b/packages/material-ui/src/Link/Link.d.ts
index a05b381d63..e933974967 100644
--- a/packages/material-ui/src/Link/Link.d.ts
+++ b/packages/material-ui/src/Link/Link.d.ts
@@ -73,7 +73,7 @@ declare const Link: OverridableComponent<LinkTypeMap>;
export type LinkClassKey = keyof NonNullable<LinkTypeMap['props']['classes']>;
export type LinkBaseProps = Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'color'> &
- DistributiveOmit<TypographyProps, 'children' | 'component' | 'color' | 'variant'>;
+ DistributiveOmit<TypographyProps<'a'>, 'children' | 'component' | 'color' | 'variant'>;
export type LinkProps<
D extends React.ElementType = LinkTypeMap['defaultComponent'], or we can reproduce the ButtonBase approach: diff --git a/packages/material-ui/src/Link/Link.d.ts b/packages/material-ui/src/Link/Link.d.ts
index a05b381d63..88636b9315 100644
--- a/packages/material-ui/src/Link/Link.d.ts
+++ b/packages/material-ui/src/Link/Link.d.ts
@@ -1,60 +1,66 @@
import * as React from 'react';
-import { DistributiveOmit } from '@material-ui/types';
import { SxProps } from '@material-ui/system';
-import { OverridableComponent, OverrideProps } from '../OverridableComponent';
+import { OverridableComponent, OverrideProps, OverridableTypeMap } from '../OverridableComponent';
import { Theme } from '../styles';
-import { TypographyProps } from '../Typography';
+import { TypographyProps, TypographyTypeMap } from '../Typography';
-export interface LinkTypeMap<P = {}, D extends React.ElementType = 'a'> {
- props: P &
- LinkBaseProps & {
- /**
- * The content of the component.
- */
- children?: React.ReactNode;
- /**
- * Override or extend the styles applied to the component.
- */
- classes?: {
- /** Styles applied to the root element. */
- root?: string;
- /** Styles applied to the root element if `underline="none"`. */
- underlineNone?: string;
- /** Styles applied to the root element if `underline="hover"`. */
- underlineHover?: string;
- /** Styles applied to the root element if `underline="always"`. */
- underlineAlways?: string;
- /** Styles applied to the root element if `component="button"`. */
- button?: string;
- /** Pseudo-class applied to the root element if the link is keyboard focused. */
- focusVisible?: string;
- };
- /**
- * The color of the link.
- * @default 'primary'
- */
- color?: TypographyProps['color'];
- /**
- * The system prop that allows defining system overrides as well as additional CSS styles.
- */
- sx?: SxProps<Theme>;
- /**
- * `classes` prop applied to the [`Typography`](/api/typography/) element.
- */
- TypographyClasses?: TypographyProps['classes'];
- /**
- * Controls when the link should have an underline.
- * @default 'hover'
- */
- underline?: 'none' | 'hover' | 'always';
- /**
- * Applies the theme typography styles.
- * @default 'inherit'
- */
- variant?: TypographyProps['variant'];
+
+export interface ExtendTypographyTypeMap<M extends OverridableTypeMap> {
+ props: M['props'] & Omit<TypographyTypeMap['props'], 'classes'>;
+ defaultComponent: M['defaultComponent'];
+}
+
+export type LinkTypeMap<P = {}, D extends React.ElementType = 'a'> = ExtendTypographyTypeMap<{
+ props: P & {
+ /**
+ * The content of the component.
+ */
+ children?: React.ReactNode;
+ /**
+ * Override or extend the styles applied to the component.
+ */
+ classes?: {
+ /** Styles applied to the root element. */
+ root?: string;
+ /** Styles applied to the root element if `underline="none"`. */
+ underlineNone?: string;
+ /** Styles applied to the root element if `underline="hover"`. */
+ underlineHover?: string;
+ /** Styles applied to the root element if `underline="always"`. */
+ underlineAlways?: string;
+ /** Styles applied to the root element if `component="button"`. */
+ button?: string;
+ /** Pseudo-class applied to the root element if the link is keyboard focused. */
+ focusVisible?: string;
};
+ /**
+ * The color of the link.
+ * @default 'primary'
+ */
+ color?: TypographyProps['color'];
+ /**
+ * The system prop that allows defining system overrides as well as additional CSS styles.
+ */
+ sx?: SxProps<Theme>;
+ /**
+ * `classes` prop applied to the [`Typography`](/api/typography/) element.
+ */
+ TypographyClasses?: TypographyProps['classes'];
+ /**
+ * Controls when the link should have an underline.
+ * @default 'hover'
+ */
+ underline?: 'none' | 'hover' | 'always';
+ /**
+ * Applies the theme typography styles.
+ * @default 'inherit'
+ */
+ variant?: TypographyProps['variant'];
+ };
defaultComponent: D;
-}
+}>;
/**
*
@@ -72,9 +78,6 @@ declare const Link: OverridableComponent<LinkTypeMap>;
export type LinkClassKey = keyof NonNullable<LinkTypeMap['props']['classes']>;
-export type LinkBaseProps = Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'color'> &
- DistributiveOmit<TypographyProps, 'children' | 'component' | 'color' | 'variant'>;
-
export type LinkProps<
D extends React.ElementType = LinkTypeMap['defaultComponent'],
P = {} @eps1lon A preference? Both will allow removing the any in the Next.js Link integration: diff --git a/docs/src/modules/components/Link.tsx b/docs/src/modules/components/Link.tsx
index 7ec2d025e2..3f1b732f7c 100644
--- a/docs/src/modules/components/Link.tsx
+++ b/docs/src/modules/components/Link.tsx
@@ -79,14 +79,14 @@ const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(function Link(props,
if (isExternal) {
if (noLinkStyle) {
- return <a className={className} href={href as string} ref={ref as any} {...other} />;
+ return <a className={className} href={href as string} ref={ref} {...other} />;
}
return <MuiLink className={className} href={href as string} ref={ref} {...other} />;
}
if (noLinkStyle) {
- return <NextLinkComposed className={className} ref={ref as any} to={href} {...other} />;
+ return <NextLinkComposed className={className} ref={ref} to={href} {...other} />;
}
let linkAs = linkAsProp || (href as string); |
We have a non-minimal repro here: VulcanJS/vulcan-next#114 (exact commit: VulcanJS/vulcan-next@3de85da) Update: first, current demo implementation (here) seems to pass Update 2: gave it another shot https://github.com/VulcanJS/vulcan-next/blob/d2fb4ac5206d8076f64db51472325799bc6d7b37/packages/%40vulcanjs/next-material-ui/components/Link.tsx |
Is there any update on this? |
Sure, looks like no one is working on it. |
Current Behavior 😯
The property
ref
passed toLink
component is expected to be of typeHTMLSpanElement
instead ofHTMLAnchorElement
Expected Behavior 🤔
Not sure. Shouldn't it be
HTMLAnchorElement
?Reproduction
The reproduction code is based on the example 'nextjs-with-typescript'. In that example, there is Link component wrapping around Next Link and available as
NextLinkComposed
. When I define another component using forwardRef and use eithera
orNextLinkComposed
and pass-through properties from MuiLink, then I get the type error on ref property of botha
andNextLinkComposed
.Type error:
Context 🔦
I was digging through the code and it appears that it is coming from where
LinkBaseProps
usesTypographyProps
here. Typography props use default element in this case, which is span. It should get fixed ifHTMLAnchorElement
is explicitly passed toTypographyProps
withTypographyProps<HTMLAnchorElement>
.Additionally, it seems that this fix would remove the need to pass
any
type in these spots:Your Environment 🌎
`npx @material-ui/envinfo`
tsconfig.json
The text was updated successfully, but these errors were encountered: