"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.useToolsPanelItem = useToolsPanelItem;
var _compose = require("@wordpress/compose");
var _element = require("@wordpress/element");
var styles = _interopRequireWildcard(require("../styles"));
var _context = require("../context");
var _context2 = require("../../context");
var _useCx = require("../../utils/hooks/use-cx");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
/**
 * WordPress dependencies
 */

/**
 * Internal dependencies
 */

const noop = () => {};
function useToolsPanelItem(props) {
  const {
    className,
    hasValue,
    isShownByDefault = false,
    label,
    panelId,
    resetAllFilter = noop,
    onDeselect,
    onSelect,
    ...otherProps
  } = (0, _context2.useContextSystem)(props, 'ToolsPanelItem');
  const {
    panelId: currentPanelId,
    menuItems,
    registerResetAllFilter,
    deregisterResetAllFilter,
    registerPanelItem,
    deregisterPanelItem,
    flagItemCustomization,
    isResetting,
    shouldRenderPlaceholderItems: shouldRenderPlaceholder,
    firstDisplayedItem,
    lastDisplayedItem,
    __experimentalFirstVisibleItemClass,
    __experimentalLastVisibleItemClass
  } = (0, _context.useToolsPanelContext)();

  // hasValue is a new function on every render, so do not add it as a
  // dependency to the useCallback hook! If needed, we should use a ref.
  const hasValueCallback = (0, _element.useCallback)(hasValue, [panelId]);
  // resetAllFilter is a new function on every render, so do not add it as a
  // dependency to the useCallback hook! If needed, we should use a ref.
  const resetAllFilterCallback = (0, _element.useCallback)(resetAllFilter, [panelId]);
  const previousPanelId = (0, _compose.usePrevious)(currentPanelId);
  const hasMatchingPanel = currentPanelId === panelId || currentPanelId === null;

  // Registering the panel item allows the panel to include it in its
  // automatically generated menu and determine its initial checked status.
  //
  // This is performed in a layout effect to ensure that the panel item
  // is registered before it is rendered preventing a rendering glitch.
  // See: https://github.com/WordPress/gutenberg/issues/56470
  (0, _element.useLayoutEffect)(() => {
    if (hasMatchingPanel && previousPanelId !== null) {
      registerPanelItem({
        hasValue: hasValueCallback,
        isShownByDefault,
        label,
        panelId
      });
    }
    return () => {
      if (previousPanelId === null && !!currentPanelId || currentPanelId === panelId) {
        deregisterPanelItem(label);
      }
    };
  }, [currentPanelId, hasMatchingPanel, isShownByDefault, label, hasValueCallback, panelId, previousPanelId, registerPanelItem, deregisterPanelItem]);
  (0, _element.useEffect)(() => {
    if (hasMatchingPanel) {
      registerResetAllFilter(resetAllFilterCallback);
    }
    return () => {
      if (hasMatchingPanel) {
        deregisterResetAllFilter(resetAllFilterCallback);
      }
    };
  }, [registerResetAllFilter, deregisterResetAllFilter, resetAllFilterCallback, hasMatchingPanel]);

  // Note: `label` is used as a key when building menu item state in
  // `ToolsPanel`.
  const menuGroup = isShownByDefault ? 'default' : 'optional';
  const isMenuItemChecked = menuItems?.[menuGroup]?.[label];
  const wasMenuItemChecked = (0, _compose.usePrevious)(isMenuItemChecked);
  const isRegistered = menuItems?.[menuGroup]?.[label] !== undefined;
  const isValueSet = hasValue();
  // Notify the panel when an item's value has changed except for optional
  // items without value because the item should not cause itself to hide.
  (0, _element.useEffect)(() => {
    if (!isShownByDefault && !isValueSet) {
      return;
    }
    flagItemCustomization(isValueSet, label, menuGroup);
  }, [isValueSet, menuGroup, label, flagItemCustomization, isShownByDefault]);

  // Determine if the panel item's corresponding menu is being toggled and
  // trigger appropriate callback if it is.
  (0, _element.useEffect)(() => {
    // We check whether this item is currently registered as items rendered
    // via fills can persist through the parent panel being remounted.
    // See: https://github.com/WordPress/gutenberg/pull/45673
    if (!isRegistered || isResetting || !hasMatchingPanel) {
      return;
    }
    if (isMenuItemChecked && !isValueSet && !wasMenuItemChecked) {
      onSelect?.();
    }
    if (!isMenuItemChecked && isValueSet && wasMenuItemChecked) {
      onDeselect?.();
    }
  }, [hasMatchingPanel, isMenuItemChecked, isRegistered, isResetting, isValueSet, wasMenuItemChecked, onSelect, onDeselect]);

  // The item is shown if it is a default control regardless of whether it
  // has a value. Optional items are shown when they are checked or have
  // a value.
  const isShown = isShownByDefault ? menuItems?.[menuGroup]?.[label] !== undefined : isMenuItemChecked;
  const cx = (0, _useCx.useCx)();
  const classes = (0, _element.useMemo)(() => {
    const shouldApplyPlaceholderStyles = shouldRenderPlaceholder && !isShown;
    const firstItemStyle = firstDisplayedItem === label && __experimentalFirstVisibleItemClass;
    const lastItemStyle = lastDisplayedItem === label && __experimentalLastVisibleItemClass;
    return cx(styles.ToolsPanelItem, shouldApplyPlaceholderStyles && styles.ToolsPanelItemPlaceholder, !shouldApplyPlaceholderStyles && className, firstItemStyle, lastItemStyle);
  }, [isShown, shouldRenderPlaceholder, className, cx, firstDisplayedItem, lastDisplayedItem, __experimentalFirstVisibleItemClass, __experimentalLastVisibleItemClass, label]);
  return {
    ...otherProps,
    isShown,
    shouldRenderPlaceholder,
    className: classes
  };
}
//# sourceMappingURL=hook.js.map