Keeping placeholder on react-select
Asked Answered
A

3

5

I have tried everything I can think of, but I cannot prevent the placeholder in react-select from disappearing (I assume changed to display: none because it is no longer in the HTML) when a value is selected for the component.

I've read through both posts with similar issues: https://github.com/JedWatson/react-select/issues/2152 https://github.com/JedWatson/react-select/issues/2143

But haven't found any success

My Styling on the placeholder element is:

valueContainer: base => ({
        overflow: 'visible'
      }),
placeholder: (provided, state) => ({
        ...provided,
        position: "absolute",
        marginTop: '-30px',
        display: 
      state.isFocused || state.isSelected || state.selectProps.inputValue || state.value
      ? 'block'
      : 'block',
      }),

Here is a stackblitz. The end goal is to start the placeholder in the center and move it up to the spot it is here on focus and selection. The problem is, once something is selected, the placeholder disappears. https://stackblitz.com/edit/react-egf4va

Alyworth answered 19/5, 2020 at 16:15 Comment(4)
can you please provide any stackblitz???Doucet
@PALLAMOLLASAI yes, Stackblitz added! Thank you!Alyworth
seems the link you provided just keeps on loading that's it is not loadingDoucet
@PALLAMOLLASAI updated to the edit version of the stackblitz instead of the app. Sometimes the .io is blocked by my browser too. Let me know if that works betterAlyworth
M
10

You need to create a custom ValueContainer, and return the Placeholder in it. Then pass it in property components on the Select component:

import React, { Component } from 'react';

import { render } from 'react-dom';
import Select, {components} from 'react-select';
import Hello from './Hello';
import './style.css';
const { ValueContainer, Placeholder } = components;

const CustomValueContainer = ({ children, ...props }) => {
  return (
    <ValueContainer {...props}>
      <Placeholder {...props} isFocused={props.isFocused}>
        {props.selectProps.placeholder}
      </Placeholder>
      {React.Children.map(children, child =>
        child && child.type !== Placeholder ? child : null
      )}
    </ValueContainer>
  );
};
class App extends Component {
  constructor() {
    super();
    this.state = {
      name: 'React'
    };
  }

  render() {
    const customStyles = {
      container: base => ({
        ...base,
        width: '100%',
      }),
      control: base => ({
        ...base,
        border: 0,
        // This line disable the blue border
        boxShadow: 'none',
        height: '42px',
        borderRadius: '6px'
      }),
      valueContainer: base => ({
        ...base,
        fontSize: '15px',
        top: '3.5px',
        marginLeft: '4px',
        overflow: 'visible'
      }),
      placeholder: base => ({
        ...base,
        fontStyle: 'italic',
        marginTop: '20px',
        position: 'absolute',
      })
    }
    const options = [
     { value: 'chocolate', label: 'Chocolate' },
     { value: 'strawberry', label: 'Strawberry' },
     { value: 'vanilla', label: 'Vanilla' }
   ];
    return (

      <div>
        <Select components={{ValueContainer: CustomValueContainer}}
        options={options} placeholder="Select" isClearable="true" styles={customStyles} className="react-select" classNamePrefix="react-select"/>
      </div>
    );
  }
}

render(<App />, document.getElementById('root'));
Malign answered 19/5, 2020 at 18:17 Comment(1)
Is there a way to handle text overflow for large values? currently implementing this solution, and the placeholder overlaps with my selected value.Cambria
C
1

Fixing float placeholder status "isFocused" in react-select component

const CustomValueContainer = ({ children, ...props }) => {
  return (
    <ValueContainer {...props}>
      <Placeholder {...props} isFocused={props.isFocused}>
        {props.selectProps.placeholder}
      </Placeholder>
      {React.Children.map(children, child =>
        child && child.key !== 'placeholder' ? child : null
      )}
    </ValueContainer>
  );
};

const SingleSelect = () => {
  const [focused, setFocused] = useState(false)
 
    return (
      <Select
        components={{
          ValueContainer: CustomValueContainer
        }}
        onFocus={() => setFocused(true)}
        onBlur={() => setFocused(false)}
        isFocused={focused}
        placeholder="My Cool Label and work Focused"
        styles={{
          placeholder: (base, state)=>({
            ...base,
            position: 'absolute',
            top:
                (state.hasValue || state.selectProps.inputValue || state.selectProps.isFocused) ? '-120%' : '0%',
            transition: 'top 0.2s, font-size 0.2s',
            fontSize:
                (state.hasValue || state.selectProps.inputValue || state.selectProps.isFocused) && 14,
        }),
        }}
      />
    );
  }

Edit react-select: Keep Placeholder (make it float) (forked)

Cohberg answered 2/7, 2022 at 0:14 Comment(0)
T
1

Set the initial state as null instead of an empty object.

Instead of this:

const [defectSelected, setDefectSelected] = useState({});

Use this:

const [defectSelected, setDefectSelected] = useState(null);
Trudge answered 4/6 at 8:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.