"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const jsxDevRuntime = require("react/jsx-dev-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(props);
    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__ */ jsxDevRuntime.jsxDEV(ui.FieldContainer, { label, useLabelElement: false, children: /* @__PURE__ */ jsxDevRuntime.jsxDEV(ReferencesProvider.ReferencesProvider, { getReferencedEntity, children: /* @__PURE__ */ jsxDevRuntime.jsxDEV(SortedBlocksContext.SortedBlocksContext.Provider, { value: sortedBlocksRef.current, children: /* @__PURE__ */ jsxDevRuntime.jsxDEV(
      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__ */ jsxDevRuntime.jsxDEV(slateReact.Slate, { editor, value: nodes, onChange, children: /* @__PURE__ */ jsxDevRuntime.jsxDEV(
          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__ */ jsxDevRuntime.jsxDEV(
                HoveringToolbars.HoveringToolbars,
                {
                  toolbarScheme,
                  shouldDisplayInlineToolbar,
                  inlineButtons,
                  showLabels: showToolbarLabels,
                  blockButtons: /* @__PURE__ */ jsxDevRuntime.jsxDEV(
                    BlockHoveringToolbarContents.BlockHoveringToolbarContents,
                    {
                      editorReferenceBlocks,
                      blockButtons,
                      otherBlockButtons,
                      showLabels: showToolbarLabels
                    },
                    void 0,
                    false,
                    {
                      fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
                      lineNumber: 251,
                      columnNumber: 14
                    },
                    void 0
                  )
                },
                void 0,
                false,
                {
                  fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
                  lineNumber: 245,
                  columnNumber: 12
                },
                void 0
              ),
              [blockButtons, editorReferenceBlocks, inlineButtons, otherBlockButtons, shouldDisplayInlineToolbar, showToolbarLabels, toolbarScheme]
            )
          },
          void 0,
          false,
          {
            fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
            lineNumber: 223,
            columnNumber: 9
          },
          void 0
        ) }, void 0, false, {
          fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
          lineNumber: 222,
          columnNumber: 8
        }, void 0)
      },
      void 0,
      false,
      {
        fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
        lineNumber: 207,
        columnNumber: 7
      },
      void 0
    ) }, void 0, false, {
      fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
      lineNumber: 206,
      columnNumber: 6
    }, void 0) }, void 0, false, {
      fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
      lineNumber: 205,
      columnNumber: 5
    }, void 0) }, void 0, false, {
      fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
      lineNumber: 204,
      columnNumber: 4
    }, void 0);
  },
  (props, environment) => {
    assertStaticBlockEditorInvariants(props);
    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__ */ jsxDevRuntime.jsxDEV(
      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__ */ jsxDevRuntime.jsxDEV(Content, { referenceId: "", editor: 0, selection: null, onSuccess: reactUtils.noop, onCancel: reactUtils.noop }, i, false, {
              fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
              lineNumber: 290,
              columnNumber: 8
            }, void 0);
          }),
          /* @__PURE__ */ jsxDevRuntime.jsxDEV(reactBinding.SugaredField, { field: props.referenceDiscriminationField }, void 0, false, {
            fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
            lineNumber: 293,
            columnNumber: 5
          }, void 0),
          props.children,
          props.embedContentDiscriminationField && /* @__PURE__ */ jsxDevRuntime.jsxDEV(jsxDevRuntime.Fragment, { children: [
            /* @__PURE__ */ jsxDevRuntime.jsxDEV(reactBinding.SugaredField, { field: props.embedContentDiscriminationField }, void 0, false, {
              fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
              lineNumber: 297,
              columnNumber: 7
            }, void 0),
            embedHandlers.map((handler, i) => /* @__PURE__ */ jsxDevRuntime.jsxDEV(react.Fragment, { children: handler.staticRender(environment) }, i, false, {
              fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
              lineNumber: 299,
              columnNumber: 8
            }, void 0))
          ] }, void 0, true, {
            fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
            lineNumber: 296,
            columnNumber: 6
          }, void 0)
        ]
      },
      void 0,
      true,
      {
        fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
        lineNumber: 282,
        columnNumber: 4
      },
      void 0
    );
    return /* @__PURE__ */ jsxDevRuntime.jsxDEV(jsxDevRuntime.Fragment, { children: [
      props.leadingFieldBackedElements?.map((item, i) => "element" in item ? /* @__PURE__ */ jsxDevRuntime.jsxDEV(react.Fragment, { children: item.element }, `leading_${i}`, false, {
        fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
        lineNumber: 309,
        columnNumber: 26
      }, void 0) : /* @__PURE__ */ jsxDevRuntime.jsxDEV(reactBinding.SugaredField, { field: item.field }, `leading_${i}`, false, {
        fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
        lineNumber: 309,
        columnNumber: 85
      }, void 0)),
      props.trailingFieldBackedElements?.map((item, i) => "element" in item ? /* @__PURE__ */ jsxDevRuntime.jsxDEV(react.Fragment, { children: item.element }, `trailing_${i}`, false, {
        fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
        lineNumber: 312,
        columnNumber: 26
      }, void 0) : /* @__PURE__ */ jsxDevRuntime.jsxDEV(reactBinding.SugaredField, { field: item.field }, `trailing_${i}`, false, {
        fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
        lineNumber: 312,
        columnNumber: 86
      }, void 0)),
      /* @__PURE__ */ jsxDevRuntime.jsxDEV(Repeater.Repeater, { ...props, label: props.label ?? "", initialEntityCount: 0, children: [
        /* @__PURE__ */ jsxDevRuntime.jsxDEV(reactBinding.SugaredField, { field: props.sortableBy }, void 0, false, {
          fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
          lineNumber: 315,
          columnNumber: 6
        }, void 0),
        /* @__PURE__ */ jsxDevRuntime.jsxDEV(reactBinding.SugaredField, { field: props.contentField }, void 0, false, {
          fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
          lineNumber: 316,
          columnNumber: 6
        }, void 0),
        !props.monolithicReferencesMode && references
      ] }, void 0, true, {
        fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
        lineNumber: 314,
        columnNumber: 5
      }, void 0),
      props.monolithicReferencesMode && references
    ] }, void 0, true, {
      fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
      lineNumber: 307,
      columnNumber: 4
    }, void 0);
  },
  "BlockEditor"
);
const BlockEditor = Object.assign(BlockEditorComponent, {
  ContentOutlet: ContentOutlet.ContentOutlet
});
const useFieldBackedElementFields = (elements) => {
  return /* @__PURE__ */ jsxDevRuntime.jsxDEV(jsxDevRuntime.Fragment, { children: elements.map((el, i) => {
    if ("element" in el) {
      return /* @__PURE__ */ jsxDevRuntime.jsxDEV(react.Fragment, { children: el.element }, i, false, {
        fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
        lineNumber: 345,
        columnNumber: 12
      }, void 0);
    }
    if (el.format === "plainText") {
      return /* @__PURE__ */ jsxDevRuntime.jsxDEV(
        reactFormFieldsUi.TextareaField,
        {
          distinction: "seamless",
          field: el.field,
          label: void 0,
          placeholder: el.placeholder,
          size: el.size
        },
        i,
        false,
        {
          fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
          lineNumber: 349,
          columnNumber: 6
        },
        void 0
      );
    }
    return /* @__PURE__ */ jsxDevRuntime.jsxDEV(RichTextField.RichTextField, { field: el.field, label: void 0, placeholder: el.placeholder, distinction: el.distinction ?? "seamless" }, i, false, {
      fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
      lineNumber: 359,
      columnNumber: 11
    }, void 0);
  }) }, void 0, false, {
    fileName: "/__w/interface/interface/packages/admin/src/components/bindingFacade/richText/blockEditor/BlockEditor.tsx",
    lineNumber: 342,
    columnNumber: 9
  }, void 0);
};
const assertStaticBlockEditorInvariants = (props, environment) => {
  {
    if (props.referencesField !== void 0 && props.referenceDiscriminationField === void 0) {
      throw new reactBinding.BindingError(
        `BlockEditor: missing the 'referenceDiscriminationField' prop. Without it the editor cannot tell different kinds of references apart!`
      );
    }
    if (props.referencesField === void 0 && props.referenceDiscriminationField !== void 0) {
      throw new reactBinding.BindingError(
        `BlockEditor: supplied the 'referenceDiscriminationField' prop but missing 'referencesField'. Either remove 'referenceDiscriminationField' to get rid of this error or provide 'referencesField' to enable content references.`
      );
    }
    if (props.referencesField !== void 0 && (props.embedReferenceDiscriminateBy === void 0 || props.embedContentDiscriminationField === void 0 || props.embedHandlers === void 0) && (props.embedReferenceDiscriminateBy !== void 0 || props.embedContentDiscriminationField !== void 0 || props.embedHandlers !== void 0)) {
      throw new reactBinding.BindingError(
        `BlockEditor: trying to enable embeds without content references being enabled. In order to use embeds, provide both the 'referenceDiscriminationField' as well as the 'referencesField' prop`
      );
    }
    if (props.embedReferenceDiscriminateBy !== void 0) {
      if (props.embedContentDiscriminationField === void 0) {
        throw new reactBinding.BindingError(
          `BlockEditor: You enabled embed blocks by supplying the 'embedReferenceDiscriminateBy' prop but then failed to also supply the 'embedContentDiscriminationField'. Without it, the editor would not be able to distinguish between the kinds of embedded content.`
        );
      }
      if (!props.embedHandlers || Array.from(props.embedHandlers).length === 0) {
        throw new reactBinding.BindingError(
          `BlockEditor: You enabled embed blocks by supplying the 'embedReferenceDiscriminateBy' prop but then failed to also supply any embed handlers. Without them, the editor would not be able to recognize any embedded content.`
        );
      }
    }
  }
};
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
