UNPKG

ultra-design

Version:
324 lines (284 loc) 11.4 kB
import _taggedTemplateLiteral from '@babel/runtime/helpers/taggedTemplateLiteral'; import _defineProperty from '@babel/runtime/helpers/defineProperty'; import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties'; import _slicedToArray from '@babel/runtime/helpers/slicedToArray'; import React, { forwardRef, useRef, useState, useCallback, useMemo, isValidElement, useEffect, useImperativeHandle } from 'react'; import { selectStyles, selectLayerStyles } from './select-style.js'; import clsx from 'clsx'; import Option from './option.js'; import { Close, Up, Down } from '@icon-park/react'; import Trigger from '../trigger/trigger.js'; import { useMergeProps } from '../utils/mergeProps.js'; import withStyle from '../utils/withStyle.js'; import { css } from '@emotion/react'; import { jsxs, jsx } from '@emotion/react/jsx-runtime'; var _templateObject; var _excluded = ["onClick", "onMouseEnter", "className"]; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var defaultProps = { name: 'ultra-select' }; var SelectComponent = /*#__PURE__*/forwardRef(function (p, ref) { var props = useMergeProps(defaultProps, p); var disabled = props.disabled, onChange = props.onChange, value = props.value, defaultValue = props.defaultValue, placeholder = props.placeholder, clearable = props.clearable, filterable = props.filterable, children = props.children, className = props.className, style = props.style; var selfRef = useRef(null); var _useState = useState(''), _useState2 = _slicedToArray(_useState, 2), inputValue = _useState2[0], setInputValue = _useState2[1]; var _useState3 = useState(true), _useState4 = _slicedToArray(_useState3, 2), filterFinished = _useState4[0], setFilterFinished = _useState4[1]; var _useState5 = useState('value' in props ? value : defaultValue), _useState6 = _slicedToArray(_useState5, 2), selectValue = _useState6[0], setSelectValue = _useState6[1]; var _useState7 = useState(-1), _useState8 = _slicedToArray(_useState7, 2), hoverIndex = _useState8[0], setHoverIndex = _useState8[1]; var _useState9 = useState(false), _useState10 = _slicedToArray(_useState9, 2), dropdownVisivle = _useState10[0], setDropdownVisivle = _useState10[1]; var _useState11 = useState(false), _useState12 = _slicedToArray(_useState11, 2), focus = _useState12[0], setFocus = _useState12[1]; var _useState13 = useState('0'), _useState14 = _slicedToArray(_useState13, 2), layerMinWidth = _useState14[0], setLayerMinWidth = _useState14[1]; var selfFilterMethod = function selfFilterMethod(option) { var label_ = 'label' in option ? option.label : typeof option.children === 'string' ? option.children : ''; if (!label_) return false; return label_.toLowerCase().includes(inputValue.toLowerCase()); }; var filterMethod = useCallback(function (option) { if (typeof filterable === 'function') { return filterable(inputValue, option); } else { return selfFilterMethod(option); } }, [filterable, inputValue]); var optionList = useMemo(function () { var childs = []; React.Children.toArray(children).forEach(function (child) { if ( /*#__PURE__*/isValidElement(child)) { childs.push(child.props); } }); return childs; }, [children]); var filteredOptionList = useMemo(function () { var filteredData = !filterable || filterFinished ? optionList : optionList.filter(filterMethod); return filteredData; }, [filterable, filterFinished, optionList, filterMethod]); var selectIndex = filteredOptionList.findIndex(function (opt) { return (opt.value || opt.label || opt.children) === selectValue; }); var selectionLabel = useMemo(function () { if (!selectValue) return undefined; if (selectIndex >= 0) { setHoverIndex(selectIndex); var _filteredOptionList$s = filteredOptionList[selectIndex], _children = _filteredOptionList$s.children, label = _filteredOptionList$s.label; if (filterable) { setInputValue(typeof _children === 'string' ? _children : label); } return _children || label; } }, [selectValue, filteredOptionList, selectIndex]); useEffect(function () { setSelectValue(value); }, [value]); useImperativeHandle(ref, function () { return { value: selectValue }; }, [selectValue]); var handleChange = function handleChange(data) { var optionValue = data.value; var finalValue = optionValue !== null && optionValue !== void 0 ? optionValue : data.children || data.label; setSelectValue(finalValue); if (!data.label && typeof data.children === 'string') { setInputValue(data.children); } setFilterFinished(true); var v = filteredOptionList.find(function (o) { return o.value === optionValue; }); if (v) { setTimeout(function () { onChange === null || onChange === void 0 ? void 0 : onChange(finalValue); }); } setDropdownVisivle(false); }; var handleKeyDown = function handleKeyDown(e) { e.preventDefault(); var optsLen = filteredOptionList.length; if (disabled || !optsLen) return; if (filteredOptionList.every(function (o) { return o.disabled; })) return; if (e.code === 'ArrowDown' && dropdownVisivle) { setHoverIndex(function (i) { while (filteredOptionList[(i + 1) % optsLen].disabled) { i += 1; } return (i + 1) % optsLen; }); } else if (e.code === 'ArrowUp' && dropdownVisivle) { setHoverIndex(function (i) { while (filteredOptionList[(i - 1 + optsLen) % optsLen].disabled) { i -= 1; } return (i - 1 + optsLen) % optsLen; }); } else if (e.code === 'Enter') { var noHover = hoverIndex <= -1; if (noHover) { return; } setDropdownVisivle(!dropdownVisivle); if (dropdownVisivle && !noHover) { if (!filteredOptionList[hoverIndex]) { return; } handleChange(filteredOptionList[hoverIndex]); } } }; var handleInputKeyDown = function handleInputKeyDown(_e) { _e.stopPropagation(); // if (!['ArrowDown', 'ArrowUp', 'Enter', 'Backspace'].includes(e.code)) { // e.stopPropagation(); // } }; var handleMouseDown = function handleMouseDown(e) { if (dropdownVisivle) { e.preventDefault(); } }; var handleInput = function handleInput(e) { setInputValue(e.currentTarget.value); setDropdownVisivle(true); setFilterFinished(false); }; var handleClear = function handleClear() { setInputValue(''); setSelectValue(undefined); setTimeout(function () { onChange === null || onChange === void 0 ? void 0 : onChange(selectValue); }); }; useEffect(function () { if (!dropdownVisivle && !filteredOptionList.length) { if (typeof selectionLabel === 'string') { setInputValue(selectionLabel); } } }, [dropdownVisivle]); var renderOptionItem = function renderOptionItem(props, index) { var _onClick = props.onClick, _onMouseEnter = props.onMouseEnter, className = props.className, rest = _objectWithoutProperties(props, _excluded); var idx = filteredOptionList.findIndex(function (opt) { return (opt.value || opt.children || opt.label) === selectValue; }); return /*#__PURE__*/React.cloneElement(jsx(Option, {}), _objectSpread(_objectSpread({}, rest), {}, { key: index, id: "ultra-select-option_".concat(index), className: clsx(className, idx === index && 'ultra-select-option--active', hoverIndex === index && 'ultra-select-option--hover'), onClick: function onClick(e) { _onClick === null || _onClick === void 0 ? void 0 : _onClick(e); !props.disabled && handleChange(props); }, onMouseEnter: function onMouseEnter(e) { _onMouseEnter === null || _onMouseEnter === void 0 ? void 0 : _onMouseEnter(e); setHoverIndex(index); } })); }; return jsxs("div", { className: clsx(['ultra-select', className, focus && 'ultra-select--focused', disabled && 'ultra-select--disabled']), tabIndex: 1, style: style, css: selectStyles(props), onKeyDown: handleKeyDown, onMouseDown: handleMouseDown, onFocus: function onFocus() { return setFocus(true); }, onBlur: function onBlur() { return setFocus(false); }, ref: function ref(node) { if (!node) return; selfRef.current = node; setLayerMinWidth(getComputedStyle(node).width); }, children: [jsx(Trigger, _objectSpread(_objectSpread({ triggerRef: selfRef, visible: dropdownVisivle, showDelay: 0, onVisibleChange: function onVisibleChange(v) { return setDropdownVisivle(v); }, showArrow: false, placement: "bottomLeft", trigger: "click", content: filteredOptionList.length ? filteredOptionList.map(renderOptionItem) : jsx("p", { style: { textAlign: 'center' }, children: "No Data" }) }, props), {}, { name: "ultra-select", transitionClassName: "ultra-select-layer-slide", getLayerContainer: function getLayerContainer(node) { return node === null || node === void 0 ? void 0 : node.parentNode; }, css: [selectLayerStyles(props), css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n min-width: ", ";\n "])), layerMinWidth)] })), filterable ? jsx("input", { onKeyDown: handleInputKeyDown, onInput: handleInput, value: inputValue, disabled: disabled, placeholder: placeholder }) : jsx("div", { className: "ultra-select__selection", children: selectionLabel || selectValue || jsx("span", { className: "ultra-select__placeholder", children: placeholder }) }), jsx("div", { className: "ultra-select__icon", children: clearable ? jsx(Close, { onClick: handleClear }) : dropdownVisivle ? jsx(Up, { className: "ultra-icon" }) : jsx(Down, { className: "ultra-icon" }) })] }); }); SelectComponent.displayName = 'UltraSelect'; var Select = withStyle(SelectComponent); var SelectComponent$1 = Select; export { SelectComponent$1 as default };