Home > OS >  How to customize react-select singleValue field with styled-components
How to customize react-select singleValue field with styled-components

Time:08-24

I made a custom select using react-select and styled it with styled-components. I was able to style everything (control, menu, option, placeholder) using the selectors and change things dynamically via props. I should also be able to target the singleValue field according to the docs but it won't work. I want to be able to control the color of the text dynamically. As soon as I select an option, the text changes to black and that's it. So if I'm in dark mode, I can't see the text. I tried targeting different fields to see if that worked but no.

import styled from 'styled-components';
import ReactSelect from 'react-select';

export const CustomSelect = styled(ReactSelect)`
  width: 30rem;
  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.1);
  border-radius: 0.5rem;
 

  & .Select__control {
    height: 6rem;
    border: none;
    font-family: 'Nunito Sans';
    font-size: 1.5rem;
    font-weight: 600;    
    background-color: ${(props) =>
      props.isDark ? 'hsl(209, 23%, 22%)' : 'hsl(0, 0%, 100%)'};     
  }

  & .Select__option {
    font-size: 1.5rem;
    font-weight: 600;
    color: ${props => props.isDark? 'hsl(0, 0%, 100%)': 'hsl(200, 15%, 8%)'};
    &:hover{
      background-color: grey;
    }
  }

  & .Select__menu {
    font-family: 'Nunito Sans';
    background-color: ${(props) =>
      props.isDark ? 'hsl(209, 23%, 22%)' : 'hsl(0, 0%, 100%)'};
  }

  & .Select__placeholder {
    font-size: 1.5rem;
    color: ${props => props.isDark? 'hsl(0, 0%, 100%)': 'hsl(200, 15%, 8%)'}; 
  }  

  & .Select__inputValue {    
    color: ${props => props.isDark? 'hsl(0, 0%, 100%)': 'hsl(200, 15%, 8%)'};
  }

  & .Select__ValueContainer {    
    color: ${props => props.isDark? 'hsl(0, 0%, 100%)': 'hsl(200, 15%, 8%)'};  }  
 

  & .Select__singleValue {  
    font-size: 5rem;
    color: ${props => props.isDark? 'hsl(0, 0%, 100%)': 'hsl(200, 15%, 8%)'};
  }

  
`;

I can use custom styles as shown to target the singleValue that way but then I can't use my props to make it dynamic so I had to choose a text color that would work for both. Definitely not ideal. It seems crazy that everything would work so easily except this one field. Is there something I'm missing here.

import { CustomSelect } from './filter-dropdown.styles';

const Filters = ({ isDark, options }) => {


  const customStyles =  {
    singleValue: (provided, state) => ({
      ...provided,
      color: 'grey',
    })    
  }
  
  return (
    <CustomSelect
      classNamePrefix={'Select'}
      isDark={isDark}
      options={options}
      placeholder="Filter by region..."     
      styles={customStyles}
    />
  );
};

export default Filters;

CodePudding user response:

Update: I was wrong on not being able to pass props to the custom styles. I must have missed it in the docs. I still can't style the singleValue using the selector but I can set a conditional in a different prop and set the value of color that way. Hope this saves someone out there some time.

import { CustomSelect } from './filter-dropdown.styles';

const Filters = ({ isDark, options }) => {

  const customStyles =  {
    singleValue: (provided, state) => ({
      ...provided,
      color: state.selectProps.changeInput,
    })    
  }

  return (
    <CustomSelect
      classNamePrefix={'Select'}
      isDark={isDark}
      options={options}
      placeholder="Filter by region..."    
      changeInput={isDark? 'hsl(0, 0%, 100%)' : 'hsl(200, 15%, 8%)'} 
      styles={customStyles}
    />
  );
};

export default Filters;

CodePudding user response:

For the case to do dynamic styling in styled-components, I would recommend using Theme Provider from styled-components library and pass to it your selected theme like that :

<ThemeProvider theme={theme === 'dark' ? darkTheme : lightTheme}>
</ThemeProvider>

theme variable could be state in redux or in context, theme object should contain the theme attribs and you can use it like so in react component :

const Example = styled.div`
  background-image: url(${({ theme }) => theme.backgroundImage});
`;
  • Related