UNPKG

@wordpress/block-editor

Version:
204 lines (200 loc) 6.98 kB
/** * External dependencies */ import clsx from 'clsx'; /** * WordPress dependencies */ import { cloneBlock } from '@wordpress/blocks'; import { useEffect, useState, forwardRef, useMemo } from '@wordpress/element'; import { Composite, VisuallyHidden, Tooltip, __experimentalHStack as HStack } from '@wordpress/components'; import { useInstanceId } from '@wordpress/compose'; import { __ } from '@wordpress/i18n'; import { Icon, symbol } from '@wordpress/icons'; /** * Internal dependencies */ import BlockPreview from '../block-preview'; import InserterDraggableBlocks from '../inserter-draggable-blocks'; import BlockPatternsPaging from '../block-patterns-paging'; import { INSERTER_PATTERN_TYPES } from '../inserter/block-patterns-tab/utils'; import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; const WithToolTip = ({ showTooltip, title, children }) => { if (showTooltip) { return /*#__PURE__*/_jsx(Tooltip, { text: title, children: children }); } return /*#__PURE__*/_jsx(_Fragment, { children: children }); }; function BlockPattern({ id, isDraggable, pattern, onClick, onHover, showTitlesAsTooltip, category, isSelected }) { const [isDragging, setIsDragging] = useState(false); const { blocks, viewportWidth } = pattern; const instanceId = useInstanceId(BlockPattern); const descriptionId = `block-editor-block-patterns-list__item-description-${instanceId}`; const isUserPattern = pattern.type === INSERTER_PATTERN_TYPES.user; // When we have a selected category and the pattern is draggable, we need to update the // pattern's categories in metadata to only contain the selected category, and pass this to // InserterDraggableBlocks component. We do that because we use this information for pattern // shuffling and it makes more sense to show only the ones from the initially selected category during insertion. const patternBlocks = useMemo(() => { if (!category || !isDraggable) { return blocks; } return (blocks !== null && blocks !== void 0 ? blocks : []).map(block => { const clonedBlock = cloneBlock(block); if (clonedBlock.attributes.metadata?.categories?.includes(category)) { clonedBlock.attributes.metadata.categories = [category]; } return clonedBlock; }); }, [blocks, isDraggable, category]); return /*#__PURE__*/_jsx(InserterDraggableBlocks, { isEnabled: isDraggable, blocks: patternBlocks, pattern: pattern, children: ({ draggable, onDragStart, onDragEnd }) => /*#__PURE__*/_jsx("div", { className: "block-editor-block-patterns-list__list-item", draggable: draggable, onDragStart: event => { setIsDragging(true); if (onDragStart) { onHover?.(null); onDragStart(event); } }, onDragEnd: event => { setIsDragging(false); if (onDragEnd) { onDragEnd(event); } }, children: /*#__PURE__*/_jsx(WithToolTip, { showTooltip: showTitlesAsTooltip && !isUserPattern, title: pattern.title, children: /*#__PURE__*/_jsxs(Composite.Item, { render: /*#__PURE__*/_jsx("div", { role: "option", "aria-label": pattern.title, "aria-describedby": pattern.description ? descriptionId : undefined, className: clsx('block-editor-block-patterns-list__item', { 'block-editor-block-patterns-list__list-item-synced': pattern.type === INSERTER_PATTERN_TYPES.user && !pattern.syncStatus, 'is-selected': isSelected }) }), id: id, onClick: () => { onClick(pattern, blocks); onHover?.(null); }, onMouseEnter: () => { if (isDragging) { return; } onHover?.(pattern); }, onMouseLeave: () => onHover?.(null), children: [/*#__PURE__*/_jsx(BlockPreview.Async, { placeholder: /*#__PURE__*/_jsx(BlockPatternPlaceholder, {}), children: /*#__PURE__*/_jsx(BlockPreview, { blocks: blocks, viewportWidth: viewportWidth }) }), (!showTitlesAsTooltip || isUserPattern) && /*#__PURE__*/_jsxs(HStack, { className: "block-editor-patterns__pattern-details", spacing: 2, children: [isUserPattern && !pattern.syncStatus && /*#__PURE__*/_jsx("div", { className: "block-editor-patterns__pattern-icon-wrapper", children: /*#__PURE__*/_jsx(Icon, { className: "block-editor-patterns__pattern-icon", icon: symbol }) }), /*#__PURE__*/_jsx("div", { className: "block-editor-block-patterns-list__item-title", children: pattern.title })] }), !!pattern.description && /*#__PURE__*/_jsx(VisuallyHidden, { id: descriptionId, children: pattern.description })] }) }) }) }); } function BlockPatternPlaceholder() { return /*#__PURE__*/_jsx("div", { className: "block-editor-block-patterns-list__item is-placeholder" }); } function BlockPatternsList({ isDraggable, blockPatterns, onHover, onClickPattern, orientation, label = __('Block patterns'), category, showTitlesAsTooltip, pagingProps }, ref) { const [activeCompositeId, setActiveCompositeId] = useState(undefined); const [activePattern, setActivePattern] = useState(null); // State to track active pattern useEffect(() => { // Reset the active composite item whenever the available patterns change, // to make sure that Composite widget can receive focus correctly when its // composite items change. The first composite item will receive focus. const firstCompositeItemId = blockPatterns[0]?.name; setActiveCompositeId(firstCompositeItemId); }, [blockPatterns]); const handleClickPattern = (pattern, blocks) => { setActivePattern(pattern.name); onClickPattern(pattern, blocks); }; return /*#__PURE__*/_jsxs(Composite, { orientation: orientation, activeId: activeCompositeId, setActiveId: setActiveCompositeId, role: "listbox", className: "block-editor-block-patterns-list", "aria-label": label, ref: ref, children: [blockPatterns.map(pattern => /*#__PURE__*/_jsx(BlockPattern, { id: pattern.name, pattern: pattern, onClick: handleClickPattern, onHover: onHover, isDraggable: isDraggable, showTitlesAsTooltip: showTitlesAsTooltip, category: category, isSelected: !!activePattern && activePattern === pattern.name }, pattern.name)), pagingProps && /*#__PURE__*/_jsx(BlockPatternsPaging, { ...pagingProps })] }); } export default forwardRef(BlockPatternsList); //# sourceMappingURL=index.js.map