Skip to content

styled API is removing TS definition from components #37961

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

Closed
2 tasks done
rishavpandey43 opened this issue Jul 14, 2023 · 3 comments
Closed
2 tasks done

styled API is removing TS definition from components #37961

rishavpandey43 opened this issue Jul 14, 2023 · 3 comments
Labels
duplicate This issue or pull request already exists package: system Specific to @mui/system typescript

Comments

@rishavpandey43
Copy link

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

Steps to reproduce 🕹

Link to live example:

Steps:

  1. Open https://codesandbox.io/s/serverless-field-hkw82y?file=/src/App.tsx and wait for the application to load
  2. Or you can open the live app by clicking on https://codesandbox.io/s/serverless-field-hkw82y?file=/src/App.tsx and see the image.
  3. Check the codebase, for the typescript error

Current behavior 😯

I'm styling my component with the styled API provided by Mui and it results in errors in using some of the props like component. If the component is styled by styled API, and props like component="p" is used it's not being recognised by TS and throws an error in the IDE. But as per functionality, it works fine.


Styled Typescript -

const StyledTypography = styled(Typography)({
  color: "inherit"
});

<Typography variant="h6" component="p"> // no error while using component props
Inside Text
</Typography>

<StyledTypography variant="h6" component="p"> // error while using component props
Inside Text
</StyledTypography>

Expected behavior 🤔

Even though any components are styled using styled API their type definition should not behave differently than the actual one.

Below is the screenshot error, I'm getting in my actual file.
Screenshot 2023-07-14 at 3 43 33 PM

You can also check out for live preview - https://hkw82y.csb.app/

Context 🔦

I was creating a Design System and wanted some pre-defined props to be passed after styling the components, like Typography, Button, etc. But whenever I style the components, it loses the TS definition and results in a TS error even though it's correct.

No matter if any component is being styled or not, none of the TS definitions should be lost.

Your environment 🌎

`npx @mui/envinfo`
System:
    OS: macOS 13.3.1
  Binaries:
    Node: 16.18.1 - ~/.nvm/versions/node/v16.18.1/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 8.19.2 - ~/.nvm/versions/node/v16.18.1/bin/npm
  Browsers:
    Chrome: 114.0.5735.198
    Edge: Not Found
    Firefox: Not Found
    Safari: 16.4
  npmPackages:
    @emotion/react: ^11.10.5 => 11.10.5 
    @emotion/styled: ^11.10.5 => 11.10.5 
    @mui/base:  5.0.0-alpha.116 
    @mui/core-downloads-tracker:  5.11.7 
    @mui/icons-material: ^5.11.0 => 5.11.0 
    @mui/lab: ^5.0.0-alpha.79 => 5.0.0-alpha.87 
    @mui/material: ^5.11.7 => 5.11.7 
    @mui/private-theming:  5.8.4 
    @mui/styled-engine:  5.8.0 
    @mui/system:  5.8.5 
    @mui/types:  7.2.3 
    @mui/utils:  5.8.4 
    @mui/x-date-pickers: ^6.9.0 => 6.9.1 
    @types/react:  18.0.14 
    react: ^18.1.0 => 18.2.0 
    react-dom: ^18.1.0 => 18.2.0 
    typescript: ^4.7.3 => 4.7.4
tconfig configuration

{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"declaration": true,
"declarationDir": "types",
"sourceMap": false,
"outDir": "dist",
"strict": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"emitDeclarationOnly": true,
"jsx": "react-jsx",
"baseUrl": "src",
"lib": ["ES2021", "dom"],
"rootDir": "src"
},
"include": ["src"],
"exclude": [
"src//*.spec.ts",
"src/
/.stories.tsx",
"src/**/
.cy.tsx",
"src/theme/"
]
}

@rishavpandey43 rishavpandey43 added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Jul 14, 2023
@mj12albert
Copy link
Member

@rishavpandey43 Thanks for reporting this ~ I can reproduce your issue, is there a specific reason you want to use styled() instead of other styling methods though?

If you are building a design system, the recommended method to do "global" (or design-system-wide) styling is in the theme using style overrides: https://mui.com/material-ui/customization/theme-components/#theme-style-overrides

It's also the recommended way to set default props, e.g. globally change all your h6s to p: https://mui.com/material-ui/react-typography/#changing-the-semantic-element

@mj12albert mj12albert added typescript package: system Specific to @mui/system labels Jul 14, 2023
@mj12albert
Copy link
Member

Duplicate of #37551

@mj12albert mj12albert marked this as a duplicate of #37551 Jul 14, 2023
@github-actions github-actions bot added duplicate This issue or pull request already exists and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Jul 14, 2023
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Jul 14, 2023
@rishavpandey43
Copy link
Author

rishavpandey43 commented Jul 14, 2023

@mj12albert

I cannot change all h6 to p, because this is not what I want. Also, global config can't be done. As I don't want all typography components to inherit this new styling. Only create a new one for specific usage.

I want to create a TruncatedText component, which will truncate the text passed to it.
Also, want to style with the caption variant, but it will return a span tag that does not inherit width/maxWidth properties. So, I need to explicitly say to use the p tag with caption styling. But I do not want to globally override this.

And this is a basic usage, If someone wants to create a wrapper kind of component but does not want to make the global changes these issues should not come. It's a basic usage while working with any UI libraries. There should be flexibility to work, everyone does not have the same needs/requirements. I hope you understand my point here.

Can you suggest any workaround in my case here? I've got the same issue with other components like Button. Any help would be greatly appreciated.

Below is the component I created -

import { useState } from 'react';
import Tooltip from '@mui/material/Tooltip';
import { Typography, TypographyProps, TooltipProps } from '@mui/material';
import { styled } from '@mui/material/styles';

const TruncatedTextTypography = styled(Typography)({
  overflow: 'hidden',
  textOverflow: 'ellipsis',
  width: 'inherit',
  whiteSpace: 'nowrap',
  color: 'inherit',
});

export interface TruncatedTextProps extends TypographyProps {
  /**
   * Text to truncate
   */
  text: React.ReactNode;
  /**
   * if `true`, displays tooltip
   * @default 'false'
   */
  tooltip?: boolean;
  /**
   * Tooltip Props to override, if required.
   */
  TooltipProps?: TooltipProps;
  /**
   * The max-width of text for truncating it.
   * @default 'inherit'
   */
  maxWidth?: TypographyProps['maxWidth'];
}

const TruncatedText = ({
  text,
  tooltip,
  TooltipProps,
  ...rest
}: TruncatedTextProps) => {
  const [isEllipsisActive, setIsEllipsisActive] = useState(false);

  function onMouseOverHandler(e: any) {
    setIsEllipsisActive(e.target?.offsetWidth < e.target?.scrollWidth);
  }
  function onMouseOutHandler() {
    setIsEllipsisActive(false);
  }

  return tooltip ? (
    <Tooltip
      title={text}
      placement="top"
      open={isEllipsisActive}
      {...TooltipProps}
    >
      <TruncatedTextTypography
        {...rest}
        onMouseOver={onMouseOverHandler}
        onMouseOut={onMouseOutHandler}
        component="p"
      >
        {text}
      </TruncatedTextTypography>
    </Tooltip>
  ) : (
    <TruncatedTextTypography component="p" {...rest}>
      {text}
    </TruncatedTextTypography>
  );
};

TruncatedText.defaultProps = {
  tooltip: true,
};

export default TruncatedText;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists package: system Specific to @mui/system typescript
Projects
None yet
Development

No branches or pull requests

2 participants