Search code examples
javascriptcssreactjsstyled-componentsinline-styles

Styling a nested styled-component from an outer one


Using styled-components, I am trying to style a nested <Input /> component that I have created, which is being used within a different component that has a dropdown appear when typing. I need to add padding-left: 3rem to this nested input but I cannot access it from the component <Dropdown />.

<Dropdown
  options={options}
/>

The above is imported where I need it. I need to access the below input from the above <Dropdown />.

<div>
  <Input {...props}/> // I need to edit the padding in this component
  // rendered input unique to this new component would go here
</div>

The above <Input /> is imported from another component which is used in all instances where I require an input.

export const Dropdown = styled(DropDown)`
  padding-left: 3rem !important;
`;

The component works fine but this fails to affect the inner padding of the Input that I need to target.

What do I do?


Solution

  • From what you've said, I'd suggest that the dependency of padding the Input component is with your Dropdown (which you seem to realise already).

    Therefore you'd be better off having that "unqiue" styling coupled with your Dropdown component via a wrapping styled component within it.

    The following example is crude (and by no means complete or working), but hopefully it illustrates how the ownership of the padding-left should be within the Dropdown and not a sporadic styled component floating some where else in your code base.

    ./Input/Input.jsx

    const Input = ({ value }) => (
      <input value={value} />
    );
    

    ./Dropdown/styled.js

    const InputWrapper = styled.div`
      position: relative;
      padding-left: 3rem !important; /* Your padding */
    `;
    
    const Icon = styled.div`
      position: absolute;
      top: 0;
      left: 0;
      width: 3rem;
      height: 3rem;
      background: blue;
    `;
    
    const Menu = styled.ul`/* whatever */`;
    

    ./Dropdown/Dropdown.jsx

    import Input from '...';
    import { InputWrapper, Icon, Menu } from './styled';
    const Dropdown = ({ options }) => (
      <div>
        <InputWrapper>
          <Icon />
          <Input value={'bleh'} />
        </InputWrapper>
        <Menu>{options}</Menu>
      </div>
    );
    

    This setup will promote reusable self-contained components.