@react-email/editor 0.0.0-experimental.21 → 0.0.0-experimental.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -3,9 +3,9 @@ import { Body as Body$1, Button as Button$1, CodeBlock, Column, Head, Heading as
3
3
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
4
  import { Extension, InputRule, Mark, Node as Node$1, findChildren, mergeAttributes } from "@tiptap/core";
5
5
  import { UndoRedo } from "@tiptap/extensions";
6
- import { NodeViewContent, NodeViewWrapper, ReactNodeViewRenderer, ReactRenderer, useCurrentEditor, useEditor as useEditor$1, useEditorState } from "@tiptap/react";
6
+ import { NodeViewContent, NodeViewWrapper, ReactNodeViewRenderer, useCurrentEditor, useEditor as useEditor$1, useEditorState } from "@tiptap/react";
7
7
  import * as React from "react";
8
- import { useCallback, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState } from "react";
8
+ import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
9
9
  import TipTapStarterKit from "@tiptap/starter-kit";
10
10
  import BlockquoteBase from "@tiptap/extension-blockquote";
11
11
  import BoldBase from "@tiptap/extension-bold";
@@ -32,8 +32,9 @@ import { generateJSON } from "@tiptap/html";
32
32
  import { AlignCenterIcon, AlignLeftIcon, AlignRightIcon, BoldIcon, CaseUpperIcon, Check, ChevronDown, Code as Code$1, CodeIcon, Columns2, Columns3, Columns4, ExternalLinkIcon, Heading1, Heading2, Heading3, ItalicIcon, LinkIcon, List, ListOrdered, MousePointer, PencilIcon, Rows2, SplitSquareVertical, SquareCode, StrikethroughIcon, Text, TextIcon, TextQuote, UnderlineIcon, UnlinkIcon } from "lucide-react";
33
33
  import * as Popover from "@radix-ui/react-popover";
34
34
  import { BubbleMenu as BubbleMenu$1 } from "@tiptap/react/menus";
35
+ import { autoUpdate, flip, offset, shift, useFloating } from "@floating-ui/react-dom";
35
36
  import Suggestion from "@tiptap/suggestion";
36
- import tippy from "tippy.js";
37
+ import { createPortal } from "react-dom";
37
38
 
38
39
  //#region src/core/event-bus.ts
39
40
  const EVENT_PREFIX = "@react-email/editor:";
@@ -2999,7 +3000,7 @@ function BubbleMenuNodeSelector({ omit = [], className, triggerContent, open, on
2999
3000
 
3000
3001
  //#endregion
3001
3002
  //#region src/ui/bubble-menu/root.tsx
3002
- function BubbleMenuRoot({ excludeNodes = [], placement = "bottom", offset = 8, onHide, className, children }) {
3003
+ function BubbleMenuRoot({ excludeNodes = [], placement = "bottom", offset: offset$1 = 8, onHide, className, children }) {
3003
3004
  const { editor } = useCurrentEditor();
3004
3005
  if (!editor) return null;
3005
3006
  return /* @__PURE__ */ jsx(BubbleMenu$1, {
@@ -3012,7 +3013,7 @@ function BubbleMenuRoot({ excludeNodes = [], placement = "bottom", offset = 8, o
3012
3013
  },
3013
3014
  options: {
3014
3015
  placement,
3015
- offset,
3016
+ offset: offset$1,
3016
3017
  onHide
3017
3018
  },
3018
3019
  className,
@@ -3052,7 +3053,7 @@ const BubbleMenuUppercase = createMarkBubbleItem({
3052
3053
 
3053
3054
  //#endregion
3054
3055
  //#region src/ui/bubble-menu/default.tsx
3055
- function BubbleMenuDefault({ excludeItems = [], excludeNodes, placement, offset, onHide, className }) {
3056
+ function BubbleMenuDefault({ excludeItems = [], excludeNodes, placement, offset: offset$1, onHide, className }) {
3056
3057
  const [isNodeSelectorOpen, setIsNodeSelectorOpen] = React.useState(false);
3057
3058
  const [isLinkSelectorOpen, setIsLinkSelectorOpen] = React.useState(false);
3058
3059
  const has = (item) => !excludeItems.includes(item);
@@ -3074,7 +3075,7 @@ function BubbleMenuDefault({ excludeItems = [], excludeNodes, placement, offset,
3074
3075
  return /* @__PURE__ */ jsxs(BubbleMenuRoot, {
3075
3076
  excludeNodes,
3076
3077
  placement,
3077
- offset,
3078
+ offset: offset$1,
3078
3079
  onHide: handleHide,
3079
3080
  className,
3080
3081
  children: [
@@ -3171,7 +3172,7 @@ function ButtonBubbleMenuEditLink({ className, children, onClick, onMouseDown, .
3171
3172
 
3172
3173
  //#endregion
3173
3174
  //#region src/ui/button-bubble-menu/root.tsx
3174
- function ButtonBubbleMenuRoot({ onHide, placement = "top", offset = 8, className, children }) {
3175
+ function ButtonBubbleMenuRoot({ onHide, placement = "top", offset: offset$1 = 8, className, children }) {
3175
3176
  const { editor } = useCurrentEditor();
3176
3177
  const [isEditing, setIsEditing] = React.useState(false);
3177
3178
  if (!editor) return null;
@@ -3181,7 +3182,7 @@ function ButtonBubbleMenuRoot({ onHide, placement = "top", offset = 8, className
3181
3182
  shouldShow: ({ editor: e, view }) => e.isActive("button") && !view.dom.classList.contains("dragging"),
3182
3183
  options: {
3183
3184
  placement,
3184
- offset,
3185
+ offset: offset$1,
3185
3186
  onHide: () => {
3186
3187
  setIsEditing(false);
3187
3188
  onHide?.();
@@ -3213,10 +3214,10 @@ function ButtonBubbleMenuToolbar({ children, ...rest }) {
3213
3214
 
3214
3215
  //#endregion
3215
3216
  //#region src/ui/button-bubble-menu/default.tsx
3216
- function ButtonBubbleMenuDefault({ excludeItems = [], placement, offset, onHide, className }) {
3217
+ function ButtonBubbleMenuDefault({ excludeItems = [], placement, offset: offset$1, onHide, className }) {
3217
3218
  return /* @__PURE__ */ jsx(ButtonBubbleMenuRoot, {
3218
3219
  placement,
3219
- offset,
3220
+ offset: offset$1,
3220
3221
  onHide,
3221
3222
  className,
3222
3223
  children: !excludeItems.includes("edit-link") && /* @__PURE__ */ jsx(ButtonBubbleMenuToolbar, { children: /* @__PURE__ */ jsx(ButtonBubbleMenuEditLink, {}) })
@@ -3266,7 +3267,7 @@ function ImageBubbleMenuEditLink({ className, children, onClick, onMouseDown, ..
3266
3267
 
3267
3268
  //#endregion
3268
3269
  //#region src/ui/image-bubble-menu/root.tsx
3269
- function ImageBubbleMenuRoot({ onHide, placement = "top", offset = 8, className, children }) {
3270
+ function ImageBubbleMenuRoot({ onHide, placement = "top", offset: offset$1 = 8, className, children }) {
3270
3271
  const { editor } = useCurrentEditor();
3271
3272
  const [isEditing, setIsEditing] = React.useState(false);
3272
3273
  if (!editor) return null;
@@ -3276,7 +3277,7 @@ function ImageBubbleMenuRoot({ onHide, placement = "top", offset = 8, className,
3276
3277
  shouldShow: ({ editor: e, view }) => e.isActive("image") && !view.dom.classList.contains("dragging"),
3277
3278
  options: {
3278
3279
  placement,
3279
- offset,
3280
+ offset: offset$1,
3280
3281
  onHide: () => {
3281
3282
  setIsEditing(false);
3282
3283
  onHide?.();
@@ -3308,10 +3309,10 @@ function ImageBubbleMenuToolbar({ children, ...rest }) {
3308
3309
 
3309
3310
  //#endregion
3310
3311
  //#region src/ui/image-bubble-menu/default.tsx
3311
- function ImageBubbleMenuDefault({ excludeItems = [], placement, offset, onHide, className }) {
3312
+ function ImageBubbleMenuDefault({ excludeItems = [], placement, offset: offset$1, onHide, className }) {
3312
3313
  return /* @__PURE__ */ jsx(ImageBubbleMenuRoot, {
3313
3314
  placement,
3314
- offset,
3315
+ offset: offset$1,
3315
3316
  onHide,
3316
3317
  className,
3317
3318
  children: !excludeItems.includes("edit-link") && /* @__PURE__ */ jsx(ImageBubbleMenuToolbar, { children: /* @__PURE__ */ jsx(ImageBubbleMenuEditLink, {}) })
@@ -3483,7 +3484,7 @@ function LinkBubbleMenuOpenLink({ className, children, ...rest }) {
3483
3484
 
3484
3485
  //#endregion
3485
3486
  //#region src/ui/link-bubble-menu/root.tsx
3486
- function LinkBubbleMenuRoot({ onHide, placement = "top", offset = 8, className, children }) {
3487
+ function LinkBubbleMenuRoot({ onHide, placement = "top", offset: offset$1 = 8, className, children }) {
3487
3488
  const { editor } = useCurrentEditor();
3488
3489
  const [isEditing, setIsEditing] = React.useState(false);
3489
3490
  const linkHref = useEditorState({
@@ -3497,7 +3498,7 @@ function LinkBubbleMenuRoot({ onHide, placement = "top", offset = 8, className,
3497
3498
  shouldShow: ({ editor: e }) => e.isActive("link") && e.view.state.selection.content().size === 0,
3498
3499
  options: {
3499
3500
  placement,
3500
- offset,
3501
+ offset: offset$1,
3501
3502
  onHide: () => {
3502
3503
  setIsEditing(false);
3503
3504
  onHide?.();
@@ -3553,11 +3554,11 @@ function LinkBubbleMenuUnlink({ className, children, onClick, onMouseDown, ...re
3553
3554
 
3554
3555
  //#endregion
3555
3556
  //#region src/ui/link-bubble-menu/default.tsx
3556
- function LinkBubbleMenuDefault({ excludeItems = [], placement, offset, onHide, className, validateUrl, onLinkApply, onLinkRemove }) {
3557
+ function LinkBubbleMenuDefault({ excludeItems = [], placement, offset: offset$1, onHide, className, validateUrl, onLinkApply, onLinkRemove }) {
3557
3558
  const has = (item) => !excludeItems.includes(item);
3558
3559
  return /* @__PURE__ */ jsxs(LinkBubbleMenuRoot, {
3559
3560
  placement,
3560
- offset,
3561
+ offset: offset$1,
3561
3562
  onHide,
3562
3563
  className,
3563
3564
  children: [(has("edit-link") || has("open-link") || has("unlink")) && /* @__PURE__ */ jsxs(LinkBubbleMenuToolbar, { children: [
@@ -3643,42 +3644,14 @@ function CommandItem({ item, selected, onSelect }) {
3643
3644
  children: [item.icon, /* @__PURE__ */ jsx("span", { children: item.title })]
3644
3645
  });
3645
3646
  }
3646
- function CommandList({ items, command, query, ref }) {
3647
- const [selectedIndex, setSelectedIndex] = useState(0);
3647
+ function CommandList({ items, query, selectedIndex, onSelect }) {
3648
3648
  const containerRef = useRef(null);
3649
- useEffect(() => {
3650
- setSelectedIndex(0);
3651
- }, [items]);
3652
3649
  useLayoutEffect(() => {
3653
3650
  const container = containerRef.current;
3654
3651
  if (!container) return;
3655
3652
  const selected = container.querySelector("[data-selected]");
3656
3653
  if (selected) updateScrollView(container, selected);
3657
3654
  }, [selectedIndex]);
3658
- const selectItem = useCallback((index) => {
3659
- const item = items[index];
3660
- if (item) command(item);
3661
- }, [items, command]);
3662
- useImperativeHandle(ref, () => ({ onKeyDown: ({ event }) => {
3663
- if (items.length === 0) return false;
3664
- if (event.key === "ArrowUp") {
3665
- setSelectedIndex((i) => (i + items.length - 1) % items.length);
3666
- return true;
3667
- }
3668
- if (event.key === "ArrowDown") {
3669
- setSelectedIndex((i) => (i + 1) % items.length);
3670
- return true;
3671
- }
3672
- if (event.key === "Enter") {
3673
- selectItem(selectedIndex);
3674
- return true;
3675
- }
3676
- return false;
3677
- } }), [
3678
- items.length,
3679
- selectItem,
3680
- selectedIndex
3681
- ]);
3682
3655
  if (items.length === 0) return /* @__PURE__ */ jsx("div", {
3683
3656
  "data-re-slash-command": "",
3684
3657
  children: /* @__PURE__ */ jsx("div", {
@@ -3691,7 +3664,7 @@ function CommandList({ items, command, query, ref }) {
3691
3664
  ref: containerRef,
3692
3665
  children: items.map((item, index) => /* @__PURE__ */ jsx(CommandItem, {
3693
3666
  item,
3694
- onSelect: () => selectItem(index),
3667
+ onSelect: () => onSelect(index),
3695
3668
  selected: index === selectedIndex
3696
3669
  }, item.title))
3697
3670
  });
@@ -3707,7 +3680,7 @@ function CommandList({ items, command, query, ref }) {
3707
3680
  const currentIndex = flatIndex++;
3708
3681
  return /* @__PURE__ */ jsx(CommandItem, {
3709
3682
  item,
3710
- onSelect: () => selectItem(currentIndex),
3683
+ onSelect: () => onSelect(currentIndex),
3711
3684
  selected: currentIndex === selectedIndex
3712
3685
  }, item.title);
3713
3686
  })] }, group.category))
@@ -3925,76 +3898,6 @@ const defaultSlashCommands = [
3925
3898
  FOUR_COLUMNS
3926
3899
  ];
3927
3900
 
3928
- //#endregion
3929
- //#region src/ui/slash-command/extension.ts
3930
- const SlashCommandExtension = Extension.create({
3931
- name: "slash-command",
3932
- addOptions() {
3933
- return { suggestion: {
3934
- char: "/",
3935
- allow: ({ editor }) => !editor.isActive("codeBlock"),
3936
- command: ({ editor, range, props }) => {
3937
- props.command({
3938
- editor,
3939
- range
3940
- });
3941
- }
3942
- } };
3943
- },
3944
- addProseMirrorPlugins() {
3945
- return [Suggestion({
3946
- pluginKey: new PluginKey("slash-command"),
3947
- editor: this.editor,
3948
- ...this.options.suggestion
3949
- })];
3950
- }
3951
- });
3952
-
3953
- //#endregion
3954
- //#region src/ui/slash-command/render.tsx
3955
- function createRenderItems(component = CommandList) {
3956
- return () => {
3957
- let renderer = null;
3958
- let popup = null;
3959
- return {
3960
- onStart: (props) => {
3961
- renderer = new ReactRenderer(component, {
3962
- props,
3963
- editor: props.editor
3964
- });
3965
- if (!props.clientRect) return;
3966
- popup = tippy("body", {
3967
- getReferenceClientRect: props.clientRect,
3968
- appendTo: () => document.body,
3969
- content: renderer.element,
3970
- showOnCreate: true,
3971
- interactive: true,
3972
- trigger: "manual",
3973
- placement: "bottom-start"
3974
- });
3975
- },
3976
- onUpdate: (props) => {
3977
- if (!renderer) return;
3978
- renderer.updateProps(props);
3979
- if (popup?.[0] && props.clientRect) popup[0].setProps({ getReferenceClientRect: props.clientRect });
3980
- },
3981
- onKeyDown: (props) => {
3982
- if (props.event.key === "Escape") {
3983
- popup?.[0]?.hide();
3984
- return true;
3985
- }
3986
- return renderer?.ref?.onKeyDown(props) ?? false;
3987
- },
3988
- onExit: () => {
3989
- popup?.[0]?.destroy();
3990
- renderer?.destroy();
3991
- popup = null;
3992
- renderer = null;
3993
- }
3994
- };
3995
- };
3996
- }
3997
-
3998
3901
  //#endregion
3999
3902
  //#region src/ui/slash-command/search.ts
4000
3903
  function scoreItem(item, query) {
@@ -4025,23 +3928,145 @@ function filterAndRankItems(items, query) {
4025
3928
  }
4026
3929
 
4027
3930
  //#endregion
4028
- //#region src/ui/slash-command/create-slash-command.ts
3931
+ //#region src/ui/slash-command/root.tsx
3932
+ const pluginKey = new PluginKey("slash-command");
3933
+ const INITIAL_STATE = {
3934
+ active: false,
3935
+ query: "",
3936
+ items: [],
3937
+ clientRect: null
3938
+ };
4029
3939
  function defaultFilterItems(items, query, editor) {
4030
3940
  return filterAndRankItems(isAtMaxColumnsDepth(editor) ? items.filter((item) => item.category !== "Layout" || !item.title.includes("column")) : items, query);
4031
3941
  }
4032
- function createSlashCommand(options) {
4033
- const items = options?.items ?? defaultSlashCommands;
4034
- const filterFn = options?.filterItems ?? defaultFilterItems;
4035
- return SlashCommandExtension.configure({ suggestion: {
4036
- items: ({ query, editor }) => filterFn(items, query, editor),
4037
- render: createRenderItems(options?.component)
4038
- } });
3942
+ function SlashCommandRoot({ items: itemsProp, filterItems: filterItemsProp, char = "/", allow: allowProp, children }) {
3943
+ const { editor } = useCurrentEditor();
3944
+ const [state, setState] = useState(INITIAL_STATE);
3945
+ const [selectedIndex, setSelectedIndex] = useState(0);
3946
+ const itemsRef = useRef(itemsProp ?? defaultSlashCommands);
3947
+ const filterRef = useRef(filterItemsProp ?? defaultFilterItems);
3948
+ const allowRef = useRef(allowProp ?? (({ editor: e }) => !e.isActive("codeBlock")));
3949
+ itemsRef.current = itemsProp ?? defaultSlashCommands;
3950
+ filterRef.current = filterItemsProp ?? defaultFilterItems;
3951
+ allowRef.current = allowProp ?? (({ editor: e }) => !e.isActive("codeBlock"));
3952
+ const commandRef = useRef(null);
3953
+ const suggestionItemsRef = useRef([]);
3954
+ const selectedIndexRef = useRef(0);
3955
+ suggestionItemsRef.current = state.items;
3956
+ selectedIndexRef.current = selectedIndex;
3957
+ const { refs, floatingStyles } = useFloating({
3958
+ open: state.active,
3959
+ placement: "bottom-start",
3960
+ middleware: [
3961
+ offset(8),
3962
+ flip(),
3963
+ shift({ padding: 8 })
3964
+ ],
3965
+ whileElementsMounted: autoUpdate
3966
+ });
3967
+ useEffect(() => {
3968
+ if (!state.clientRect) return;
3969
+ refs.setReference({ getBoundingClientRect: state.clientRect });
3970
+ }, [state.clientRect, refs]);
3971
+ useEffect(() => {
3972
+ setSelectedIndex(0);
3973
+ }, [state.items]);
3974
+ const onSelect = useCallback((index) => {
3975
+ const item = suggestionItemsRef.current[index];
3976
+ if (item && commandRef.current) commandRef.current(item);
3977
+ }, []);
3978
+ useEffect(() => {
3979
+ if (!editor) return;
3980
+ const plugin = Suggestion({
3981
+ pluginKey,
3982
+ editor,
3983
+ char,
3984
+ allow: ({ editor: e }) => allowRef.current({ editor: e }),
3985
+ command: ({ editor: e, range, props }) => {
3986
+ props.command({
3987
+ editor: e,
3988
+ range
3989
+ });
3990
+ },
3991
+ items: ({ query, editor: e }) => filterRef.current(itemsRef.current, query, e),
3992
+ render: () => ({
3993
+ onStart: (props) => {
3994
+ commandRef.current = props.command;
3995
+ setState({
3996
+ active: true,
3997
+ query: props.query,
3998
+ items: props.items,
3999
+ clientRect: props.clientRect ?? null
4000
+ });
4001
+ },
4002
+ onUpdate: (props) => {
4003
+ commandRef.current = props.command;
4004
+ setState({
4005
+ active: true,
4006
+ query: props.query,
4007
+ items: props.items,
4008
+ clientRect: props.clientRect ?? null
4009
+ });
4010
+ },
4011
+ onKeyDown: ({ event }) => {
4012
+ if (event.key === "Escape") {
4013
+ setState(INITIAL_STATE);
4014
+ return true;
4015
+ }
4016
+ const items = suggestionItemsRef.current;
4017
+ if (items.length === 0) return false;
4018
+ if (event.key === "ArrowUp") {
4019
+ setSelectedIndex((i) => (i + items.length - 1) % items.length);
4020
+ return true;
4021
+ }
4022
+ if (event.key === "ArrowDown") {
4023
+ setSelectedIndex((i) => (i + 1) % items.length);
4024
+ return true;
4025
+ }
4026
+ if (event.key === "Enter") {
4027
+ const item = items[selectedIndexRef.current];
4028
+ if (item && commandRef.current) commandRef.current(item);
4029
+ return true;
4030
+ }
4031
+ return false;
4032
+ },
4033
+ onExit: () => {
4034
+ setState(INITIAL_STATE);
4035
+ requestAnimationFrame(() => {
4036
+ commandRef.current = null;
4037
+ });
4038
+ }
4039
+ })
4040
+ });
4041
+ editor.registerPlugin(plugin, (newPlugin, plugins) => [newPlugin, ...plugins]);
4042
+ return () => {
4043
+ editor.unregisterPlugin(pluginKey);
4044
+ };
4045
+ }, [editor, char]);
4046
+ if (!editor || !state.active) return null;
4047
+ const renderProps = {
4048
+ items: state.items,
4049
+ query: state.query,
4050
+ selectedIndex,
4051
+ onSelect
4052
+ };
4053
+ let content;
4054
+ if (children) content = children(renderProps);
4055
+ else content = /* @__PURE__ */ jsx(CommandList, { ...renderProps });
4056
+ return createPortal(/* @__PURE__ */ jsx("div", {
4057
+ ref: refs.setFloating,
4058
+ style: floatingStyles,
4059
+ children: content
4060
+ }), document.body);
4039
4061
  }
4040
4062
 
4041
4063
  //#endregion
4042
4064
  //#region src/ui/slash-command/index.ts
4043
- const SlashCommand = createSlashCommand();
4065
+ const SlashCommand = {
4066
+ Root: SlashCommandRoot,
4067
+ CommandList
4068
+ };
4044
4069
 
4045
4070
  //#endregion
4046
- export { AlignmentAttribute, BULLET_LIST, BUTTON, Blockquote, Body, Bold, BubbleMenu, BubbleMenuAlignCenter, BubbleMenuAlignLeft, BubbleMenuAlignRight, BubbleMenuBold, BubbleMenuCode, BubbleMenuDefault, BubbleMenuItalic, BubbleMenuItem, BubbleMenuItemGroup, BubbleMenuLinkSelector, BubbleMenuNodeSelector, BubbleMenuRoot, BubbleMenuSeparator, BubbleMenuStrike, BubbleMenuUnderline, BubbleMenuUppercase, BulletList, Button, ButtonBubbleMenu, ButtonBubbleMenuDefault, ButtonBubbleMenuEditLink, ButtonBubbleMenuRoot, ButtonBubbleMenuToolbar, CODE, COLUMN_PARENT_TYPES, ClassAttribute, Code, CodeBlockPrism, ColumnsColumn, CommandList, DIVIDER, Div, Divider, EmailNode, FOUR_COLUMNS, FourColumns, GlobalContent, H1, H2, H3, HardBreak, Heading, ImageBubbleMenu, ImageBubbleMenuDefault, ImageBubbleMenuEditLink, ImageBubbleMenuRoot, ImageBubbleMenuToolbar, Italic, Link, LinkBubbleMenu, LinkBubbleMenuDefault, LinkBubbleMenuEditLink, LinkBubbleMenuForm, LinkBubbleMenuOpenLink, LinkBubbleMenuRoot, LinkBubbleMenuToolbar, LinkBubbleMenuUnlink, ListItem, MAX_COLUMNS_DEPTH, MaxNesting, NUMBERED_LIST, NodeSelectorContent, NodeSelectorRoot, NodeSelectorTrigger, OrderedList, Paragraph, Placeholder, PreservedStyle, PreviewText, QUOTE, SECTION, Section, SlashCommand, StarterKit, Strike, StyleAttribute, Sup, TEXT, THREE_COLUMNS, TWO_COLUMNS, Table, TableCell, TableHeader, TableRow, ThreeColumns, TwoColumns, Underline, Uppercase, composeReactEmail, createSlashCommand, defaultSlashCommands, editorEventBus, filterAndRankItems, getColumnsDepth, getGlobalContent, isAtMaxColumnsDepth, isDocumentVisuallyEmpty, isInsideNode, processStylesForUnlink, scoreItem, setTextAlignment, useButtonBubbleMenuContext, useEditor, useImageBubbleMenuContext, useLinkBubbleMenuContext };
4071
+ export { AlignmentAttribute, BULLET_LIST, BUTTON, Blockquote, Body, Bold, BubbleMenu, BubbleMenuAlignCenter, BubbleMenuAlignLeft, BubbleMenuAlignRight, BubbleMenuBold, BubbleMenuCode, BubbleMenuDefault, BubbleMenuItalic, BubbleMenuItem, BubbleMenuItemGroup, BubbleMenuLinkSelector, BubbleMenuNodeSelector, BubbleMenuRoot, BubbleMenuSeparator, BubbleMenuStrike, BubbleMenuUnderline, BubbleMenuUppercase, BulletList, Button, ButtonBubbleMenu, ButtonBubbleMenuDefault, ButtonBubbleMenuEditLink, ButtonBubbleMenuRoot, ButtonBubbleMenuToolbar, CODE, COLUMN_PARENT_TYPES, ClassAttribute, Code, CodeBlockPrism, ColumnsColumn, CommandList, DIVIDER, Div, Divider, EmailNode, FOUR_COLUMNS, FourColumns, GlobalContent, H1, H2, H3, HardBreak, Heading, ImageBubbleMenu, ImageBubbleMenuDefault, ImageBubbleMenuEditLink, ImageBubbleMenuRoot, ImageBubbleMenuToolbar, Italic, Link, LinkBubbleMenu, LinkBubbleMenuDefault, LinkBubbleMenuEditLink, LinkBubbleMenuForm, LinkBubbleMenuOpenLink, LinkBubbleMenuRoot, LinkBubbleMenuToolbar, LinkBubbleMenuUnlink, ListItem, MAX_COLUMNS_DEPTH, MaxNesting, NUMBERED_LIST, NodeSelectorContent, NodeSelectorRoot, NodeSelectorTrigger, OrderedList, Paragraph, Placeholder, PreservedStyle, PreviewText, QUOTE, SECTION, Section, SlashCommand, StarterKit, Strike, StyleAttribute, Sup, TEXT, THREE_COLUMNS, TWO_COLUMNS, Table, TableCell, TableHeader, TableRow, ThreeColumns, TwoColumns, Underline, Uppercase, composeReactEmail, defaultSlashCommands, editorEventBus, filterAndRankItems, getColumnsDepth, getGlobalContent, isAtMaxColumnsDepth, isDocumentVisuallyEmpty, isInsideNode, processStylesForUnlink, scoreItem, setTextAlignment, useButtonBubbleMenuContext, useEditor, useImageBubbleMenuContext, useLinkBubbleMenuContext };
4047
4072
  //# sourceMappingURL=index.mjs.map