swordev/suid

Forwarding props doesn't supporting by styled

Closed this issue · 2 comments

Take for instance this example from mui library.
It does wrapping Drawer and AppBar with styled components. Also uses open prop to add/remove specific stylings.

Mui styled use @emotion/styled to wrap Components. I see that you @juanrgm avoided using this lib.
But do you have any plans to allow passing props. Let me put here a piece of code to explain when we need it.

const AppBar = styled(MuiAppBar, {
  shouldForwardProp: (prop: MuiAppBarProps) => prop !== 'open',
})<AppBarProps>(({ theme, open }) => {
  return {
    zIndex: theme.zIndex.drawer + 1,
      transition: theme.transitions.create(['width', 'margin'], {
    easing: theme.transitions.easing.sharp,
    duration: theme.transitions.duration.leavingScreen,
  }),
  ...(open && {
    marginLeft: drawerWidth,
    width: `calc(100% - ${drawerWidth}px)`,
    transition: theme.transitions.create(['width', 'margin'], {
      easing: theme.transitions.easing.sharp,
      duration: theme.transitions.duration.enteringScreen,
    }),
  }),
  }
})

const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open' })(
  ({ theme, open }) => ({
    '& .MuiDrawer-paper': {
      position: 'relative',
      whiteSpace: 'nowrap',
      width: drawerWidth,
      transition: theme.transitions.create('width', {
        easing: theme.transitions.easing.sharp,
        duration: theme.transitions.duration.enteringScreen,
      }),
      boxSizing: 'border-box',
      ...(!open && {
        overflowX: 'hidden',
        transition: theme.transitions.create('width', {
          easing: theme.transitions.easing.sharp,
          duration: theme.transitions.duration.leavingScreen,
        }),
        width: theme.spacing(7),
        [theme.breakpoints.up('sm')]: {
          width: theme.spacing(9),
        },
      }),
    },
  }),
)

(Source code is here)

Even if you don't want to use @emotion/styled probably it's possible to provide compatibility with styled from mui and also accept shouldForwardProp function in the option object and/or additionally not remove passed props from Component.

P.S. Also you might have seen this import path updates and probably for that reason created system/src/styled copy. Do you plan to migrate the solution to a single point? (@suid/system/styled)

Found out that possible to pass open via options.props.open. Only thing @suid/codemod doesn't convert it automatically.

Mean, this code works:

const AppBar = styled(MuiAppBar)<AppBarProps>(({ theme, props }) => {
  return {
    zIndex: theme.zIndex.drawer + 1,
      transition: theme.transitions.create(['width', 'margin'], {
    easing: theme.transitions.easing.sharp,
    duration: theme.transitions.duration.leavingScreen,
  }),
  ...(props.open && {
    marginLeft: drawerWidth,
    width: `calc(100% - ${drawerWidth}px)`,
    transition: theme.transitions.create(['width', 'margin'], {
      easing: theme.transitions.easing.sharp,
      duration: theme.transitions.duration.enteringScreen,
    }),
  }),
  }
})

const Drawer = styled(MuiDrawer)(
  ({ theme, props }) => ({
    '& .MuiDrawer-paper': {
      position: 'relative',
      whiteSpace: 'nowrap',
      width: drawerWidth,
      transition: theme.transitions.create('width', {
        easing: theme.transitions.easing.sharp,
        duration: theme.transitions.duration.enteringScreen,
      }),
      boxSizing: 'border-box',
      ...(!props.open && {
        overflowX: 'hidden',
        transition: theme.transitions.create('width', {
          easing: theme.transitions.easing.sharp,
          duration: theme.transitions.duration.leavingScreen,
        }),
        width: theme.spacing(7),
        [theme.breakpoints.up('sm')]: {
          width: theme.spacing(9),
        },
      }),
    },
  }),
)

You can use skipProps:

skipProps?: string[];