"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// packages/block-editor/src/hooks/block-bindings.js
var block_bindings_exports = {};
__export(block_bindings_exports, {
  BlockBindingsPanel: () => BlockBindingsPanel,
  default: () => block_bindings_default
});
module.exports = __toCommonJS(block_bindings_exports);
var import_es6 = __toESM(require("fast-deep-equal/es6"));
var import_i18n = require("@wordpress/i18n");
var import_blocks = require("@wordpress/blocks");
var import_components = require("@wordpress/components");
var import_data = require("@wordpress/data");
var import_element = require("@wordpress/element");
var import_compose = require("@wordpress/compose");
var import_block_bindings = require("../utils/block-bindings");
var import_lock_unlock = require("../lock-unlock");
var import_inspector_controls = __toESM(require("../components/inspector-controls"));
var import_block_context = __toESM(require("../components/block-context"));
var import_block_edit = require("../components/block-edit");
var import_store = require("../store");
var import_jsx_runtime = require("react/jsx-runtime");
var { Menu } = (0, import_lock_unlock.unlock)(import_components.privateApis);
var getAttributeType = (blockName, attribute) => {
  const _attributeType = (0, import_blocks.getBlockType)(blockName).attributes?.[attribute]?.type;
  return _attributeType === "rich-text" ? "string" : _attributeType;
};
var useToolsPanelDropdownMenuProps = () => {
  const isMobile = (0, import_compose.useViewportMatch)("medium", "<");
  return !isMobile ? {
    popoverProps: {
      placement: "left-start",
      // For non-mobile, inner sidebar width (248px) - button width (24px) - border (1px) + padding (16px) + spacing (20px)
      offset: 259
    }
  } : {};
};
function BlockBindingsPanelMenuContent({ attribute, binding, sources }) {
  const { clientId } = (0, import_block_edit.useBlockEditContext)();
  const { updateBlockBindings } = (0, import_block_bindings.useBlockBindingsUtils)();
  const isMobile = (0, import_compose.useViewportMatch)("medium", "<");
  const blockContext = (0, import_element.useContext)(import_block_context.default);
  const { attributeType, select } = (0, import_data.useSelect)(
    (_select) => {
      const { name: blockName } = _select(import_store.store).getBlock(clientId);
      return {
        attributeType: getAttributeType(blockName, attribute),
        select: _select
      };
    },
    [clientId, attribute]
  );
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu, { placement: isMobile ? "bottom-start" : "left-start", children: Object.entries(sources).map(([sourceKey, data]) => {
    const sourceDataItems = data.filter(
      (item) => item.type === attributeType
    );
    const noItemsAvailable = !sourceDataItems || sourceDataItems.length === 0;
    if (noItemsAvailable) {
      return null;
    }
    const source = (0, import_blocks.getBlockBindingsSource)(sourceKey);
    return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
      Menu,
      {
        placement: isMobile ? "bottom-start" : "left-start",
        children: [
          /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.SubmenuTriggerItem, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.ItemLabel, { children: source.label }) }),
          /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.Popover, { gutter: 8, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.Group, { children: sourceDataItems.map((item) => {
            const itemBindings = {
              source: sourceKey,
              args: item.args || {
                key: item.key
              }
            };
            let values = {};
            try {
              values = source.getValues({
                select,
                context: blockContext,
                bindings: {
                  [attribute]: itemBindings
                }
              });
            } catch (e) {
            }
            return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
              Menu.CheckboxItem,
              {
                onChange: () => {
                  const isCurrentlySelected = (0, import_es6.default)(
                    binding?.args,
                    item.args
                  ) ?? // Deprecate key dependency in 7.0.
                  item.key === binding?.args?.key;
                  if (isCurrentlySelected) {
                    updateBlockBindings({
                      [attribute]: void 0
                    });
                  } else {
                    updateBlockBindings({
                      [attribute]: itemBindings
                    });
                  }
                },
                name: attribute + "-binding",
                value: values[attribute],
                checked: (0, import_es6.default)(
                  binding?.args,
                  item.args
                ) ?? // Deprecate key dependency in 7.0.
                item.key === binding?.args?.key,
                children: [
                  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.ItemLabel, { children: item.label }),
                  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.ItemHelpText, { children: values[attribute] })
                ]
              },
              sourceKey + JSON.stringify(
                item.args
              ) || item.key
            );
          }) }) })
        ]
      },
      sourceKey
    );
  }) });
}
function BlockBindingsAttribute({ attribute, binding, sources, blockName }) {
  const { source: sourceName, args } = binding || {};
  const data = sources?.[sourceName];
  const source = (0, import_blocks.getBlockBindingsSource)(sourceName);
  let displayText;
  let isValid = true;
  const isNotBound = binding === void 0;
  if (isNotBound) {
    const attributeType = getAttributeType(blockName, attribute);
    const hasCompatibleSources = Object.values(sources).some(
      (items) => items.some((item) => item.type === attributeType)
    );
    if (!hasCompatibleSources) {
      displayText = (0, import_i18n.__)("No sources available");
    } else {
      displayText = (0, import_i18n.__)("Not connected");
    }
    isValid = true;
  } else if (!source) {
    isValid = false;
    displayText = (0, import_i18n.__)("Source not registered");
  } else {
    displayText = data?.find((item) => (0, import_es6.default)(item.args, args))?.label || source?.label || sourceName;
  }
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.__experimentalVStack, { className: "block-editor-bindings__item", spacing: 0, children: [
    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.__experimentalText, { truncate: true, children: attribute }),
    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
      import_components.__experimentalText,
      {
        truncate: true,
        variant: isValid ? "muted" : void 0,
        isDestructive: !isValid,
        children: displayText
      }
    )
  ] });
}
function ReadOnlyBlockBindingsPanelItem({
  attribute,
  binding,
  sources,
  blockName
}) {
  const isMobile = (0, import_compose.useViewportMatch)("medium", "<");
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.__experimentalToolsPanelItem, { hasValue: () => !!binding, label: attribute, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu, { placement: isMobile ? "bottom-start" : "left-start", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.TriggerButton, { render: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.__experimentalItem, {}), disabled: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    BlockBindingsAttribute,
    {
      attribute,
      binding,
      sources,
      blockName
    }
  ) }) }) });
}
function EditableBlockBindingsPanelItem({
  attribute,
  binding,
  sources,
  blockName
}) {
  const { updateBlockBindings } = (0, import_block_bindings.useBlockBindingsUtils)();
  const isMobile = (0, import_compose.useViewportMatch)("medium", "<");
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    import_components.__experimentalToolsPanelItem,
    {
      hasValue: () => !!binding,
      label: attribute,
      onDeselect: () => {
        updateBlockBindings({
          [attribute]: void 0
        });
      },
      children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Menu, { placement: isMobile ? "bottom-start" : "left-start", children: [
        /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.TriggerButton, { render: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.__experimentalItem, {}), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
          BlockBindingsAttribute,
          {
            attribute,
            binding,
            sources,
            blockName
          }
        ) }),
        /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu.Popover, { gutter: isMobile ? 8 : 36, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
          BlockBindingsPanelMenuContent,
          {
            attribute,
            binding,
            sources
          }
        ) })
      ] })
    }
  );
}
var BlockBindingsPanel = ({ name: blockName, metadata }) => {
  const blockContext = (0, import_element.useContext)(import_block_context.default);
  const { removeAllBlockBindings } = (0, import_block_bindings.useBlockBindingsUtils)();
  const dropdownMenuProps = useToolsPanelDropdownMenuProps();
  const { canUpdateBlockBindings, bindableAttributes } = (0, import_data.useSelect)(
    (select) => {
      const { __experimentalBlockBindingsSupportedAttributes } = select(import_store.store).getSettings();
      return {
        canUpdateBlockBindings: select(import_store.store).getSettings().canUpdateBlockBindings,
        bindableAttributes: __experimentalBlockBindingsSupportedAttributes?.[blockName]
      };
    },
    [blockName]
  );
  const sources = (0, import_data.useSelect)(
    (select) => {
      const { getAllBlockBindingsSources } = (0, import_lock_unlock.unlock)(
        select(import_blocks.store)
      );
      const data = {};
      Object.entries(getAllBlockBindingsSources()).forEach(
        ([sourceName, source]) => {
          if (!source.getFieldsList) {
            return;
          }
          const context = {};
          if (source.usesContext?.length) {
            for (const key of source.usesContext) {
              context[key] = blockContext[key];
            }
          }
          const items = source.getFieldsList({
            select,
            context
          });
          if (items?.length) {
            data[sourceName] = items;
          }
        }
      );
      return data;
    },
    [blockContext]
  );
  if (!bindableAttributes || bindableAttributes.length === 0) {
    return null;
  }
  const { bindings } = metadata || {};
  const hasCompatibleData = Object.keys(sources).length > 0;
  const readOnly = !canUpdateBlockBindings || !hasCompatibleData;
  if (bindings === void 0 && !hasCompatibleData) {
    return null;
  }
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_inspector_controls.default, { group: "bindings", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
    import_components.__experimentalToolsPanel,
    {
      label: (0, import_i18n.__)("Attributes"),
      resetAll: () => {
        removeAllBlockBindings();
      },
      dropdownMenuProps,
      className: "block-editor-bindings__panel",
      children: [
        /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.__experimentalItemGroup, { isBordered: true, isSeparated: true, children: bindableAttributes.map((attribute) => {
          const binding = bindings?.[attribute];
          const attributeType = getAttributeType(
            blockName,
            attribute
          );
          const hasCompatibleDataForAttribute = Object.values(
            sources
          ).some(
            (data) => data.some((item) => item.type === attributeType)
          );
          const isAttributeReadOnly = readOnly || !hasCompatibleDataForAttribute;
          return isAttributeReadOnly ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
            ReadOnlyBlockBindingsPanelItem,
            {
              attribute,
              binding,
              sources,
              blockName
            },
            attribute
          ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
            EditableBlockBindingsPanelItem,
            {
              attribute,
              binding,
              sources,
              blockName
            },
            attribute
          );
        }) }),
        /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.__experimentalText, { as: "div", variant: "muted", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: (0, import_i18n.__)(
          "Attributes connected to custom fields or other dynamic data."
        ) }) })
      ]
    }
  ) });
};
var block_bindings_default = {
  edit: BlockBindingsPanel,
  attributeKeys: ["metadata"],
  hasSupport(name) {
    return ![
      "core/post-date",
      "core/navigation-link",
      "core/navigation-submenu"
    ].includes(name);
  }
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  BlockBindingsPanel
});
//# sourceMappingURL=block-bindings.js.map
