@onesy/ui-react
Version:
UI for React
201 lines (200 loc) • 7.85 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(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
import React from 'react';
import { is, unique } from '@onesy/utils';
import { classNames, style as styleMethod, useOnesyTheme } from '@onesy/style-react';
import IconMaterialClose from '@onesy/icons-material-rounded-react/IconMaterialCloseW100';
import IconMaterialWidgets from '@onesy/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',
'&.onesy-IconButton-root': {
position: 'absolute'
}
}
}), {
name: 'onesy-Widgets'
});
const Widgets = /*#__PURE__*/React.forwardRef((props_, ref) => {
const theme = useOnesyTheme();
const l = theme.l;
const props = React.useMemo(() => _objectSpread(_objectSpread(_objectSpread({}, theme?.ui?.elements?.all?.props?.default), theme?.ui?.elements?.onesyWidgets?.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, other), 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 : `${l('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) && [`onesy-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) && [`onesy-Widgets-icon-button`], classes.iconButton])
}, /*#__PURE__*/React.createElement(IconCloseItem, null)), /*#__PURE__*/React.cloneElement(item.element, _objectSpread({
className: classNames([staticClassName('Widgets', theme) && [`onesy-Widgets-widget`], classes.widget])
}, ['onesy-Weather', 'onesy-Watch'].includes(item.element.type?.displayName) ? {
shadow: true,
style: {
boxShadow: 'none'
}
} : undefined))));
})), children);
});
Widgets.displayName = 'onesy-Widgets';
export default Widgets;