@atlaskit/editor-plugin-selection-extension
Version:
editor-plugin-selection-extension plugin for @atlaskit/editor-core
214 lines (213 loc) • 7.36 kB
TypeScript
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 {};