UNPKG

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