// packages/block-library/src/button/edit.js
import clsx from "clsx";
import { NEW_TAB_TARGET, NOFOLLOW_REL } from "./constants";
import { getUpdatedLinkAttributes } from "./get-updated-link-attributes";
import removeAnchorTag from "../utils/remove-anchor-tag";
import { useToolsPanelDropdownMenuProps } from "../utils/hooks";
import { unlock } from "../lock-unlock";
import { __, sprintf } from "@wordpress/i18n";
import {
  useEffect,
  useState,
  useRef,
  useMemo,
  createInterpolateElement
} from "@wordpress/element";
import {
  TextControl,
  ToolbarButton,
  Popover,
  ExternalLink,
  __experimentalToolsPanel as ToolsPanel,
  __experimentalToolsPanelItem as ToolsPanelItem,
  __experimentalToggleGroupControl as ToggleGroupControl,
  __experimentalToggleGroupControlOption as ToggleGroupControlOption
} from "@wordpress/components";
import {
  AlignmentControl,
  BlockControls,
  InspectorControls,
  RichText,
  useBlockProps,
  LinkControl,
  __experimentalUseBorderProps as useBorderProps,
  __experimentalUseColorProps as useColorProps,
  __experimentalGetSpacingClassesAndStyles as useSpacingProps,
  __experimentalGetShadowClassesAndStyles as useShadowProps,
  __experimentalGetElementClassName,
  store as blockEditorStore,
  useBlockEditingMode,
  getTypographyClassesAndStyles as useTypographyProps,
  useSettings,
  privateApis as blockEditorPrivateApis
} from "@wordpress/block-editor";
import { displayShortcut, isKeyboardEvent, ENTER } from "@wordpress/keycodes";
import { link, linkOff } from "@wordpress/icons";
import {
  createBlock,
  cloneBlock,
  getDefaultBlockName,
  getBlockBindingsSource
} from "@wordpress/blocks";
import { useMergeRefs, useRefEffect } from "@wordpress/compose";
import { useSelect, useDispatch } from "@wordpress/data";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
var { HTMLElementControl } = unlock(blockEditorPrivateApis);
var LINK_SETTINGS = [
  ...LinkControl.DEFAULT_LINK_SETTINGS,
  {
    id: "nofollow",
    title: __("Mark as nofollow")
  }
];
function useEnter(props) {
  const { replaceBlocks, selectionChange } = useDispatch(blockEditorStore);
  const { getBlock, getBlockRootClientId, getBlockIndex } = useSelect(blockEditorStore);
  const propsRef = useRef(props);
  propsRef.current = props;
  return useRefEffect((element) => {
    function onKeyDown(event) {
      if (event.defaultPrevented || event.keyCode !== ENTER) {
        return;
      }
      const { content, clientId } = propsRef.current;
      if (content.length) {
        return;
      }
      event.preventDefault();
      const topParentListBlock = getBlock(
        getBlockRootClientId(clientId)
      );
      const blockIndex = getBlockIndex(clientId);
      const head = cloneBlock({
        ...topParentListBlock,
        innerBlocks: topParentListBlock.innerBlocks.slice(
          0,
          blockIndex
        )
      });
      const middle = createBlock(getDefaultBlockName());
      const after = topParentListBlock.innerBlocks.slice(
        blockIndex + 1
      );
      const tail = after.length ? [
        cloneBlock({
          ...topParentListBlock,
          innerBlocks: after
        })
      ] : [];
      replaceBlocks(
        topParentListBlock.clientId,
        [head, middle, ...tail],
        1
      );
      selectionChange(middle.clientId);
    }
    element.addEventListener("keydown", onKeyDown);
    return () => {
      element.removeEventListener("keydown", onKeyDown);
    };
  }, []);
}
function WidthPanel({ selectedWidth, setAttributes }) {
  const dropdownMenuProps = useToolsPanelDropdownMenuProps();
  return /* @__PURE__ */ jsx(
    ToolsPanel,
    {
      label: __("Settings"),
      resetAll: () => setAttributes({ width: void 0 }),
      dropdownMenuProps,
      children: /* @__PURE__ */ jsx(
        ToolsPanelItem,
        {
          label: __("Width"),
          isShownByDefault: true,
          hasValue: () => !!selectedWidth,
          onDeselect: () => setAttributes({ width: void 0 }),
          __nextHasNoMarginBottom: true,
          children: /* @__PURE__ */ jsx(
            ToggleGroupControl,
            {
              label: __("Width"),
              value: selectedWidth,
              onChange: (newWidth) => setAttributes({ width: newWidth }),
              isBlock: true,
              __next40pxDefaultSize: true,
              __nextHasNoMarginBottom: true,
              children: [25, 50, 75, 100].map((widthValue) => {
                return /* @__PURE__ */ jsx(
                  ToggleGroupControlOption,
                  {
                    value: widthValue,
                    label: sprintf(
                      /* translators: %d: Percentage value. */
                      __("%d%%"),
                      widthValue
                    )
                  },
                  widthValue
                );
              })
            }
          )
        }
      )
    }
  );
}
function ButtonEdit(props) {
  const {
    attributes,
    setAttributes,
    className,
    isSelected,
    onReplace,
    mergeBlocks,
    clientId,
    context
  } = props;
  const {
    tagName,
    textAlign,
    linkTarget,
    placeholder,
    rel,
    style,
    text,
    url,
    width,
    metadata
  } = attributes;
  const TagName = tagName || "a";
  function onKeyDown(event) {
    if (isKeyboardEvent.primary(event, "k")) {
      startEditing(event);
    } else if (isKeyboardEvent.primaryShift(event, "k")) {
      unlink();
      richTextRef.current?.focus();
    }
  }
  const [popoverAnchor, setPopoverAnchor] = useState(null);
  const borderProps = useBorderProps(attributes);
  const colorProps = useColorProps(attributes);
  const spacingProps = useSpacingProps(attributes);
  const shadowProps = useShadowProps(attributes);
  const ref = useRef();
  const richTextRef = useRef();
  const blockProps = useBlockProps({
    ref: useMergeRefs([setPopoverAnchor, ref]),
    onKeyDown
  });
  const blockEditingMode = useBlockEditingMode();
  const [isEditingURL, setIsEditingURL] = useState(false);
  const isURLSet = !!url;
  const opensInNewTab = linkTarget === NEW_TAB_TARGET;
  const nofollow = !!rel?.includes(NOFOLLOW_REL);
  const isLinkTag = "a" === TagName;
  const {
    createPageEntity,
    userCanCreatePages,
    lockUrlControls = false
  } = useSelect(
    (select) => {
      if (!isSelected) {
        return {};
      }
      const _settings = select(blockEditorStore).getSettings();
      const blockBindingsSource = getBlockBindingsSource(
        metadata?.bindings?.url?.source
      );
      return {
        createPageEntity: _settings.__experimentalCreatePageEntity,
        userCanCreatePages: _settings.__experimentalUserCanCreatePages,
        lockUrlControls: !!metadata?.bindings?.url && !blockBindingsSource?.canUserEditValue?.({
          select,
          context,
          args: metadata?.bindings?.url?.args
        })
      };
    },
    [context, isSelected, metadata?.bindings?.url]
  );
  async function handleCreate(pageTitle) {
    const page = await createPageEntity({
      title: pageTitle,
      status: "draft"
    });
    return {
      id: page.id,
      type: page.type,
      title: page.title.rendered,
      url: page.link,
      kind: "post-type"
    };
  }
  function createButtonText(searchTerm) {
    return createInterpolateElement(
      sprintf(
        /* translators: %s: search term. */
        __("Create page: <mark>%s</mark>"),
        searchTerm
      ),
      { mark: /* @__PURE__ */ jsx("mark", {}) }
    );
  }
  function startEditing(event) {
    event.preventDefault();
    setIsEditingURL(true);
  }
  function unlink() {
    setAttributes({
      url: void 0,
      linkTarget: void 0,
      rel: void 0
    });
    setIsEditingURL(false);
  }
  useEffect(() => {
    if (!isSelected) {
      setIsEditingURL(false);
    }
  }, [isSelected]);
  const linkValue = useMemo(
    () => ({ url, opensInNewTab, nofollow }),
    [url, opensInNewTab, nofollow]
  );
  const useEnterRef = useEnter({ content: text, clientId });
  const mergedRef = useMergeRefs([useEnterRef, richTextRef]);
  const [fluidTypographySettings, layout] = useSettings(
    "typography.fluid",
    "layout"
  );
  const typographyProps = useTypographyProps(attributes, {
    typography: {
      fluid: fluidTypographySettings
    },
    layout: {
      wideSize: layout?.wideSize
    }
  });
  const hasNonContentControls = blockEditingMode === "default";
  const hasBlockControls = hasNonContentControls || isLinkTag && !lockUrlControls;
  return /* @__PURE__ */ jsxs(Fragment, { children: [
    /* @__PURE__ */ jsx(
      "div",
      {
        ...blockProps,
        className: clsx(blockProps.className, {
          [`has-custom-width wp-block-button__width-${width}`]: width
        }),
        children: /* @__PURE__ */ jsx(
          RichText,
          {
            ref: mergedRef,
            "aria-label": __("Button text"),
            placeholder: placeholder || __("Add text\u2026"),
            value: text,
            onChange: (value) => setAttributes({
              text: removeAnchorTag(value)
            }),
            withoutInteractiveFormatting: true,
            className: clsx(
              className,
              "wp-block-button__link",
              colorProps.className,
              borderProps.className,
              typographyProps.className,
              {
                [`has-text-align-${textAlign}`]: textAlign,
                // For backwards compatibility add style that isn't
                // provided via block support.
                "no-border-radius": style?.border?.radius === 0,
                [`has-custom-font-size`]: blockProps.style.fontSize
              },
              __experimentalGetElementClassName("button")
            ),
            style: {
              ...borderProps.style,
              ...colorProps.style,
              ...spacingProps.style,
              ...shadowProps.style,
              ...typographyProps.style,
              writingMode: void 0
            },
            onReplace,
            onMerge: mergeBlocks,
            identifier: "text"
          }
        )
      }
    ),
    hasBlockControls && /* @__PURE__ */ jsxs(BlockControls, { group: "block", children: [
      hasNonContentControls && /* @__PURE__ */ jsx(
        AlignmentControl,
        {
          value: textAlign,
          onChange: (nextAlign) => {
            setAttributes({ textAlign: nextAlign });
          }
        }
      ),
      isLinkTag && !lockUrlControls && /* @__PURE__ */ jsx(
        ToolbarButton,
        {
          name: "link",
          icon: !isURLSet ? link : linkOff,
          title: !isURLSet ? __("Link") : __("Unlink"),
          shortcut: !isURLSet ? displayShortcut.primary("k") : displayShortcut.primaryShift("k"),
          onClick: !isURLSet ? startEditing : unlink,
          isActive: isURLSet
        }
      )
    ] }),
    isLinkTag && isSelected && (isEditingURL || isURLSet) && !lockUrlControls && /* @__PURE__ */ jsx(
      Popover,
      {
        placement: "bottom",
        onClose: () => {
          setIsEditingURL(false);
          richTextRef.current?.focus();
        },
        anchor: popoverAnchor,
        focusOnMount: isEditingURL ? "firstElement" : false,
        __unstableSlotName: "__unstable-block-tools-after",
        shift: true,
        children: /* @__PURE__ */ jsx(
          LinkControl,
          {
            value: linkValue,
            onChange: ({
              url: newURL,
              opensInNewTab: newOpensInNewTab,
              nofollow: newNofollow
            }) => setAttributes(
              getUpdatedLinkAttributes({
                rel,
                url: newURL,
                opensInNewTab: newOpensInNewTab,
                nofollow: newNofollow
              })
            ),
            onRemove: () => {
              unlink();
              richTextRef.current?.focus();
            },
            forceIsEditingLink: isEditingURL,
            settings: LINK_SETTINGS,
            createSuggestion: createPageEntity && handleCreate,
            withCreateSuggestion: userCanCreatePages,
            createSuggestionButtonText: createButtonText
          }
        )
      }
    ),
    /* @__PURE__ */ jsx(InspectorControls, { children: /* @__PURE__ */ jsx(
      WidthPanel,
      {
        selectedWidth: width,
        setAttributes
      }
    ) }),
    /* @__PURE__ */ jsxs(InspectorControls, { group: "advanced", children: [
      /* @__PURE__ */ jsx(
        HTMLElementControl,
        {
          tagName,
          onChange: (value) => setAttributes({ tagName: value }),
          options: [
            { label: __("Default (<a>)"), value: "a" },
            { label: "<button>", value: "button" }
          ]
        }
      ),
      isLinkTag && /* @__PURE__ */ jsx(
        TextControl,
        {
          __next40pxDefaultSize: true,
          __nextHasNoMarginBottom: true,
          label: __("Link relation"),
          help: createInterpolateElement(
            __(
              "The <a>Link Relation</a> attribute defines the relationship between a linked resource and the current document."
            ),
            {
              a: /* @__PURE__ */ jsx(ExternalLink, { href: "https://developer.mozilla.org/docs/Web/HTML/Attributes/rel" })
            }
          ),
          value: rel || "",
          onChange: (newRel) => setAttributes({ rel: newRel })
        }
      )
    ] })
  ] });
}
var edit_default = ButtonEdit;
export {
  edit_default as default
};
//# sourceMappingURL=edit.js.map
