UNPKG

@fluent-windows/core

Version:

React components that inspired by Microsoft's Fluent Design System.

98 lines (96 loc) 3.32 kB
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } import * as React from 'react'; import classNames from 'classnames'; import { createUseStyles } from '@fluent-windows/styles'; import { styles } from './Select.styled'; import { usePopper, useClick, useClickOutside } from '@fluent-windows/hooks'; import { ArrowDownSLine as ArrowDownSLineIcon } from '@fluent-windows/icons'; import { SelectPropTypes } from './Select.type'; import Transition from '../Transition'; import List from '../List'; export const name = 'Select'; const useStyles = createUseStyles(styles, { name }); const Select = React.forwardRef((props, ref) => { const { as: Component = 'span', className: classNameProp, style, value, onChange, disabled = false, children, ...rest } = props; const [referenceRef, popperRef] = usePopper({ placement: 'bottom-start', positionFixed: false }); const [visible, setVisible] = React.useState(false); const handleVisible = React.useCallback(status => { disabled !== true && setVisible(status); }, [disabled]); const [_, bind] = useClick(handleVisible); useClickOutside(referenceRef, () => { setVisible(false); }); const [currentText, setCurrentText] = React.useState(''); React.useEffect(() => { React.Children.forEach(children, child => { const active = child.props.value === value; active && setCurrentText(child.props.children); }); }, [children, value]); const theChildren = React.useMemo(() => React.Children.map(children, child => { function onClick() { child.props.value && onChange && onChange(child.props.value); setCurrentText(child.props.children); setVisible(false); } const active = child.props.value === value; return React.cloneElement(child, { onClick, active }); }), [children, value, setCurrentText, setVisible, onChange]); const classes = useStyles(props); const className = classNames(classes.root, { [classes.disabled]: disabled }, classNameProp); const selectClassName = classNames(classes.select, { [classes.selectDisabled]: disabled }); const iconClassName = classNames(classes.icon, { [classes.disabledIcon]: disabled }); return React.createElement(Component, _extends({ className: className, style: style, ref: referenceRef }, bind), React.createElement("button", { className: selectClassName }, currentText), React.createElement("span", { className: iconClassName }, React.createElement(ArrowDownSLineIcon, null)), React.createElement("input", _extends({ type: "hidden", value: value, disabled: disabled, ref: ref }, rest)), React.createElement(Transition, { type: "grow", visible: visible, wrapper: false, mountOnEnter: true, unmountOnExit: true }, React.createElement(List, { zIndex: 1002, ref: popperRef }, theChildren))); }); Select.displayName = `F${name}`; Select.propTypes = SelectPropTypes; Select.defaultProps = { disabled: false }; export default Select;