Arrow is broken after style changes React-select

Viewed 22

I'm kind of new to React-Select, and after changing its styles the arrow broke, I've spent 3 hours searching for the arrow placement controls to no avail, I've found how to replace it but it doesn't solve the issue, I'm deciding if I should abandon the lib approach and make the dropdown from scratch since the code looks horrendous, I apologize

This is how it currently looks like:

enter image description here

This is how I'm trying to make it behave like:

enter image description here

import Select from "react-select";


interface DropdownV2 {
  color?: string[];
  options: string[];
  name: string;
}

export const DropdownV2: React.FC<DropdownV2> = ({ color, options, name }) => {
  let optionsList: any[] = [];

  let counter = 0;
  options.map((option) => {
    if (color) {
      optionsList.push({ label: option, value: option });
    } else {
      optionsList.push({ label: option, value: option });
    }
  });

  return (
    <Select
      defaultValue={options[0]}
      isMulti={false}
      placeholder={"Choose " + name}
      styles={customStyles}
      options={optionsList}
    />
  );
};
const customStyles = {
  option: (provided: any, state: { isSelected: any }) => ({
    ...provided,
    borderBottom: "1px solid #e9e9e2",
    borderLeft: "1px solid #e9e9e2",
    borderRight: "1px solid #e9e9e2",
    borderRadius: "4px",
    color: state.isSelected ? "#290363" : "#150132",
    backgroundColor: state.isSelected ? "#e9e9e2" : "white",
    cursor: "pointer",
    padding: 20,
  }),
  control: () => ({
    // none of react-select's styles are passed to <Control />
    width: 200,
  }),
  menu: (provided: any) => ({
    ...provided,
    border: "1px solid #e9e9e2",
  }),
  placeholder: (base: any) => ({
    ...base,
    color: "#150132",
    fontFamily: "inter",
    fontStyle: "normal",
    fontWeight: "400",
    fontSize: "14px",
    lineHeight: "24px",
    boxSizing: "border-box",
    border: "1px solid #150132",
    borderRadius: "4px",
    padding: "12px 18px",
    gap: "10px",
  }),
  singleValue: (provided: any, state: { isDisabled: any }) => {
    const opacity = state.isDisabled ? 0.5 : 1;
    const transition = "opacity 300ms";
    const width = "100%";
    const height = "50px";
    const textAlign = "left";
    const fontFamily = "inter";
    const fontStyle = "normal";
    const fontWeight = "400";
    const fontSize = "14px";
    const lineHeight = "24px";
    const boxSizing = "border-box";
    const display = "block";
    const flexDirection = "row";
    const justifyContent = "space-between";
    const alignItems = "center";
    const padding = "12px 18px";
    const gap = "10px";
    const border = "1px solid #150132";
    const borderRadius = "4px";
    const flex = "none";
    const order = "0";
    const alignSelf = "stretch";
    const flexGrow = "0";
    const backgroundPositionX = "244px";
    const marginBottom = "10px";

    return {
      ...provided,
      opacity,
      transition,
      border,
      width,
      height,
      textAlign,
      padding,
      fontFamily,
      fontStyle,
      fontWeight,
      fontSize,
      lineHeight,
      boxSizing,
      display,
      flexDirection,
      justifyContent,
      alignItems,
      gap,
      borderRadius,
      flex,
      order,
      alignSelf,
      flexGrow,
      backgroundPositionX,
      marginBottom,
    };
  },
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

1 Answers

I provide a custom DropdownIndicator to my react-select.

import React from 'react';
import { components } from 'react-select';
import classnames from 'classnames';
import Icon from '../../../../components/Icon.component';
import styles from '../Select.module.scss';

const DropdownIndicator = ({
  className,
  selectProps,
  ...props
}) => (
  <components.DropdownIndicator
    {...props}
    className={classnames(styles.selectIndicator, className)}
    selectProps={selectProps}
  >
    <Icon glyph={`caret-${selectProps.menuIsOpen ? 'up' : 'down'}`} />
  </components.DropdownIndicator>
);

You can also change base styling of your component using a custom styles function

export const dropdownIndicatorStyles = (base, state) => {
  const { isDisabled } = state;
  return {
    ...base,
    ...(isDisabled && { display: 'none' }),
  };
};

That I then pass it all in to my Select

import DropdownIndicator from './DropdownIndicator';
import {dropdownIndicatorStyles} from './styleFunctions';
// ...
const {components, styles} = useMemo(() => ({
  components: {
    DropdownIndicator
  },
  styles: {
    dropdownIndicator: dropdownIndicatorStyles
  }
}), []);
// ...
<Select components={components} styles={styles} {...otherProps} />
Related