UNPKG

@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
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;