UNPKG

@amaui/ui-react

Version:
356 lines (354 loc) 13.3 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _extends from "@babel/runtime/helpers/extends"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; const _excluded = ["className"], _excluded2 = ["in", "simple", "onExited", "fullWidth", "noExitAnimation", "add", "className", "style"], _excluded3 = ["tonal", "color", "version", "colorSelected", "size", "value", "valueDefault", "onChange", "select", "unselect", "orientation", "noCheckIcon", "elevation", "border", "chip", "fullWidth", "disabled", "className", "children"]; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); 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 = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } import React from 'react'; import { is, unique } from '@amaui/utils'; import { classNames, style as styleMethod, useAmauiTheme } from '@amaui/style-react'; import TransitionElement from '../Transition'; import LineElement from '../Line'; import { staticClassName, valueBreakpoints } from '../utils'; import useMediaQuery from '../useMediaQuery'; import Icon from '../Icon'; export const IconMaterialDone = /*#__PURE__*/React.forwardRef((props, ref) => { const { className } = props, other = _objectWithoutProperties(props, _excluded); return /*#__PURE__*/React.createElement(Icon, _extends({ ref: ref, name: "DoneSharp", short_name: "Done" }, other), /*#__PURE__*/React.createElement("path", { className: className, fill: "none", d: "M4.5 11.5L9.5 16.5L19.5 6.5" })); }); const useStyle = styleMethod(theme => ({ root: { position: 'relative', borderRadius: theme.methods.shape.radius.value('xl', 'px') }, orientation_horizontal_size_small: { '&:not(.amaui-ToggleButtons-root) > *': { height: '28px' } }, orientation_horizontal_size_regular: { '&:not(.amaui-ToggleButtons-root) > *': { height: '42px' } }, orientation_horizontal_size_large: { '&:not(.amaui-ToggleButtons-root) > *': { height: '63px' } }, orientation_vertical: { flexDirection: 'column', '& > *': { width: '100% !important' } }, // Size size_small: { borderRadius: `${theme.shape.radius.unit * 2}px` }, size_regular: { borderRadius: `${theme.shape.radius.unit * 2.5}px` }, size_large: { borderRadius: `${theme.shape.radius.unit * 3.5}px` }, // Size chip_size_small: { borderRadius: `${theme.shape.radius.unit - theme.shape.radius.unit / 4}px` }, chip_size_regular: { borderRadius: `${theme.shape.radius.unit}px` }, chip_size_large: { borderRadius: `${theme.shape.radius.unit + theme.shape.radius.unit / 4}px` }, // Shadows elevation: { boxShadow: theme.shadows.values.neutral[1], transition: theme.methods.transitions.make('box-shadow'), '&:hover': { boxShadow: theme.shadows.values.neutral[3] } }, start_orientation_horizontal: { '&:not(:first-of-type)': { borderStartStartRadius: '0px', borderEndStartRadius: '0px', '&$outlined': { marginInlineStart: '-1px' }, '&$border:not($outlined)': { borderInlineStart: '1px solid currentColor' } } }, end_orientation_horizontal: { '&:not(:last-of-type)': { borderStartEndRadius: '0px', borderEndEndRadius: '0px' } }, start_orientation_vertical: { '&:not(:first-of-type)': { borderStartStartRadius: '0px', borderStartEndRadius: '0px', '&$outlined': { marginBlockStart: '-1px' }, '&$border:not($outlined)': { borderBlockStart: '1px solid currentColor' } } }, end_orientation_vertical: { '&:not(:last-of-type)': { borderEndEndRadius: '0px', borderEndStartRadius: '0px' } }, path: { strokeWidth: '1.5px', strokeDasharray: '30', strokeDashoffset: '30', stroke: 'currentcolor', transition: theme.methods.transitions.make('stroke-dashoffset', { duration: 'xxs', timing_function: 'accelerated' }) }, pathIn: { strokeDashoffset: '0', transition: theme.methods.transitions.make('stroke-dashoffset', { duration: 'xxs', delay: 45, timing_function: 'accelerated' }) }, fullWidth: { width: '100%' }, selected: { zIndex: '1' }, disabled: {} }), { name: 'amaui-Buttons' }); export const IconDoneAnimated = props => { const { classes } = useStyle(); const theme = useAmauiTheme(); const Transition = React.useMemo(() => theme?.elements?.Transition || TransitionElement, [theme]); const { in: inProp, simple, onExited, fullWidth, noExitAnimation, add, className, style } = props, other = _objectWithoutProperties(props, _excluded2); const styles = props.simple ? {} : { adding: { width: style?.fontSize }, added: { width: style?.fontSize } }; return /*#__PURE__*/React.createElement(Transition, { in: inProp, onExited: () => { if (is('function', onExited) && !simple) onExited(); }, add: add, enterOnAdd: false }, status => /*#__PURE__*/React.cloneElement( /*#__PURE__*/React.createElement("span", { className: className, style: style }, /*#__PURE__*/React.createElement(IconMaterialDone, _extends({ className: classNames([classes.path, (['adding', 'added', 'enter', 'entering', 'entered'].includes(status) || noExitAnimation) && classes.pathIn]), size: "inherit" }, other))), { style: _objectSpread(_objectSpread(_objectSpread({ display: 'inline-flex', overflow: 'hidden' }, !simple ? { width: 0 } : {}), {}, { transition: theme.methods.transitions.make('width', { duration: 'xs', timing_function: 'accelerated' }) }, styles[status]), style) })); }; const Buttons = /*#__PURE__*/React.forwardRef((props_, ref) => { const theme = useAmauiTheme(); const props = React.useMemo(() => _objectSpread(_objectSpread(_objectSpread({}, theme?.ui?.elements?.all?.props?.default), theme?.ui?.elements?.amauiButtons?.props?.default), props_), [props_]); const Line = React.useMemo(() => theme?.elements?.Line || LineElement, [theme]); const { tonal = true, color = 'primary', version = 'outlined', colorSelected = props.color, size = 'regular', value, valueDefault, onChange, select, unselect = true, orientation: orientation_, noCheckIcon, elevation = true, border = true, chip, fullWidth, disabled, className, children: children_ } = props, other = _objectWithoutProperties(props, _excluded3); const { classes } = useStyle(); const [init, setInit] = React.useState(false); const [preSelected, setPreSelected] = React.useState([]); const [selected, setSelected] = React.useState(() => { const valueNew = valueDefault !== undefined ? valueDefault : value; return valueNew !== undefined ? is('array', valueNew) ? valueNew : [valueNew] : []; }); const refs = { root: React.useRef(undefined), noCheckIcon: React.useRef(noCheckIcon) }; const keys = React.useMemo(() => { const result = []; const items = [orientation_]; items.forEach(item => { if (is('object', item)) Object.keys(item).filter(key => theme.breakpoints.media[key]).forEach(key => result.push(key)); }); return unique(result); }, [orientation_]); const breakpoints = {}; keys.forEach(key => { breakpoints[key] = useMediaQuery(theme.breakpoints.media[key], { element: refs.root.current }); }); const orientation = valueBreakpoints(orientation_, 'horizontal', breakpoints, theme); refs.noCheckIcon.current = noCheckIcon; React.useEffect(() => { setInit(true); }, []); React.useEffect(() => { if (init && value !== selected) setSelected(is('array', value) ? value : [value]); }, [value]); const onSelect = function (itemProps) { let start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; let valueNew; if (start) { if (selected.includes(itemProps.value)) { valueNew = selected.filter(item => item !== itemProps.value); } else { if (select === 'single') valueNew = [itemProps.value]; if (select === 'multiple') valueNew = unique([...selected, itemProps.value]); } } else { // Unselect if (selected.includes(itemProps.value) && (unselect || select === 'multiple' && selected.length > 1)) { if (!refs.noCheckIcon.current) { setPreSelected(items => items.filter(item => item !== itemProps.value)); } else { valueNew = selected.filter(item => item !== itemProps.value); } } else { if (select === 'single') { if (!refs.noCheckIcon.current) { setPreSelected([itemProps.value]); valueNew = [...selected, itemProps.value]; } else valueNew = [itemProps.value]; } if (select === 'multiple') { if (!refs.noCheckIcon.current) { setPreSelected(items => unique([...items, itemProps.value])); valueNew = unique([...selected, itemProps.value]); } else valueNew = unique([...selected, itemProps.value]); } } } if (valueNew !== undefined) { // Update inner or controlled if (!props.hasOwnProperty('value')) setSelected(valueNew); if (is('function', onChange)) onChange(valueNew); } }; const updateSelected = itemProps => { const valueNew = selected.filter(item => item !== itemProps.value); // Update inner or controlled if (!props.hasOwnProperty('value')) setSelected(valueNew); if (is('function', onChange)) onChange(valueNew); }; const children = React.Children.toArray(children_) // Clamp array to max of 5 values // .slice(0, 5) .map((item, index) => /*#__PURE__*/React.cloneElement(item, _objectSpread(_objectSpread(_objectSpread({ key: index, className: classNames([item.className, classes.item, classes[version], classes[`start_orientation_${orientation}`], classes[`end_orientation_${orientation}`], selected.includes(item.props.value) && classes.selected, border && classes.border]), onClick: () => { onSelect(item.props, !!item.props.start); // Invoke items on click method if (is('function', item.props.onClick)) item.props.onClick(); } }, !refs.noCheckIcon.current && item.props.start && selected.includes(item.props.value) ? { start: /*#__PURE__*/React.createElement(IconDoneAnimated, { simple: true, in: true, add: true }) } : {}), !refs.noCheckIcon.current && !item.props.start && (selected.includes(item.props.value) || preSelected.includes(item.props.value)) ? { start: /*#__PURE__*/React.createElement(IconDoneAnimated, { in: (item.props.start ? selected : preSelected).includes(index), onExited: () => updateSelected(item.props), add: true }) } : {}), {}, { version: item.props?.version !== undefined ? item.props.version : version, color: selected.includes(item.props.value) ? colorSelected || (item.props?.color !== undefined ? item.props.color : color) : item.props?.color !== undefined ? item.props.color : color, size: item.props?.size !== undefined ? item.props.size : size, tonal: item.props?.tonal !== undefined ? item.props.tonal : tonal, elevation: false, selected: item.props.selected !== undefined ? item.props.selected : selected.includes(item.props.value), disabled: item.props?.disabled !== undefined ? item.props.disabled : disabled }))); return /*#__PURE__*/React.createElement(Line, _extends({ ref: item => { if (ref) { if (is('function', ref)) ref(item);else ref.current = item; } refs.root.current = item; }, gap: 0, direction: "row", display: "inline-flex", className: classNames([staticClassName('Buttons', theme) && ['amaui-Buttons-root', `amaui-Buttons-version-${version}`, `amaui-Buttons-size-${size}`, disabled && `amaui-Buttons-disabled`], className, classes.root, classes[`size_${size}`], chip && classes[`chip_size_${size}`], classes[`orientation_${orientation}`], classes[`orientation_${orientation}_size_${size}`], fullWidth && classes.fullWidth, elevation && !disabled && ['filled', 'tonal'].includes(version) && classes.elevation, disabled && classes.disabled]) }, other), children); }); Buttons.displayName = 'amaui-Buttons'; export default Buttons;