UNPKG

@shopgate/engage

Version:
144 lines (140 loc) 4.57 kB
import React, { Suspense, useCallback } from 'react'; import PropTypes from 'prop-types'; import { makeStyles } from '@shopgate/engage/styles'; import { VisibilityOffIcon, TimeIcon, Loading } from '@shopgate/engage/components'; import { usePressHandler } from '@shopgate/engage/core/hooks'; import WidgetProvider from "./WidgetProvider"; import { dispatchWidgetPreviewEvent } from "./events"; import { useWidgetsPreview } from "./hooks"; import Tooltip from "./Tooltip"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; const useStyles = makeStyles()((theme, { marginTop, marginLeft }) => ({ root: { position: 'relative' }, widgetInfo: { zIndex: 12, position: 'absolute', top: -marginTop + (theme.spacing(0.5) + 1), left: -marginLeft + theme.spacing(0.5), fontSize: 24, padding: theme.spacing(0.5), display: 'flex', gap: theme.spacing(1), background: '#fff', borderRadius: 4, border: '1px solid rgba(0, 0, 0, 0.23)', ':empty': { display: 'none' } }, preview: { cursor: 'pointer' }, visibilityIcon: { color: '#f44336' }, scheduledIcon: { color: '#347DD3' }, scheduledIconExpired: { color: '#f44336' } })); /** * @typedef {import('./types').WidgetDefinition} WidgetDefinition */ /** * @typedef {import('./types').ScheduledStatus} ScheduledStatus */ /** * The Widget component. * @param {Object} props The component props. * @param {React.ComponentType} props.component The widget component to render. * @param {WidgetDefinition} props.definition The widget definition data. * @param {boolean} props.isPreview Whether the widget is in preview mode. * @param {boolean} props.isCustomLegacyWidget Whether the widget is a legacy custom widget provided * by an extension that's configured via an HTML comment inside a HTML widget. * @returns {JSX.Element} */ const Widget = ({ component: Component, definition, isPreview, isCustomLegacyWidget }) => { const { classes, cx } = useStyles({ marginTop: definition?.layout?.marginTop ?? 0, marginBottom: definition?.layout?.marginBottom ?? 0, marginLeft: definition?.layout?.marginLeft ?? 0, marginRight: definition?.layout?.marginRight ?? 0 }); const { setActiveWidget, activeWidget } = useWidgetsPreview(); // Handle clicks on the widget container in preview mode. Take care that highlighting only happens // when the widget is not already active, otherwise it would be confusing when users want to // interact with widget elements. const handleInteraction = useCallback(() => { setActiveWidget(definition.code, activeWidget !== definition.code); dispatchWidgetPreviewEvent('widget-clicked', definition.code); }, [activeWidget, definition.code, setActiveWidget]); const handlers = usePressHandler(handleInteraction); if (!Component) { return null; } return /*#__PURE__*/_jsxs("section", { id: `widget-code-${definition.code}`, className: cx(classes.root, { [classes.preview]: isPreview }), style: { marginTop: definition?.layout?.marginTop, marginBottom: definition?.layout?.marginBottom, marginLeft: definition?.layout?.marginLeft, marginRight: definition?.layout?.marginRight }, "data-widget-name": definition.widgetConfigDefinitionCode, ...(isPreview && { ...handlers }), children: [isPreview && definition?.meta && /*#__PURE__*/_jsxs("div", { className: classes.widgetInfo, children: [definition.meta?.scheduled?.isScheduled && /*#__PURE__*/_jsx(Tooltip, { text: definition.meta?.scheduled?.tooltip, children: /*#__PURE__*/_jsx(TimeIcon, { className: cx(classes.scheduledIcon, { [classes.scheduledIconExpired]: definition.meta?.scheduled?.isExpired }) }) }), definition.meta?.hidden?.isHidden && /*#__PURE__*/_jsx(Tooltip, { text: definition.meta?.hidden?.tooltip, children: /*#__PURE__*/_jsx(VisibilityOffIcon, { className: classes.visibilityIcon }) })] }), /*#__PURE__*/_jsx(WidgetProvider, { definition: definition, isPreview: isPreview, children: /*#__PURE__*/_jsx(Suspense, { fallback: /*#__PURE__*/_jsx(Loading, {}), children: /*#__PURE__*/_jsx(Component, { ...(isCustomLegacyWidget ? { settings: definition.widgetConfig } : {}) }) }) })] }); }; Widget.defaultProps = { isCustomLegacyWidget: false }; export default Widget;