UNPKG

@wordpress/interface

Version:

Interface module for WordPress. The package contains shared functionality across the modern JavaScript-based WordPress screens.

277 lines (272 loc) 10.1 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _clsx = _interopRequireDefault(require("clsx")); var _components = require("@wordpress/components"); var _data = require("@wordpress/data"); var _i18n = require("@wordpress/i18n"); var _icons = require("@wordpress/icons"); var _element = require("@wordpress/element"); var _viewport = require("@wordpress/viewport"); var _preferences = require("@wordpress/preferences"); var _compose = require("@wordpress/compose"); var _plugins = require("@wordpress/plugins"); var _complementaryAreaHeader = _interopRequireDefault(require("../complementary-area-header")); var _complementaryAreaMoreMenuItem = _interopRequireDefault(require("../complementary-area-more-menu-item")); var _complementaryAreaToggle = _interopRequireDefault(require("../complementary-area-toggle")); var _pinnedItems = _interopRequireDefault(require("../pinned-items")); var _store = require("../../store"); var _jsxRuntime = require("react/jsx-runtime"); /** * External dependencies */ /** * WordPress dependencies */ /** * Internal dependencies */ const ANIMATION_DURATION = 0.3; function ComplementaryAreaSlot({ scope, ...props }) { return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Slot, { name: `ComplementaryArea/${scope}`, ...props }); } const SIDEBAR_WIDTH = 280; const variants = { open: { width: SIDEBAR_WIDTH }, closed: { width: 0 }, mobileOpen: { width: '100vw' } }; function ComplementaryAreaFill({ activeArea, isActive, scope, children, className, id }) { const disableMotion = (0, _compose.useReducedMotion)(); const isMobileViewport = (0, _compose.useViewportMatch)('medium', '<'); // This is used to delay the exit animation to the next tick. // The reason this is done is to allow us to apply the right transition properties // When we switch from an open sidebar to another open sidebar. // we don't want to animate in this case. const previousActiveArea = (0, _compose.usePrevious)(activeArea); const previousIsActive = (0, _compose.usePrevious)(isActive); const [, setState] = (0, _element.useState)({}); (0, _element.useEffect)(() => { setState({}); }, [isActive]); const transition = { type: 'tween', duration: disableMotion || isMobileViewport || !!previousActiveArea && !!activeArea && activeArea !== previousActiveArea ? 0 : ANIMATION_DURATION, ease: [0.6, 0, 0.4, 1] }; return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Fill, { name: `ComplementaryArea/${scope}`, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__unstableAnimatePresence, { initial: false, children: (previousIsActive || isActive) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__unstableMotion.div, { variants: variants, initial: "closed", animate: isMobileViewport ? 'mobileOpen' : 'open', exit: "closed", transition: transition, className: "interface-complementary-area__fill", children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { id: id, className: className, style: { width: isMobileViewport ? '100vw' : SIDEBAR_WIDTH }, children: children }) }) }) }); } function useAdjustComplementaryListener(scope, identifier, activeArea, isActive, isSmall) { const previousIsSmallRef = (0, _element.useRef)(false); const shouldOpenWhenNotSmallRef = (0, _element.useRef)(false); const { enableComplementaryArea, disableComplementaryArea } = (0, _data.useDispatch)(_store.store); (0, _element.useEffect)(() => { // If the complementary area is active and the editor is switching from // a big to a small window size. if (isActive && isSmall && !previousIsSmallRef.current) { disableComplementaryArea(scope); // Flag the complementary area to be reopened when the window size // goes from small to big. shouldOpenWhenNotSmallRef.current = true; } else if ( // If there is a flag indicating the complementary area should be // enabled when we go from small to big window size and we are going // from a small to big window size. shouldOpenWhenNotSmallRef.current && !isSmall && previousIsSmallRef.current) { // Remove the flag indicating the complementary area should be // enabled. shouldOpenWhenNotSmallRef.current = false; enableComplementaryArea(scope, identifier); } else if ( // If the flag is indicating the current complementary should be // reopened but another complementary area becomes active, remove // the flag. shouldOpenWhenNotSmallRef.current && activeArea && activeArea !== identifier) { shouldOpenWhenNotSmallRef.current = false; } if (isSmall !== previousIsSmallRef.current) { previousIsSmallRef.current = isSmall; } }, [isActive, isSmall, scope, identifier, activeArea, disableComplementaryArea, enableComplementaryArea]); } function ComplementaryArea({ children, className, closeLabel = (0, _i18n.__)('Close plugin'), identifier: identifierProp, header, headerClassName, icon: iconProp, isPinnable = true, panelClassName, scope, name, title, toggleShortcut, isActiveByDefault }) { const context = (0, _plugins.usePluginContext)(); const icon = iconProp || context.icon; const identifier = identifierProp || `${context.name}/${name}`; // This state is used to delay the rendering of the Fill // until the initial effect runs. // This prevents the animation from running on mount if // the complementary area is active by default. const [isReady, setIsReady] = (0, _element.useState)(false); const { isLoading, isActive, isPinned, activeArea, isSmall, isLarge, showIconLabels } = (0, _data.useSelect)(select => { const { getActiveComplementaryArea, isComplementaryAreaLoading, isItemPinned } = select(_store.store); const { get } = select(_preferences.store); const _activeArea = getActiveComplementaryArea(scope); return { isLoading: isComplementaryAreaLoading(scope), isActive: _activeArea === identifier, isPinned: isItemPinned(scope, identifier), activeArea: _activeArea, isSmall: select(_viewport.store).isViewportMatch('< medium'), isLarge: select(_viewport.store).isViewportMatch('large'), showIconLabels: get('core', 'showIconLabels') }; }, [identifier, scope]); const isMobileViewport = (0, _compose.useViewportMatch)('medium', '<'); useAdjustComplementaryListener(scope, identifier, activeArea, isActive, isSmall); const { enableComplementaryArea, disableComplementaryArea, pinItem, unpinItem } = (0, _data.useDispatch)(_store.store); (0, _element.useEffect)(() => { // Set initial visibility: For large screens, enable if it's active by // default. For small screens, always initially disable. if (isActiveByDefault && activeArea === undefined && !isSmall) { enableComplementaryArea(scope, identifier); } else if (activeArea === undefined && isSmall) { disableComplementaryArea(scope, identifier); } setIsReady(true); }, [activeArea, isActiveByDefault, scope, identifier, isSmall, enableComplementaryArea, disableComplementaryArea]); if (!isReady) { return; } return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, { children: [isPinnable && /*#__PURE__*/(0, _jsxRuntime.jsx)(_pinnedItems.default, { scope: scope, children: isPinned && /*#__PURE__*/(0, _jsxRuntime.jsx)(_complementaryAreaToggle.default, { scope: scope, identifier: identifier, isPressed: isActive && (!showIconLabels || isLarge), "aria-expanded": isActive, "aria-disabled": isLoading, label: title, icon: showIconLabels ? _icons.check : icon, showTooltip: !showIconLabels, variant: showIconLabels ? 'tertiary' : undefined, size: "compact", shortcut: toggleShortcut }) }), name && isPinnable && /*#__PURE__*/(0, _jsxRuntime.jsx)(_complementaryAreaMoreMenuItem.default, { target: name, scope: scope, icon: icon, children: title }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(ComplementaryAreaFill, { activeArea: activeArea, isActive: isActive, className: (0, _clsx.default)('interface-complementary-area', className), scope: scope, id: identifier.replace('/', ':'), children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_complementaryAreaHeader.default, { className: headerClassName, closeLabel: closeLabel, onClose: () => disableComplementaryArea(scope), toggleButtonProps: { label: closeLabel, size: 'compact', shortcut: toggleShortcut, scope, identifier }, children: header || /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, { children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("h2", { className: "interface-complementary-area-header__title", children: title }), isPinnable && !isMobileViewport && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Button, { className: "interface-complementary-area__pin-unpin-item", icon: isPinned ? _icons.starFilled : _icons.starEmpty, label: isPinned ? (0, _i18n.__)('Unpin from toolbar') : (0, _i18n.__)('Pin to toolbar'), onClick: () => (isPinned ? unpinItem : pinItem)(scope, identifier), isPressed: isPinned, "aria-expanded": isPinned, size: "compact" })] }) }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Panel, { className: panelClassName, children: children })] })] }); } ComplementaryArea.Slot = ComplementaryAreaSlot; var _default = exports.default = ComplementaryArea; //# sourceMappingURL=index.js.map