compiled icon indicating copy to clipboard operation
compiled copied to clipboard

Props injected with clone element do not get forward onto a component that uses CSS prop

Open v1rtl opened this issue 5 years ago • 3 comments

Describe the bug

Whenever an HTML element has a css prop within a Link component the link doesn't get created and instead becomes static text.

To Reproduce

import React from 'react'
import Link from 'next/link'
import { css } from '@compiled/react'

// ...
  return <Link href="/" passHref><a css={css`color: red`}>link</a></Link> 
// ..

Expected behavior Styles should apply and href should be passed to the <a> element (like with Emotion)

Additional context

Temporary solution is to define styles for a in the container, like this:

<div css={css`a { color: red }`}>
  <Link href="/" passHref>
    <a>link</a>
  </Link>
</div>

.babelrc:

{
  "presets": ["next/babel"],
  "plugins": ["@babel/plugin-syntax-jsx"]
}

next.config.js:

module.exports = {
  webpack: (config) => {
    config.module.rules.push({
      test: /\.(js|ts|tsx)$/,
      exclude: /node_modules/,
      use: ['@compiled/webpack-loader']
    })

    return config
  },
  future: {
    webpack5: true
  }
}
  • Next.js version: 10.1.3
  • Compiled version: 0.6.10

v1rtl avatar Apr 12 '21 15:04 v1rtl

Another workaround is to wrap the child element of Link with React.forwardRef:

import React from 'react';
import { styled } from '@compiled/react';
import Link from 'next/link';

const Anchor = styled.a`
  color: red;
`;

const primary = {
  textDecoration: 'underline',
};

const StyledLink = React.forwardRef(({ variant, className, style, ...anchorProps }, ref) => {
  return (
    <Anchor {...anchorProps} style={style} className={className} css={[variant === 'primary' && primary]} ref={ref} />
  );
});

const Component = () => (
  <Link href="/" passHref>
    <StyledLink variant="primary" />
  </Link>
);

skoob13 avatar May 08 '21 12:05 skoob13

Another good practice with next is to create a custom link component that bundles Link with a, handling any logic you use in your app, including deciding where to send style/className props. Then style that component. The bonus is that you don't have to constantly be wrapping your links with Links.

mikestopcontinues avatar Jun 23 '21 09:06 mikestopcontinues

Thanks for raising this! Would you be interested in contributing a fix? Could be fun to dip your toes in.

itsdouges avatar Dec 01 '21 07:12 itsdouges