"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const jsxRuntime = require("react/jsx-runtime");
const reactBinding = require("@contember/react-binding");
const reactUtils = require("@contember/react-utils");
const ui = require("@contember/ui");
const react = require("react");
const Slate = require("slate");
const slateReact = require("slate-react");
const reactFormFieldsUi = require("@contember/react-form-fields-ui");
const utilities = require("@contember/utilities");
const EditableCanvas = require("../baseEditor/EditableCanvas.cjs");
const RichEditor = require("../RichEditor.cjs");
const BlockHoveringToolbarContents = require("./BlockHoveringToolbarContents.cjs");
const ReferencesProvider = require("./references/ReferencesProvider.cjs");
const useGetReferencedEntity = require("./references/useGetReferencedEntity.cjs");
const useInsertElementWithReference = require("./references/useInsertElementWithReference.cjs");
const SortedBlocksContext = require("./state/SortedBlocksContext.cjs");
const useBlockEditorState = require("./state/useBlockEditorState.cjs");
const useEditorReferenceBlocks = require("./templating/useEditorReferenceBlocks.cjs");
const useCreateElementReference = require("./references/useCreateElementReference.cjs");
const initBlockEditor = require("./editor/initBlockEditor.cjs");
const SortableRepeaterContainer = require("../../collections/Repeater/SortableRepeaterContainer.cjs");
const ContentOutlet = require("./templating/ContentOutlet.cjs");
const RichTextField = require("../RichTextField/RichTextField.cjs");
const useDiscriminatedData = require("../../discrimination/useDiscriminatedData.cjs");
const useNormalizedBlocks = require("../../blocks/useNormalizedBlocks.cjs");
const getDiscriminatedBlock = require("../../blocks/getDiscriminatedBlock.cjs");
const createEditorWithEssentials = require("../baseEditor/createEditorWithEssentials.cjs");
const ParagraphElement = require("../plugins/element/paragraphs/ParagraphElement.cjs");
const HoveringToolbars = require("../toolbars/HoveringToolbars.cjs");
const Repeater = require("../../collections/Repeater/Repeater.cjs");
const BlockEditorComponent = reactBinding.Component(
  (props) => {
    const environment = reactBinding.useEnvironment();
    assertStaticBlockEditorInvariants();
    const {
      contentField,
      label,
      placeholder,
      sortableBy,
      children,
      size,
      leadingFieldBackedElements = reactUtils.emptyArray,
      trailingFieldBackedElements = reactUtils.emptyArray,
      referencesField,
      referenceDiscriminationField,
      monolithicReferencesMode = false,
      embedReferenceDiscriminateBy,
      embedContentDiscriminationField,
      embedHandlers = reactUtils.emptyArray,
      toolbarScheme,
      inlineButtons = defaultInlineButtons,
      blockButtons,
      otherBlockButtons,
      showToolbarLabels,
      plugins,
      augmentEditor,
      augmentEditorBuiltins,
      ...blockListProps
    } = props;
    const desugaredReferenceDiscriminationField = reactBinding.useDesugaredRelativeSingleField(referenceDiscriminationField);
    const desugaredEmbedContentDiscriminationField = reactBinding.useDesugaredRelativeSingleField(embedContentDiscriminationField);
    const editorReferenceBlocks = useEditorReferenceBlocks.useEditorReferenceBlocks(children);
    const discriminatedEmbedHandlers = useDiscriminatedData.useDiscriminatedData(embedHandlers);
    const embedReferenceDiscriminant = react.useMemo(() => {
      if (embedReferenceDiscriminateBy !== void 0) {
        return reactBinding.VariableInputTransformer.transformValue(embedReferenceDiscriminateBy, environment);
      }
      return void 0;
    }, [embedReferenceDiscriminateBy, environment]);
    const embedSubBlocks = useNormalizedBlocks.useNormalizedBlocks(
      embedReferenceDiscriminant !== void 0 ? getDiscriminatedBlock.getDiscriminatedBlock(editorReferenceBlocks, embedReferenceDiscriminant)?.datum.children : void 0
      // TODO this may crash
    );
    const [baseEditor] = react.useState(() => createEditorWithEssentials.createEditorWithEssentials(ParagraphElement.paragraphElementType));
    const { nodes, onChange, sortedBlocksRef, refreshBlocks } = useBlockEditorState.useBlockEditorState({
      editor: baseEditor,
      blockList: blockListProps,
      contentField,
      sortableBy,
      monolithicReferencesMode,
      referencesField
    });
    const getReferencedEntity = useGetReferencedEntity.useGetReferencedEntity({
      monolithicReferencesMode,
      referencesField,
      sortedBlocksRef
    });
    const createElementReference = useCreateElementReference.useCreateElementReference({
      sortedBlocksRef,
      monolithicReferencesMode,
      referenceDiscriminationField,
      referencesField,
      refreshBlocks
    });
    const stableCreateElementReference = reactUtils.useReferentiallyStableCallback(createElementReference);
    const insertElementWithReference = useInsertElementWithReference.useInsertElementWithReference({
      editor: baseEditor,
      createElementReference: stableCreateElementReference
    });
    const stableGetReferencedEntity = reactUtils.useReferentiallyStableCallback(getReferencedEntity);
    const [editor] = react.useState(() => initBlockEditor.initBlockEditor({
      editor: baseEditor,
      augmentEditor,
      augmentEditorBuiltins,
      editorReferenceBlocks,
      embedContentDiscriminationField: desugaredEmbedContentDiscriminationField,
      embedHandlers: discriminatedEmbedHandlers,
      embedReferenceDiscriminateBy: embedReferenceDiscriminant,
      embedSubBlocks,
      plugins,
      referenceDiscriminationField: desugaredReferenceDiscriminationField,
      createElementReferences: stableCreateElementReference,
      getReferencedEntity: stableGetReferencedEntity,
      insertElementWithReference
    }));
    const shouldDisplayInlineToolbar = react.useCallback(() => {
      const selection = baseEditor.selection;
      return !(!selection || Slate.Range.isCollapsed(selection));
    }, [baseEditor]);
    const leadingElements = useFieldBackedElementFields(leadingFieldBackedElements);
    const trailingElements = useFieldBackedElementFields(trailingFieldBackedElements);
    const [_, setMeaninglessState] = react.useState(0);
    react.useLayoutEffect(() => {
      if (editor.children !== nodes && JSON.stringify(editor.children) !== JSON.stringify(nodes)) {
        editor.children = nodes;
        setMeaninglessState((meaninglessState) => meaninglessState + 1);
      }
    }, [nodes, editor]);
    return /* @__PURE__ */ jsxRuntime.jsx(ui.FieldContainer, { label, useLabelElement: false, children: /* @__PURE__ */ jsxRuntime.jsx(ReferencesProvider.ReferencesProvider, { getReferencedEntity, children: /* @__PURE__ */ jsxRuntime.jsx(SortedBlocksContext.SortedBlocksContext.Provider, { value: sortedBlocksRef.current, children: /* @__PURE__ */ jsxRuntime.jsx(
      SortableRepeaterContainer.SortableRepeaterContainer,
      {
        axis: "y",
        lockAxis: "y",
        helperClass: "is-dragged",
        lockToContainerEdges: true,
        useWindowAsScrollContainer: true,
        useDragHandle: true,
        onSortEnd: react.useCallback((data) => {
          Slate.Transforms.moveNodes(editor, {
            at: [data.oldIndex],
            to: [data.newIndex]
          });
        }, [editor]),
        shouldCancelStart: utilities.shouldCancelStart,
        children: /* @__PURE__ */ jsxRuntime.jsx(slateReact.Slate, { editor, value: nodes, onChange, children: /* @__PURE__ */ jsxRuntime.jsx(
          ui.EditorCanvas,
          {
            inset: "hovering-toolbar",
            underlyingComponent: EditableCanvas.EditableCanvas,
            componentProps: {
              renderElement: baseEditor.renderElement,
              renderLeaf: baseEditor.renderLeaf,
              onKeyDown: baseEditor.onKeyDown,
              onFocusCapture: baseEditor.onFocus,
              onBlurCapture: baseEditor.onBlur,
              onDOMBeforeInput: baseEditor.onDOMBeforeInput,
              onDrop: (e) => {
                e.preventDefault();
              },
              placeholder,
              leading: leadingElements,
              trailing: trailingElements
            },
            size: size ?? "large",
            children: react.useMemo(
              () => /* @__PURE__ */ jsxRuntime.jsx(
                HoveringToolbars.HoveringToolbars,
                {
                  toolbarScheme,
                  shouldDisplayInlineToolbar,
                  inlineButtons,
                  showLabels: showToolbarLabels,
                  blockButtons: /* @__PURE__ */ jsxRuntime.jsx(
                    BlockHoveringToolbarContents.BlockHoveringToolbarContents,
                    {
                      editorReferenceBlocks,
                      blockButtons,
                      otherBlockButtons,
                      showLabels: showToolbarLabels
                    }
                  )
                }
              ),
              [blockButtons, editorReferenceBlocks, inlineButtons, otherBlockButtons, shouldDisplayInlineToolbar, showToolbarLabels, toolbarScheme]
            )
          }
        ) })
      }
    ) }) }) });
  },
  (props, environment) => {
    assertStaticBlockEditorInvariants();
    const embedHandlers = Array.from(props.embedHandlers || []);
    const inlineButtons = props.inlineButtons ? (Array.isArray(props.inlineButtons[0]) ? props.inlineButtons : [props.inlineButtons]).flat() : reactUtils.emptyArray;
    const references = !!(props.referencesField && props.referenceDiscriminationField) && /* @__PURE__ */ jsxRuntime.jsxs(
      reactBinding.HasMany,
      {
        ...typeof props.referencesField === "string" ? { field: props.referencesField } : props.referencesField,
        initialEntityCount: 0,
        children: [
          inlineButtons.filter((button) => "referenceContent" in button).map(({ referenceContent: Content }, i) => {
            return /* @__PURE__ */ jsxRuntime.jsx(Content, { referenceId: "", editor: 0, selection: null, onSuccess: reactUtils.noop, onCancel: reactUtils.noop }, i);
          }),
          /* @__PURE__ */ jsxRuntime.jsx(reactBinding.SugaredField, { field: props.referenceDiscriminationField }),
          props.children,
          props.embedContentDiscriminationField && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
            /* @__PURE__ */ jsxRuntime.jsx(reactBinding.SugaredField, { field: props.embedContentDiscriminationField }),
            embedHandlers.map((handler, i) => /* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children: handler.staticRender(environment) }, i))
          ] })
        ]
      }
    );
    return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
      props.leadingFieldBackedElements?.map((item, i) => "element" in item ? /* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children: item.element }, `leading_${i}`) : /* @__PURE__ */ jsxRuntime.jsx(reactBinding.SugaredField, { field: item.field }, `leading_${i}`)),
      props.trailingFieldBackedElements?.map((item, i) => "element" in item ? /* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children: item.element }, `trailing_${i}`) : /* @__PURE__ */ jsxRuntime.jsx(reactBinding.SugaredField, { field: item.field }, `trailing_${i}`)),
      /* @__PURE__ */ jsxRuntime.jsxs(Repeater.Repeater, { ...props, label: props.label ?? "", initialEntityCount: 0, children: [
        /* @__PURE__ */ jsxRuntime.jsx(reactBinding.SugaredField, { field: props.sortableBy }),
        /* @__PURE__ */ jsxRuntime.jsx(reactBinding.SugaredField, { field: props.contentField }),
        !props.monolithicReferencesMode && references
      ] }),
      props.monolithicReferencesMode && references
    ] });
  },
  "BlockEditor"
);
const BlockEditor = Object.assign(BlockEditorComponent, {
  ContentOutlet: ContentOutlet.ContentOutlet
});
const useFieldBackedElementFields = (elements) => {
  return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: elements.map((el, i) => {
    if ("element" in el) {
      return /* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children: el.element }, i);
    }
    if (el.format === "plainText") {
      return /* @__PURE__ */ jsxRuntime.jsx(
        reactFormFieldsUi.TextareaField,
        {
          distinction: "seamless",
          field: el.field,
          label: void 0,
          placeholder: el.placeholder,
          size: el.size
        },
        i
      );
    }
    return /* @__PURE__ */ jsxRuntime.jsx(RichTextField.RichTextField, { field: el.field, label: void 0, placeholder: el.placeholder, distinction: el.distinction ?? "seamless" }, i);
  }) });
};
const assertStaticBlockEditorInvariants = (props, environment) => {
};
const RB = RichEditor.RichEditor.buttons;
const defaultInlineButtons = [
  [RB.bold, RB.italic, RB.underline, RB.anchor],
  [RB.headingOne, RB.headingTwo],
  [RB.strikeThrough, RB.code]
];
exports.BlockEditor = BlockEditor;
//# sourceMappingURL=BlockEditor.cjs.map
