Search code examples
javascriptreactjssemantic-uistyled-components

Color each selected Dropdown item in react semantic-ui


I have the following jsx code (react-semantic-ui) in render method:

{!this.props.loading &&
      <ControlRow>
        <Grid.Column width={5}>
          <Dropdown
            multiple
            fluid
            selection
            options={myOptions}
            onChange={this.navigateToMyFunc}
          />
...
...

And I am using styled-components to style my elements:

https://github.com/styled-components/styled-components

Unfortunately the only working styling for the Dropdown due to some weird specifics of the environment is indirect from ControlRow:

const ControlsRow = styled(Grid.Row)`
  .ui.multiple.dropdown > .label {
    color: white !important;
    background-color: #2185d0;
  }
`

See also the following thread: Dropdown in semantic ui can't be made of multiple selection type when wrapped with styled-components

Now the Dropdown as you can see is of type multiple. Each selected item should be colored according to the specified in the myOptions options. I can pass myOptions to the ControlRow which will make the array to be accessible in it, but I am not sure how to write the styled-components part of it:

.ui.multiple.dropdown > .label {
    color: white !important;
    background-color: ${props => props.myOptions..??};
  }

I need to also know which item it is to select correct myOptions color. Here is how it looks:

enter image description here

Right now it is just always blue, but I need it to be colored according to each option.

Update

Seems like it is an absent feature in semantic-ui-react - coloring by hex - codes (only a few regular color names allowed) - so I posted this feature to their github:

https://github.com/Semantic-Org/Semantic-UI-React/issues/3889


Solution

  • You don't need to use CSS styling for this. And nothing related to Styled Components needs to be done.

    SemanticUI lets you use a custom render function for labels.

    You would use it like this:

    const renderLabel = (option) => ({
      color: option.color,
      content: option.text,
    })
    
    const myOptions = [
      { text: "option one", color: "blue" },
      { text: "option two", color: "red" },
      // more options...
    ]
    
    // ...
    
    <Dropdown
      multiple
      fluid
      selection
      options={myOptions}
      onChange={this.navigateToMyFunc}
      renderLabel={renderLabel} // here
    />
    

    This assumes that your option objects have a color property and a text property. You'll need to adjust to the shape of your option objects.

    Also, the color property will need to be one of the available label colors in SemanticUI:

    const colors = [
      'red',
      'orange',
      'yellow',
      'olive',
      'green',
      'teal',
      'blue',
      'violet',
      'purple',
      'pink',
      'brown',
      'grey',
      'black',
    ]