@atlaskit/editor-plugin-media-insert
Version:
Media Insert plugin for @atlaskit/editor-core
128 lines (127 loc) • 5.01 kB
TypeScript
import type { ComponentType, ReactNode } from 'react';
import type { AnalyticsEventPayload } from '@atlaskit/editor-common/analytics';
import type { MediaProvider } from '@atlaskit/editor-common/provider-factory';
import type { EditorCommand, NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
import type { FeatureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
import type { MediaPlugin } from '@atlaskit/editor-plugin-media';
import type { CustomizedHelperMessage, InsertMediaSingle } from './types';
/**
* Props provided to a registered insert tab inside the media insert picker.
*
* The picker owns the popup chrome and provides the editor-side context
* needed to insert media; the registering plugin provides the actual UI.
*/
export type MediaInsertTabProps = {
closeMediaInsertPicker: () => void;
dispatchAnalyticsEvent?: (payload: AnalyticsEventPayload) => void;
insertMediaSingle: InsertMediaSingle;
mediaProvider: MediaProvider;
};
/**
* Descriptor for an insert tab registered onto the media insert picker via
* `api.mediaInsert.actions.registerInsertTab(...)`.
*
* Other plugins (typically private `@atlassian/*` plugins like
* `editor-plugin-ai-image-generation`) call `registerInsertTab` from inside
* their own setup so the public `editor-plugin-media-insert` package never
* needs to import them directly.
*/
export type RegisterInsertTab = {
/**
* Stable identifier for this tab. Used to de-duplicate registrations so
* calling `registerInsertTab` with the same key twice replaces the prior
* registration rather than appending a duplicate tab.
*/
key: string;
/**
* Label rendered inside the tab. Typically a `<FormattedMessage />` so the
* registering plugin owns its own i18n.
*/
label: ReactNode;
/**
* Component rendered inside the picker when this tab is active.
*/
component: ComponentType<MediaInsertTabProps>;
};
export type MediaInsertPluginState = {
isOpen?: boolean;
mountInfo?: {
mountPoint: HTMLElement;
ref: HTMLElement;
};
};
export type MediaInsertPluginDependencies = [
OptionalPlugin<AnalyticsPlugin>,
MediaPlugin,
OptionalPlugin<FeatureFlagsPlugin>
];
export type MediaInsertPluginCommands = {
showMediaInsertPopup: (mountInfo?: {
mountPoint: HTMLElement;
ref: HTMLElement;
}) => EditorCommand;
};
export type MediaInsertPluginActions = {
/**
* Returns the list of insert tabs that have been registered with the
* picker. Order matches registration order.
*/
getInsertTabs: () => RegisterInsertTab[];
/**
* Register an additional tab inside the media insert picker. Idempotent
* by `key`: re-registering with the same key replaces the prior entry.
*
* Intended to be called from another plugin's setup, e.g.:
*
* ```tsx
* // inside aiImageGenerationPlugin
* api?.mediaInsert?.actions.registerInsertTab({
* key: 'ai-image-generation',
* label: <FormattedMessage {...messages.generateTabTitle} />,
* component: MediaInsertImageGenerationTab,
* });
* ```
*/
registerInsertTab: (tab: RegisterInsertTab) => void;
};
export type MediaInsertPluginConfig = {
customizedHelperMessage?: CustomizedHelperMessage;
customizedUrlValidation?: (input: string) => boolean;
/**
* This will only allow users to insert media using URLs, they cannot insert media using files from their computer.
* Files that are inserted with a URL will attempt to be uploaded using `editor-plugin-media`
*
* @example
* ```typescript
* createDefaultPreset({ featureFlags: {}, paste: {} })
* .add(listPlugin)
* .add(gridPlugin)
* .add([mediaPlugin, { provider, allowMediaSingle: true, }])
* .add(insertBlockPlugin)
* .add(contentInsertionPlugin)
* .add([mediaInsertPlugin, { isOnlyExternalLinks: true }])
* ```
*
* To disable trying to upload media from the external URLs we also need to disable this auto upload, in the media plugin:
*
* @example
* ```typescript
* createDefaultPreset({ featureFlags: {}, paste: {} })
* .add(listPlugin)
* .add(gridPlugin)
* .add([mediaPlugin, { provider, allowMediaSingle: true, isExternalMediaUploadDisabled: true }])
* .add(insertBlockPlugin)
* .add(contentInsertionPlugin)
* .add([mediaInsertPlugin, { isOnlyExternalLinks: true }])
* ```
*/
isOnlyExternalLinks?: boolean;
};
export type MediaInsertPlugin = NextEditorPlugin<'mediaInsert', {
actions: MediaInsertPluginActions;
commands: MediaInsertPluginCommands;
dependencies: MediaInsertPluginDependencies;
pluginConfiguration: MediaInsertPluginConfig | undefined;
sharedState: MediaInsertPluginState;
}>;