UNPKG

@gechiui/block-editor

Version:
209 lines (191 loc) 6.24 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import { createElement, Fragment } from "@gechiui/element"; /** * External dependencies */ import classnames from 'classnames'; import { has } from 'lodash'; /** * GeChiUI dependencies */ import { createHigherOrderComponent, useInstanceId } from '@gechiui/compose'; import { addFilter } from '@gechiui/hooks'; import { getBlockSupport, hasBlockSupport } from '@gechiui/blocks'; import { useSelect } from '@gechiui/data'; import { Button, ButtonGroup, ToggleControl, PanelBody } from '@gechiui/components'; import { __ } from '@gechiui/i18n'; import { useContext, createPortal } from '@gechiui/element'; /** * Internal dependencies */ import { store as blockEditorStore } from '../store'; import { InspectorControls } from '../components'; import useSetting from '../components/use-setting'; import { LayoutStyle } from '../components/block-list/layout'; import BlockList from '../components/block-list'; import { getLayoutType, getLayoutTypes } from '../layouts'; const layoutBlockSupportKey = '__experimentalLayout'; function LayoutPanel(_ref) { let { setAttributes, attributes, name: blockName } = _ref; const { layout } = attributes; const defaultThemeLayout = useSetting('layout'); const themeSupportsLayout = useSelect(select => { const { getSettings } = select(blockEditorStore); return getSettings().supportsLayout; }, []); const layoutBlockSupport = getBlockSupport(blockName, layoutBlockSupportKey, {}); const { allowSwitching, allowEditing = true, allowInheriting = true, default: defaultBlockLayout } = layoutBlockSupport; if (!allowEditing) { return null; } const usedLayout = layout || defaultBlockLayout || {}; const { inherit = false, type = 'default' } = usedLayout; /** * `themeSupportsLayout` is only relevant to the `default/flow` * layout and it should not be taken into account when other * `layout` types are used. */ if (type === 'default' && !themeSupportsLayout) { return null; } const layoutType = getLayoutType(type); const onChangeType = newType => setAttributes({ layout: { type: newType } }); const onChangeLayout = newLayout => setAttributes({ layout: newLayout }); return createElement(Fragment, null, createElement(InspectorControls, null, createElement(PanelBody, { title: __('布局') }, allowInheriting && !!defaultThemeLayout && createElement(ToggleControl, { label: __('继承默认布局'), checked: !!inherit, onChange: () => setAttributes({ layout: { inherit: !inherit } }) }), !inherit && allowSwitching && createElement(LayoutTypeSwitcher, { type: type, onChange: onChangeType }), !inherit && layoutType && createElement(layoutType.inspectorControls, { layout: usedLayout, onChange: onChangeLayout, layoutBlockSupport: layoutBlockSupport }))), !inherit && layoutType && createElement(layoutType.toolBarControls, { layout: usedLayout, onChange: onChangeLayout, layoutBlockSupport: layoutBlockSupport })); } function LayoutTypeSwitcher(_ref2) { let { type, onChange } = _ref2; return createElement(ButtonGroup, null, getLayoutTypes().map(_ref3 => { let { name, label } = _ref3; return createElement(Button, { key: name, isPressed: type === name, onClick: () => onChange(name) }, label); })); } /** * Filters registered block settings, extending attributes to include `layout`. * * @param {Object} settings Original block settings. * * @return {Object} Filtered block settings. */ export function addAttribute(settings) { if (has(settings.attributes, ['layout', 'type'])) { return settings; } if (hasBlockSupport(settings, layoutBlockSupportKey)) { settings.attributes = { ...settings.attributes, layout: { type: 'object' } }; } return settings; } /** * Override the default edit UI to include layout controls * * @param {Function} BlockEdit Original component. * * @return {Function} Wrapped component. */ export const withInspectorControls = createHigherOrderComponent(BlockEdit => props => { const { name: blockName } = props; const supportLayout = hasBlockSupport(blockName, layoutBlockSupportKey); return [supportLayout && createElement(LayoutPanel, _extends({ key: "layout" }, props)), createElement(BlockEdit, _extends({ key: "edit" }, props))]; }, 'withInspectorControls'); /** * Override the default block element to add the layout styles. * * @param {Function} BlockListBlock Original component. * * @return {Function} Wrapped component. */ export const withLayoutStyles = createHigherOrderComponent(BlockListBlock => props => { const { name, attributes } = props; const shouldRenderLayoutStyles = hasBlockSupport(name, layoutBlockSupportKey); const id = useInstanceId(BlockListBlock); const defaultThemeLayout = useSetting('layout') || {}; const element = useContext(BlockList.__unstableElementContext); const { layout } = attributes; const { default: defaultBlockLayout } = getBlockSupport(name, layoutBlockSupportKey) || {}; const usedLayout = layout !== null && layout !== void 0 && layout.inherit ? defaultThemeLayout : layout || defaultBlockLayout || {}; const className = classnames(props === null || props === void 0 ? void 0 : props.className, { [`gc-container-${id}`]: shouldRenderLayoutStyles }); return createElement(Fragment, null, shouldRenderLayoutStyles && element && createPortal(createElement(LayoutStyle, { selector: `.gc-container-${id}`, layout: usedLayout, style: attributes === null || attributes === void 0 ? void 0 : attributes.style }), element), createElement(BlockListBlock, _extends({}, props, { className: className }))); }); addFilter('blocks.registerBlockType', 'core/layout/addAttribute', addAttribute); addFilter('editor.BlockListBlock', 'core/editor/layout/with-layout-styles', withLayoutStyles); addFilter('editor.BlockEdit', 'core/editor/layout/with-inspector-controls', withInspectorControls); //# sourceMappingURL=layout.js.map