UNPKG

@ckeditor/ckeditor5-ui

Version:

The UI framework and standard UI library of CKEditor 5.

311 lines (310 loc) • 11.2 kB
/** * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options */ /** * @module ui/panel/balloon/contextualballoon */ import { BalloonPanelView } from './balloonpanelview.js'; import { View } from '../../view.js'; import { ButtonView } from '../../button/buttonview.js'; import { type ViewCollection } from '../../viewcollection.js'; import { Plugin, type Editor } from '@ckeditor/ckeditor5-core'; import { FocusTracker, type Locale, type DomOptimalPositionOptions, type DecoratedMethodEvent } from '@ckeditor/ckeditor5-utils'; import '../../../theme/components/panel/balloonrotator.css'; import '../../../theme/components/panel/fakepanel.css'; /** * Provides the common contextual balloon for the editor. * * The role of this plugin is to unify the contextual balloons logic, simplify views management and help * avoid the unnecessary complexity of handling multiple {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView} * instances in the editor. * * This plugin allows for creating single or multiple panel stacks. * * Each stack may have multiple views, with the one on the top being visible. When the visible view is removed from the stack, * the previous view becomes visible. * * It might be useful to implement nested navigation in a balloon. For instance, a toolbar view may contain a link button. * When you click it, a link view (which lets you set the URL) is created and put on top of the toolbar view, so the link panel * is displayed. When you finish editing the link and close (remove) the link view, the toolbar view is visible again. * * However, there are cases when there are multiple independent balloons to be displayed, for instance, if the selection * is inside two inline comments at the same time. For such cases, you can create two independent panel stacks. * The contextual balloon plugin will create a navigation bar to let the users switch between these panel stacks using the "Next" * and "Previous" buttons. * * If there are no views in the current stack, the balloon panel will try to switch to the next stack. If there are no * panels in any stack, the balloon panel will be hidden. * * **Note**: To force the balloon panel to show only one view, even if there are other stacks, use the `singleViewMode=true` option * when {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon#add adding} a view to a panel. * * From the implementation point of view, the contextual ballon plugin is reusing a single * {@link module:ui/panel/balloon/balloonpanelview~BalloonPanelView} instance to display multiple contextual balloon * panels in the editor. It also creates a special {@link module:ui/panel/balloon/contextualballoon~RotatorView rotator view}, * used to manage multiple panel stacks. Rotator view is a child of the balloon panel view and the parent of the specific * view you want to display. If there is more than one panel stack to be displayed, the rotator view will add a * navigation bar. If there is only one stack, the rotator view is transparent (it does not add any UI elements). */ export declare class ContextualBalloon extends Plugin { /** * The {@link module:utils/dom/position~DomOptimalPositionOptions#limiter position limiter} * for the {@link #view balloon}, used when no `limiter` has been passed into {@link #add} * or {@link #updatePosition}. * * By default, a function that obtains the farthest DOM * {@link module:engine/view/rooteditableelement~ViewRootEditableElement} * of the {@link module:engine/view/document~ViewDocument#selection}. */ positionLimiter: DomOptimalPositionOptions['limiter']; visibleStack?: string; /** * The currently visible view or `null` when there are no views in any stack. * * @readonly * @observable */ visibleView: View | null; /** * A total number of all stacks in the balloon. * * @private * @readonly * @observable */ _numberOfStacks: number; /** * A flag that controls the single view mode. * * @private * @readonly * @observable */ _singleViewMode: boolean; /** * The map of views and their stacks. */ private _viewToStack; /** * The map of IDs and stacks. */ private _idToStack; /** * The common balloon panel view. */ private _view; /** * Rotator view embedded in the contextual balloon. * Displays the currently visible view in the balloon and provides navigation for switching stacks. */ private _rotatorView; /** * Displays fake panels under the balloon panel view when multiple stacks are added to the balloon. */ private _fakePanelsView; /** * @inheritDoc */ static get pluginName(): "ContextualBalloon"; /** * @inheritDoc */ static get isOfficialPlugin(): true; /** * @inheritDoc */ constructor(editor: Editor); /** * @inheritDoc */ destroy(): void; /** * The common balloon panel view. */ get view(): BalloonPanelView; /** * Returns `true` when the given view is in one of the stacks. Otherwise returns `false`. */ hasView(view: View): boolean; /** * Adds a new view to the stack and makes it visible if the current stack is visible * or it is the first view in the balloon. * * @param data The configuration of the view. * @param data.stackId The ID of the stack that the view is added to. Defaults to `'main'`. * @param data.view The content of the balloon. * @param data.position Positioning options. * @param data.balloonClassName An additional CSS class added to the {@link #view balloon} when visible. * @param data.withArrow Whether the {@link #view balloon} should be rendered with an arrow. Defaults to `true`. * @param data.singleViewMode Whether the view should be the only visible view even if other stacks were added. Defaults to `false`. */ add(data: ViewConfiguration): void; /** * Removes the given view from the stack. If the removed view was visible, * the view preceding it in the stack will become visible instead. * When there is no view in the stack, the next stack will be displayed. * When there are no more stacks, the balloon will hide. * * @param view A view to be removed from the balloon. */ remove(view: View): void; /** * Updates the position of the balloon using the position data of the first visible view in the stack. * When new position data is given, the position data of the currently visible view will be updated. * * @param position Position options. */ updatePosition(position?: Partial<DomOptimalPositionOptions>): void; /** * Returns position options of the last view in the stack. * This keeps the balloon in the same position when the view is changed. */ getPositionOptions(): Partial<DomOptimalPositionOptions> | undefined; /** * Shows the last view from the stack of a given ID. */ showStack(id: string): void; /** * Initializes view instances. */ private _createPanelView; /** * Returns the stack of the currently visible view. */ private get _visibleStack(); /** * Returns the ID of the given stack. */ private _getStackId; /** * Shows the last view from the next stack. */ private _showNextStack; /** * Shows the last view from the previous stack. */ private _showPrevStack; /** * Creates a rotator view. */ private _createRotatorView; /** * Creates a fake panels view. */ private _createFakePanelsView; /** * Sets the view as the content of the balloon and attaches the balloon using position * options of the first view. * * @param data Configuration. * @param data.view The view to show in the balloon. * @param data.balloonClassName Additional class name which will be added to the {@link #view balloon}. * @param data.withArrow Whether the {@link #view balloon} should be rendered with an arrow. */ private _showView; } /** * An event fired when the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon} is about to get the position of the balloon. * * @eventName ~ContextualBalloon#getPositionOptions */ export type ContextualBalloonGetPositionOptionsEvent = DecoratedMethodEvent<ContextualBalloon, 'getPositionOptions'>; /** * The configuration of the view. */ export interface ViewConfiguration { /** * The ID of the stack that the view is added to. * * @default 'main' */ stackId?: string; /** * The content of the balloon. */ view: View; /** * Positioning options. */ position?: Partial<DomOptimalPositionOptions>; /** * An additional CSS class added to the {@link #view balloon} when visible. */ balloonClassName?: string; /** * Whether the {@link #view balloon} should be rendered with an arrow. * * @default true */ withArrow?: boolean; /** * Whether the view should be the only visible view even if other stacks were added. * * @default false */ singleViewMode?: boolean; } /** * Rotator view is a helper class for the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon ContextualBalloon}. * It is used for displaying the last view from the current stack and providing navigation buttons for switching stacks. * See the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon ContextualBalloon} documentation to learn more. * @internal */ export declare class RotatorView extends View { /** * Used for checking if a view is focused or not. */ readonly focusTracker: FocusTracker; /** * Navigation button for switching the stack to the previous one. */ readonly buttonPrevView: ButtonView; /** * Navigation button for switching the stack to the next one. */ readonly buttonNextView: ButtonView; /** * A collection of the child views that creates the rotator content. */ readonly content: ViewCollection; /** * Defines whether navigation is visible or not. * * @observable */ isNavigationVisible: boolean; /** * @observable */ counter: string; /** * @inheritDoc */ constructor(locale: Locale); /** * @inheritDoc */ render(): void; /** * @inheritDoc */ destroy(): void; /** * Shows a given view. * * @param view The view to show. */ showView(view: View): void; /** * Hides the currently displayed view. */ hideView(): void; /** * Creates a navigation button view. * * @param label The button label. * @param icon The button icon. */ private _createButtonView; }