UNPKG

@atlaskit/editor-plugin-block-menu

Version:

BlockMenu plugin for @atlaskit/editor-core

126 lines (125 loc) 4.96 kB
import type { EditorCommand, NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types'; import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics'; import type { BlockControlsPlugin } from '@atlaskit/editor-plugin-block-controls'; import type { DecorationsPlugin } from '@atlaskit/editor-plugin-decorations'; import type { SelectionPlugin } from '@atlaskit/editor-plugin-selection'; import type { UserIntentPlugin } from '@atlaskit/editor-plugin-user-intent'; import type { NodeType } from '@atlaskit/editor-prosemirror/model'; import type { TransformNodeMetadata } from './editor-commands/types'; export declare enum FLAG_ID { LINK_COPIED_TO_CLIPBOARD = "link-copied-to-clipboard" } type TransformNodeCommand = (targetType: NodeType, metadata?: TransformNodeMetadata) => EditorCommand; export type BlockMenuPlugin = NextEditorPlugin<'blockMenu', { actions: { getBlockMenuComponents: () => Array<RegisterBlockMenuComponent>; isTransformOptionDisabled: (optionNodeTypeName: string, optionNodeTypeAttrs?: Record<string, unknown>) => boolean; registerBlockMenuComponents: (blockMenuComponents: Array<RegisterBlockMenuComponent>) => void; }; commands: { transformNode: TransformNodeCommand; }; dependencies: [ OptionalPlugin<BlockControlsPlugin>, OptionalPlugin<UserIntentPlugin>, OptionalPlugin<SelectionPlugin>, OptionalPlugin<DecorationsPlugin>, OptionalPlugin<AnalyticsPlugin> ]; pluginConfiguration?: BlockMenuPluginOptions; sharedState: BlockMenuSharedState; }>; export type BlockMenuPluginOptions = { /** * Optional hash prefix used for block-specific URL to create a deep link to specific block * Default value from DEFAULT_BLOCK_LINK_HASH_PREFIX in @atlaskit/editor-common/block-menu */ blockLinkHashPrefix?: string; /** * Optional function to retrieve the current link path for the editor context. * @returns The current link path as a string, or null if no path is available */ getLinkPath?: () => string | null; /** * When true, nodes maintain their standard width without negative margins * for block menu compatibility. Used in contexts like Jira issue descriptions * where block menu controls need consistent spacing. * @default false */ useStandardNodeWidth?: boolean; }; export type BlockMenuSharedState = { /** * The name of the currently selected node type that triggered the block menu * This exposes the menuTriggerBy value from blockControls plugin */ currentSelectedNodeName: string | undefined; /** * Whether to show a flag (e.g. for copy confirmation) */ showFlag: FLAG_ID | false; /** * When true, nodes maintain their standard width without negative margins * for block menu compatibility. */ useStandardNodeWidth?: boolean; } | undefined; type WithRank<T> = T & { rank: number; }; export type Parent<T> = WithRank<T>; type ComponentType = BlockMenuSection | BlockMenuItem | BlockMenuNested; export type ComponentTypes = Array<ComponentType>; /** * The relationship between BlockMenuItem, BlockMenuSection, BlockMenuNested * BlockMenuSection can have BlockMenuItem or BlockMenuNested as children * BlockMenuNested can have BlockMenuSection as children, * BlockMenuNested, with BlockMenuSection and BlockMenuItem, is a nested menu * _______________________________________ * | Block menu (no typing) * | |BlockMenuSection * | | |BlockMenuItem * | | |BlockMenuNested * | | | |BlockMenuSection * | | | | |BlockMenuItem */ type BlockMenuItem = { key: string; type: 'block-menu-item'; }; type BlockMenuSection = { key: string; type: 'block-menu-section'; }; type BlockMenuNested = { key: string; type: 'block-menu-nested'; }; export type BlockMenuNestedComponent = (props: { children: React.ReactNode; }) => React.ReactNode; export type BlockMenuSectionComponent = (props: { children: React.ReactNode; }) => React.ReactNode; export type BlockMenuNestedSectionComponent = (props: { children: React.ReactNode; }) => React.ReactNode; export type BlockMenuItemComponent = () => React.ReactNode; export type RegisterBlockMenuNested = BlockMenuNested & { component?: BlockMenuNestedComponent; isHidden?: () => boolean; parent: Parent<BlockMenuSection>; }; export type RegisterBlockMenuSection = BlockMenuSection & { component?: BlockMenuSectionComponent; parent?: Parent<BlockMenuNested>; rank?: number; }; export type RegisterBlockMenuItem = BlockMenuItem & { component?: BlockMenuItemComponent; isHidden?: () => boolean; parent: Parent<BlockMenuSection>; }; export type RegisterBlockMenuComponent = RegisterBlockMenuNested | RegisterBlockMenuSection | RegisterBlockMenuItem; export type RegisterBlockMenuComponentType = RegisterBlockMenuComponent['type']; export {};