@adaptabletools/adaptable
Version:
Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
100 lines (99 loc) • 4.46 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useState, useRef } from 'react';
import join from '../utils/join';
import useProperty from '../utils/useProperty';
import Arrows from './Arrows';
import SimpleButton from '../SimpleButton';
import { Flex } from '../Flex';
import { twMerge } from '../../twMerge';
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 || (typeof props.placeholder === 'string' ? props.placeholder : null) || '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;
}
const renderClearButton = () => (_jsx(SimpleButton, { variant: "text", icon: "close", tone: "none", tooltip: "Clear", iconSize: 20, ...clearButtonProps, className: twMerge('twa:p-0 twa:mr-1 twa:z-10 twa:color-inherit', clearButtonProps?.className), style: {
...(clearButtonProps ? clearButtonProps.style : null),
}, onClick: (e) => {
e.preventDefault();
onChange(null, e);
} }));
return (_jsxs(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, children: [_jsxs("div", { className: `${baseClassName}__text twa:inline-block`, children: [selectedText, _jsx(Arrows, {})] }), _jsx("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, children: finalOptions.map((o) => {
return (_jsx("option", { value: o.value, children: o.label }, o.value));
}) }), showClearButton && selectedOption ? renderClearButton() : null] }));
};
export default Dropdown;