123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- import React, { useState, useEffect, useRef } from 'react';
- import Icon from '../Icon';
- import Divider from '../Divider';
- import {
- Wrapper,
- Selected,
- Content,
- InputContent,
- OptionWrapper,
- Option,
- } from './styled';
- type Option = {
- key: string | number;
- content: React.ReactNode;
- };
- type Props = {
- onChange?: (item: Option | React.ReactNode) => void;
- options: Option[];
- defaultValue?: React.ReactNode;
- isDivide?: boolean;
- width?: string;
- useInput?: boolean;
- style?: {};
- };
- const SelectBox: React.FunctionComponent<Props>= ({
- onChange,
- options ,
- defaultValue,
- isDivide,
- width = 'auto',
- useInput = false,
- style,
- }) => {
- const selectRef = useRef<HTMLDivElement>(null);
- const optionRef = useRef<HTMLDivElement>(null);
- const [isCollapse, setCollapse] = useState(true);
- const [value, setValue] = useState(defaultValue);
- const handleClick = () => {
- setCollapse(!isCollapse);
- }
- const handleSelect = (index: number) => {
- setValue(options[index].content);
- if (onChange) {
- onChange(options[index]);
- }
- }
- const handleBlur = () => {
- setCollapse(true);
- }
- const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
- setValue(e.target.value || 0);
- }
- const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
- if (e.keyCode === 13 && onChange && value) {
- onChange(value);
- setCollapse(true);
- }
- }
- useEffect(() => {
- if (!defaultValue || options[0]) {
- setValue(options[0].content);
- }
- }, []);
- useEffect(() => {
- if (!isCollapse && selectRef.current) {
- const position = selectRef.current.getBoundingClientRect();
- if (optionRef.current) {
- optionRef.current.style.top = `${selectRef.current.clientHeight + position.top}px`;
- optionRef.current.style.left = `${position.left}px`;
- }
- }
- });
- return (
- <Wrapper width={width} style={style}>
- <Selected
- ref={selectRef}
- onMouseDown={handleClick}
- onBlur={handleBlur}
- tabIndex={0}
- >
- {
- useInput && (typeof value === "string" || typeof value === "number") ? (
- <InputContent
- value={value}
- onChange={handleChange}
- onKeyDown={handleKeyDown}
- />
- ) : (
- <Content>
- {value}
- </Content>
- )
- }
- {isDivide ? <Divider /> : null}
- <Icon glyph="down-arrow" />
- </Selected>
- {
- !isCollapse ? (
- <OptionWrapper ref={optionRef}>
- {
- options.map((option: Option, index: number) => (
- <Option
- key={option.key}
- onMouseDown={() => { handleSelect(index); }}
- >
- {option.content}
- </Option>
- ))
- }
- </OptionWrapper>
- ) : null
- }
- </Wrapper>
- );
- };
- SelectBox.defaultProps = {
- defaultValue: '',
- onChange: () => {},
- isDivide: false,
- };
- export default SelectBox;
|