UNPKG

@wordpress/block-editor

Version:
366 lines (365 loc) 11.1 kB
// packages/block-editor/src/components/child-layout-control/index.js import { __experimentalToggleGroupControl as ToggleGroupControl, __experimentalToggleGroupControlOption as ToggleGroupControlOption, __experimentalUnitControl as UnitControl, __experimentalInputControl as InputControl, __experimentalVStack as VStack, __experimentalToolsPanelItem as ToolsPanelItem, __experimentalUseCustomUnits as useCustomUnits, Flex, FlexItem } from "@wordpress/components"; import { __, _x } from "@wordpress/i18n"; import { useEffect } from "@wordpress/element"; import { useSelect, useDispatch } from "@wordpress/data"; import { useGetNumberOfBlocksBeforeCell } from "../grid/use-get-number-of-blocks-before-cell"; import { store as blockEditorStore } from "../../store"; import { useSettings } from "../use-settings"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; function helpText(selfStretch, parentLayout) { const { orientation = "horizontal" } = parentLayout; if (selfStretch === "fill") { return __("Stretch to fill available space."); } if (selfStretch === "fixed" && orientation === "horizontal") { return __("Specify a fixed width."); } else if (selfStretch === "fixed") { return __("Specify a fixed height."); } return __("Fit contents."); } function ChildLayoutControl({ value: childLayout = {}, onChange, parentLayout, isShownByDefault, panelId }) { const { type: parentType, default: { type: defaultParentType = "default" } = {} } = parentLayout ?? {}; const parentLayoutType = parentType || defaultParentType; if (parentLayoutType === "flex") { return /* @__PURE__ */ jsx( FlexControls, { childLayout, onChange, parentLayout, isShownByDefault, panelId } ); } else if (parentLayoutType === "grid") { return /* @__PURE__ */ jsx( GridControls, { childLayout, onChange, parentLayout, isShownByDefault, panelId } ); } return null; } function FlexControls({ childLayout, onChange, parentLayout, isShownByDefault, panelId }) { const { selfStretch, flexSize } = childLayout; const { orientation = "horizontal" } = parentLayout ?? {}; const hasFlexValue = () => !!selfStretch; const flexResetLabel = orientation === "horizontal" ? __("Width") : __("Height"); const [availableUnits] = useSettings("spacing.units"); const units = useCustomUnits({ availableUnits: availableUnits || [ "%", "px", "em", "rem", "vh", "vw" ] }); const resetFlex = () => { onChange({ selfStretch: void 0, flexSize: void 0 }); }; useEffect(() => { if (selfStretch === "fixed" && !flexSize) { onChange({ ...childLayout, selfStretch: "fit" }); } }, []); return /* @__PURE__ */ jsxs( VStack, { as: ToolsPanelItem, spacing: 2, hasValue: hasFlexValue, label: flexResetLabel, onDeselect: resetFlex, isShownByDefault, panelId, children: [ /* @__PURE__ */ jsxs( ToggleGroupControl, { __nextHasNoMarginBottom: true, size: "__unstable-large", label: childLayoutOrientation(parentLayout), value: selfStretch || "fit", help: helpText(selfStretch, parentLayout), onChange: (value) => { const newFlexSize = value !== "fixed" ? null : flexSize; onChange({ selfStretch: value, flexSize: newFlexSize }); }, isBlock: true, children: [ /* @__PURE__ */ jsx( ToggleGroupControlOption, { value: "fit", label: _x( "Fit", "Intrinsic block width in flex layout" ) }, "fit" ), /* @__PURE__ */ jsx( ToggleGroupControlOption, { value: "fill", label: _x( "Grow", "Block with expanding width in flex layout" ) }, "fill" ), /* @__PURE__ */ jsx( ToggleGroupControlOption, { value: "fixed", label: _x( "Fixed", "Block with fixed width in flex layout" ) }, "fixed" ) ] } ), selfStretch === "fixed" && /* @__PURE__ */ jsx( UnitControl, { size: "__unstable-large", units, onChange: (value) => { onChange({ selfStretch, flexSize: value }); }, value: flexSize, min: 0, label: flexResetLabel, hideLabelFromVision: true } ) ] } ); } function childLayoutOrientation(parentLayout) { const { orientation = "horizontal" } = parentLayout; return orientation === "horizontal" ? __("Width") : __("Height"); } function GridControls({ childLayout, onChange, parentLayout, isShownByDefault, panelId }) { const { columnStart, rowStart, columnSpan, rowSpan } = childLayout; const { columnCount, rowCount } = parentLayout ?? {}; const rootClientId = useSelect( (select) => select(blockEditorStore).getBlockRootClientId(panelId) ); const { moveBlocksToPosition, __unstableMarkNextChangeAsNotPersistent } = useDispatch(blockEditorStore); const getNumberOfBlocksBeforeCell = useGetNumberOfBlocksBeforeCell( rootClientId, columnCount || 3 ); const hasStartValue = () => !!columnStart || !!rowStart; const hasSpanValue = () => !!columnSpan || !!rowSpan; const resetGridStarts = () => { onChange({ columnStart: void 0, rowStart: void 0 }); }; const resetGridSpans = () => { onChange({ columnSpan: void 0, rowSpan: void 0 }); }; const maxColumnSpan = columnCount ? columnCount - (columnStart ?? 1) + 1 : void 0; const maxRowSpan = window.__experimentalEnableGridInteractivity && rowCount ? rowCount - (rowStart ?? 1) + 1 : void 0; return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsxs( Flex, { as: ToolsPanelItem, hasValue: hasSpanValue, label: __("Grid span"), onDeselect: resetGridSpans, isShownByDefault, panelId, children: [ /* @__PURE__ */ jsx(FlexItem, { style: { width: "50%" }, children: /* @__PURE__ */ jsx( InputControl, { size: "__unstable-large", label: __("Column span"), type: "number", onChange: (value) => { const newColumnSpan = value === "" ? 1 : parseInt(value, 10); const constrainedValue = maxColumnSpan ? Math.min(newColumnSpan, maxColumnSpan) : newColumnSpan; onChange({ columnStart, rowStart, rowSpan, columnSpan: constrainedValue }); }, value: columnSpan ?? 1, min: 1, max: maxColumnSpan } ) }), /* @__PURE__ */ jsx(FlexItem, { style: { width: "50%" }, children: /* @__PURE__ */ jsx( InputControl, { size: "__unstable-large", label: __("Row span"), type: "number", onChange: (value) => { const newRowSpan = value === "" ? 1 : parseInt(value, 10); const constrainedValue = maxRowSpan ? Math.min(newRowSpan, maxRowSpan) : newRowSpan; onChange({ columnStart, rowStart, columnSpan, rowSpan: constrainedValue }); }, value: rowSpan ?? 1, min: 1, max: maxRowSpan } ) }) ] } ), window.__experimentalEnableGridInteractivity && // Use Flex with an explicit width on the FlexItem instead of HStack to // work around an issue in webkit where inputs with a max attribute are // sized incorrectly. /* @__PURE__ */ jsxs( Flex, { as: ToolsPanelItem, hasValue: hasStartValue, label: __("Grid placement"), onDeselect: resetGridStarts, isShownByDefault: false, panelId, children: [ /* @__PURE__ */ jsx(FlexItem, { style: { width: "50%" }, children: /* @__PURE__ */ jsx( InputControl, { size: "__unstable-large", label: __("Column"), type: "number", onChange: (value) => { const newColumnStart = value === "" ? 1 : parseInt(value, 10); onChange({ columnStart: newColumnStart, rowStart, columnSpan, rowSpan }); __unstableMarkNextChangeAsNotPersistent(); moveBlocksToPosition( [panelId], rootClientId, rootClientId, getNumberOfBlocksBeforeCell( newColumnStart, rowStart ) ); }, value: columnStart ?? 1, min: 1, max: columnCount ? columnCount - (columnSpan ?? 1) + 1 : void 0 } ) }), /* @__PURE__ */ jsx(FlexItem, { style: { width: "50%" }, children: /* @__PURE__ */ jsx( InputControl, { size: "__unstable-large", label: __("Row"), type: "number", onChange: (value) => { const newRowStart = value === "" ? 1 : parseInt(value, 10); onChange({ columnStart, rowStart: newRowStart, columnSpan, rowSpan }); __unstableMarkNextChangeAsNotPersistent(); moveBlocksToPosition( [panelId], rootClientId, rootClientId, getNumberOfBlocksBeforeCell( columnStart, newRowStart ) ); }, value: rowStart ?? 1, min: 1, max: rowCount ? rowCount - (rowSpan ?? 1) + 1 : void 0 } ) }) ] } ) ] }); } export { childLayoutOrientation, ChildLayoutControl as default }; //# sourceMappingURL=index.js.map