UNPKG

@wordpress/block-library

Version:
249 lines (218 loc) 7.98 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _element = require("@wordpress/element"); var _classnames = _interopRequireDefault(require("classnames")); var _lodash = require("lodash"); var _i18n = require("@wordpress/i18n"); var _components = require("@wordpress/components"); var _blockEditor = require("@wordpress/block-editor"); var _data = require("@wordpress/data"); var _blocks = require("@wordpress/blocks"); var _utils = require("./utils"); /** * External dependencies */ /** * WordPress dependencies */ /** * Internal dependencies */ /** * Allowed blocks constant is passed to InnerBlocks precisely as specified here. * The contents of the array should never change. * The array should contain the name of each block that is allowed. * In columns block, the only block we allow is 'core/column'. * * @constant * @type {string[]} */ const ALLOWED_BLOCKS = ['core/column']; function ColumnsEditContainer(_ref) { let { attributes, setAttributes, updateAlignment, updateColumns, clientId } = _ref; const { isStackedOnMobile, verticalAlignment } = attributes; const { count } = (0, _data.useSelect)(select => { return { count: select(_blockEditor.store).getBlockCount(clientId) }; }, [clientId]); const classes = (0, _classnames.default)({ [`are-vertically-aligned-${verticalAlignment}`]: verticalAlignment, [`is-not-stacked-on-mobile`]: !isStackedOnMobile }); const blockProps = (0, _blockEditor.useBlockProps)({ className: classes }); const innerBlocksProps = (0, _blockEditor.useInnerBlocksProps)(blockProps, { allowedBlocks: ALLOWED_BLOCKS, orientation: 'horizontal', renderAppender: false }); return (0, _element.createElement)(_element.Fragment, null, (0, _element.createElement)(_blockEditor.BlockControls, null, (0, _element.createElement)(_blockEditor.BlockVerticalAlignmentToolbar, { onChange: updateAlignment, value: verticalAlignment })), (0, _element.createElement)(_blockEditor.InspectorControls, null, (0, _element.createElement)(_components.PanelBody, null, (0, _element.createElement)(_components.RangeControl, { label: (0, _i18n.__)('Columns'), value: count, onChange: value => updateColumns(count, value), min: 1, max: Math.max(6, count) }), count > 6 && (0, _element.createElement)(_components.Notice, { status: "warning", isDismissible: false }, (0, _i18n.__)('This column count exceeds the recommended amount and may cause visual breakage.')), (0, _element.createElement)(_components.ToggleControl, { label: (0, _i18n.__)('Stack on mobile'), checked: isStackedOnMobile, onChange: () => setAttributes({ isStackedOnMobile: !isStackedOnMobile }) }))), (0, _element.createElement)("div", innerBlocksProps)); } const ColumnsEditContainerWrapper = (0, _data.withDispatch)((dispatch, ownProps, registry) => ({ /** * Update all child Column blocks with a new vertical alignment setting * based on whatever alignment is passed in. This allows change to parent * to overide anything set on a individual column basis. * * @param {string} verticalAlignment the vertical alignment setting */ updateAlignment(verticalAlignment) { const { clientId, setAttributes } = ownProps; const { updateBlockAttributes } = dispatch(_blockEditor.store); const { getBlockOrder } = registry.select(_blockEditor.store); // Update own alignment. setAttributes({ verticalAlignment }); // Update all child Column Blocks to match. const innerBlockClientIds = getBlockOrder(clientId); innerBlockClientIds.forEach(innerBlockClientId => { updateBlockAttributes(innerBlockClientId, { verticalAlignment }); }); }, /** * Updates the column count, including necessary revisions to child Column * blocks to grant required or redistribute available space. * * @param {number} previousColumns Previous column count. * @param {number} newColumns New column count. */ updateColumns(previousColumns, newColumns) { const { clientId } = ownProps; const { replaceInnerBlocks } = dispatch(_blockEditor.store); const { getBlocks } = registry.select(_blockEditor.store); let innerBlocks = getBlocks(clientId); const hasExplicitWidths = (0, _utils.hasExplicitPercentColumnWidths)(innerBlocks); // Redistribute available width for existing inner blocks. const isAddingColumn = newColumns > previousColumns; if (isAddingColumn && hasExplicitWidths) { // If adding a new column, assign width to the new column equal to // as if it were `1 / columns` of the total available space. const newColumnWidth = (0, _utils.toWidthPrecision)(100 / newColumns); // Redistribute in consideration of pending block insertion as // constraining the available working width. const widths = (0, _utils.getRedistributedColumnWidths)(innerBlocks, 100 - newColumnWidth); innerBlocks = [...(0, _utils.getMappedColumnWidths)(innerBlocks, widths), ...Array.from({ length: newColumns - previousColumns }).map(() => { return (0, _blocks.createBlock)('core/column', { width: `${newColumnWidth}%` }); })]; } else if (isAddingColumn) { innerBlocks = [...innerBlocks, ...Array.from({ length: newColumns - previousColumns }).map(() => { return (0, _blocks.createBlock)('core/column'); })]; } else { // The removed column will be the last of the inner blocks. innerBlocks = innerBlocks.slice(0, -(previousColumns - newColumns)); if (hasExplicitWidths) { // Redistribute as if block is already removed. const widths = (0, _utils.getRedistributedColumnWidths)(innerBlocks, 100); innerBlocks = (0, _utils.getMappedColumnWidths)(innerBlocks, widths); } } replaceInnerBlocks(clientId, innerBlocks); } }))(ColumnsEditContainer); function Placeholder(_ref2) { let { clientId, name, setAttributes } = _ref2; const { blockType, defaultVariation, variations } = (0, _data.useSelect)(select => { const { getBlockVariations, getBlockType, getDefaultBlockVariation } = select(_blocks.store); return { blockType: getBlockType(name), defaultVariation: getDefaultBlockVariation(name, 'block'), variations: getBlockVariations(name, 'block') }; }, [name]); const { replaceInnerBlocks } = (0, _data.useDispatch)(_blockEditor.store); const blockProps = (0, _blockEditor.useBlockProps)(); return (0, _element.createElement)("div", blockProps, (0, _element.createElement)(_blockEditor.__experimentalBlockVariationPicker, { icon: (0, _lodash.get)(blockType, ['icon', 'src']), label: (0, _lodash.get)(blockType, ['title']), variations: variations, onSelect: function () { let nextVariation = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultVariation; if (nextVariation.attributes) { setAttributes(nextVariation.attributes); } if (nextVariation.innerBlocks) { replaceInnerBlocks(clientId, (0, _blocks.createBlocksFromInnerBlocksTemplate)(nextVariation.innerBlocks), true); } }, allowSkip: true })); } const ColumnsEdit = props => { const { clientId } = props; const hasInnerBlocks = (0, _data.useSelect)(select => select(_blockEditor.store).getBlocks(clientId).length > 0, [clientId]); const Component = hasInnerBlocks ? ColumnsEditContainerWrapper : Placeholder; return (0, _element.createElement)(Component, props); }; var _default = ColumnsEdit; exports.default = _default; //# sourceMappingURL=edit.js.map