UNPKG

@wordpress/block-library

Version:
202 lines (201 loc) 7.34 kB
// packages/block-library/src/post-excerpt/edit.js import clsx from "clsx"; import { useEntityProp, store as coreStore } from "@wordpress/core-data"; import { useMemo } from "@wordpress/element"; import { AlignmentToolbar, BlockControls, InspectorControls, RichText, Warning, useBlockProps, useBlockEditingMode } from "@wordpress/block-editor"; import { ToggleControl, RangeControl, __experimentalToolsPanel as ToolsPanel, __experimentalToolsPanelItem as ToolsPanelItem } from "@wordpress/components"; import { __, _x } from "@wordpress/i18n"; import { useSelect } from "@wordpress/data"; import { useCanEditEntity, useToolsPanelDropdownMenuProps } from "../utils/hooks"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; var ELLIPSIS = "\u2026"; function PostExcerptEditor({ attributes: { textAlign, moreText, showMoreOnNewLine, excerptLength }, setAttributes, isSelected, context: { postId, postType, queryId } }) { const blockEditingMode = useBlockEditingMode(); const showControls = blockEditingMode === "default"; const isDescendentOfQueryLoop = Number.isFinite(queryId); const userCanEdit = useCanEditEntity("postType", postType, postId); const [ rawExcerpt, setExcerpt, { rendered: renderedExcerpt, protected: isProtected } = {} ] = useEntityProp("postType", postType, "excerpt", postId); const dropdownMenuProps = useToolsPanelDropdownMenuProps(); const postTypeSupportsExcerpts = useSelect( (select) => { if (postType === "page") { return true; } return !!select(coreStore).getPostType(postType)?.supports?.excerpt; }, [postType] ); const isEditable = userCanEdit && !isDescendentOfQueryLoop && postTypeSupportsExcerpts; const blockProps = useBlockProps({ className: clsx({ [`has-text-align-${textAlign}`]: textAlign }) }); const wordCountType = _x("words", "Word count type. Do not translate!"); const strippedRenderedExcerpt = useMemo(() => { if (!renderedExcerpt) { return ""; } const document = new window.DOMParser().parseFromString( renderedExcerpt, "text/html" ); return document.body.textContent || document.body.innerText || ""; }, [renderedExcerpt]); if (!postType || !postId) { return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx(BlockControls, { children: /* @__PURE__ */ jsx( AlignmentToolbar, { value: textAlign, onChange: (newAlign) => setAttributes({ textAlign: newAlign }) } ) }), /* @__PURE__ */ jsx("div", { ...blockProps, children: /* @__PURE__ */ jsx("p", { children: __("This block will display the excerpt.") }) }) ] }); } if (isProtected && !userCanEdit) { return /* @__PURE__ */ jsx("div", { ...blockProps, children: /* @__PURE__ */ jsx(Warning, { children: __( "The content is currently protected and does not have the available excerpt." ) }) }); } const readMoreLink = /* @__PURE__ */ jsx( RichText, { identifier: "moreText", className: "wp-block-post-excerpt__more-link", tagName: "a", "aria-label": __("\u201CRead more\u201D link text"), placeholder: __('Add "read more" link text'), value: moreText, onChange: (newMoreText) => setAttributes({ moreText: newMoreText }), withoutInteractiveFormatting: true } ); const excerptClassName = clsx("wp-block-post-excerpt__excerpt", { "is-inline": !showMoreOnNewLine }); const rawOrRenderedExcerpt = (rawExcerpt || strippedRenderedExcerpt).trim(); let trimmedExcerpt = ""; if (wordCountType === "words") { trimmedExcerpt = rawOrRenderedExcerpt.split(" ", excerptLength).join(" "); } else if (wordCountType === "characters_excluding_spaces") { const excerptWithSpaces = rawOrRenderedExcerpt.split("", excerptLength).join(""); const numberOfSpaces = excerptWithSpaces.length - excerptWithSpaces.replaceAll(" ", "").length; trimmedExcerpt = rawOrRenderedExcerpt.split("", excerptLength + numberOfSpaces).join(""); } else if (wordCountType === "characters_including_spaces") { trimmedExcerpt = rawOrRenderedExcerpt.split("", excerptLength).join(""); } const isTrimmed = trimmedExcerpt !== rawOrRenderedExcerpt; const excerptContent = isEditable ? /* @__PURE__ */ jsx( RichText, { className: excerptClassName, "aria-label": __("Excerpt text"), value: isSelected ? rawOrRenderedExcerpt : (!isTrimmed ? rawOrRenderedExcerpt : trimmedExcerpt + ELLIPSIS) || __("No excerpt found"), onChange: setExcerpt, tagName: "p" } ) : /* @__PURE__ */ jsx("p", { className: excerptClassName, children: !isTrimmed ? rawOrRenderedExcerpt || __("No excerpt found") : trimmedExcerpt + ELLIPSIS }); return /* @__PURE__ */ jsxs(Fragment, { children: [ showControls && /* @__PURE__ */ jsx(BlockControls, { children: /* @__PURE__ */ jsx( AlignmentToolbar, { value: textAlign, onChange: (newAlign) => setAttributes({ textAlign: newAlign }) } ) }), /* @__PURE__ */ jsx(InspectorControls, { children: /* @__PURE__ */ jsxs( ToolsPanel, { label: __("Settings"), resetAll: () => { setAttributes({ showMoreOnNewLine: true, excerptLength: 55 }); }, dropdownMenuProps, children: [ /* @__PURE__ */ jsx( ToolsPanelItem, { hasValue: () => showMoreOnNewLine !== true, label: __("Show link on new line"), onDeselect: () => setAttributes({ showMoreOnNewLine: true }), isShownByDefault: true, children: /* @__PURE__ */ jsx( ToggleControl, { __nextHasNoMarginBottom: true, label: __("Show link on new line"), checked: showMoreOnNewLine, onChange: (newShowMoreOnNewLine) => setAttributes({ showMoreOnNewLine: newShowMoreOnNewLine }) } ) } ), /* @__PURE__ */ jsx( ToolsPanelItem, { hasValue: () => excerptLength !== 55, label: __("Max number of words"), onDeselect: () => setAttributes({ excerptLength: 55 }), isShownByDefault: true, children: /* @__PURE__ */ jsx( RangeControl, { __next40pxDefaultSize: true, __nextHasNoMarginBottom: true, label: __("Max number of words"), value: excerptLength, onChange: (value) => { setAttributes({ excerptLength: value }); }, min: "10", max: "100" } ) } ) ] } ) }), /* @__PURE__ */ jsxs("div", { ...blockProps, children: [ excerptContent, !showMoreOnNewLine && " ", showMoreOnNewLine ? /* @__PURE__ */ jsx("p", { className: "wp-block-post-excerpt__more-text", children: readMoreLink }) : readMoreLink ] }) ] }); } export { PostExcerptEditor as default }; //# sourceMappingURL=edit.js.map