UNPKG

@gechiui/block-editor

Version:
188 lines (178 loc) 4.87 kB
/** * GeChiUI dependencies */ import { useDispatch } from '@gechiui/data'; import { cloneBlock } from '@gechiui/blocks'; import { VisuallyHidden, __unstableComposite as Composite, __unstableUseCompositeState as useCompositeState, __unstableCompositeItem as CompositeItem, } from '@gechiui/components'; import { useState } from '@gechiui/element'; import { useInstanceId } from '@gechiui/compose'; import { __ } from '@gechiui/i18n'; /** * Internal dependencies */ import { store as blockEditorStore } from '../../store'; import BlockPreview from '../block-preview'; import SetupToolbar from './setup-toolbar'; import usePatternsSetup from './use-patterns-setup'; import { VIEWMODES } from './constants'; const SetupContent = ( { viewMode, activeSlide, patterns, onBlockPatternSelect, } ) => { const composite = useCompositeState(); const containerClass = 'block-editor-block-pattern-setup__container'; if ( viewMode === VIEWMODES.carousel ) { const slideClass = new Map( [ [ activeSlide, 'active-slide' ], [ activeSlide - 1, 'previous-slide' ], [ activeSlide + 1, 'next-slide' ], ] ); return ( <div className={ containerClass }> <ul className="carousel-container"> { patterns.map( ( pattern, index ) => ( <BlockPatternSlide className={ slideClass.get( index ) || '' } key={ pattern.name } pattern={ pattern } /> ) ) } </ul> </div> ); } return ( <Composite { ...composite } role="listbox" className={ containerClass } aria-label={ __( '区块样板列表' ) } > { patterns.map( ( pattern ) => ( <BlockPattern key={ pattern.name } pattern={ pattern } onSelect={ onBlockPatternSelect } composite={ composite } /> ) ) } </Composite> ); }; function BlockPattern( { pattern, onSelect, composite } ) { const baseClassName = 'block-editor-block-pattern-setup-list'; const { blocks, title, description, viewportWidth = 700 } = pattern; const descriptionId = useInstanceId( BlockPattern, `${ baseClassName }__item-description` ); return ( <div className={ `${ baseClassName }__list-item` } aria-label={ pattern.title } aria-describedby={ pattern.description ? descriptionId : undefined } > <CompositeItem role="option" as="div" { ...composite } className={ `${ baseClassName }__item` } onClick={ () => onSelect( blocks ) } > <BlockPreview blocks={ blocks } viewportWidth={ viewportWidth } /> <div className={ `${ baseClassName }__item-title` }> { title } </div> </CompositeItem> { !! description && ( <VisuallyHidden id={ descriptionId }> { description } </VisuallyHidden> ) } </div> ); } function BlockPatternSlide( { className, pattern } ) { const { blocks, title, description } = pattern; const descriptionId = useInstanceId( BlockPatternSlide, 'block-editor-block-pattern-setup-list__item-description' ); return ( <li className={ `pattern-slide ${ className }` } aria-label={ title } aria-describedby={ description ? descriptionId : undefined } > <BlockPreview blocks={ blocks } __experimentalLive /> { !! description && ( <VisuallyHidden id={ descriptionId }> { description } </VisuallyHidden> ) } </li> ); } const BlockPatternSetup = ( { clientId, blockName, filterPatternsFn, startBlankComponent, onBlockPatternSelect, } ) => { const [ viewMode, setViewMode ] = useState( VIEWMODES.carousel ); const [ activeSlide, setActiveSlide ] = useState( 0 ); const [ showBlank, setShowBlank ] = useState( false ); const { replaceBlock } = useDispatch( blockEditorStore ); const patterns = usePatternsSetup( clientId, blockName, filterPatternsFn ); if ( ! patterns?.length || showBlank ) { return startBlankComponent; } const onBlockPatternSelectDefault = ( blocks ) => { const clonedBlocks = blocks.map( ( block ) => cloneBlock( block ) ); replaceBlock( clientId, clonedBlocks ); }; const onPatternSelectCallback = onBlockPatternSelect || onBlockPatternSelectDefault; return ( <div className={ `block-editor-block-pattern-setup view-mode-${ viewMode }` } > <SetupToolbar viewMode={ viewMode } setViewMode={ setViewMode } activeSlide={ activeSlide } totalSlides={ patterns.length } handleNext={ () => { setActiveSlide( ( active ) => active + 1 ); } } handlePrevious={ () => { setActiveSlide( ( active ) => active - 1 ); } } onBlockPatternSelect={ () => { onPatternSelectCallback( patterns[ activeSlide ].blocks ); } } onStartBlank={ () => { setShowBlank( true ); } } /> <SetupContent viewMode={ viewMode } activeSlide={ activeSlide } patterns={ patterns } onBlockPatternSelect={ onPatternSelectCallback } /> </div> ); }; export default BlockPatternSetup;