UNPKG

@atlaskit/editor-plugin-selection-extension

Version:

editor-plugin-selection-extension plugin for @atlaskit/editor-core

214 lines (213 loc) 7.36 kB
import type { ComponentType, PropsWithChildren } from 'react'; import type { ADFEntity } from '@atlaskit/adf-utils/types'; import type { BlockMenuPlacement } from '@atlaskit/editor-common/block-menu'; import type { MenuItem } from '@atlaskit/editor-common/ui-menu'; import type { ViewMode } from '@atlaskit/editor-plugin-editor-viewmode'; import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model'; export type MenuItemsType = Array<{ items: MenuItem[]; }>; export type SelectionExtensionComponentProps = { closeExtension: () => void; selection: SelectionExtensionSelectionInfo; }; export type SelectionExtensionCallbackOptions = { selectedNodeAdf?: ADFEntity; selection?: SelectionExtensionSelectionInfo; selectionRanges?: SelectionRange[]; }; export type SelectionExtensionSelectionInfo = { coords: SelectionExtensionCoords; from: number; text: string; to: number; }; export type SelectionCoords = { bottom: number; left: number; right: number; top: number; }; export type SelectionExtension = { component?: ComponentType<SelectionExtensionComponentProps>; icon?: ComponentType<PropsWithChildren<{ label: string; }>>; isDisabled?: (params: SelectionExtensionCallbackOptions) => boolean; name: string; onClick?: (params: SelectionExtensionCallbackOptions) => void; }; export type SelectionPointer = { pointer: string; position?: number; }; export type SelectionRange = { end: SelectionPointer; start: SelectionPointer; }; export type SelectionExtensions = { external?: SelectionExtension[]; firstParty?: SelectionExtension[]; }; type SelectionExtensionModes = ViewMode; export type SelectionExtensionPluginOptions = { extensionList?: ExtensionConfiguration[]; extensions?: SelectionExtensions; pageModes?: SelectionExtensionModes | SelectionExtensionModes[]; }; /** * @private * @deprecated Use {@link SelectionExtensionPluginOptions} instead. * @see https://product-fabric.atlassian.net/browse/ED-27496 */ export type SelectionExtensionPluginConfiguration = SelectionExtensionPluginOptions; export type SelectionExtensionCoords = { bottom: number; left: number; right: number; top: number; }; export type BoundingBoxOffset = { bottom: number; top: number; }; export type InsertPosition = { from?: number; pointer: string; to?: number; }; export type LinkInsertionOption = { insertPosition: InsertPosition; link: string; }; export declare enum SelectionExtensionActionTypes { SET_ACTIVE_EXTENSION = "set-active-extension", UPDATE_ACTIVE_EXTENSION_COORDS = "update-active-extension-coords", CLEAR_ACTIVE_EXTENSION = "clear-active-extension", SET_SELECTED_NODE = "set-selected-node", START_TRACK_CHANGES = "start-track-changes" } export type UpdateActiveExtensionAction = { extension: SelectionExtension; type: SelectionExtensionActionTypes.SET_ACTIVE_EXTENSION; } | { coords: SelectionExtensionCoords; type: SelectionExtensionActionTypes.UPDATE_ACTIVE_EXTENSION_COORDS; } | { type: SelectionExtensionActionTypes.CLEAR_ACTIVE_EXTENSION; }; export type SelectionExtensionPluginState = { activeExtension?: { coords: SelectionExtensionCoords; extension: SelectionExtension | ExtensionMenuItemConfiguration; selection: SelectionExtensionSelectionInfo; }; docChangedAfterClick?: boolean; nodePos?: number; selectedNode?: PMNode; startTrackChanges?: boolean; }; export type ReplaceWithAdfStatus = 'success' | 'document-changed' | 'failed-to-replace'; export type ReplaceWithAdfResult = { status: ReplaceWithAdfStatus; }; export type InsertAdfAtEndOfDocResult = { status: 'success' | 'failed'; }; export type SelectionAdfResult = { selectedNodeAdf?: ADFEntity; selectionRanges?: SelectionRange[]; } | null; export type ExtensionSource = 'first-party' | 'external'; export type ExtensionConfiguration = { blockMenu?: BlockMenuExtensionConfiguration; inlineToolbar?: ToolbarExtensionConfiguration; key: string; primaryToolbar?: ToolbarExtensionConfiguration; source: ExtensionSource; }; export type GetToolbarItemFn = () => ExtensionToolbarItemConfiguration; export type GetMenuItemsFn = () => Array<ExtensionMenuItemConfiguration>; export type GetNestedMenuItemsFn = () => Array<ExtensionMenuItemNestedConfiguration>; export type ToolbarExtensionConfiguration = { getMenuItems?: GetMenuItemsFn; getToolbarItem?: GetToolbarItemFn; }; export type BlockMenuExtensionConfiguration = { getMenuItems: GetMenuItemsFn; /** * Optional placement hint to control where the menu items appear in the block menu * - 'default' (or undefined): Items appear in their normal nested location under create section * - 'featured': Items are promoted to top-level alongside the "Turn into" menu */ placement?: BlockMenuPlacement; }; export type ExtensionToolbarItemConfiguration = { icon: ComponentType<PropsWithChildren<{ label: string; }>>; isDisabled?: boolean; /** * Optional key to identify the toolbar item in analytics events */ key?: string; label?: string; onClick?: () => void; tooltip: string; }; /** * Common fields applicable to all extension menu items */ type ExtensionMenuItemBaseConfiguration = { icon: ComponentType<PropsWithChildren<{ label: string; size?: 'small' | 'medium'; }>>; isDisabled?: boolean; /** * Optional key to identify the menu item in analytics events */ key?: string; label: string; }; /** * Fields for a dropdown item (i.e., an item that does not have further nested menu items) */ type ExtensionDropdownItemFields = { /** * Optional content component to render when this menu item is selected * * Used for forge app extensions that need to render custom UI when selected from the block menu. */ contentComponent?: ComponentType<SelectionExtensionComponentProps>; /** * Optional lozenge to display next to the label in the menu */ lozenge?: { label: string; }; onClick?: () => void; }; /** * Fields for a nested dropdown menu (i.e., an menu item that has further nested menu items) */ type ExtensionNestedDropdownMenuFields = { getMenuItems: GetNestedMenuItemsFn; }; export type ExtensionDropdownItemConfiguration = ExtensionMenuItemBaseConfiguration & AllNever<ExtensionNestedDropdownMenuFields> & ExtensionDropdownItemFields; export type ExtensionNestedDropdownMenuConfiguration = ExtensionMenuItemBaseConfiguration & AllNever<ExtensionDropdownItemFields> & ExtensionNestedDropdownMenuFields; type AllNever<T> = { [K in keyof T]?: never; }; /** * This type represents either a dropdown item or a dropdown menu, but not both. * * We mark all fields of the other type as `never` to enforce this exclusivity. */ export type ExtensionMenuItemConfiguration = ExtensionDropdownItemConfiguration | ExtensionNestedDropdownMenuConfiguration; /** * We intentionally only support dropdown items nested within dropdown menus, i.e. no menus nested * within menus – so there will be at max two levels of nesting from extension menu items */ type ExtensionMenuItemNestedConfiguration = ExtensionDropdownItemConfiguration; export {};