UNPKG

@wordpress/block-library

Version:
193 lines (187 loc) 7.95 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = TableOfContentsEdit; var _blockEditor = require("@wordpress/block-editor"); var _blocks = require("@wordpress/blocks"); var _components = require("@wordpress/components"); var _data = require("@wordpress/data"); var _element = require("@wordpress/element"); var _i18n = require("@wordpress/i18n"); var _compose = require("@wordpress/compose"); var _notices = require("@wordpress/notices"); var _icons = require("@wordpress/icons"); var _list = _interopRequireDefault(require("./list")); var _utils = require("./utils"); var _hooks = require("./hooks"); var _hooks2 = require("../utils/hooks"); var _jsxRuntime = require("react/jsx-runtime"); /** * WordPress dependencies */ /** * Internal dependencies */ /** @typedef {import('./utils').HeadingData} HeadingData */ /** * Table of Contents block edit component. * * @param {Object} props The props. * @param {Object} props.attributes The block attributes. * @param {HeadingData[]} props.attributes.headings The list of data for each heading in the post. * @param {boolean} props.attributes.onlyIncludeCurrentPage Whether to only include headings from the current page (if the post is paginated). * @param {number|undefined} props.attributes.maxLevel The maximum heading level to include, or null to include all levels. * @param {string} props.clientId The client id. * @param {(attributes: Object) => void} props.setAttributes The set attributes function. * * @return {Component} The component. */function TableOfContentsEdit({ attributes: { headings = [], onlyIncludeCurrentPage, maxLevel }, clientId, setAttributes }) { (0, _hooks.useObserveHeadings)(clientId); const blockProps = (0, _blockEditor.useBlockProps)(); const instanceId = (0, _compose.useInstanceId)(TableOfContentsEdit, 'table-of-contents'); // If a user clicks to a link prevent redirection and show a warning. const { createWarningNotice } = (0, _data.useDispatch)(_notices.store); const showRedirectionPreventedNotice = event => { event.preventDefault(); createWarningNotice((0, _i18n.__)('Links are disabled in the editor.'), { id: `block-library/core/table-of-contents/redirection-prevented/${instanceId}`, type: 'snackbar' }); }; const canInsertList = (0, _data.useSelect)(select => { const { getBlockRootClientId, canInsertBlockType } = select(_blockEditor.store); const rootClientId = getBlockRootClientId(clientId); return canInsertBlockType('core/list', rootClientId); }, [clientId]); const { replaceBlocks } = (0, _data.useDispatch)(_blockEditor.store); const dropdownMenuProps = (0, _hooks2.useToolsPanelDropdownMenuProps)(); const headingTree = (0, _utils.linearToNestedHeadingList)(headings); const toolbarControls = canInsertList && /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockEditor.BlockControls, { children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ToolbarGroup, { children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ToolbarButton, { onClick: () => replaceBlocks(clientId, (0, _blocks.createBlock)('core/list', { ordered: true, values: (0, _element.renderToString)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_list.default, { nestedHeadingList: headingTree })) })), children: (0, _i18n.__)('Convert to static list') }) }) }); const inspectorControls = /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockEditor.InspectorControls, { children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_components.__experimentalToolsPanel, { label: (0, _i18n.__)('Settings'), resetAll: () => { setAttributes({ onlyIncludeCurrentPage: false, maxLevel: undefined }); }, dropdownMenuProps: dropdownMenuProps, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalToolsPanelItem, { hasValue: () => !!onlyIncludeCurrentPage, label: (0, _i18n.__)('Only include current page'), onDeselect: () => setAttributes({ onlyIncludeCurrentPage: false }), isShownByDefault: true, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ToggleControl, { __nextHasNoMarginBottom: true, label: (0, _i18n.__)('Only include current page'), checked: onlyIncludeCurrentPage, onChange: value => setAttributes({ onlyIncludeCurrentPage: value }), help: onlyIncludeCurrentPage ? (0, _i18n.__)('Only including headings from the current page (if the post is paginated).') : (0, _i18n.__)('Include headings from all pages (if the post is paginated).') }) }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalToolsPanelItem, { hasValue: () => !!maxLevel, label: (0, _i18n.__)('Limit heading levels'), onDeselect: () => setAttributes({ maxLevel: undefined }), isShownByDefault: true, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.SelectControl, { __nextHasNoMarginBottom: true, __next40pxDefaultSize: true, label: (0, _i18n.__)('Include headings down to level'), value: maxLevel || '', options: [{ value: '', label: (0, _i18n.__)('All levels') }, { value: '1', label: (0, _i18n.__)('Heading 1') }, { value: '2', label: (0, _i18n.__)('Heading 2') }, { value: '3', label: (0, _i18n.__)('Heading 3') }, { value: '4', label: (0, _i18n.__)('Heading 4') }, { value: '5', label: (0, _i18n.__)('Heading 5') }, { value: '6', label: (0, _i18n.__)('Heading 6') }], onChange: value => setAttributes({ maxLevel: value ? parseInt(value) : undefined }), help: !maxLevel ? (0, _i18n.__)('Including all heading levels in the table of contents.') : (0, _i18n.__)('Only include headings up to and including this level.') }) })] }) }); // If there are no headings or the only heading is empty. // Note that the toolbar controls are intentionally omitted since the // "Convert to static list" option is useless to the placeholder state. if (headings.length === 0) { return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, { children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", { ...blockProps, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Placeholder, { icon: /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockEditor.BlockIcon, { icon: _icons.tableOfContents }), label: (0, _i18n.__)('Table of Contents'), instructions: (0, _i18n.__)('Start adding Heading blocks to create a table of contents. Headings with HTML anchors will be linked here.') }) }), inspectorControls] }); } return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, { children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("nav", { ...blockProps, children: /*#__PURE__*/(0, _jsxRuntime.jsx)("ol", { children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_list.default, { nestedHeadingList: headingTree, disableLinkActivation: true, onClick: showRedirectionPreventedNotice }) }) }), toolbarControls, inspectorControls] }); } //# sourceMappingURL=edit.js.map