UNPKG

@wordpress/block-editor

Version:
351 lines (347 loc) 13.1 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BlockList; var _reactNative = require("react-native"); var _element = require("@wordpress/element"); var _data = require("@wordpress/data"); var _blocks = require("@wordpress/blocks"); var _components = require("@wordpress/components"); var _i18n = require("@wordpress/i18n"); var _style = _interopRequireDefault(require("./style.scss")); var _blockListAppender = _interopRequireDefault(require("../block-list-appender")); var _blockListItem = _interopRequireDefault(require("./block-list-item")); var _blockListItemCell = _interopRequireDefault(require("./block-list-item-cell")); var _blockListContext = require("./block-list-context"); var _blockDraggable = require("../block-draggable"); var _useEditorWrapperStyles = require("../../hooks/use-editor-wrapper-styles"); var _store = require("../../store"); var _jsxRuntime = require("react/jsx-runtime"); /** * External dependencies */ /** * WordPress dependencies */ /** * Internal dependencies */ const identity = x => x; const stylesMemo = {}; const getStyles = (isStackedHorizontally, horizontalAlignment) => { const styleName = `${isStackedHorizontally}-${horizontalAlignment}`; if (stylesMemo[styleName]) { return stylesMemo[styleName]; } const computedStyles = [isStackedHorizontally && _style.default.horizontal, horizontalAlignment && _style.default[`is-aligned-${horizontalAlignment}`], _style.default.overflowVisible]; stylesMemo[styleName] = computedStyles; return computedStyles; }; function BlockList({ blockWidth: initialBlockWidth, contentResizeMode, contentStyle, filterInnerBlocks, gridProperties, header, horizontal, horizontalAlignment, marginHorizontal = _style.default.defaultBlock.marginLeft, marginVertical = _style.default.defaultBlock.marginTop, onAddBlock, onDeleteBlock, orientation, parentWidth, renderAppender, renderFooterAppender, rootClientId, withFooter = true }) { const { blockClientIds, blockCount, blockInsertionPointIsVisible, isReadOnly, isRootList, isFloatingToolbarVisible, isStackedHorizontally, maxWidth, isRTL } = (0, _data.useSelect)(select => { const { getBlockCount, getBlockHierarchyRootClientId, getBlockOrder, getSelectedBlockClientId, isBlockInsertionPointVisible, getSettings } = select(_store.store); const selectedBlockClientId = getSelectedBlockClientId(); const rootBlockId = getBlockHierarchyRootClientId(selectedBlockClientId); let blockOrder = getBlockOrder(rootClientId); // Display only block which fulfill the condition in passed `filterInnerBlocks` function. if (filterInnerBlocks) { blockOrder = filterInnerBlocks(blockOrder); } const { isRTL: isRTLSetting, maxWidth: maxWidthSetting, readOnly } = getSettings(); return { blockClientIds: blockOrder, blockCount: getBlockCount(), blockInsertionPointIsVisible: _reactNative.Platform.OS === 'ios' && isBlockInsertionPointVisible(), isReadOnly: readOnly, isRootList: rootClientId === undefined, isFloatingToolbarVisible: !!selectedBlockClientId && !!getBlockCount(rootBlockId), isStackedHorizontally: orientation === 'horizontal', maxWidth: maxWidthSetting, isRTL: isRTLSetting }; }, [filterInnerBlocks, orientation, rootClientId]); const { insertBlock, clearSelectedBlock } = (0, _data.useDispatch)(_store.store); const extraData = (0, _element.useRef)({ parentWidth, renderFooterAppender, renderAppender, onDeleteBlock, contentStyle }); const [blockWidth, setBlockWidth] = (0, _element.useState)(initialBlockWidth || 0); const addBlockToEndOfPost = newBlock => { insertBlock(newBlock, blockCount); }; const scrollRef = (0, _element.useRef)(null); const shouldFlatListPreventAutomaticScroll = () => blockInsertionPointIsVisible; const shouldShowInnerBlockAppender = () => renderAppender && blockClientIds.length > 0; const getExtraData = () => { if (extraData.current.parentWidth !== parentWidth || extraData.current.renderFooterAppender !== renderFooterAppender || extraData.current.onDeleteBlock !== onDeleteBlock || extraData.current.contentStyle !== contentStyle || extraData.current.renderAppender !== renderAppender || extraData.current.blockWidth !== blockWidth || extraData.current.gridProperties !== gridProperties) { extraData.current = { parentWidth, renderFooterAppender, onDeleteBlock, contentStyle, renderAppender, blockWidth, gridProperties }; } return extraData.current; }; const onLayout = ({ nativeEvent }) => { const { layout } = nativeEvent; const layoutWidth = Math.floor(layout.width); if (isRootList && blockWidth !== layoutWidth) { setBlockWidth(Math.min(layoutWidth, maxWidth)); } else if (!isRootList && !blockWidth) { setBlockWidth(Math.min(layoutWidth, maxWidth)); } }; const renderItem = ({ item: clientId, index }) => { // Extracting the grid item properties here to avoid // re-renders in the blockListItem component. const isGridItem = !!gridProperties; const gridItemProps = gridProperties && { numOfColumns: gridProperties.numColumns, tileCount: blockClientIds.length, tileIndex: blockClientIds.indexOf(clientId) }; return /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockListItem.default, { index: index, isStackedHorizontally: isStackedHorizontally, rootClientId: rootClientId, clientId: clientId, parentWidth: parentWidth, contentResizeMode: contentResizeMode, contentStyle: contentStyle, onAddBlock: onAddBlock, marginVertical: marginVertical, marginHorizontal: marginHorizontal, onDeleteBlock: onDeleteBlock, shouldShowInnerBlockAppender: shouldShowInnerBlockAppender, blockWidth: blockWidth, isGridItem: isGridItem, ...gridItemProps }); }; const { blockToolbar, floatingToolbar } = _style.default; const containerStyle = { flex: isRootList ? 1 : 0, // We set negative margin in the parent to remove the edge spacing between parent block and child block in ineer blocks. marginVertical: isRootList ? 0 : -marginVertical, marginHorizontal: isRootList ? 0 : -marginHorizontal }; const isContentStretch = contentResizeMode === 'stretch'; const isMultiBlocks = blockClientIds.length > 1; const { isWider } = _components.alignmentHelpers; const extraScrollHeight = blockToolbar.height + (isFloatingToolbarVisible ? floatingToolbar.height : 0); return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: containerStyle, onAccessibilityEscape: clearSelectedBlock, onLayout: onLayout, testID: "block-list-wrapper", children: [isRootList ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockListContext.BlockListProvider, { value: { ..._blockListContext.DEFAULT_BLOCK_LIST_CONTEXT, scrollRef: scrollRef.current }, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockDraggable.BlockDraggableWrapper, { isRTL: isRTL, children: ({ onScroll }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.KeyboardAwareFlatList, { accessibilityLabel: "block-list", ref: scrollRef, extraScrollHeight: extraScrollHeight, keyboardShouldPersistTaps: "always", extraData: getExtraData(), scrollEnabled: isRootList, contentContainerStyle: [horizontal && _style.default.horizontalContentContainer, isWider(blockWidth, 'medium') && (isContentStretch && isMultiBlocks ? _style.default.horizontalContentContainerStretch : _style.default.horizontalContentContainerCenter)], data: blockClientIds, keyExtractor: identity, renderItem: renderItem, CellRendererComponent: _blockListItemCell.default, shouldPreventAutomaticScroll: shouldFlatListPreventAutomaticScroll, ListHeaderComponent: header, ListEmptyComponent: !isReadOnly && /*#__PURE__*/(0, _jsxRuntime.jsx)(EmptyList, { orientation: orientation, rootClientId: rootClientId, renderAppender: renderAppender, renderFooterAppender: renderFooterAppender }), ListFooterComponent: /*#__PURE__*/(0, _jsxRuntime.jsx)(Footer, { addBlockToEndOfPost: addBlockToEndOfPost, isReadOnly: isReadOnly, renderFooterAppender: renderFooterAppender, withFooter: withFooter }), onScroll: onScroll }) }) }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, { children: blockClientIds.length > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: [{ flex: 0 }, _style.default.overflowVisible], children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: [...getStyles(isStackedHorizontally, horizontalAlignment), horizontal && _style.default.horizontalContentContainer], children: [blockClientIds.map((currentClientId, index) => { return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { children: renderItem({ item: currentClientId, index }) }, currentClientId); }), /*#__PURE__*/(0, _jsxRuntime.jsx)(Footer, { addBlockToEndOfPost: addBlockToEndOfPost, isReadOnly: isReadOnly, renderFooterAppender: renderFooterAppender, withFooter: withFooter })] }) }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(EmptyList, { orientation: orientation, rootClientId: rootClientId, renderAppender: renderAppender, renderFooterAppender: renderFooterAppender }) }), shouldShowInnerBlockAppender() && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: { marginHorizontal: marginHorizontal - _style.default.innerAppender.marginLeft }, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockListAppender.default, { rootClientId: rootClientId, renderAppender: renderAppender, showSeparator: true }) })] }); } function Footer({ addBlockToEndOfPost, isReadOnly, renderFooterAppender, withFooter }) { const onAddParagraphBlock = (0, _element.useCallback)(() => { const paragraphBlock = (0, _blocks.createBlock)('core/paragraph'); addBlockToEndOfPost(paragraphBlock); }, [addBlockToEndOfPost]); if (!isReadOnly && withFooter) { return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, { accessibilityLabel: (0, _i18n.__)('Add paragraph block'), testID: (0, _i18n.__)('Add paragraph block'), onPress: onAddParagraphBlock, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: _style.default.blockListFooter }) }); } else if (renderFooterAppender) { return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { children: renderFooterAppender() }); } return null; } function EmptyList({ orientation, renderAppender, renderFooterAppender, rootClientId }) { const { shouldShowInsertionPoint } = (0, _data.useSelect)(select => { const { getBlockOrder, getBlockInsertionPoint, isBlockInsertionPointVisible } = select(_store.store); const isStackedHorizontally = orientation === 'horizontal'; const blockClientIds = getBlockOrder(rootClientId); const insertionPoint = getBlockInsertionPoint(); const blockInsertionPointIsVisible = isBlockInsertionPointVisible(); return { shouldShowInsertionPoint: !isStackedHorizontally && blockInsertionPointIsVisible && insertionPoint.rootClientId === rootClientId && ( // If list is empty, show the insertion point (via the default appender) blockClientIds.length === 0 || // Or if the insertion point is right before the denoted block. !blockClientIds[insertionPoint.index]) }; }); const align = renderAppender ? _components.WIDE_ALIGNMENTS.alignments.full : undefined; const [wrapperStyles] = (0, _useEditorWrapperStyles.useEditorWrapperStyles)({ align }); if (renderFooterAppender || renderAppender === false) { return null; } const containerStyles = [_style.default.defaultAppender, wrapperStyles]; return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, { style: containerStyles, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_blockListAppender.default, { rootClientId: rootClientId, renderAppender: renderAppender, showSeparator: shouldShowInsertionPoint }) }); } //# sourceMappingURL=index.native.js.map