UNPKG

@wordpress/block-library

Version:
250 lines (249 loc) 7.5 kB
// packages/block-library/src/navigation-link/link-ui/index.js import { __unstableStripHTML as stripHTML } from "@wordpress/dom"; import { Popover, Button, VisuallyHidden, __experimentalVStack as VStack } from "@wordpress/components"; import { __ } from "@wordpress/i18n"; import { LinkControl, useBlockEditingMode } from "@wordpress/block-editor"; import { useMemo, useState, useRef, useEffect, forwardRef } from "@wordpress/element"; import { useResourcePermissions } from "@wordpress/core-data"; import { plus } from "@wordpress/icons"; import { useInstanceId } from "@wordpress/compose"; import { LinkUIPageCreator } from "./page-creator"; import LinkUIBlockInserter from "./block-inserter"; import { useEntityBinding } from "../shared/use-entity-binding"; import { jsx, jsxs } from "react/jsx-runtime"; function getSuggestionsQuery(type, kind) { switch (type) { case "post": case "page": return { type: "post", subtype: type }; case "category": return { type: "term", subtype: "category" }; case "tag": return { type: "term", subtype: "post_tag" }; case "post_format": return { type: "post-format" }; default: if (kind === "taxonomy") { return { type: "term", subtype: type }; } if (kind === "post-type") { return { type: "post", subtype: type }; } return { // for custom link which has no type // always show pages as initial suggestions initialSuggestionsSearchOptions: { type: "post", subtype: "page", perPage: 20 } }; } } function UnforwardedLinkUI(props, ref) { const { label, url, opensInNewTab, type, kind, id } = props.link; const { clientId } = props; const postType = type || "page"; const [addingBlock, setAddingBlock] = useState(false); const [addingPage, setAddingPage] = useState(false); const [focusAddBlockButton, setFocusAddBlockButton] = useState(false); const [focusAddPageButton, setFocusAddPageButton] = useState(false); const permissions = useResourcePermissions({ kind: "postType", name: postType }); const { isBoundEntityAvailable } = useEntityBinding({ clientId, attributes: props.link }); const link = useMemo( () => ({ url, opensInNewTab, title: label && stripHTML(label), kind, type, id }), [label, opensInNewTab, url, kind, type, id] ); const handlePageCreated = (pageLink) => { props.onChange(pageLink); setAddingPage(false); }; const dialogTitleId = useInstanceId( LinkUI, "link-ui-link-control__title" ); const dialogDescriptionId = useInstanceId( LinkUI, "link-ui-link-control__description" ); const blockEditingMode = useBlockEditingMode(); return /* @__PURE__ */ jsxs( Popover, { ref, placement: "bottom", onClose: props.onClose, anchor: props.anchor, shift: true, children: [ !addingBlock && !addingPage && /* @__PURE__ */ jsxs( "div", { role: "dialog", "aria-labelledby": dialogTitleId, "aria-describedby": dialogDescriptionId, children: [ /* @__PURE__ */ jsxs(VisuallyHidden, { children: [ /* @__PURE__ */ jsx("h2", { id: dialogTitleId, children: __("Add link") }), /* @__PURE__ */ jsx("p", { id: dialogDescriptionId, children: __( "Search for and add a link to your Navigation." ) }) ] }), /* @__PURE__ */ jsx( LinkControl, { hasTextControl: true, hasRichPreviews: true, value: link, showInitialSuggestions: true, withCreateSuggestion: false, noDirectEntry: !!type, noURLSuggestion: !!type, suggestionsQuery: getSuggestionsQuery(type, kind), onChange: props.onChange, onRemove: props.onRemove, onCancel: props.onCancel, handleEntities: isBoundEntityAvailable, renderControlBottom: () => { if (link?.url?.length) { return null; } return /* @__PURE__ */ jsx( LinkUITools, { focusAddBlockButton, focusAddPageButton, setAddingBlock: () => { setAddingBlock(true); setFocusAddBlockButton(false); }, setAddingPage: () => { setAddingPage(true); setFocusAddPageButton(false); }, canAddPage: permissions?.canCreate && type === "page", canAddBlock: blockEditingMode === "default" } ); } } ) ] } ), addingBlock && /* @__PURE__ */ jsx( LinkUIBlockInserter, { clientId: props.clientId, onBack: () => { setAddingBlock(false); setFocusAddBlockButton(true); setFocusAddPageButton(false); }, onBlockInsert: props?.onBlockInsert } ), addingPage && /* @__PURE__ */ jsx( LinkUIPageCreator, { postType, onBack: () => { setAddingPage(false); setFocusAddPageButton(true); setFocusAddBlockButton(false); }, onPageCreated: handlePageCreated, initialTitle: link?.url || "" } ) ] } ); } var LinkUI = forwardRef(UnforwardedLinkUI); var LinkUITools = ({ setAddingBlock, setAddingPage, focusAddBlockButton, focusAddPageButton, canAddPage, canAddBlock }) => { const blockInserterAriaRole = "listbox"; const addBlockButtonRef = useRef(); const addPageButtonRef = useRef(); useEffect(() => { if (focusAddBlockButton) { addBlockButtonRef.current?.focus(); } }, [focusAddBlockButton]); useEffect(() => { if (focusAddPageButton) { addPageButtonRef.current?.focus(); } }, [focusAddPageButton]); if (!canAddPage && !canAddBlock) { return null; } return /* @__PURE__ */ jsxs(VStack, { spacing: 0, className: "link-ui-tools", children: [ canAddPage && /* @__PURE__ */ jsx( Button, { __next40pxDefaultSize: true, ref: addPageButtonRef, icon: plus, onClick: (e) => { e.preventDefault(); setAddingPage(true); }, "aria-haspopup": blockInserterAriaRole, children: __("Create page") } ), canAddBlock && /* @__PURE__ */ jsx( Button, { __next40pxDefaultSize: true, ref: addBlockButtonRef, icon: plus, onClick: (e) => { e.preventDefault(); setAddingBlock(true); }, "aria-haspopup": blockInserterAriaRole, children: __("Add block") } ) ] }); }; var link_ui_default = LinkUITools; export { LinkUI, link_ui_default as default, getSuggestionsQuery }; //# sourceMappingURL=index.js.map