UNPKG

@blocknote/mantine

Version:

A "Notion-style" block-based extensible text editor built on top of Prosemirror and Tiptap.

1 lines 72 kB
{"version":3,"file":"blocknote-mantine.cjs","names":[],"sources":["../src/BlockNoteTheme.ts","../src/toolbar/ToolbarButton.tsx","../src/badge/Badge.tsx","../src/comments/Card.tsx","../src/comments/Comment.tsx","../src/comments/Editor.tsx","../src/form/TextInput.tsx","../src/menu/Menu.tsx","../src/menu/Button.tsx","../src/panel/Panel.tsx","../src/panel/PanelButton.tsx","../src/panel/PanelFileInput.tsx","../src/panel/PanelTab.tsx","../src/panel/PanelTextInput.tsx","../src/popover/Popover.tsx","../src/sideMenu/SideMenu.tsx","../src/sideMenu/SideMenuButton.tsx","../src/suggestionMenu/SuggestionMenu.tsx","../src/suggestionMenu/SuggestionMenuEmptyItem.tsx","../src/suggestionMenu/SuggestionMenuItem.tsx","../src/suggestionMenu/SuggestionMenuLabel.tsx","../src/suggestionMenu/SuggestionMenuLoader.tsx","../src/suggestionMenu/gridSuggestionMenu/GridSuggestionMenu.tsx","../src/suggestionMenu/gridSuggestionMenu/GridSuggestionMenuEmptyItem.tsx","../src/suggestionMenu/gridSuggestionMenu/GridSuggestionMenuItem.tsx","../src/suggestionMenu/gridSuggestionMenu/GridSuggestionMenuLoader.tsx","../src/tableHandle/ExtendButton.tsx","../src/tableHandle/TableHandle.tsx","../src/toolbar/Toolbar.tsx","../src/toolbar/ToolbarSelect.tsx","../src/components.tsx","../src/BlockNoteView.tsx","../src/defaultThemes.ts"],"sourcesContent":["export type CombinedColor = Partial<{\n text: string;\n background: string;\n}>;\n\nexport type ColorScheme = Partial<{\n editor: CombinedColor;\n menu: CombinedColor;\n tooltip: CombinedColor;\n hovered: CombinedColor;\n selected: CombinedColor;\n disabled: CombinedColor;\n shadow: string;\n border: string;\n sideMenu: string;\n highlights: Partial<{\n gray: CombinedColor;\n brown: CombinedColor;\n red: CombinedColor;\n orange: CombinedColor;\n yellow: CombinedColor;\n green: CombinedColor;\n blue: CombinedColor;\n purple: CombinedColor;\n pink: CombinedColor;\n }>;\n}>;\n\nexport type Theme = Partial<{\n colors: ColorScheme;\n borderRadius: number;\n fontFamily: string;\n}>;\n\ntype NestedObject = { [key: string]: number | string | NestedObject };\n\nconst cssVariablesHelper = (\n theme: Theme,\n editorDOM: HTMLElement,\n unset = false,\n) => {\n const result: string[] = [];\n\n function traverse(current: NestedObject, currentKey = \"--bn\") {\n for (const key in current) {\n const kebabCaseKey = key\n .replace(/([a-z])([A-Z])/g, \"$1-$2\")\n .toLowerCase();\n const fullKey = `${currentKey}-${kebabCaseKey}`;\n\n if (typeof current[key] !== \"object\") {\n // Convert numbers to px\n if (typeof current[key] === \"number\") {\n current[key] = `${current[key]}px`;\n }\n\n if (unset) {\n editorDOM.style.removeProperty(fullKey);\n } else {\n editorDOM.style.setProperty(fullKey, current[key].toString());\n }\n } else {\n traverse(current[key] as NestedObject, fullKey);\n }\n }\n }\n\n traverse(theme);\n\n return result;\n};\n\nexport const applyBlockNoteCSSVariablesFromTheme = (\n theme: Theme,\n editorDOM: HTMLElement,\n) => cssVariablesHelper(theme, editorDOM);\n\n// We don't need a theme to remove the CSS variables, but having access to a\n// theme object allows us to use the same logic to set/unset them, so this\n// placeholder theme is used.\nconst placeholderTheme: Theme = {\n colors: {\n editor: {\n text: undefined as any,\n background: undefined as any,\n },\n menu: {\n text: undefined as any,\n background: undefined as any,\n },\n tooltip: {\n text: undefined as any,\n background: undefined as any,\n },\n hovered: {\n text: undefined as any,\n background: undefined as any,\n },\n selected: {\n text: undefined as any,\n background: undefined as any,\n },\n disabled: {\n text: undefined as any,\n background: undefined as any,\n },\n shadow: undefined as any,\n border: undefined as any,\n sideMenu: undefined as any,\n highlights: {\n gray: {\n text: undefined as any,\n background: undefined as any,\n },\n brown: {\n text: undefined as any,\n background: undefined as any,\n },\n red: {\n text: undefined as any,\n background: undefined as any,\n },\n orange: {\n text: undefined as any,\n background: undefined as any,\n },\n yellow: {\n text: undefined as any,\n background: undefined as any,\n },\n green: {\n text: undefined as any,\n background: undefined as any,\n },\n blue: {\n text: undefined as any,\n background: undefined as any,\n },\n purple: {\n text: undefined as any,\n background: undefined as any,\n },\n pink: {\n text: undefined as any,\n background: undefined as any,\n },\n },\n },\n borderRadius: undefined as any,\n fontFamily: undefined as any,\n};\nexport const removeBlockNoteCSSVariables = (editorDOM: HTMLElement) =>\n cssVariablesHelper(placeholderTheme, editorDOM, true);\n","import {\n ActionIcon as MantineActionIcon,\n Button as MantineButton,\n Stack as MantineStack,\n Text as MantineText,\n Tooltip as MantineTooltip,\n} from \"@mantine/core\";\n\nimport { assertEmpty, isSafari } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef, useState } from \"react\";\n\nexport const TooltipContent = (props: {\n mainTooltip: string;\n secondaryTooltip?: string;\n}) => (\n <MantineStack gap={0} className={\"bn-tooltip\"}>\n <MantineText size={\"sm\"} lineClamp={5}>\n {props.mainTooltip}\n </MantineText>\n {props.secondaryTooltip && (\n <MantineText size={\"xs\"} lineClamp={5}>\n {props.secondaryTooltip}\n </MantineText>\n )}\n </MantineStack>\n);\n\ntype ToolbarButtonProps = ComponentProps[\"Generic\"][\"Toolbar\"][\"Button\"];\n\n/**\n * Helper for basic buttons that show in the formatting toolbar.\n */\nexport const ToolbarButton = forwardRef<HTMLButtonElement, ToolbarButtonProps>(\n (props, ref) => {\n const {\n className,\n children,\n mainTooltip,\n secondaryTooltip,\n icon,\n isSelected,\n isDisabled,\n onClick,\n label,\n variant,\n ...rest\n } = props;\n\n // false, because rest props can be added by mantine when button is used as a trigger\n // assertEmpty in this case is only used at typescript level, not runtime level\n assertEmpty(rest, false);\n\n const [hideTooltip, setHideTooltip] = useState(false);\n\n const button = children ? (\n <MantineButton\n aria-label={label}\n className={className}\n // Needed as Safari doesn't focus button elements on mouse down\n // unlike other browsers.\n onMouseDown={(e) => {\n if (isSafari()) {\n (e.currentTarget as HTMLButtonElement).focus();\n }\n }}\n onClick={(event) => {\n setHideTooltip(true);\n onClick?.(event);\n }}\n // Mantine Menu.Target elements block mouseleave events for some reason,\n // but pointerleave events work fine.\n onPointerLeave={() => setHideTooltip(false)}\n aria-pressed={isSelected}\n data-selected={isSelected || undefined}\n data-test={\n mainTooltip\n ? mainTooltip.slice(0, 1).toLowerCase() +\n mainTooltip.replace(/\\s+/g, \"\").slice(1)\n : undefined\n }\n size={variant === \"compact\" ? \"compact-xs\" : \"xs\"}\n disabled={isDisabled || false}\n ref={ref}\n {...rest}\n >\n {children}\n </MantineButton>\n ) : (\n <MantineActionIcon\n className={className}\n aria-label={label}\n // Needed as Safari doesn't focus button elements on mouse down\n // unlike other browsers.\n onMouseDown={(e) => {\n if (isSafari()) {\n (e.currentTarget as HTMLButtonElement).focus();\n }\n }}\n onClick={(event) => {\n // We manually hide the tooltip onclick, because the click event\n // might open a popover which would then show both the tooltip and the popover\n // this is similar to default behavior of shadcn / radix\n setHideTooltip(true);\n onClick?.(event);\n }}\n // Mantine Menu.Target elements block mouseleave events for some reason,\n // but pointerleave events work fine.\n onPointerLeave={() => setHideTooltip(false)}\n aria-pressed={isSelected}\n data-selected={isSelected || undefined}\n data-test={\n mainTooltip\n ? mainTooltip.slice(0, 1).toLowerCase() +\n mainTooltip.replace(/\\s+/g, \"\").slice(1)\n : undefined\n }\n size={variant === \"compact\" ? 20 : 30}\n disabled={isDisabled || false}\n ref={ref}\n {...rest}\n >\n {icon}\n </MantineActionIcon>\n );\n\n if (!mainTooltip) {\n return button;\n }\n\n return (\n <MantineTooltip\n disabled={hideTooltip}\n withinPortal={false}\n label={\n <TooltipContent\n mainTooltip={mainTooltip}\n secondaryTooltip={secondaryTooltip}\n />\n }\n >\n {button}\n </MantineTooltip>\n );\n },\n);\n","import {\n Chip as MantineChip,\n Group as MantineGroup,\n Tooltip as MantineTooltip,\n} from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { MouseEvent, forwardRef, useState } from \"react\";\n\nimport { TooltipContent } from \"../toolbar/ToolbarButton.js\";\n\nexport const Badge = forwardRef<\n HTMLInputElement,\n ComponentProps[\"Generic\"][\"Badge\"][\"Root\"]\n>((props, ref) => {\n const {\n className,\n text,\n icon,\n isSelected,\n mainTooltip,\n secondaryTooltip,\n onClick,\n onMouseEnter,\n ...rest\n } = props;\n\n // false, because rest props can be added by mantine when chip is used as a trigger\n // assertEmpty in this case is only used at typescript level, not runtime level\n assertEmpty(rest, false);\n\n const [hideTooltip, setHideTooltip] = useState(false);\n\n const badge = (\n <MantineChip\n className={className}\n checked={isSelected === true}\n wrapperProps={{\n onMouseEnter,\n onMouseLeave: () => setHideTooltip(false),\n onClick: (event: MouseEvent) => {\n setHideTooltip(true);\n onClick?.(event);\n },\n }}\n variant={\"light\"}\n icon={null}\n ref={ref}\n >\n <span>{icon}</span>\n <span>{text}</span>\n </MantineChip>\n );\n\n if (!mainTooltip || hideTooltip) {\n return badge;\n }\n\n return (\n <MantineTooltip\n refProp=\"rootRef\"\n withinPortal={false}\n label={\n <TooltipContent\n mainTooltip={mainTooltip}\n secondaryTooltip={secondaryTooltip}\n />\n }\n >\n {badge}\n </MantineTooltip>\n );\n});\n\nexport const BadgeGroup = forwardRef<\n HTMLDivElement,\n ComponentProps[\"Generic\"][\"Badge\"][\"Group\"]\n>((props, ref) => {\n const { className, children, ...rest } = props;\n\n assertEmpty(rest);\n\n return (\n <MantineGroup className={className} ref={ref}>\n {children}\n </MantineGroup>\n );\n});\n","import { assertEmpty, mergeCSSClasses } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport {\n Card as MantineCard,\n Divider as MantineDivider,\n Text as MantineText,\n} from \"@mantine/core\";\nimport { forwardRef } from \"react\";\n\nexport const Card = forwardRef<\n HTMLDivElement,\n ComponentProps[\"Comments\"][\"Card\"]\n>((props, ref) => {\n const {\n className,\n children,\n headerText,\n selected,\n onFocus,\n onBlur,\n tabIndex,\n ...rest\n } = props;\n\n assertEmpty(rest, false);\n\n return (\n <MantineCard\n className={mergeCSSClasses(className, selected ? \"selected\" : \"\")}\n onFocus={onFocus}\n onBlur={onBlur}\n tabIndex={tabIndex}\n ref={ref}\n >\n {headerText && (\n <MantineText className={\"bn-header-text\"}>{headerText}</MantineText>\n )}\n {children}\n </MantineCard>\n );\n});\n\nexport const CardSection = forwardRef<\n HTMLDivElement,\n ComponentProps[\"Comments\"][\"CardSection\"]\n>((props, ref) => {\n const { className, children, ...rest } = props;\n\n assertEmpty(rest, false);\n\n return (\n <MantineCard.Section className={className} ref={ref}>\n {children}\n </MantineCard.Section>\n );\n});\n\nexport const ExpandSectionsPrompt = forwardRef<\n HTMLDivElement,\n ComponentProps[\"Comments\"][\"ExpandSectionsPrompt\"]\n>((props, ref) => {\n const { className, children, ...rest } = props;\n\n assertEmpty(rest, false);\n\n return (\n <MantineDivider\n className={className}\n label={<MantineText>{children}</MantineText>}\n ref={ref}\n />\n );\n});\n","import { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps, mergeRefs, useDictionary } from \"@blocknote/react\";\nimport { Avatar, Group, Skeleton, Text } from \"@mantine/core\";\nimport { useHover } from \"@mantine/hooks\";\nimport { forwardRef } from \"react\";\n\nconst AuthorInfo = forwardRef<\n HTMLDivElement,\n Pick<\n ComponentProps[\"Comments\"][\"Comment\"],\n \"authorInfo\" | \"timeString\" | \"edited\"\n >\n>((props, _ref) => {\n const { authorInfo, timeString, edited, ...rest } = props;\n const dict = useDictionary();\n\n assertEmpty(rest, false);\n\n if (authorInfo === \"loading\") {\n return (\n <Group>\n <Skeleton height={24} width={24} />\n <div>\n <Skeleton height={12} width={100} />\n </div>\n </Group>\n );\n }\n\n return (\n <Group>\n <Avatar\n src={authorInfo.avatarUrl}\n alt={authorInfo.username}\n radius=\"xl\"\n size=\"sm\"\n // name={authorInfo.username} TODO: upgrade mantine?\n color=\"initials\"\n />\n\n <Text fz=\"sm\" fw={\"bold\"}>\n {authorInfo.username}\n <Text fz=\"xs\" c=\"dimmed\" span ml={\"xs\"}>\n {timeString} {edited && `(${dict.comments.edited})`}\n </Text>\n </Text>\n </Group>\n );\n});\n\nexport const Comment = forwardRef<\n HTMLDivElement,\n ComponentProps[\"Comments\"][\"Comment\"]\n>((props, ref) => {\n const {\n className,\n showActions,\n authorInfo,\n timeString,\n edited,\n actions,\n emojiPickerOpen,\n children,\n ...rest\n } = props;\n\n const { hovered, ref: hoverRef } = useHover();\n const mergedRef = mergeRefs([ref, hoverRef]);\n assertEmpty(rest, false);\n\n const doShowActions =\n actions &&\n (showActions === true ||\n showActions === undefined ||\n (showActions === \"hover\" && hovered) ||\n emojiPickerOpen);\n\n return (\n <Group pos=\"relative\" ref={mergedRef} className={className}>\n {doShowActions ? (\n <Group\n style={{\n position: \"absolute\",\n right: 0,\n top: 0,\n zIndex: 10,\n }}\n >\n {actions}\n </Group>\n ) : null}\n <AuthorInfo {...props} />\n {children}\n </Group>\n );\n});\n","import { assertEmpty } from \"@blocknote/core\";\nimport {\n ComponentProps,\n FormattingToolbar,\n FormattingToolbarController,\n getFormattingToolbarItems,\n useBlockNoteContext,\n} from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\nimport { BlockNoteView } from \"../BlockNoteView.js\";\n\nexport const Editor = forwardRef<\n HTMLDivElement,\n ComponentProps[\"Comments\"][\"Editor\"]\n>((props, ref) => {\n const { className, autoFocus, onFocus, onBlur, editor, editable, ...rest } =\n props;\n\n assertEmpty(rest, false);\n\n const blockNoteContext = useBlockNoteContext();\n\n return (\n <BlockNoteView\n autoFocus={autoFocus}\n className={className}\n editor={props.editor}\n sideMenu={false}\n slashMenu={false}\n tableHandles={false}\n filePanel={false}\n formattingToolbar={false}\n editable={editable}\n theme={blockNoteContext?.colorSchemePreference}\n ref={ref}\n onFocus={onFocus}\n onBlur={onBlur}\n >\n <FormattingToolbarController\n formattingToolbar={CustomFormattingToolbar}\n />\n </BlockNoteView>\n );\n});\n\nconst CustomFormattingToolbar = () => {\n const items = getFormattingToolbarItems([]).filter(\n (el) => el.key !== \"nestBlockButton\" && el.key !== \"unnestBlockButton\",\n );\n return (\n <FormattingToolbar blockTypeSelectItems={[]}>{items}</FormattingToolbar>\n );\n};\n","import { TextInput as MantineTextInput } from \"@mantine/core\";\n\nimport { assertEmpty, mergeCSSClasses } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const TextInput = forwardRef<\n HTMLInputElement,\n ComponentProps[\"Generic\"][\"Form\"][\"TextInput\"]\n>((props, ref) => {\n const {\n className,\n name,\n label,\n variant,\n icon,\n value,\n autoFocus,\n placeholder,\n disabled,\n onKeyDown,\n onChange,\n onSubmit,\n autoComplete,\n \"aria-activedescendant\": ariaActivedescendant,\n rightSection,\n ...rest\n } = props;\n\n assertEmpty(rest);\n\n return (\n <MantineTextInput\n size={\"xs\"}\n className={mergeCSSClasses(\n className || \"\",\n variant === \"large\" ? \"bn-mt-input-large\" : \"\",\n )}\n ref={ref}\n name={name}\n label={label}\n leftSection={icon}\n value={value}\n autoFocus={autoFocus}\n data-autofocus={autoFocus ? \"true\" : undefined}\n rightSection={rightSection}\n placeholder={placeholder}\n disabled={disabled}\n onKeyDown={onKeyDown}\n onChange={onChange}\n onSubmit={onSubmit}\n autoComplete={autoComplete}\n aria-activedescendant={ariaActivedescendant}\n />\n );\n});\n","import {\n CheckIcon as MantineCheckIcon,\n Menu as MantineMenu,\n} from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { createContext, forwardRef, useContext } from \"react\";\n\nconst SubMenuContext = createContext<\n | {\n onMenuMouseOver: () => void;\n onMenuMouseLeave: () => void;\n }\n | undefined\n>(undefined);\n\nexport const Menu = (props: ComponentProps[\"Generic\"][\"Menu\"][\"Root\"]) => {\n const { children, onOpenChange, position, sub, ...rest } = props;\n\n assertEmpty(rest);\n\n if (sub) {\n return (\n <MantineMenu.Sub\n transitionProps={{ duration: 250, exitDelay: 250 }}\n withinPortal={false}\n middlewares={{ flip: true, shift: true, inline: false, size: true }}\n onChange={onOpenChange}\n position={position}\n >\n {children}\n </MantineMenu.Sub>\n );\n }\n\n return (\n <MantineMenu\n withinPortal={false}\n middlewares={{ flip: true, shift: true, inline: false, size: true }}\n onChange={onOpenChange}\n position={position}\n returnFocus={false}\n >\n {children}\n </MantineMenu>\n );\n};\n\nexport const MenuItem = forwardRef<\n HTMLButtonElement & HTMLDivElement,\n ComponentProps[\"Generic\"][\"Menu\"][\"Item\"]\n>((props, ref) => {\n const { className, children, icon, checked, subTrigger, onClick, ...rest } =\n props;\n\n // false, because rest props can be added by mantine when button is used as a trigger\n // assertEmpty in this case is only used at typescript level, not runtime level\n assertEmpty(rest, false);\n\n if (subTrigger) {\n return (\n <MantineMenu.Sub.Item\n className={className}\n ref={ref}\n leftSection={icon}\n rightSection={\n checked ? (\n <MantineCheckIcon size={10} />\n ) : checked === false ? (\n <div className={\"bn-tick-space\"} />\n ) : null\n }\n onClick={onClick}\n {...rest}\n >\n {children}\n </MantineMenu.Sub.Item>\n );\n }\n\n return (\n <MantineMenu.Item\n className={className}\n ref={ref}\n leftSection={icon}\n rightSection={\n checked ? (\n <MantineCheckIcon size={10} />\n ) : checked === false ? (\n <div className={\"bn-tick-space\"} />\n ) : null\n }\n onClick={onClick}\n {...rest}\n >\n {children}\n </MantineMenu.Item>\n );\n});\n\nexport const MenuTrigger = (\n props: ComponentProps[\"Generic\"][\"Menu\"][\"Trigger\"],\n) => {\n const {\n children,\n sub, // unused\n ...rest\n } = props;\n\n assertEmpty(rest);\n\n if (sub) {\n return <MantineMenu.Sub.Target>{children}</MantineMenu.Sub.Target>;\n }\n\n return <MantineMenu.Target>{children}</MantineMenu.Target>;\n};\n\nexport const MenuDropdown = forwardRef<\n HTMLDivElement,\n ComponentProps[\"Generic\"][\"Menu\"][\"Dropdown\"]\n>((props, ref) => {\n const {\n className,\n children,\n sub, //unused\n ...rest\n } = props;\n\n assertEmpty(rest);\n\n const ctx = useContext(SubMenuContext);\n\n if (sub) {\n return (\n <MantineMenu.Sub.Dropdown\n className={className}\n ref={ref}\n onMouseOver={ctx?.onMenuMouseOver}\n onMouseLeave={ctx?.onMenuMouseLeave}\n >\n {children}\n </MantineMenu.Sub.Dropdown>\n );\n }\n\n return (\n <MantineMenu.Dropdown\n className={className}\n ref={ref}\n onMouseOver={ctx?.onMenuMouseOver}\n onMouseLeave={ctx?.onMenuMouseLeave}\n >\n {children}\n </MantineMenu.Dropdown>\n );\n});\n\nexport const MenuDivider = forwardRef<\n HTMLDivElement,\n ComponentProps[\"Generic\"][\"Menu\"][\"Divider\"]\n>((props, ref) => {\n const { className, ...rest } = props;\n\n assertEmpty(rest);\n\n return <MantineMenu.Divider className={className} ref={ref} />;\n});\n\nexport const MenuLabel = forwardRef<\n HTMLDivElement,\n ComponentProps[\"Generic\"][\"Menu\"][\"Label\"]\n>((props, ref) => {\n const { className, children, ...rest } = props;\n\n assertEmpty(rest);\n\n return (\n <MantineMenu.Label className={className} ref={ref}>\n {children}\n </MantineMenu.Label>\n );\n});\n","import {\n ActionIcon as MantineActionIcon,\n Button as MantineButton,\n} from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const Button = forwardRef<\n HTMLButtonElement,\n ComponentProps[\"Generic\"][\"Menu\"][\"Button\"]\n>((props, ref) => {\n const {\n className,\n children,\n icon,\n onClick,\n onDragEnd,\n onDragStart,\n draggable,\n label,\n ...rest\n } = props;\n\n // false, because rest props can be added by mantine when button is used as a trigger\n // assertEmpty in this case is only used at typescript level, not runtime level\n assertEmpty(rest, false);\n\n if (icon) {\n return (\n <MantineActionIcon\n size={24}\n className={className}\n ref={ref}\n onClick={onClick}\n onDragEnd={onDragEnd}\n onDragStart={onDragStart}\n draggable={draggable}\n aria-label={label}\n {...rest}\n >\n {icon}\n </MantineActionIcon>\n );\n }\n\n return (\n <MantineButton\n className={className}\n ref={ref}\n onClick={onClick}\n onDragEnd={onDragEnd}\n onDragStart={onDragStart}\n draggable={draggable}\n aria-label={label}\n {...rest}\n >\n {children}\n </MantineButton>\n );\n});\n","import {\n Group as MantineGroup,\n LoadingOverlay as MantineLoadingOverlay,\n Tabs as MantineTabs,\n} from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const Panel = forwardRef<\n HTMLDivElement,\n ComponentProps[\"FilePanel\"][\"Root\"]\n>((props, ref) => {\n const {\n className,\n tabs,\n defaultOpenTab,\n openTab,\n setOpenTab,\n loading,\n ...rest\n } = props;\n\n assertEmpty(rest);\n\n return (\n <MantineGroup className={className} ref={ref}>\n <MantineTabs\n value={openTab}\n defaultValue={defaultOpenTab}\n onChange={setOpenTab as any}\n >\n {loading && <MantineLoadingOverlay visible={loading} />}\n\n <MantineTabs.List>\n {tabs.map((tab) => (\n <MantineTabs.Tab\n data-test={`${tab.name.toLowerCase()}-tab`}\n value={tab.name}\n key={tab.name}\n >\n {tab.name}\n </MantineTabs.Tab>\n ))}\n </MantineTabs.List>\n\n {tabs.map((tab) => (\n <MantineTabs.Panel value={tab.name} key={tab.name}>\n {tab.tabPanel}\n </MantineTabs.Panel>\n ))}\n </MantineTabs>\n </MantineGroup>\n );\n});\n","import { Button as MantineButton } from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const PanelButton = forwardRef<\n HTMLButtonElement,\n ComponentProps[\"FilePanel\"][\"Button\"]\n>((props, ref) => {\n const { className, children, onClick, label, ...rest } = props;\n\n assertEmpty(rest);\n\n return (\n <MantineButton\n size={\"xs\"}\n aria-label={label}\n className={className}\n ref={ref}\n onClick={onClick}\n {...rest}\n >\n {children}\n </MantineButton>\n );\n});\n","import { FileInput as MantineFileInput } from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const PanelFileInput = forwardRef<\n HTMLButtonElement,\n ComponentProps[\"FilePanel\"][\"FileInput\"]\n>((props, ref) => {\n const { className, accept, value, placeholder, onChange, ...rest } = props;\n\n assertEmpty(rest);\n\n return (\n <MantineFileInput\n size={\"xs\"}\n className={className}\n ref={ref}\n accept={accept}\n value={value}\n placeholder={placeholder}\n onChange={onChange}\n {...rest}\n />\n );\n});\n","import { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const PanelTab = forwardRef<\n HTMLDivElement,\n ComponentProps[\"FilePanel\"][\"TabPanel\"]\n>((props, ref) => {\n const { className, children, ...rest } = props;\n\n assertEmpty(rest);\n\n return (\n <div className={className} ref={ref}>\n {children}\n </div>\n );\n});\n","import { TextInput as MantineTextInput } from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const PanelTextInput = forwardRef<\n HTMLInputElement,\n ComponentProps[\"FilePanel\"][\"TextInput\"]\n>((props, ref) => {\n const { className, value, placeholder, onKeyDown, onChange, ...rest } = props;\n\n assertEmpty(rest);\n\n return (\n <MantineTextInput\n size={\"xs\"}\n data-test={\"embed-input\"}\n className={className}\n ref={ref}\n value={value}\n placeholder={placeholder}\n onKeyDown={onKeyDown}\n onChange={onChange}\n />\n );\n});\n","import {\n Popover as MantinePopover,\n PopoverDropdown as MantinePopoverDropdown,\n PopoverTarget as MantinePopoverTarget,\n} from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const Popover = (\n props: ComponentProps[\"Generic\"][\"Popover\"][\"Root\"],\n) => {\n const { open, onOpenChange, position, portalRoot, children, ...rest } = props;\n\n assertEmpty(rest);\n\n return (\n <MantinePopover\n middlewares={{ size: { padding: 20 } }}\n withinPortal={!!portalRoot}\n portalProps={portalRoot ? { target: portalRoot } : undefined}\n opened={open}\n onChange={onOpenChange}\n position={position}\n >\n {children}\n </MantinePopover>\n );\n};\n\nexport const PopoverTrigger = (\n props: ComponentProps[\"Generic\"][\"Popover\"][\"Trigger\"],\n) => {\n const { children, ...rest } = props;\n\n assertEmpty(rest);\n\n return <MantinePopoverTarget>{children}</MantinePopoverTarget>;\n};\n\nexport const PopoverContent = forwardRef<\n HTMLDivElement,\n ComponentProps[\"Generic\"][\"Popover\"][\"Content\"]\n>((props, ref) => {\n const {\n className,\n children,\n variant, // unused\n ...rest\n } = props;\n\n assertEmpty(rest);\n\n return (\n <MantinePopoverDropdown className={className} ref={ref}>\n {children}\n </MantinePopoverDropdown>\n );\n});\n","import { Group as MantineGroup } from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const SideMenu = forwardRef<\n HTMLDivElement,\n ComponentProps[\"SideMenu\"][\"Root\"]\n>((props, ref) => {\n const { className, children, ...rest } = props;\n\n assertEmpty(rest, false);\n\n return (\n <MantineGroup\n align={\"center\"}\n gap={0}\n className={className}\n ref={ref}\n {...rest}\n >\n {children}\n </MantineGroup>\n );\n});\n","import {\n ActionIcon as MantineActionIcon,\n Button as MantineButton,\n} from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const SideMenuButton = forwardRef<\n HTMLButtonElement,\n ComponentProps[\"SideMenu\"][\"Button\"]\n>((props, ref) => {\n const {\n className,\n children,\n icon,\n onClick,\n onDragEnd,\n onDragStart,\n draggable,\n label,\n ...rest\n } = props;\n\n // false, because rest props can be added by mantine when button is used as a trigger\n // assertEmpty in this case is only used at typescript level, not runtime level\n assertEmpty(rest, false);\n\n if (icon) {\n return (\n <MantineActionIcon\n size={24}\n className={className}\n ref={ref}\n onClick={onClick}\n onDragEnd={onDragEnd}\n onDragStart={onDragStart}\n draggable={draggable}\n aria-label={label}\n {...rest}\n >\n {icon}\n </MantineActionIcon>\n );\n }\n\n return (\n <MantineButton\n className={className}\n ref={ref}\n onClick={onClick}\n onDragEnd={onDragEnd}\n onDragStart={onDragStart}\n draggable={draggable}\n aria-label={label}\n {...rest}\n >\n {children}\n </MantineButton>\n );\n});\n","import { Stack as MantineStack } from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const SuggestionMenu = forwardRef<\n HTMLDivElement,\n ComponentProps[\"SuggestionMenu\"][\"Root\"]\n>((props, ref) => {\n const { className, children, id, ...rest } = props;\n\n assertEmpty(rest);\n\n return (\n <MantineStack\n gap={0}\n className={className}\n ref={ref}\n id={id}\n role=\"listbox\"\n >\n {children}\n </MantineStack>\n );\n});\n","import { Group as MantineGroup } from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const SuggestionMenuEmptyItem = forwardRef<\n HTMLDivElement,\n ComponentProps[\"SuggestionMenu\"][\"EmptyItem\"]\n>((props, ref) => {\n const { className, children, ...rest } = props;\n\n assertEmpty(rest);\n\n return (\n <MantineGroup className={className} ref={ref}>\n <MantineGroup className=\"bn-mt-suggestion-menu-item-title\">\n {children}\n </MantineGroup>\n </MantineGroup>\n );\n});\n","import {\n Badge as MantineBadge,\n Group as MantineGroup,\n Stack as MantineStack,\n Text as MantineText,\n} from \"@mantine/core\";\nimport { mergeRefs } from \"@mantine/hooks\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps, elementOverflow } from \"@blocknote/react\";\nimport { forwardRef, useEffect, useRef } from \"react\";\n\nexport const SuggestionMenuItem = forwardRef<\n HTMLDivElement,\n ComponentProps[\"SuggestionMenu\"][\"Item\"]\n>((props, ref) => {\n const { className, isSelected, onClick, item, id, ...rest } = props;\n\n assertEmpty(rest);\n\n const itemRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!itemRef.current || !isSelected) {\n return;\n }\n\n const overflow = elementOverflow(\n itemRef.current,\n itemRef.current.closest(\".bn-suggestion-menu, #ai-suggestion-menu\")!,\n );\n\n if (overflow !== \"none\") {\n itemRef.current.scrollIntoView({ block: \"nearest\" });\n }\n }, [isSelected]);\n\n return (\n <MantineGroup\n gap={0}\n className={className}\n ref={mergeRefs(ref, itemRef)}\n id={id}\n role=\"option\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={onClick}\n aria-selected={isSelected || undefined}\n >\n {item.icon && (\n <MantineGroup\n className=\"bn-mt-suggestion-menu-item-section\"\n data-position=\"left\"\n >\n {item.icon}\n </MantineGroup>\n )}\n <MantineStack gap={0} className=\"bn-mt-suggestion-menu-item-body\">\n <MantineText className=\"bn-mt-suggestion-menu-item-title\">\n {item.title}\n </MantineText>\n <MantineText className=\"bn-mt-suggestion-menu-item-subtitle\">\n {item.subtext}\n </MantineText>\n </MantineStack>\n {item.badge && (\n <MantineGroup\n data-position=\"right\"\n className=\"bn-mt-suggestion-menu-item-section\"\n >\n <MantineBadge size={\"xs\"}>{item.badge}</MantineBadge>\n </MantineGroup>\n )}\n </MantineGroup>\n );\n});\n","import { Group as MantineGroup } from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const SuggestionMenuLabel = forwardRef<\n HTMLDivElement,\n ComponentProps[\"SuggestionMenu\"][\"Label\"]\n>((props, ref) => {\n const { className, children, ...rest } = props;\n\n assertEmpty(rest);\n\n return (\n <MantineGroup className={className} ref={ref}>\n {children}\n </MantineGroup>\n );\n});\n","import { Loader as MantineLoader } from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const SuggestionMenuLoader = forwardRef<\n HTMLDivElement,\n ComponentProps[\"SuggestionMenu\"][\"Loader\"]\n>((props, ref) => {\n const { className, ...rest } = props;\n\n assertEmpty(rest);\n\n return (\n <div ref={ref}>\n <MantineLoader className={className} type=\"dots\" size={16} />\n </div>\n );\n});\n","import { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const GridSuggestionMenu = forwardRef<\n HTMLDivElement,\n ComponentProps[\"GridSuggestionMenu\"][\"Root\"]\n>((props, ref) => {\n const { className, children, id, columns, ...rest } = props;\n\n assertEmpty(rest);\n\n return (\n <div\n className={className}\n style={{ gridTemplateColumns: `repeat(${columns}, 1fr)` } as any}\n ref={ref}\n id={id}\n role=\"grid\"\n >\n {children}\n </div>\n );\n});\n","import { Group as MantineGroup } from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const GridSuggestionMenuEmptyItem = forwardRef<\n HTMLDivElement,\n ComponentProps[\"GridSuggestionMenu\"][\"EmptyItem\"]\n>((props, ref) => {\n const { className, children, columns, ...rest } = props;\n\n assertEmpty(rest);\n\n return (\n <MantineGroup\n className={className}\n style={{ gridColumn: `1 / ${columns + 1}` }}\n ref={ref}\n >\n <MantineGroup className=\"bn-mt-suggestion-menu-item-title\">\n {children}\n </MantineGroup>\n </MantineGroup>\n );\n});\n","import { mergeRefs } from \"@mantine/hooks\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps, elementOverflow } from \"@blocknote/react\";\nimport { forwardRef, useEffect, useRef } from \"react\";\n\nexport const GridSuggestionMenuItem = forwardRef<\n HTMLDivElement,\n ComponentProps[\"GridSuggestionMenu\"][\"Item\"]\n>((props, ref) => {\n const { className, isSelected, onClick, item, id, ...rest } = props;\n\n assertEmpty(rest);\n\n const itemRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!itemRef.current || !isSelected) {\n return;\n }\n\n const overflow = elementOverflow(\n itemRef.current,\n itemRef.current.closest(\".bn-grid-suggestion-menu\")!,\n );\n\n if (overflow !== \"none\") {\n itemRef.current.scrollIntoView({ block: \"nearest\" });\n }\n }, [isSelected]);\n\n return (\n <div\n className={className}\n ref={mergeRefs(ref, itemRef)}\n id={id}\n role=\"option\"\n onClick={onClick}\n aria-selected={isSelected || undefined}\n >\n {item.icon}\n </div>\n );\n});\n","import { Loader as MantineLoader } from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const GridSuggestionMenuLoader = forwardRef<\n HTMLDivElement,\n ComponentProps[\"GridSuggestionMenu\"][\"Loader\"]\n>((props, ref) => {\n const {\n className,\n children, // unused, using \"dots\" instead\n columns,\n ...rest\n } = props;\n\n assertEmpty(rest);\n\n return (\n <div style={{ gridColumn: `1 / ${columns + 1}` }} ref={ref}>\n <MantineLoader className={className} type=\"dots\" />\n </div>\n );\n});\n","import { Button as MantineButton } from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const ExtendButton = forwardRef<\n HTMLButtonElement,\n ComponentProps[\"TableHandle\"][\"ExtendButton\"]\n>((props, ref) => {\n const { children, className, onMouseDown, onClick, ...rest } = props;\n\n // false, because rest props can be added by mantine when button is used as a trigger\n // assertEmpty in this case is only used at typescript level, not runtime level\n assertEmpty(rest, false);\n\n return (\n <MantineButton\n className={className}\n ref={ref}\n onMouseDown={onMouseDown}\n onClick={onClick}\n {...rest}\n >\n {children}\n </MantineButton>\n );\n});\n","import { Button as MantineButton } from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\n\nexport const TableHandle = forwardRef<\n HTMLButtonElement,\n ComponentProps[\"TableHandle\"][\"Root\"]\n>((props, ref) => {\n const {\n className,\n children,\n draggable,\n onDragStart,\n onDragEnd,\n style,\n label,\n ...rest\n } = props;\n\n // false, because rest props can be added by mantine when button is used as a trigger\n // assertEmpty in this case is only used at typescript level, not runtime level\n assertEmpty(rest, false);\n\n return (\n <MantineButton\n className={className}\n ref={ref}\n aria-label={label}\n draggable={draggable}\n onDragStart={onDragStart}\n onDragEnd={onDragEnd}\n style={style}\n {...rest}\n >\n {children}\n </MantineButton>\n );\n});\n","import { Flex } from \"@mantine/core\";\n\nimport { assertEmpty } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { mergeRefs, useFocusTrap, useFocusWithin } from \"@mantine/hooks\";\nimport { forwardRef } from \"react\";\n\ntype ToolbarProps = ComponentProps[\"Generic\"][\"Toolbar\"][\"Root\"];\n\nexport const Toolbar = forwardRef<HTMLDivElement, ToolbarProps>(\n (props, ref) => {\n const {\n className,\n children,\n onMouseEnter,\n onMouseLeave,\n variant,\n ...rest\n } = props;\n\n assertEmpty(rest);\n\n // use a focus trap so that tab cycles through toolbar buttons, but only if focus is within the toolbar\n const { ref: focusRef, focused } = useFocusWithin();\n\n const trapRef = useFocusTrap(focused);\n\n const combinedRef = mergeRefs(ref, focusRef, trapRef);\n\n return (\n <Flex\n className={className}\n ref={combinedRef}\n role=\"toolbar\"\n // TODO: aria-label\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n gap={variant === \"action-toolbar\" ? 2 : undefined}\n >\n {children}\n </Flex>\n );\n },\n);\n","import {\n Button as MantineButton,\n CheckIcon as MantineCheckIcon,\n Menu as MantineMenu,\n} from \"@mantine/core\";\n\nimport { assertEmpty, isSafari } from \"@blocknote/core\";\nimport { ComponentProps } from \"@blocknote/react\";\nimport { forwardRef } from \"react\";\nimport { HiChevronDown } from \"react-icons/hi\";\n\n// TODO: Turn into select?\nexport const ToolbarSelect = forwardRef<\n HTMLDivElement,\n ComponentProps[\"FormattingToolbar\"][\"Select\"]\n>((props, ref) => {\n const { className, items, isDisabled, ...rest } = props;\n\n assertEmpty(rest);\n\n const selectedItem = items.filter((p) => p.isSelected)[0];\n\n if (!selectedItem) {\n return null;\n }\n\n return (\n <MantineMenu\n withinPortal={false}\n transitionProps={{\n exitDuration: 0,\n }}\n disabled={isDisabled}\n middlewares={{ flip: true, shift: true, inline: false, size: true }}\n >\n <MantineMenu.Target>\n <MantineButton\n // Needed as Safari doesn't focus button elements on mouse down\n // unlike other browsers.\n onMouseDown={(e) => {\n if (isSafari()) {\n (e.currentTarget as HTMLButtonElement).focus();\n }\n }}\n leftSection={selectedItem.icon}\n rightSection={<HiChevronDown />}\n size={\"xs\"}\n variant={\"subtle\"}\n disabled={isDisabled}\n >\n {selectedItem.text}\n </MantineButton>\n </MantineMenu.Target>\n <MantineMenu.Dropdown className={className} ref={ref}>\n {items.map((item) => (\n <MantineMenu.Item\n key={item.text}\n onClick={item.onClick}\n leftSection={item.icon}\n rightSection={\n item.isSelected ? (\n <MantineCheckIcon size={10} className={\"bn-tick-icon\"} />\n ) : (\n // Ensures space for tick even if item isn't currently selected.\n <div className={\"bn-tick-space\"} />\n )\n }\n disabled={item.isDisabled}\n >\n {item.text}\n </MantineMenu.Item>\n ))}\n </MantineMenu.Dropdown>\n </MantineMenu>\n );\n});\n","import { Components } from \"@blocknote/react\";\nimport { Badge, BadgeGroup } from \"./badge/Badge.js\";\nimport { Card, CardSection, ExpandSectionsPrompt } from \"./comments/Card.js\";\nimport { Comment } from \"./comments/Comment.js\";\nimport { Editor } from \"./comments/Editor.js\";\nimport { TextInput } from \"./form/TextInput.js\";\nimport {\n Menu,\n MenuDivider,\n MenuDropdown,\n MenuItem,\n MenuLabel,\n MenuTrigger,\n} from \"./menu/Menu.js\";\nimport { Button } from \"./menu/Button.js\";\nimport { Panel } from \"./panel/Panel.js\";\nimport { PanelButton } from \"./panel/PanelButton.js\";\nimport { PanelFileInput } from \"./panel/PanelFileInput.js\";\nimport { PanelTab } from \"./panel/PanelTab.js\";\nimport { PanelTextInput } from \"./panel/PanelTextInput.js\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover/Popover.js\";\nimport { SideMenu } from \"./sideMenu/SideMenu.js\";\nimport { SideMenuButton } from \"./sideMenu/SideMenuButton.js\";\nimport { SuggestionMenu } from \"./suggestionMenu/SuggestionMenu.js\";\nimport { SuggestionMenuEmptyItem } from \"./suggestionMenu/SuggestionMenuEmptyItem.js\";\nimport { SuggestionMenuItem } from \"./suggestionMenu/SuggestionMenuItem.js\";\nimport { SuggestionMenuLabel } from \"./suggestionMenu/SuggestionMenuLabel.js\";\nimport { SuggestionMenuLoader } from \"./suggestionMenu/SuggestionMenuLoader.js\";\nimport { GridSuggestionMenu } from \"./suggestionMenu/gridSuggestionMenu/GridSuggestionMenu.js\";\nimport { GridSuggestionMenuEmptyItem } from \"./suggestionMenu/gridSuggestionMenu/GridSuggestionMenuEmptyItem.js\";\nimport { GridSuggestionMenuItem } from \"./suggestionMenu/gridSuggestionMenu/GridSuggestionMenuItem.js\";\nimport { GridSuggestionMenuLoader } from \"./suggestionMenu/gridSuggestionMenu/GridSuggestionMenuLoader.js\";\nimport { ExtendButton } from \"./tableHandle/ExtendButton.js\";\nimport { TableHandle } from \"./tableHandle/TableHandle.js\";\nimport { Toolbar } from \"./toolbar/Toolbar.js\";\nimport { ToolbarButton } from \"./toolbar/ToolbarButton.js\";\nimport { ToolbarSelect } from \"./toolbar/ToolbarSelect.js\";\n\nexport const components: Components = {\n FormattingToolbar: {\n Root: Toolbar,\n Button: ToolbarButton,\n Select: ToolbarSelect,\n },\n FilePanel: {\n Root: Panel,\n Button: PanelButton,\n FileInput: PanelFileInput,\n TabPanel: PanelTab,\n TextInput: PanelTextInput,\n },\n GridSuggestionMenu: {\n Root: GridSuggestionMenu,\n Item: GridSuggestionMenuItem,\n EmptyItem: GridSuggestionMenuEmptyItem,\n Loader: GridSuggestionMenuLoader,\n },\n LinkToolbar: {\n Root: Toolbar,\n Button: ToolbarButton,\n Select: ToolbarSelect,\n },\n SideMenu: {\n Root: SideMenu,\n Button: SideMenuButton,\n },\n SuggestionMenu: {\n Root: SuggestionMenu,\n Item: SuggestionMenuItem,\n EmptyItem: SuggestionMenuEmptyItem,\n Label: SuggestionMenuLabel,\n Loader: SuggestionMenuLoader,\n },\n TableHandle: {\n Root: TableHandle,\n ExtendButton: ExtendButton,\n },\n Generic: {\n Badge: {\n Root: Badge,\n Group: BadgeGroup,\n },\n Form: {\n Root: (props) => <div>{props.children}</div>,\n TextInput: TextInput,\n },\n Menu: {\n Root: Menu,\n Trigger: MenuTrigger,\n Dropdown: MenuDropdown,\n Divider: MenuDivider,\n Label: MenuLabel,\n Item: MenuItem,\n Button: Button,\n },\n Popover: {\n Root: Popover,\n Trigger: PopoverTrigger,\n Content: PopoverContent,\n },\n Toolbar: {\n Root: Toolbar,\n Button: ToolbarButton,\n Select: ToolbarSelect,\n },\n },\n Comments: {\n Comment,\n Editor,\n Card,\n CardSection,\n ExpandSectionsPrompt,\n },\n};\n","import {\n BlockSchema,\n InlineContentSchema,\n mergeCSSClasses,\n StyleSchema,\n} from \"@blocknote/core\";\nimport {\n BlockNoteViewRaw,\n ComponentsContext,\n useBlockNoteContext,\n usePrefersColorScheme,\n} from \"@blocknote/react\";\nimport { MantineContext, MantineProvider } from \"@mantine/core\";\nimport React, { useCallback, useContext, useEffect } from \"react\";\nimport {\n applyBlockNoteCSSVariablesFromTheme,\n removeBlockNoteCSSVariables,\n Theme,\n} from \"./BlockNoteTheme.js\";\nimport { components } from \"./components.js\";\n\nexport const BlockNoteView = <\n BSchema extends BlockSchema,\n ISchema extends InlineContentSchema,\n SSchema extends StyleSchema,\n>(\n props: Omit<\n React.ComponentProps<typeof BlockNoteViewRaw<BSchema, ISchema, SSchema>>,\n \"theme\"\n > & {\n theme?:\n | \"light\"\n | \"dark\"\n | Theme\n | {\n light: Theme;\n dark: Theme;\n };\n },\n) => {\n const { className, theme, editor, ...rest } = props;\n\n const existingContext = useBlockNoteContext();\n const systemColorScheme = usePrefersColorScheme();\n const defaultColorScheme =\n existingContext?.colorSchemePreference || systemColorScheme;\n\n const finalTheme =\n typeof theme === \"string\"\n ? theme\n : defaultColorScheme !== \"no-preference\"\n ? defaultColorScheme\n : \"light\";\n\n const applyThemeVariables = useCallback(\n (node: HTMLElement | null) => {\n if (!node) {\n return;\n }\n\n removeBlockNoteCSSVariables(node);\n\n if (typeof theme === \"object\") {\n if (\"light\" in theme && \"dark\" in theme) {\n applyBlockNoteCSSVariablesFromTheme(\n theme[defaultColorScheme === \"dark\" ? \"dark\" : \"ligh