Mum*_*wiz 6 reactjs react-select
我正在尝试使用 React-Select 选项创建自定义选择。我希望我的搜索不在控制框中,而是在菜单中。我试过这个:
import React from "react";
import Select, { components } from "react-select";
import { colourOptions, groupedOptions } from "./docs/data";
const MenuList = props => {
return (
<components.MenuList {...props}>
<components.Input {...props} />;
{props.selectProps.inputValue.length > 1 ? props.children : ""}
</components.MenuList>
);
};
export default () => (
<Select
defaultValue={colourOptions[1]}
options={groupedOptions}
components={{ MenuList }}
/>
);
Run Code Online (Sandbox Code Playgroud)
问题是我收到一条错误消息
Uncaught Invariant Violation: input is a void element tag and must neither have children nor use dangerouslySetInnerHTML
Run Code Online (Sandbox Code Playgroud)
我猜反应选择components.Input是在input标签内渲染另一个 div或类似的东西。有没有人知道如何做到这一点?
它的灵感来自https://codesandbox.io/embed/m75wlyx3oy解决方案。
默认值与首先在下拉列表中显示选项MenuList进行交换。CustomMenuWithInput选项列表由 提供{ props.children }。最后一个选项下方是输入字段。
onFocus={onMenuInputFocus}防止关闭输入中键入的每个字母的下拉菜单。
const CustomMenuWithInput = ({ selectProps: { onMenuInputFocus }, ...props }) => {
const [value, setValue] = useState('')
return (
<div>
{ props.children }
<input
id='add-option'
label='Add option'
placeholder='option'
autoCorrect='off'
autoComplete='off'
spellCheck='false'
type='text'
value={value}
onChange={(e) => setValue(e.target.value)}
onMouseDown={(e) => {
e.stopPropagation()
e.target.focus()
}}
onFocus={onMenuInputFocus}
/>
</div>
)
}
const SelectView = ({ onChange }) => {
const [inputValue, setInputValue] = useState('')
const [isFocused, setIsFocused] = useState(false)
return (
<Select
id=''
label={'List'}
options={list}
onChange={opt => {
onChange(opt.value, opt)
setIsFocused(false)
}}
onInputChange={setInputValue}
onMenuInputFocus={() => setIsFocused(true)}
inputValue={inputValue}
placeholder='Select...'
components={{
MenuList: CustomMenuWithInput,
}}
isSearchable
{...{
menuIsOpen: isFocused || undefined,
isFocused: isFocused || undefined
}}
/>
)
}
Run Code Online (Sandbox Code Playgroud)
您应该通过以下部分的文档中的建议来启发自己Advanced: https: //react-select.com/advanced。
我在 CodeSandbox 中重新创建了一个实时示例,以便您可以看到它的实际效果并使用它。但主要思想是将原始Select元素嵌入到一些受控元素中,然后编辑你的样式Select,使其感觉像一个单一的MenuList。
class PopoutExample extends Component<*, State> {
state = { isOpen: false, value: undefined };
toggleOpen = () => {
this.setState(state => ({ isOpen: !state.isOpen }));
};
onSelectChange = value => {
this.toggleOpen();
this.setState({ value });
};
render() {
const { isOpen, value } = this.state;
return (
<Dropdown
isOpen={isOpen}
onClose={this.toggleOpen}
target={
<Button
iconAfter={<ChevronDown />}
onClick={this.toggleOpen}
isSelected={isOpen}
>
{value ? `State: ${value.label}` : "Select a State"}
</Button>
}
>
<Select
autoFocus
backspaceRemovesValue={false}
components={{ DropdownIndicator, IndicatorSeparator: null }}
controlShouldRenderValue={false}
hideSelectedOptions={false}
isClearable={false}
menuIsOpen
onChange={this.onSelectChange}
options={stateOptions}
placeholder="Search..."
styles={selectStyles}
tabSelectsValue={false}
value={value}
/>
</Dropdown>
);
}
}
// styled components
const Menu = props => {
const shadow = "hsla(218, 50%, 10%, 0.1)";
return (
<div
css={{
backgroundColor: "white",
borderRadius: 4,
boxShadow: `0 0 0 1px ${shadow}, 0 4px 11px ${shadow}`,
marginTop: 8,
position: "absolute",
zIndex: 2
}}
{...props}
/>
);
};
const Blanket = props => (
<div
css={{
bottom: 0,
left: 0,
top: 0,
right: 0,
position: "fixed",
zIndex: 1
}}
{...props}
/>
);
const Dropdown = ({ children, isOpen, target, onClose }) => (
<div css={{ position: "relative" }}>
{target}
{isOpen ? <Menu>{children}</Menu> : null}
{isOpen ? <Blanket onClick={onClose} /> : null}
</div>
);
const Svg = p => (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
focusable="false"
role="presentation"
{...p}
/>
);
const DropdownIndicator = () => (
<div css={{ color: colors.neutral20, height: 24, width: 32 }}>
<Svg>
<path
d="M16.436 15.085l3.94 4.01a1 1 0 0 1-1.425 1.402l-3.938-4.006a7.5 7.5 0 1 1 1.423-1.406zM10.5 16a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11z"
fill="currentColor"
fillRule="evenodd"
/>
</Svg>
</div>
);
const ChevronDown = () => (
<Svg style={{ marginRight: -6 }}>
<path
d="M8.292 10.293a1.009 1.009 0 0 0 0 1.419l2.939 2.965c.218.215.5.322.779.322s.556-.107.769-.322l2.93-2.955a1.01 1.01 0 0 0 0-1.419.987.987 0 0 0-1.406 0l-2.298 2.317-2.307-2.327a.99.99 0 0 0-1.406 0z"
fill="currentColor"
fillRule="evenodd"
/>
</Svg>
);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12690 次 |
| 最近记录: |