@amaui/ui-react
Version:
UI for React
200 lines (199 loc) • 7.97 kB
JavaScript
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;