// packages/block-editor/src/layouts/flex.js
import { __, _x } from "@wordpress/i18n";
import {
  justifyLeft,
  justifyCenter,
  justifyRight,
  justifySpaceBetween,
  justifyStretch,
  justifyTop,
  justifyCenterVertical,
  justifyBottom,
  justifyStretchVertical,
  justifySpaceBetweenVertical,
  arrowRight,
  arrowDown
} from "@wordpress/icons";
import {
  Flex,
  ToggleControl,
  __experimentalToggleGroupControl as ToggleGroupControl,
  __experimentalToggleGroupControlOptionIcon as ToggleGroupControlOptionIcon,
  __experimentalToolsPanelItem as ToolsPanelItem
} from "@wordpress/components";
import { appendSelectors, getBlockGapCSS } from "./utils.mjs";
import { getGapCSSValue, getGapBoxControlValueFromStyle } from "../hooks/gap.mjs";
import { getSpacingPresetCssVar } from "../components/spacing-sizes-control/utils.mjs";
import {
  BlockControls,
  JustifyContentControl,
  BlockVerticalAlignmentControl
} from "../components/index.mjs";
import { cleanEmptyObject, shouldSkipSerialization } from "../hooks/utils.mjs";
import { LAYOUT_DEFINITIONS } from "./definitions.mjs";
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
var justifyContentMap = {
  left: "flex-start",
  right: "flex-end",
  center: "center",
  "space-between": "space-between"
};
var alignItemsMap = {
  left: "flex-start",
  right: "flex-end",
  center: "center",
  stretch: "stretch"
};
var verticalAlignmentMap = {
  top: "flex-start",
  center: "center",
  bottom: "flex-end",
  stretch: "stretch",
  "space-between": "space-between"
};
var defaultAlignments = {
  horizontal: "center",
  vertical: "top"
};
var verticalAlignmentOptions = {
  top: {
    icon: justifyTop,
    label: _x("Align top", "Block vertical alignment setting")
  },
  center: {
    icon: justifyCenterVertical,
    label: _x("Align middle", "Block vertical alignment setting")
  },
  bottom: {
    icon: justifyBottom,
    label: _x("Align bottom", "Block vertical alignment setting")
  },
  stretch: {
    icon: justifyStretchVertical,
    label: _x("Stretch to fill", "Block vertical alignment setting")
  },
  "space-between": {
    icon: justifySpaceBetweenVertical,
    label: _x("Space between", "Block vertical alignment setting")
  }
};
var flexWrapOptions = ["wrap", "nowrap"];
var flex_default = {
  name: "flex",
  label: __("Flex"),
  inspectorControls: function FlexLayoutInspectorControls({
    layout = {},
    onChange,
    layoutBlockSupport = {},
    resetLayout = {},
    clientId
  }) {
    const {
      allowOrientation = true,
      allowJustification = true,
      allowVerticalAlignment = true,
      allowWrap = true
    } = layoutBlockSupport;
    const hasLayoutValue = (key, defaultValue) => (layout?.[key] ?? defaultValue) !== (resetLayout?.[key] ?? defaultValue);
    const hasJustificationValue = () => hasLayoutValue("justifyContent", "left");
    const hasVerticalAlignmentValue = () => hasLayoutValue(
      "verticalAlignment",
      getDefaultVerticalAlignment(layout)
    );
    const hasOrientationValue = () => hasLayoutValue("orientation", "horizontal");
    const hasWrapValue = () => hasLayoutValue("flexWrap", "wrap");
    const resetJustification = () => onChange(
      cleanEmptyObject({
        ...layout,
        justifyContent: resetLayout?.justifyContent
      })
    );
    const resetVerticalAlignment = () => onChange(
      cleanEmptyObject({
        ...layout,
        verticalAlignment: getCompatibleVerticalAlignment(
          resetLayout?.verticalAlignment,
          layout?.orientation
        )
      })
    );
    const resetOrientation = () => {
      const { verticalAlignment, justifyContent } = layout;
      const nextOrientation = resetLayout?.orientation;
      const isHorizontal = !nextOrientation || nextOrientation === "horizontal";
      onChange(
        cleanEmptyObject({
          ...layout,
          orientation: nextOrientation,
          verticalAlignment: resetLayout?.verticalAlignment ?? (isHorizontal && verticalAlignment === "space-between" ? "center" : verticalAlignment),
          justifyContent: resetLayout?.justifyContent ?? (isHorizontal && justifyContent === "stretch" ? "left" : justifyContent)
        })
      );
    };
    const resetWrap = () => onChange(
      cleanEmptyObject({
        ...layout,
        flexWrap: resetLayout?.flexWrap
      })
    );
    return /* @__PURE__ */ jsxs(Fragment, { children: [
      (allowJustification || allowOrientation) && /* @__PURE__ */ jsxs(
        Flex,
        {
          align: "flex-start",
          className: "block-editor-hooks__flex-layout-controls",
          gap: 4,
          justify: "flex-start",
          children: [
            allowJustification && /* @__PURE__ */ jsx(
              ToolsPanelItem,
              {
                label: __("Justification"),
                hasValue: hasJustificationValue,
                onDeselect: resetJustification,
                isShownByDefault: true,
                panelId: clientId,
                children: /* @__PURE__ */ jsx(
                  FlexLayoutJustifyContentControl,
                  {
                    layout,
                    onChange
                  }
                )
              }
            ),
            allowOrientation && /* @__PURE__ */ jsx(
              ToolsPanelItem,
              {
                label: __("Orientation"),
                hasValue: hasOrientationValue,
                onDeselect: resetOrientation,
                isShownByDefault: true,
                panelId: clientId,
                children: /* @__PURE__ */ jsx(
                  OrientationControl,
                  {
                    layout,
                    onChange
                  }
                )
              }
            )
          ]
        }
      ),
      allowVerticalAlignment && /* @__PURE__ */ jsx(
        ToolsPanelItem,
        {
          label: __("Alignment"),
          hasValue: hasVerticalAlignmentValue,
          onDeselect: resetVerticalAlignment,
          panelId: clientId,
          children: /* @__PURE__ */ jsx(
            FlexLayoutVerticalAlignmentControl,
            {
              layout,
              onChange
            }
          )
        }
      ),
      allowWrap && /* @__PURE__ */ jsx(
        ToolsPanelItem,
        {
          label: __("Wrapping"),
          hasValue: hasWrapValue,
          onDeselect: resetWrap,
          panelId: clientId,
          children: /* @__PURE__ */ jsx(
            FlexWrapControl,
            {
              layout,
              onChange
            }
          )
        }
      )
    ] });
  },
  toolBarControls: function FlexLayoutToolbarControls({
    layout = {},
    onChange,
    layoutBlockSupport
  }) {
    const { allowVerticalAlignment = true, allowJustification = true } = layoutBlockSupport;
    if (!allowJustification && !allowVerticalAlignment) {
      return null;
    }
    return /* @__PURE__ */ jsxs(BlockControls, { group: "block", __experimentalShareWithChildBlocks: true, children: [
      allowJustification && /* @__PURE__ */ jsx(
        FlexLayoutJustifyContentControl,
        {
          layout,
          onChange,
          isToolbar: true
        }
      ),
      allowVerticalAlignment && /* @__PURE__ */ jsx(
        FlexLayoutVerticalAlignmentControl,
        {
          layout,
          onChange,
          isToolbar: true
        }
      )
    ] });
  },
  getLayoutStyle: function getLayoutStyle({
    selector,
    layout = {},
    viewportOverrides,
    style,
    blockName,
    hasBlockGapSupport,
    globalBlockGapValue,
    layoutDefinitions = LAYOUT_DEFINITIONS
  }) {
    const hasViewportOverrides = viewportOverrides !== void 0;
    const effectiveLayout = hasViewportOverrides ? { ...layout, ...viewportOverrides } : layout;
    const hasViewportOverride = (key) => Object.hasOwn(viewportOverrides || {}, key);
    const { orientation = "horizontal" } = effectiveLayout;
    let fallbackGapValue = "0.5em";
    if (globalBlockGapValue) {
      const gapBox = getGapBoxControlValueFromStyle(globalBlockGapValue);
      fallbackGapValue = getSpacingPresetCssVar(gapBox?.left) || getSpacingPresetCssVar(gapBox?.top) || "0.5em";
    }
    const blockGapValue = style?.spacing?.blockGap && !shouldSkipSerialization(blockName, "spacing", "blockGap") ? getGapCSSValue(style?.spacing?.blockGap, fallbackGapValue) : void 0;
    const hasBlockGapOverride = !hasViewportOverrides || Object.hasOwn(style?.spacing || {}, "blockGap");
    const justifyContent = justifyContentMap[effectiveLayout.justifyContent];
    const flexWrap = flexWrapOptions.includes(effectiveLayout.flexWrap) ? effectiveLayout.flexWrap : "wrap";
    const verticalAlignment = verticalAlignmentMap[effectiveLayout.verticalAlignment];
    const alignItems = alignItemsMap[effectiveLayout.justifyContent] || alignItemsMap.left;
    let output = "";
    const rules = [];
    const shouldOutputFlexWrap = !hasViewportOverrides || hasViewportOverride("flexWrap");
    const shouldOutputFlexOrientation = !hasViewportOverrides || hasViewportOverride("orientation");
    const shouldOutputFlexJustification = !hasViewportOverrides || hasViewportOverride("justifyContent") || hasViewportOverride("orientation");
    const shouldOutputFlexAlignment = !hasViewportOverrides || hasViewportOverride("verticalAlignment") || hasViewportOverride("orientation");
    if (shouldOutputFlexWrap && flexWrap && flexWrap !== "wrap") {
      rules.push(`flex-wrap: ${flexWrap}`);
    }
    if (orientation === "horizontal") {
      if (shouldOutputFlexAlignment && verticalAlignment) {
        rules.push(`align-items: ${verticalAlignment}`);
      }
      if (shouldOutputFlexJustification && justifyContent) {
        rules.push(`justify-content: ${justifyContent}`);
      }
    } else {
      if (shouldOutputFlexAlignment && verticalAlignment) {
        rules.push(`justify-content: ${verticalAlignment}`);
      }
      if (shouldOutputFlexOrientation) {
        rules.push("flex-direction: column");
      }
      if (shouldOutputFlexJustification) {
        rules.push(`align-items: ${alignItems}`);
      }
    }
    if (rules.length) {
      output = `${appendSelectors(selector)} {
				${rules.join("; ")};
			}`;
    }
    if (hasBlockGapSupport && hasBlockGapOverride && blockGapValue) {
      output += getBlockGapCSS(
        selector,
        layoutDefinitions,
        "flex",
        blockGapValue
      );
    }
    return output;
  },
  getOrientation(layout) {
    const { orientation = "horizontal" } = layout;
    return orientation;
  },
  getAlignments() {
    return [];
  }
};
function getDefaultVerticalAlignment({ orientation = "horizontal" } = {}) {
  return orientation === "horizontal" ? defaultAlignments.horizontal : defaultAlignments.vertical;
}
function getCompatibleVerticalAlignment(verticalAlignment, orientation) {
  if (orientation === "horizontal" && verticalAlignment === "space-between" || orientation === "vertical" && verticalAlignment === "stretch") {
    return void 0;
  }
  return verticalAlignment;
}
function getVerticalAlignmentControls(orientation) {
  return orientation === "horizontal" ? ["top", "center", "bottom", "stretch"] : ["top", "center", "bottom", "space-between"];
}
function FlexLayoutVerticalAlignmentControl({
  layout,
  onChange,
  isToolbar = false
}) {
  const { orientation = "horizontal" } = layout;
  const { verticalAlignment = getDefaultVerticalAlignment(layout) } = layout;
  const onVerticalAlignmentChange = (value) => {
    onChange({
      ...layout,
      verticalAlignment: value
    });
  };
  const controls = getVerticalAlignmentControls(orientation);
  if (isToolbar) {
    return /* @__PURE__ */ jsx(
      BlockVerticalAlignmentControl,
      {
        onChange: onVerticalAlignmentChange,
        value: verticalAlignment,
        controls
      }
    );
  }
  return /* @__PURE__ */ jsx(
    ToggleGroupControl,
    {
      __next40pxDefaultSize: true,
      label: __("Alignment"),
      onChange: onVerticalAlignmentChange,
      value: verticalAlignment,
      className: "block-editor-hooks__flex-layout-alignment-controls",
      children: controls.map((control) => {
        const { icon, label } = verticalAlignmentOptions[control];
        return /* @__PURE__ */ jsx(
          ToggleGroupControlOptionIcon,
          {
            value: control,
            icon,
            label
          },
          control
        );
      })
    }
  );
}
var POPOVER_PROPS = {
  placement: "bottom-start"
};
function FlexLayoutJustifyContentControl({
  layout,
  onChange,
  isToolbar = false
}) {
  const { justifyContent = "left", orientation = "horizontal" } = layout;
  const onJustificationChange = (value) => {
    onChange({
      ...layout,
      justifyContent: value
    });
  };
  const allowedControls = ["left", "center", "right"];
  if (orientation === "horizontal") {
    allowedControls.push("space-between");
  } else {
    allowedControls.push("stretch");
  }
  if (isToolbar) {
    return /* @__PURE__ */ jsx(
      JustifyContentControl,
      {
        allowedControls,
        value: justifyContent,
        onChange: onJustificationChange,
        popoverProps: POPOVER_PROPS
      }
    );
  }
  const justificationOptions = [
    {
      value: "left",
      icon: justifyLeft,
      label: __("Justify items left")
    },
    {
      value: "center",
      icon: justifyCenter,
      label: __("Justify items center")
    },
    {
      value: "right",
      icon: justifyRight,
      label: __("Justify items right")
    }
  ];
  if (orientation === "horizontal") {
    justificationOptions.push({
      value: "space-between",
      icon: justifySpaceBetween,
      label: __("Space between items")
    });
  } else {
    justificationOptions.push({
      value: "stretch",
      icon: justifyStretch,
      label: __("Stretch items")
    });
  }
  return /* @__PURE__ */ jsx(
    ToggleGroupControl,
    {
      __next40pxDefaultSize: true,
      label: __("Justification"),
      value: justifyContent,
      onChange: onJustificationChange,
      className: "block-editor-hooks__flex-layout-justification-controls",
      children: justificationOptions.map(({ value, icon, label }) => {
        return /* @__PURE__ */ jsx(
          ToggleGroupControlOptionIcon,
          {
            value,
            icon,
            label
          },
          value
        );
      })
    }
  );
}
function FlexWrapControl({ layout, onChange }) {
  const { flexWrap = "wrap" } = layout;
  return /* @__PURE__ */ jsx(
    ToggleControl,
    {
      label: __("Allow to wrap to multiple lines"),
      onChange: (value) => {
        onChange({
          ...layout,
          flexWrap: value ? "wrap" : "nowrap"
        });
      },
      checked: flexWrap === "wrap"
    }
  );
}
function OrientationControl({ layout, onChange }) {
  const {
    orientation = "horizontal",
    verticalAlignment,
    justifyContent
  } = layout;
  return /* @__PURE__ */ jsxs(
    ToggleGroupControl,
    {
      __next40pxDefaultSize: true,
      className: "block-editor-hooks__flex-layout-orientation-controls",
      label: __("Orientation"),
      value: orientation,
      onChange: (value) => {
        let newVerticalAlignment = verticalAlignment;
        let newJustification = justifyContent;
        if (value === "horizontal") {
          if (verticalAlignment === "space-between") {
            newVerticalAlignment = "center";
          }
          if (justifyContent === "stretch") {
            newJustification = "left";
          }
        } else {
          if (verticalAlignment === "stretch") {
            newVerticalAlignment = "top";
          }
          if (justifyContent === "space-between") {
            newJustification = "left";
          }
        }
        return onChange({
          ...layout,
          orientation: value,
          verticalAlignment: newVerticalAlignment,
          justifyContent: newJustification
        });
      },
      children: [
        /* @__PURE__ */ jsx(
          ToggleGroupControlOptionIcon,
          {
            icon: arrowRight,
            value: "horizontal",
            label: __("Horizontal")
          }
        ),
        /* @__PURE__ */ jsx(
          ToggleGroupControlOptionIcon,
          {
            icon: arrowDown,
            value: "vertical",
            label: __("Vertical")
          }
        )
      ]
    }
  );
}
export {
  flex_default as default
};
//# sourceMappingURL=flex.mjs.map
