@adaptabletools/adaptable
Version:
Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
107 lines (106 loc) • 4.41 kB
JavaScript
import * as React from 'react';
import { useState, useRef } from 'react';
import { Flex } from 'rebass';
import join from '../utils/join';
import useProperty from '../utils/useProperty';
import Arrows from './Arrows';
import SimpleButton from '../SimpleButton';
const baseClassName = 'ab-Dropdown';
const Dropdown = (props) => {
let { options, multiple, name, autoFocus, showEmptyItem = true, showClearButton, disabled, allowSearch, clearButtonProps, value: _, onChange: __, style, onExpand, ...boxProps } = props;
if (showClearButton !== false) {
showClearButton = true;
}
let [value, setValue] = useProperty(props, 'value', undefined, {
onChange: props.onChange,
});
let selectedOption = null;
let [lazyOptions, setLazyOptions] = useState([]);
let onMouseDown = () => {
if (onExpand) {
onExpand();
}
};
if (typeof options === 'function') {
const lazyOptionsFn = options;
onMouseDown = () => {
const newOptions = lazyOptionsFn();
setLazyOptions(newOptions);
if (onExpand) {
onExpand();
}
};
options = lazyOptions;
}
let placeholder = props.emptyText || props.placeholder || 'Select an option';
const finalOptions = options.map((option) => {
if (typeof option === 'string') {
option = {
label: option,
value: option,
};
}
if (value === option.value) {
selectedOption = option;
}
return option;
});
if (showEmptyItem)
finalOptions.splice(0, 0, {
label: placeholder,
value: '',
});
const onChange = (option, e) => {
setValue(option ? option.value : option, e, option);
};
const selectRef = useRef(null);
const domRef = useRef(null);
const [focused, setFocused] = useState(false);
const onFocus = (e) => {
if (e.target === selectRef.current) {
setFocused(true);
return;
}
if (e.target === domRef.current) {
selectRef.current.focus();
}
};
const onBlur = () => {
setFocused(false);
};
const defaultLabel = selectedOption ? selectedOption.label : null;
let selectedText = props.renderLabel
? props.renderLabel(defaultLabel, selectedOption)
: defaultLabel;
if (!selectedOption) {
selectedText = placeholder;
}
//20 ... 20 16
const renderClearButton = () => (React.createElement(SimpleButton, { variant: "text", icon: "close", tone: "none", tooltip: "Clear", iconSize: 20, px: 0, py: 0, marginRight: 1, ...clearButtonProps, style: {
zIndex: 10,
color: 'inherit',
...(clearButtonProps ? clearButtonProps.style : null),
}, onClick: (e) => {
e.preventDefault();
onChange(null, e);
} }));
return (React.createElement(Flex, { ref: domRef, flexDirection: "row", alignItems: "center", ...boxProps, className: join(props.className, baseClassName, !selectedOption ? `${baseClassName}--empty` : `${baseClassName}--not-empty`, focused ? `${baseClassName}--focused` : `${baseClassName}--not-focused`, disabled ? `${baseClassName}--disabled` : null), style: style, tabIndex: focused ? -1 : props.tabIndex || 0, onFocus: onFocus, onBlur: onBlur },
React.createElement("div", { style: { display: 'inline-block' }, className: `${baseClassName}__text` },
selectedText,
React.createElement(Arrows, null)),
React.createElement("select", { ref: selectRef, tabIndex: -1, disabled: disabled, value: value == null ? '' : value, onChange: (e) => {
const selected = finalOptions.filter((o) => o.value == e.target.value)[0];
onChange(selected, e);
}, style: {
opacity: 0,
width: '100%',
height: '100%',
top: 0,
left: 0,
zIndex: 1,
}, onMouseDown: onMouseDown, name: name, multiple: multiple, autoFocus: autoFocus }, finalOptions.map((o) => {
return (React.createElement("option", { key: o.value, value: o.value }, o.label));
})),
showClearButton && selectedOption ? renderClearButton() : null));
};
export default Dropdown;