@wordpress/block-editor
Version:
366 lines (365 loc) • 11.1 kB
JavaScript
// 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