UNPKG

@amaui/ui-react

Version:
200 lines (199 loc) 7.97 kB
import _extends from "@babel/runtime/helpers/extends"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; const _excluded = ["widgets", "position", "move", "fixed", "onOpen", "onOpenAll", "onClose", "onCloseAll", "SpeedDialProps", "MoveProps", "Icon", "IconCloseItem", "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 IconMaterialClose from '@amaui/icons-material-rounded-react/IconMaterialCloseW100'; import IconMaterialWidgets from '@amaui/icons-material-rounded-react/IconMaterialWidgetsW100'; import SpeedDialElement from '../SpeedDial'; import SpeedDialItemElement from '../SpeedDialItem'; import TransitionElement from '../Transition'; import IconButtonElement from '../IconButton'; import MoveElement from '../Move'; import WidgetsContext from './Context'; import { staticClassName } from '../utils'; const useStyle = styleMethod(theme => ({ root: { width: '100%', padding: `0 ${theme.methods.space.value(13, 'px')}`, pointerEvents: 'none', zIndex: theme.z_index.modal - 1 }, line: { pointerEvents: 'auto' }, fixed: { position: 'fixed' }, position_top: { top: '24px' }, position_bottom: { bottom: '24px' }, widget: { userSelect: 'none', boxShadow: theme.shadows.values.default[6] }, item: { position: 'fixed', top: '40px', left: '40px', opacity: '0', transform: 'translateY(100%)', transition: theme?.methods.transitions.make(['opacity', 'transform'], { duration: 'rg', timing_function: 'standard' }), zIndex: theme.z_index.modal - 1, '&.enter': { opacity: '0', transform: 'translateY(100%)' }, '&.entering': { opacity: '1', transform: 'translateY(0%)' }, '&.entered': { opacity: '1', transform: 'translateY(0%)' }, '&.exit': { opacity: '1', transform: 'translateY(0%)' }, '&.exiting': { opacity: '0', transform: 'translateY(100%)' }, '&.exited': { opacity: '0', transform: 'translateY(100%)' } }, iconButton: { top: '8px', insetInlineEnd: '-8px', transform: `translateX(${theme.direction === 'ltr' ? '' : '-'}100%)`, zIndex: '1', '&.amaui-IconButton-root': { position: 'absolute' } } }), { name: 'amaui-Widgets' }); const Widgets = /*#__PURE__*/React.forwardRef((props_, ref) => { const theme = useAmauiTheme(); const props = React.useMemo(() => _objectSpread(_objectSpread(_objectSpread({}, theme?.ui?.elements?.all?.props?.default), theme?.ui?.elements?.amauiWidgets?.props?.default), props_), [props_]); const SpeedDial = React.useMemo(() => theme?.elements?.SpeedDial || SpeedDialElement, [theme]); const SpeedDialItem = React.useMemo(() => theme?.elements?.SpeedDialItem || SpeedDialItemElement, [theme]); const Transition = React.useMemo(() => theme?.elements?.Transition || TransitionElement, [theme]); const IconButton = React.useMemo(() => theme?.elements?.IconButton || IconButtonElement, [theme]); const Move = React.useMemo(() => theme?.elements?.Move || MoveElement, [theme]); const { widgets, position = 'bottom', move = true, fixed = true, onOpen, onOpenAll, onClose, onCloseAll, SpeedDialProps, MoveProps, Icon: Icon_ = IconMaterialWidgets, IconCloseItem = IconMaterialClose, className, children } = props, other = _objectWithoutProperties(props, _excluded); const { classes } = useStyle(); const [openItems, setOpenItems] = React.useState([]); const refs = { value: React.useRef({}), props: React.useRef(undefined) }; refs.props.current = props; const open = React.useCallback(value => { setOpenItems(items => unique([...items, value])); if (is('function', onOpen)) onOpen(value); }, []); const openAll = React.useCallback(() => { setOpenItems(() => unique((widgets || []).map(item => { const valueItem = item.value !== undefined ? item.value : item.label; return valueItem; }))); if (is('function', onOpenAll)) onOpenAll(); }, []); const close = React.useCallback(value => { setOpenItems(items => unique(items.filter(item => item !== value))); if (is('function', onClose)) onClose(value); }, []); const closeAll = React.useCallback(() => { setOpenItems([]); if (is('function', onCloseAll)) onCloseAll(); }, []); // Add to the value refs.value.current.open = open; refs.value.current.openAll = openAll; refs.value.current.close = close; refs.value.current.closeAll = closeAll; const widgetsToUse = [...(widgets || [])].reverse(); return /*#__PURE__*/React.createElement(WidgetsContext.Provider, { value: refs.value.current }, widgets?.length && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SpeedDial, _extends({ ref: ref, direction: "top", position: "bottom", alignment: "start", Icon: Icon_, noRotate: true }, SpeedDialProps), widgets.map((item, index) => { const valueItem = item.value !== undefined ? item.value : item.label; return /*#__PURE__*/React.createElement(SpeedDialItem, { key: index, onClick: () => !openItems.includes(valueItem) ? open(valueItem) : close(valueItem), label: !openItems.includes(valueItem) ? item.label : `Close ${item.label}`, Icon: item.Icon }); })), widgetsToUse.map((item, index) => { const valueItem = item.value !== undefined ? item.value : item.label; const WidgetWrapper = Move; const WidgetWrapperProps = _objectSpread({ version: 'fixed', manage: true, manageLevel: 1, disabled: !(move && item.move !== false) }, MoveProps); return /*#__PURE__*/React.createElement(Transition, { key: index, in: openItems.includes(valueItem), removeOnExited: true }, status => /*#__PURE__*/React.createElement(WidgetWrapper, _extends({ className: classNames([staticClassName('Widgets', theme) && [`amaui-Widgets-item`], classes.item, status]) }, WidgetWrapperProps), /*#__PURE__*/React.createElement(IconButton, { onClick: () => close(valueItem), color: "default", version: "filled", size: "small", elevation: false, className: classNames([staticClassName('Widgets', theme) && [`amaui-Widgets-icon-button`], classes.iconButton]) }, /*#__PURE__*/React.createElement(IconCloseItem, null)), /*#__PURE__*/React.cloneElement(item.element, _objectSpread({ className: classNames([staticClassName('Widgets', theme) && [`amaui-Widgets-widget`], classes.widget]) }, ['amaui-Weather', 'amaui-Watch'].includes(item.element.type?.displayName) ? { shadow: true, style: { boxShadow: 'none' } } : undefined)))); })), children); }); Widgets.displayName = 'amaui-Widgets'; export default Widgets;