1

Using emotion/styled v11

Background

In order to change the default type of all buttons in my project, I wrote a wrapper component WrappedButton for the HTML <button>. In order to allow this new WrappedButton component to be styled (styled(WrappedButton)({...})), I needed to wrap my WrapperButton with styled.

Problem

When trying to set the aria-label attribute on my WrappedButton I get the console error Using kebab-case for css properties in objects is not supported. Did you mean ariaLabel?

When I change aria-label to ariaLabel, there's no error, but then the label is not set.

Question

How can I get rid of the error while keeping my use cases intact?

Code

WrappedButton


type ButtonPropsType = React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>;
type RefType = ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;

/** 
  * This is needed in order to allow the button to be styled by
  * emotion (`styled(WrappedButton)({...})`
 **/
const StylableButton = styled.button({}, (props: ButtonPropsType) => ({
    ...(props as any),
}));

// change default `type` from `submit` to `button`
const defaultProps: ButtonPropsType = {
    type: 'button',
};

export const WrappedButton = forwardRef((props: ButtonPropsType, ref: RefType) => {
    return <StylableButton {...defaultProps} ref={ref} {...props} />;
});
WrappedButton.displayName = 'Button';

Usage

test('A', () => {
    render(<WrappedButton aria-label='foo'>a</WrappedButton>);
});

What I've tried:

shouldForwardProp

const StylableButton = styled('button',
  {
  //shouldForwardProp: (prop) => (prop !== 'aria-label')
  }
)({}, (props: ButtonPropsType) => ({
    shouldForwardProp: (prop) => (prop !== 'aria-label'),
    ...(props as any),
}));
DarkTrick
  • 2,447
  • 1
  • 21
  • 39
  • Does this help somehow? https://stackoverflow.com/questions/48083705/how-to-add-an-aria-attribute-to-a-styled-component I just tried in the styled components interactive demo and added an aria attribute, there was no error or warning. – Andy Nov 24 '22 at 12:51
  • It seems like the `attrs` functionality was removed :( – DarkTrick Nov 27 '22 at 03:55
  • Seems to be working on this sandbox: https://stackblitz.com/edit/react-ts-hqzqfk?file=App.tsx – vighnesh153 Nov 27 '22 at 04:21
  • @vighnesh153 I'm not sure if you're referring to `attrs`, but your solution indeed worked. It seems like `StylableButton` can be defined as `const StylableButton = styled.button()` (testing at the moment) Thank you for your help! – DarkTrick Nov 27 '22 at 06:39

1 Answers1

1

Figured out from vighnesh153's comment:

The solution is to remove mentioning of props from the definition of StylableButton:

const StylableButton = styled.button();

Apparently, everything works as expected already behind the scenes without mentioning the props.

Here's the full source:

type ButtonPropsType = React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>;
type RefType = ((instance: HTMLButtonElement | null) => void) | React.RefObject<HTMLButtonElement> | null | undefined;

/** 
  * This is needed in order to allow the button to be styled by
  * emotion (`styled(WrappedButton)({...})`
 **/
const StylableButton = styled.button();

// change default `type` from `submit` to `button`
const defaultProps: ButtonPropsType = {
    type: 'button',
};

export const WrappedButton = forwardRef((props: ButtonPropsType, ref: RefType) => {
    return <StylableButton {...defaultProps} ref={ref} {...props} />;
});
WrappedButton.displayName = 'Button';
DarkTrick
  • 2,447
  • 1
  • 21
  • 39