Search code examples
reactjsmaterial-uistorybook

Warning: Received `true` for a non-boolean attribute `shrink`. when trying to use shrink prop on a mui 5.x inputLabel on storybook react


I am using the following:

  • mui 5.2.7
  • @mui/styles 5.2.5
  • @emotion/react 11.7.1
  • @emotion/styled 11.6.0
  • react 17.0.2
  • storybook 6.5.10

and I am trying to reproduce a case where a mui InputLabel component has its label shrunk on the top when passing a shrink prop in a single select component. Here is an excerpt of the custom mui select component

 <FormControl
      {...rest}
      className={`${classes.formControl} ${className}`}
      error={error}
      variant="standard"
    >
      {label && (
        <InputLabel htmlFor={inputId} shrink={shrink} {...inputLabelProps}>
          {label}
        </InputLabel>
      )}
      <Select
        input={<Input id={inputId} {...inputProps} />}
        onChange={handleChange}
        renderValue={renderValue}
        value={value}
      >

In tests and in the actual app everything works as expected but in storybook I receive the following error

react-dom.development.js:67 Warning: Received true for a non-boolean attribute shrink.

If you want to write it to the DOM, pass a string instead: shrink="true" or shrink={value.toString()}.

but the error makes no sense because the shrink prop is declared as boolean and being passed like this both in app and unit tests.

and the input label is not shrunk when passing the relevant prop.

Here it the storybook code

function SingleTemplate(args) {
  const [value, setValue] = useState("");

  return (
    <Box width={125}>
      <EsaSelect label={label} onChange={setValue} options={options} value={value} {...args} />
    </Box>
  );
}

export const SingleSelectShrink = SingleTemplate.bind({});
SingleSelectShrink.args = { shrink: true };

I did not manage to reproduce the issue using this codesandbox. Actually there it works as expected but the configuration seems simpler than my local repository and it is a simplified version


Solution

  • I finally found that we might have an architecture problem in the way we render our Select components. At the moment we render 4 different components, a custom SingleSelect, a custom MultiSelect, a custom SingleAutocompleteSelect and a custom MutliAutocompelteSelect. These 4 components are over abstracted in one component. That means that if we want to invoke either of these 4 we call only one and then pass the desired props. Some are common but others are specific. However to achieve this we have some component specific props and then spreading the rest everywhere. This results to props of one component to end up in the props ofanother component which might not have the same API. Because we are using javascript and not typescript this works but it seems that storybook understands this differentiation and fires errors.

    So what we do is something like this:

    abstracted MySelect component:

    if (someProp1 || someProp2) {
        return someProp3 ? (
          <AutocompleteMultiSelect
            {...rest}
            cutomProp1={prop1}
            customProp2={prop2}
          />
        ) : (
          <AutocompleteSelect {...rest} customProp3={prop3} />
        );
      }
      return anotherProp ? <MultiSelect {...rest} /> : <SingleSelect {...rest} />;
    

    }