123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- import React, { useState, useEffect, useRef } from 'react';
- import Icon from '../Icon';
- import Divider from '../Divider';
- import ClickAwayListener from '../ClickAwayListener';
- import {
- Container,
- Selected,
- Content,
- InputContent,
- OptionWrapper,
- Option,
- } from './styled';
- type Props = {
- onChange?: (item: SelectOptionType) => void;
- options: SelectOptionType[];
- defaultValue?: React.ReactNode;
- isDivide?: boolean;
- useInput?: boolean;
- style?: Record<string, string>;
- };
- const SelectBox: React.FC<Props> = ({
- onChange,
- options,
- defaultValue,
- isDivide,
- useInput,
- style,
- }: Props) => {
- const selectRef = useRef<HTMLDivElement>(null);
- const optionRef = useRef<HTMLDivElement>(null);
- const [isCollapse, setCollapse] = useState(true);
- const [value, setValue] = useState(defaultValue);
- const handleClick = (): void => {
- setCollapse(!isCollapse);
- };
- const handleSelect = (index: number): void => {
- setValue(options[index].content);
- handleBlur();
- if (onChange) {
- onChange(options[index]);
- }
- };
- const handleBlur = (): void => {
- setCollapse(true);
- };
- const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
- setValue(e.target.value || 0);
- };
- const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>): void => {
- if (e.keyCode === 13 && onChange && value) {
- const param = {
- key: '',
- content: '',
- child: parseInt(value as string, 10),
- };
- onChange(param);
- setCollapse(true);
- }
- };
- useEffect(() => {
- if (defaultValue) {
- setValue(defaultValue);
- } else {
- setValue(options[0].content);
- }
- }, [defaultValue]);
- 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 (
- <ClickAwayListener onClick={handleBlur}>
- <Container style={style}>
- <Selected
- ref={selectRef}
- onMouseDown={handleClick}
- onBlur={handleBlur}
- tabIndex={0}
- data-testid="selected"
- >
- {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} data-testid="option-list">
- {options.map((option: SelectOptionType, index: number) => (
- <Option
- key={option.key}
- onMouseDown={(): void => {
- handleSelect(index);
- }}
- >
- {option.content}
- </Option>
- ))}
- </OptionWrapper>
- ) : null}
- </Container>
- </ClickAwayListener>
- );
- };
- SelectBox.defaultProps = {
- isDivide: false,
- useInput: false,
- style: {},
- defaultValue: '',
- };
- export default SelectBox;
|