UNPKG

@wordpress/block-library

Version:
224 lines (223 loc) 7.43 kB
// packages/block-library/src/table-of-contents/edit.js import { BlockControls, BlockIcon, InspectorControls, store as blockEditorStore, useBlockProps } from "@wordpress/block-editor"; import { createBlock } from "@wordpress/blocks"; import { Placeholder, ToggleControl, SelectControl, ToolbarButton, ToolbarGroup, __experimentalToolsPanel as ToolsPanel, __experimentalToolsPanelItem as ToolsPanelItem } from "@wordpress/components"; import { useDispatch, useSelect } from "@wordpress/data"; import { renderToString } from "@wordpress/element"; import { __, isRTL } from "@wordpress/i18n"; import { useInstanceId } from "@wordpress/compose"; import { store as noticeStore } from "@wordpress/notices"; import { tableOfContents as icon, formatListBullets, formatListBulletsRTL, formatListNumbered, formatListNumberedRTL } from "@wordpress/icons"; import TableOfContentsList from "./list"; import { linearToNestedHeadingList } from "./utils"; import { useObserveHeadings } from "./hooks"; import { useToolsPanelDropdownMenuProps } from "../utils/hooks"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; function TableOfContentsEdit({ attributes: { headings = [], onlyIncludeCurrentPage, maxLevel, ordered = true }, clientId, setAttributes }) { useObserveHeadings(clientId); const blockProps = useBlockProps(); const instanceId = useInstanceId( TableOfContentsEdit, "table-of-contents" ); const { createWarningNotice } = useDispatch(noticeStore); const showRedirectionPreventedNotice = (event) => { event.preventDefault(); createWarningNotice(__("Links are disabled in the editor."), { id: `block-library/core/table-of-contents/redirection-prevented/${instanceId}`, type: "snackbar" }); }; const canInsertList = useSelect( (select) => { const { getBlockRootClientId, canInsertBlockType } = select(blockEditorStore); const rootClientId = getBlockRootClientId(clientId); return canInsertBlockType("core/list", rootClientId); }, [clientId] ); const { replaceBlocks } = useDispatch(blockEditorStore); const dropdownMenuProps = useToolsPanelDropdownMenuProps(); const headingTree = linearToNestedHeadingList(headings); const toolbarControls = /* @__PURE__ */ jsxs(BlockControls, { children: [ /* @__PURE__ */ jsxs(ToolbarGroup, { children: [ /* @__PURE__ */ jsx( ToolbarButton, { icon: isRTL() ? formatListBulletsRTL : formatListBullets, title: __("Unordered"), description: __("Convert to unordered list"), onClick: () => setAttributes({ ordered: false }), isActive: ordered === false } ), /* @__PURE__ */ jsx( ToolbarButton, { icon: isRTL() ? formatListNumberedRTL : formatListNumbered, title: __("Ordered"), description: __("Convert to ordered list"), onClick: () => setAttributes({ ordered: true }), isActive: ordered === true } ) ] }), canInsertList && /* @__PURE__ */ jsx(ToolbarGroup, { children: /* @__PURE__ */ jsx( ToolbarButton, { onClick: () => replaceBlocks( clientId, createBlock("core/list", { ordered, values: renderToString( /* @__PURE__ */ jsx( TableOfContentsList, { nestedHeadingList: headingTree, ordered } ) ) }) ), children: __("Convert to static list") } ) }) ] }); const inspectorControls = /* @__PURE__ */ jsx(InspectorControls, { children: /* @__PURE__ */ jsxs( ToolsPanel, { label: __("Settings"), resetAll: () => { setAttributes({ onlyIncludeCurrentPage: false, maxLevel: void 0, ordered: true }); }, dropdownMenuProps, children: [ /* @__PURE__ */ jsx( ToolsPanelItem, { hasValue: () => !!onlyIncludeCurrentPage, label: __("Only include current page"), onDeselect: () => setAttributes({ onlyIncludeCurrentPage: false }), isShownByDefault: true, children: /* @__PURE__ */ jsx( ToggleControl, { __nextHasNoMarginBottom: true, label: __("Only include current page"), checked: onlyIncludeCurrentPage, onChange: (value) => setAttributes({ onlyIncludeCurrentPage: value }), help: onlyIncludeCurrentPage ? __( "Only including headings from the current page (if the post is paginated)." ) : __( "Include headings from all pages (if the post is paginated)." ) } ) } ), /* @__PURE__ */ jsx( ToolsPanelItem, { hasValue: () => !!maxLevel, label: __("Limit heading levels"), onDeselect: () => setAttributes({ maxLevel: void 0 }), isShownByDefault: true, children: /* @__PURE__ */ jsx( SelectControl, { __nextHasNoMarginBottom: true, __next40pxDefaultSize: true, label: __("Include headings down to level"), value: maxLevel || "", options: [ { value: "", label: __("All levels") }, { value: "1", label: __("Heading 1") }, { value: "2", label: __("Heading 2") }, { value: "3", label: __("Heading 3") }, { value: "4", label: __("Heading 4") }, { value: "5", label: __("Heading 5") }, { value: "6", label: __("Heading 6") } ], onChange: (value) => setAttributes({ maxLevel: value ? parseInt(value) : void 0 }), help: !maxLevel ? __( "Including all heading levels in the table of contents." ) : __( "Only include headings up to and including this level." ) } ) } ) ] } ) }); if (headings.length === 0) { return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx("div", { ...blockProps, children: /* @__PURE__ */ jsx( Placeholder, { icon: /* @__PURE__ */ jsx(BlockIcon, { icon }), label: __("Table of Contents"), instructions: __( "Start adding Heading blocks to create a table of contents. Headings with HTML anchors will be linked here." ) } ) }), inspectorControls ] }); } const ListTag = ordered ? "ol" : "ul"; return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx("nav", { ...blockProps, children: /* @__PURE__ */ jsx(ListTag, { children: /* @__PURE__ */ jsx( TableOfContentsList, { nestedHeadingList: headingTree, disableLinkActivation: true, onClick: showRedirectionPreventedNotice, ordered } ) }) }), toolbarControls, inspectorControls ] }); } export { TableOfContentsEdit as default }; //# sourceMappingURL=edit.js.map