UNPKG

@evg-b/evg-ui

Version:

EVG-UI library inspired by Material Design.

206 lines (183 loc) 7.49 kB
import _extends from '@babel/runtime/helpers/extends'; import _slicedToArray from '@babel/runtime/helpers/slicedToArray'; import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties'; import _defineProperty from '@babel/runtime/helpers/defineProperty'; import React, { useRef, useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import Elevation from '../styles/Elevation.js'; import withStyles from '../styles/withStyles.js'; import '@babel/runtime/helpers/construct'; import '@babel/runtime/helpers/toConsumableArray'; import '@babel/runtime/helpers/classCallCheck'; import '@babel/runtime/helpers/createClass'; import TextField from '../TextField/TextField.js'; import List from '../List/List.js'; import SelectOption from '../SelectOption/SelectOption.js'; import Popup from '../Popup/Popup.js'; import ExpandMore from '../internal/icons/Select/ExpandMore.js'; 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 styles = { base: { position: 'relative', tapHighlightColor: 'rgba(0,0,0,0)', '-webkit-tap-highlight-color': 'rgba(0,0,0,0)' }, selectIcon: { position: 'absolute', top: '18px', right: '16px', transition: 'transform 200ms cubic-bezier(0.4, 0, 0.2, 1)', pointerEvents: 'none', '&:disabled,&[disabled]': { cursor: 'default', pointerEvents: ' none', color: '#b4b4b4' } }, selectIconOpen: { transition: 'transform 200ms cubic-bezier(0.4, 0, 0.2, 1)', transform: 'rotate(180deg)' }, selectList: _objectSpread({}, Elevation(8)) }; /** * Select позволяет пользователям выбирать из меню с одним параметром. */ var Select = /*#__PURE__*/React.forwardRef(function Select(props, ref) { var classes = props.classes, className = props.className, children = props.children, value = props.value, emptyOption = props.emptyOption, onChange = props.onChange, color = props.color, disabled = props.disabled, otherProps = _objectWithoutProperties(props, ["classes", "className", "children", "value", "emptyOption", "onChange", "color", "disabled"]); var Select_ref = useRef(); Select_ref = ref || Select_ref; var _useState = useState(false), _useState2 = _slicedToArray(_useState, 2), open = _useState2[0], setOpen = _useState2[1]; var _useState3 = useState(0), _useState4 = _slicedToArray(_useState3, 2), minWidth = _useState4[0], setMinWidth = _useState4[1]; var optionMap = new Map(); React.Children.forEach(children, function (child) { var value = child.props.value; var children = child.props.children; if (value && children) { optionMap.set(value, children); } }); var _useState5 = useState(optionMap.get(value)), _useState6 = _slicedToArray(_useState5, 2), valueSelect = _useState6[0], setValueSelect = _useState6[1]; var handelClick = function handelClick(_ref) { var currentTarget = _ref.currentTarget; setValueSelect(optionMap.get(currentTarget.value)); onChange && onChange(currentTarget.value); handleCloseSelectList(); }; var emptySelectOption = function emptySelectOption() { return /*#__PURE__*/React.createElement(SelectOption, { onClick: handelClick }); }; var handleOpenSelectList = function handleOpenSelectList() { setOpen(true); }; var handleCloseSelectList = function handleCloseSelectList() { Select_ref.current.blur(); setOpen(false); }; useEffect(function () { // TODO: оптимизировать и закешировать, чтобы срабатывала только два раза // в первый render ширина может учитываться margin и clientWidth почему то не помогает(а должен) // он помогает при первом показе, вот тогда нужно зафиксировать новое значение(правильное) и больше не менять setMinWidth(Select_ref.current.clientWidth); }, []); return /*#__PURE__*/React.createElement("div", { className: classNames(classes.base, className) }, /*#__PURE__*/React.createElement(TextField, _extends({ ref: Select_ref, readOnly: true, value: valueSelect, onClick: handleOpenSelectList, style: { cursor: 'pointer' }, color: color, disabled: disabled }, otherProps)), /*#__PURE__*/React.createElement(ExpandMore, { color: open ? color : 'default', disabled: disabled, className: classNames(classes.selectIcon, _defineProperty({}, classes.selectIconOpen, open)) }), /*#__PURE__*/React.createElement(Popup, { target: Select_ref, open: open, mode: "click", onClose: handleCloseSelectList, style: { minWidth: minWidth } }, /*#__PURE__*/React.createElement(List, { color: color, className: classNames(classes.selectList, {}) }, emptyOption && emptySelectOption(), React.Children.map(children, function (child) { if (child.props.value && child.props.children) { return child && /*#__PURE__*/React.cloneElement(child, { onClick: handelClick, active: child.props.children === valueSelect }); } else { console.error("[evg-ui] <Select/>: <SelectOption/> empty 'value' or 'children'"); } })))); }); Select.propTypes = { /** * Это контент между открывающим и закрывающим тегом компонента. */ children: PropTypes.node, /** * Объект содержит jss стили компонента. */ classes: PropTypes.object, /** * Чтобы указать CSS классы, используйте этот атрибут. */ className: PropTypes.string, /** * Название цвета в разных форматах. */ color: PropTypes.string, /** * Если true, в список добавиться пустой SelectOption. */ emptyOption: PropTypes.bool, /** * Вызывается при изменении состояния. */ onChange: PropTypes.func, /** * Value - number или string. */ value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), /** * Если true, принимает состоянии disabled. */ disabled: PropTypes.bool }; Select.defaultProps = { emptyOption: false, disabled: false, color: 'default' }; Select.displayName = 'SelectEVG'; var Select$1 = withStyles(styles)(Select); export default Select$1;