"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/components/background-image-control/index.js
var background_image_control_exports = {};
__export(background_image_control_exports, {
  backgroundPositionToCoords: () => backgroundPositionToCoords,
  coordsToBackgroundPosition: () => coordsToBackgroundPosition,
  default: () => BackgroundImagePanel
});
module.exports = __toCommonJS(background_image_control_exports);
var import_clsx = __toESM(require("clsx"));
var import_components = require("@wordpress/components");
var import_icons = require("@wordpress/icons");
var import_i18n = require("@wordpress/i18n");
var import_notices = require("@wordpress/notices");
var import_url = require("@wordpress/url");
var import_element = require("@wordpress/element");
var import_data = require("@wordpress/data");
var import_dom = require("@wordpress/dom");
var import_blob = require("@wordpress/blob");
var import_global_styles_engine = require("@wordpress/global-styles-engine");
var import_background_panel = require("../global-styles/background-panel");
var import_object = require("../../utils/object");
var import_media_replace_flow = __toESM(require("../media-replace-flow"));
var import_store = require("../../store");
var import_private_keys = require("../../store/private-keys");
var import_jsx_runtime = require("react/jsx-runtime");
var IMAGE_BACKGROUND_TYPE = "image";
var BACKGROUND_POPOVER_PROPS = {
  placement: "left-start",
  offset: 36,
  shift: true,
  className: "block-editor-global-styles-background-panel__popover"
};
var noop = () => {
};
var focusToggleButton = (containerRef) => {
  window.requestAnimationFrame(() => {
    const [toggleButton] = import_dom.focus.tabbable.find(containerRef?.current);
    if (!toggleButton) {
      return;
    }
    toggleButton.focus();
  });
};
function backgroundSizeHelpText(value) {
  if (value === "cover" || value === void 0) {
    return (0, import_i18n.__)("Image covers the space evenly.");
  }
  if (value === "contain") {
    return (0, import_i18n.__)("Image is contained without distortion.");
  }
  return (0, import_i18n.__)("Image has a fixed width.");
}
var coordsToBackgroundPosition = (value) => {
  if (!value || isNaN(value.x) && isNaN(value.y)) {
    return void 0;
  }
  const x = isNaN(value.x) ? 0.5 : value.x;
  const y = isNaN(value.y) ? 0.5 : value.y;
  return `${x * 100}% ${y * 100}%`;
};
var backgroundPositionToCoords = (value) => {
  if (!value) {
    return { x: void 0, y: void 0 };
  }
  let [x, y] = value.split(" ").map((v) => parseFloat(v) / 100);
  x = isNaN(x) ? void 0 : x;
  y = isNaN(y) ? x : y;
  return { x, y };
};
function InspectorImagePreviewItem({
  as = "span",
  imgUrl,
  toggleProps = {},
  filename,
  label,
  onToggleCallback = noop
}) {
  const { isOpen, ...restToggleProps } = toggleProps;
  (0, import_element.useEffect)(() => {
    if (typeof isOpen !== "undefined") {
      onToggleCallback(isOpen);
    }
  }, [isOpen, onToggleCallback]);
  const renderPreviewContent = () => {
    return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
      import_components.__experimentalHStack,
      {
        justify: "flex-start",
        as: "span",
        className: "block-editor-global-styles-background-panel__inspector-preview-inner",
        children: [
          imgUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
            "span",
            {
              className: "block-editor-global-styles-background-panel__inspector-image-indicator-wrapper",
              "aria-hidden": true,
              children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
                "span",
                {
                  className: "block-editor-global-styles-background-panel__inspector-image-indicator",
                  style: {
                    backgroundImage: `url(${imgUrl})`
                  }
                }
              )
            }
          ),
          /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.FlexItem, { as: "span", style: imgUrl ? {} : { flexGrow: 1 }, children: [
            /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
              import_components.__experimentalTruncate,
              {
                numberOfLines: 1,
                className: "block-editor-global-styles-background-panel__inspector-media-replace-title",
                children: label
              }
            ),
            /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.VisuallyHidden, { as: "span", children: imgUrl ? (0, import_i18n.sprintf)(
              /* translators: %s: file name */
              (0, import_i18n.__)("Background image: %s"),
              filename || label
            ) : (0, import_i18n.__)("No background image selected") })
          ] })
        ]
      }
    );
  };
  return as === "button" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Button, { __next40pxDefaultSize: true, ...restToggleProps, children: renderPreviewContent() }) : renderPreviewContent();
}
function BackgroundControlsPanel({
  label,
  filename,
  url: imgUrl,
  children,
  onToggle: onToggleCallback = noop,
  hasImageValue,
  onReset,
  containerRef
}) {
  if (!hasImageValue) {
    return;
  }
  const imgLabel = label || (0, import_url.getFilename)(imgUrl) || (0, import_i18n.__)("Add background image");
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    import_components.Dropdown,
    {
      popoverProps: BACKGROUND_POPOVER_PROPS,
      renderToggle: ({ onToggle, isOpen }) => {
        const toggleProps = {
          onClick: onToggle,
          className: "block-editor-global-styles-background-panel__dropdown-toggle",
          "aria-expanded": isOpen,
          "aria-label": (0, import_i18n.__)(
            "Background size, position and repeat options."
          ),
          isOpen
        };
        return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
          /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
            InspectorImagePreviewItem,
            {
              imgUrl,
              filename,
              label: imgLabel,
              toggleProps,
              as: "button",
              onToggleCallback
            }
          ),
          onReset && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
            import_components.Button,
            {
              __next40pxDefaultSize: true,
              label: (0, import_i18n.__)("Reset"),
              className: "block-editor-global-styles-background-panel__reset",
              size: "small",
              icon: import_icons.reset,
              onClick: () => {
                onReset();
                if (isOpen) {
                  onToggle();
                }
                focusToggleButton(containerRef);
              }
            }
          )
        ] });
      },
      renderContent: () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
        import_components.__experimentalDropdownContentWrapper,
        {
          className: "block-editor-global-styles-background-panel__dropdown-content-wrapper",
          paddingSize: "medium",
          children
        }
      )
    }
  );
}
function LoadingSpinner() {
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Placeholder, { className: "block-editor-global-styles-background-panel__loading", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Spinner, {}) });
}
function BackgroundImageControls({
  onChange,
  style,
  inheritedValue,
  onRemoveImage = noop,
  onResetImage = noop,
  displayInPanel,
  defaultValues,
  containerRef
}) {
  const [isUploading, setIsUploading] = (0, import_element.useState)(false);
  const { getSettings } = (0, import_data.useSelect)(import_store.store);
  const { id, title, url } = style?.background?.backgroundImage || {
    ...inheritedValue?.background?.backgroundImage
  };
  const { createErrorNotice } = (0, import_data.useDispatch)(import_notices.store);
  const onUploadError = (message) => {
    createErrorNotice(message, { type: "snackbar" });
    setIsUploading(false);
  };
  const resetBackgroundImage = () => onChange(
    (0, import_object.setImmutably)(
      style,
      ["background", "backgroundImage"],
      void 0
    )
  );
  const onSelectMedia = (media) => {
    if (!media || !media.url) {
      resetBackgroundImage();
      setIsUploading(false);
      return;
    }
    if ((0, import_blob.isBlobURL)(media.url)) {
      setIsUploading(true);
      return;
    }
    if (media.media_type && media.media_type !== IMAGE_BACKGROUND_TYPE || !media.media_type && media.type && media.type !== IMAGE_BACKGROUND_TYPE) {
      onUploadError(
        (0, import_i18n.__)("Only images can be used as a background image.")
      );
      return;
    }
    const sizeValue = style?.background?.backgroundSize || defaultValues?.backgroundSize;
    const positionValue = style?.background?.backgroundPosition;
    onChange(
      (0, import_object.setImmutably)(style, ["background"], {
        ...style?.background,
        backgroundImage: {
          url: media.url,
          id: media.id,
          source: "file",
          title: media.title || void 0
        },
        backgroundPosition: (
          /*
           * A background image uploaded and set in the editor receives a default background position of '50% 0',
           * when the background image size is the equivalent of "Tile".
           * This is to increase the chance that the image's focus point is visible.
           * This is in-editor only to assist with the user experience.
           */
          !positionValue && ("auto" === sizeValue || !sizeValue) ? "50% 0" : positionValue
        ),
        backgroundSize: sizeValue
      })
    );
    setIsUploading(false);
    focusToggleButton(containerRef);
  };
  const onFilesDrop = (filesList) => {
    getSettings().mediaUpload({
      allowedTypes: [IMAGE_BACKGROUND_TYPE],
      filesList,
      onFileChange([image]) {
        onSelectMedia(image);
      },
      onError: onUploadError,
      multiple: false
    });
  };
  const hasValue = (0, import_background_panel.hasBackgroundImageValue)(style);
  const onRemove = () => onChange(
    (0, import_object.setImmutably)(style, ["background"], {
      backgroundImage: "none"
    })
  );
  const canRemove = !hasValue && (0, import_background_panel.hasBackgroundImageValue)(inheritedValue);
  const imgLabel = title || (0, import_url.getFilename)(url) || (0, import_i18n.__)("Add background image");
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "block-editor-global-styles-background-panel__image-tools-panel-item", children: [
    isUploading && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LoadingSpinner, {}),
    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
      import_media_replace_flow.default,
      {
        mediaId: id,
        mediaURL: url,
        allowedTypes: [IMAGE_BACKGROUND_TYPE],
        accept: "image/*",
        onSelect: onSelectMedia,
        popoverProps: {
          className: (0, import_clsx.default)({
            "block-editor-global-styles-background-panel__media-replace-popover": displayInPanel
          })
        },
        name: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
          InspectorImagePreviewItem,
          {
            imgUrl: url,
            filename: title,
            label: imgLabel
          }
        ),
        renderToggle: (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Button, { ...props, __next40pxDefaultSize: true }),
        onError: onUploadError,
        onReset: () => {
          focusToggleButton(containerRef);
          onResetImage();
        },
        children: canRemove && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
          import_components.MenuItem,
          {
            onClick: () => {
              focusToggleButton(containerRef);
              onRemove();
              onRemoveImage();
            },
            children: (0, import_i18n.__)("Remove")
          }
        )
      }
    ),
    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
      import_components.DropZone,
      {
        onFilesDrop,
        label: (0, import_i18n.__)("Drop to upload")
      }
    )
  ] });
}
function BackgroundSizeControls({
  onChange,
  style,
  inheritedValue,
  defaultValues
}) {
  const sizeValue = style?.background?.backgroundSize || inheritedValue?.background?.backgroundSize;
  const repeatValue = style?.background?.backgroundRepeat || inheritedValue?.background?.backgroundRepeat;
  const imageValue = style?.background?.backgroundImage?.url || inheritedValue?.background?.backgroundImage?.url;
  const isUploadedImage = style?.background?.backgroundImage?.id;
  const positionValue = style?.background?.backgroundPosition || inheritedValue?.background?.backgroundPosition;
  const attachmentValue = style?.background?.backgroundAttachment || inheritedValue?.background?.backgroundAttachment;
  let currentValueForToggle = !sizeValue && isUploadedImage ? defaultValues?.backgroundSize : sizeValue || "auto";
  currentValueForToggle = !["cover", "contain", "auto"].includes(
    currentValueForToggle
  ) ? "auto" : currentValueForToggle;
  const repeatCheckedValue = !(repeatValue === "no-repeat" || currentValueForToggle === "cover" && repeatValue === void 0);
  const updateBackgroundSize = (next) => {
    let nextRepeat = repeatValue;
    let nextPosition = positionValue;
    if (next === "contain") {
      nextRepeat = "no-repeat";
      nextPosition = void 0;
    }
    if (next === "cover") {
      nextRepeat = void 0;
      nextPosition = void 0;
    }
    if ((currentValueForToggle === "cover" || currentValueForToggle === "contain") && next === "auto") {
      nextRepeat = void 0;
      if (!!style?.background?.backgroundImage?.id) {
        nextPosition = "50% 0";
      }
    }
    if (!next && currentValueForToggle === "auto") {
      next = "auto";
    }
    onChange(
      (0, import_object.setImmutably)(style, ["background"], {
        ...style?.background,
        backgroundPosition: nextPosition,
        backgroundRepeat: nextRepeat,
        backgroundSize: next
      })
    );
  };
  const updateBackgroundPosition = (next) => {
    onChange(
      (0, import_object.setImmutably)(
        style,
        ["background", "backgroundPosition"],
        coordsToBackgroundPosition(next)
      )
    );
  };
  const toggleIsRepeated = () => onChange(
    (0, import_object.setImmutably)(
      style,
      ["background", "backgroundRepeat"],
      repeatCheckedValue === true ? "no-repeat" : "repeat"
    )
  );
  const toggleScrollWithPage = () => onChange(
    (0, import_object.setImmutably)(
      style,
      ["background", "backgroundAttachment"],
      attachmentValue === "fixed" ? "scroll" : "fixed"
    )
  );
  const backgroundPositionValue = !positionValue && isUploadedImage && "contain" === sizeValue ? defaultValues?.backgroundPosition : positionValue;
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.__experimentalVStack, { spacing: 3, className: "single-column", children: [
    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
      import_components.FocalPointPicker,
      {
        __nextHasNoMarginBottom: true,
        label: (0, import_i18n.__)("Focal point"),
        url: imageValue,
        value: backgroundPositionToCoords(backgroundPositionValue),
        onChange: updateBackgroundPosition
      }
    ),
    /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
      import_components.ToggleControl,
      {
        __nextHasNoMarginBottom: true,
        label: (0, import_i18n.__)("Fixed background"),
        checked: attachmentValue === "fixed",
        onChange: toggleScrollWithPage
      }
    ),
    /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
      import_components.__experimentalToggleGroupControl,
      {
        __nextHasNoMarginBottom: true,
        size: "__unstable-large",
        label: (0, import_i18n.__)("Size"),
        value: currentValueForToggle,
        onChange: updateBackgroundSize,
        isBlock: true,
        help: backgroundSizeHelpText(
          sizeValue || defaultValues?.backgroundSize
        ),
        children: [
          /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
            import_components.__experimentalToggleGroupControlOption,
            {
              value: "cover",
              label: (0, import_i18n._x)(
                "Cover",
                "Size option for background image control"
              )
            },
            "cover"
          ),
          /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
            import_components.__experimentalToggleGroupControlOption,
            {
              value: "contain",
              label: (0, import_i18n._x)(
                "Contain",
                "Size option for background image control"
              )
            },
            "contain"
          ),
          /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
            import_components.__experimentalToggleGroupControlOption,
            {
              value: "auto",
              label: (0, import_i18n._x)(
                "Tile",
                "Size option for background image control"
              )
            },
            "tile"
          )
        ]
      }
    ),
    /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.__experimentalHStack, { justify: "flex-start", spacing: 2, as: "span", children: [
      /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
        import_components.__experimentalUnitControl,
        {
          "aria-label": (0, import_i18n.__)("Background image width"),
          onChange: updateBackgroundSize,
          value: sizeValue,
          size: "__unstable-large",
          __unstableInputWidth: "100px",
          min: 0,
          placeholder: (0, import_i18n.__)("Auto"),
          disabled: currentValueForToggle !== "auto" || currentValueForToggle === void 0
        }
      ),
      /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
        import_components.ToggleControl,
        {
          __nextHasNoMarginBottom: true,
          label: (0, import_i18n.__)("Repeat"),
          checked: repeatCheckedValue,
          onChange: toggleIsRepeated,
          disabled: currentValueForToggle === "cover"
        }
      )
    ] })
  ] });
}
function BackgroundImagePanel({
  value,
  onChange,
  inheritedValue = value,
  settings,
  defaultValues = {}
}) {
  const { globalStyles, _links } = (0, import_data.useSelect)((select) => {
    const { getSettings } = select(import_store.store);
    const _settings = getSettings();
    return {
      globalStyles: _settings[import_private_keys.globalStylesDataKey],
      _links: _settings[import_private_keys.globalStylesLinksDataKey]
    };
  }, []);
  const resolvedInheritedValue = (0, import_element.useMemo)(() => {
    const resolvedValues = {
      background: {}
    };
    if (!inheritedValue?.background) {
      return inheritedValue;
    }
    Object.entries(inheritedValue?.background).forEach(
      ([key, backgroundValue]) => {
        resolvedValues.background[key] = (0, import_global_styles_engine.getResolvedValue)(
          backgroundValue,
          {
            styles: globalStyles,
            _links
          }
        );
      }
    );
    return resolvedValues;
  }, [globalStyles, _links, inheritedValue]);
  const resetBackground = () => onChange((0, import_object.setImmutably)(value, ["background"], {}));
  const { title, url } = value?.background?.backgroundImage || {
    ...resolvedInheritedValue?.background?.backgroundImage
  };
  const hasImageValue = (0, import_background_panel.hasBackgroundImageValue)(value) || (0, import_background_panel.hasBackgroundImageValue)(resolvedInheritedValue);
  const imageValue = value?.background?.backgroundImage || inheritedValue?.background?.backgroundImage;
  const shouldShowBackgroundImageControls = hasImageValue && "none" !== imageValue && (settings?.background?.backgroundSize || settings?.background?.backgroundPosition || settings?.background?.backgroundRepeat);
  const [isDropDownOpen, setIsDropDownOpen] = (0, import_element.useState)(false);
  const containerRef = (0, import_element.useRef)();
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    "div",
    {
      ref: containerRef,
      className: (0, import_clsx.default)(
        "block-editor-global-styles-background-panel__inspector-media-replace-container",
        {
          "is-open": isDropDownOpen
        }
      ),
      children: shouldShowBackgroundImageControls ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
        BackgroundControlsPanel,
        {
          label: title,
          filename: title,
          url,
          onToggle: setIsDropDownOpen,
          hasImageValue,
          onReset: resetBackground,
          containerRef,
          children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_components.__experimentalVStack, { spacing: 3, className: "single-column", children: [
            /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
              BackgroundImageControls,
              {
                onChange,
                style: value,
                inheritedValue: resolvedInheritedValue,
                displayInPanel: true,
                onResetImage: () => {
                  setIsDropDownOpen(false);
                  resetBackground();
                },
                onRemoveImage: () => setIsDropDownOpen(false),
                defaultValues,
                containerRef
              }
            ),
            /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
              BackgroundSizeControls,
              {
                onChange,
                style: value,
                defaultValues,
                inheritedValue: resolvedInheritedValue
              }
            )
          ] })
        }
      ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
        BackgroundImageControls,
        {
          onChange,
          style: value,
          inheritedValue: resolvedInheritedValue,
          defaultValues,
          onResetImage: () => {
            setIsDropDownOpen(false);
            resetBackground();
          },
          onRemoveImage: () => setIsDropDownOpen(false),
          containerRef
        }
      )
    }
  );
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  backgroundPositionToCoords,
  coordsToBackgroundPosition
});
//# sourceMappingURL=index.js.map
