@wordpress/block-library
Version:
Block library for the WordPress editor.
176 lines (173 loc) • 5.52 kB
JavaScript
/**
* WordPress dependencies
*/
import { BlockControls, useBlockProps, useInnerBlocksProps, store as blockEditorStore } from '@wordpress/block-editor';
import { ToolbarButton } from '@wordpress/components';
import { useDispatch, useSelect, useRegistry } from '@wordpress/data';
import { isRTL, __ } from '@wordpress/i18n';
import { formatListBullets, formatListBulletsRTL, formatListNumbered, formatListNumberedRTL, formatOutdent, formatOutdentRTL } from '@wordpress/icons';
import { createBlock } from '@wordpress/blocks';
import { useCallback, useEffect, Platform } from '@wordpress/element';
import deprecated from '@wordpress/deprecated';
/**
* Internal dependencies
*/
import OrderedListSettings from './ordered-list-settings';
import { migrateToListV2 } from './utils';
import TagName from './tag-name';
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
const DEFAULT_BLOCK = {
name: 'core/list-item'
};
const TEMPLATE = [['core/list-item']];
const NATIVE_MARGIN_SPACING = 8;
/**
* At the moment, deprecations don't handle create blocks from attributes
* (like when using CPT templates). For this reason, this hook is necessary
* to avoid breaking templates using the old list block format.
*
* @param {Object} attributes Block attributes.
* @param {string} clientId Block client ID.
*/
function useMigrateOnLoad(attributes, clientId) {
const registry = useRegistry();
const {
updateBlockAttributes,
replaceInnerBlocks
} = useDispatch(blockEditorStore);
useEffect(() => {
// As soon as the block is loaded, migrate it to the new version.
if (!attributes.values) {
return;
}
const [newAttributes, newInnerBlocks] = migrateToListV2(attributes);
deprecated('Value attribute on the list block', {
since: '6.0',
version: '6.5',
alternative: 'inner blocks'
});
registry.batch(() => {
updateBlockAttributes(clientId, newAttributes);
replaceInnerBlocks(clientId, newInnerBlocks);
});
}, [attributes.values]);
}
function useOutdentList(clientId) {
const {
replaceBlocks,
selectionChange
} = useDispatch(blockEditorStore);
const {
getBlockRootClientId,
getBlockAttributes,
getBlock
} = useSelect(blockEditorStore);
return useCallback(() => {
const parentBlockId = getBlockRootClientId(clientId);
const parentBlockAttributes = getBlockAttributes(parentBlockId);
// Create a new parent block without the inner blocks.
const newParentBlock = createBlock('core/list-item', parentBlockAttributes);
const {
innerBlocks
} = getBlock(clientId);
// Replace the parent block with a new parent block without inner blocks,
// and make the inner blocks siblings of the parent.
replaceBlocks([parentBlockId], [newParentBlock, ...innerBlocks]);
// Select the last child of the list being outdent.
selectionChange(innerBlocks[innerBlocks.length - 1].clientId);
}, [clientId]);
}
function IndentUI({
clientId
}) {
const outdentList = useOutdentList(clientId);
const canOutdent = useSelect(select => {
const {
getBlockRootClientId,
getBlockName
} = select(blockEditorStore);
return getBlockName(getBlockRootClientId(clientId)) === 'core/list-item';
}, [clientId]);
return /*#__PURE__*/_jsx(_Fragment, {
children: /*#__PURE__*/_jsx(ToolbarButton, {
icon: isRTL() ? formatOutdentRTL : formatOutdent,
title: __('Outdent'),
description: __('Outdent list item'),
disabled: !canOutdent,
onClick: outdentList
})
});
}
export default function Edit({
attributes,
setAttributes,
clientId,
style
}) {
const {
ordered,
type,
reversed,
start
} = attributes;
const blockProps = useBlockProps({
style: {
...(Platform.isNative && style),
listStyleType: ordered && type !== 'decimal' ? type : undefined
}
});
const innerBlocksProps = useInnerBlocksProps(blockProps, {
defaultBlock: DEFAULT_BLOCK,
directInsert: true,
template: TEMPLATE,
templateLock: false,
templateInsertUpdatesSelection: true,
...(Platform.isNative && {
marginVertical: NATIVE_MARGIN_SPACING,
marginHorizontal: NATIVE_MARGIN_SPACING,
renderAppender: false
}),
__experimentalCaptureToolbars: true
});
useMigrateOnLoad(attributes, clientId);
const controls = /*#__PURE__*/_jsxs(BlockControls, {
group: "block",
children: [/*#__PURE__*/_jsx(ToolbarButton, {
icon: isRTL() ? formatListBulletsRTL : formatListBullets,
title: __('Unordered'),
description: __('Convert to unordered list'),
isActive: ordered === false,
onClick: () => {
setAttributes({
ordered: false
});
}
}), /*#__PURE__*/_jsx(ToolbarButton, {
icon: isRTL() ? formatListNumberedRTL : formatListNumbered,
title: __('Ordered'),
description: __('Convert to ordered list'),
isActive: ordered === true,
onClick: () => {
setAttributes({
ordered: true
});
}
}), /*#__PURE__*/_jsx(IndentUI, {
clientId: clientId
})]
});
return /*#__PURE__*/_jsxs(_Fragment, {
children: [/*#__PURE__*/_jsx(TagName, {
ordered: ordered,
reversed: reversed,
start: start,
...innerBlocksProps
}), controls, ordered && /*#__PURE__*/_jsx(OrderedListSettings, {
setAttributes,
reversed,
start,
type
})]
});
}
//# sourceMappingURL=edit.js.map