diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 4edbb8a8..ce6d5e4b 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -2,6 +2,7 @@ ### 2.27.0 +- `New` — *Toolbar API* — Toolbox toggling method added. - `Refactoring` — Popover class refactored. - `Improvement` — *Toolbox* — Number of `close()` method calls optimized. - `Improvement` — The `onChange` callback won't be triggered only if all mutations contain nodes with the `data-mutation-free` attributes. diff --git a/src/components/modules/api/toolbar.ts b/src/components/modules/api/toolbar.ts index 2c01407d..321cbf4c 100644 --- a/src/components/modules/api/toolbar.ts +++ b/src/components/modules/api/toolbar.ts @@ -16,6 +16,7 @@ export default class ToolbarAPI extends Module { close: (): void => this.close(), open: (): void => this.open(), toggleBlockSettings: (openingState?: boolean): void => this.toggleBlockSettings(openingState), + toggleToolbox: (openingState?: boolean): void => this.toggleToolbox(openingState), }; } @@ -55,4 +56,27 @@ export default class ToolbarAPI extends Module { this.Editor.BlockSettings.close(); } } + + + /** + * Open toolbox + * + * @param {boolean} openingState - Opening state of toolbox + */ + public toggleToolbox(openingState: boolean): void { + if (this.Editor.BlockManager.currentBlockIndex === -1) { + _.logLabeled('Could\'t toggle the Toolbox because there is no block selected ', 'warn'); + + return; + } + + const canOpenToolbox = openingState ?? !this.Editor.Toolbar.toolbox.opened; + + if (canOpenToolbox) { + this.Editor.Toolbar.moveAndOpen(); + this.Editor.Toolbar.toolbox.open(); + } else { + this.Editor.Toolbar.toolbox.close(); + } + } } diff --git a/src/types-internal/editor-modules.d.ts b/src/types-internal/editor-modules.d.ts index 5acfbee4..65386a0c 100644 --- a/src/types-internal/editor-modules.d.ts +++ b/src/types-internal/editor-modules.d.ts @@ -22,7 +22,7 @@ import NotifierAPI from '../components/modules/api/notifier'; import SaverAPI from '../components/modules/api/saver'; import Saver from '../components/modules/saver'; import BlockSelection from '../components/modules/blockSelection'; -import RectangleSelection from '../components/modules/RectangleSelection'; +import RectangleSelection from '../components/modules/rectangleSelection'; import InlineToolbarAPI from '../components/modules/api/inlineToolbar'; import CrossBlockSelection from '../components/modules/crossBlockSelection'; import ConversionToolbar from '../components/modules/toolbar/conversion'; diff --git a/test/cypress/tests/api/toolbar.cy.ts b/test/cypress/tests/api/toolbar.cy.ts new file mode 100644 index 00000000..4a8d9237 --- /dev/null +++ b/test/cypress/tests/api/toolbar.cy.ts @@ -0,0 +1,86 @@ +/** + * There will be described test cases of 'api.toolbar.*' API + */ +import EditorJS from '../../../../types'; + +describe('api.toolbar', () => { + /** + * api.toolbar.openToolbox(openingState?: boolean) + */ + const firstBlock = { + id: 'bwnFX5LoX7', + type: 'paragraph', + data: { + text: 'The first block content mock.', + }, + }; + const editorDataMock = { + blocks: [ + firstBlock, + ], + }; + + beforeEach(function () { + cy.createEditor({ + data: editorDataMock, + readOnly: false, + }).as('editorInstance'); + }); + + afterEach(function () { + if (this.editorInstance) { + this.editorInstance.destroy(); + } + }); + + describe('*.toggleToolbox()', () => { + const isToolboxVisible = (): void => { + cy.get('[data-cy=editorjs]').find('div.ce-toolbox') + .then((toolbox) => { + if (toolbox.is(':visible')) { + assert.isOk(true, 'Toolbox visible'); + } else { + assert.isNotOk(false, 'Toolbox should be visible'); + } + }); + }; + + const isToolboxNotVisible = (): void => { + cy.get('[data-cy=editorjs]').find('div.ce-toolbox') + .then((toolbox) => { + if (!toolbox.is(':visible')) { + assert.isOk(true, 'Toolbox not visible'); + } else { + assert.isNotOk(false, 'Toolbox should not be visible'); + } + }); + }; + + it('should open the toolbox', function () { + cy.get('@editorInstance').then(async function (editor) { + editor.toolbar.toggleToolbox(true); + isToolboxVisible(); + }); + }); + + it('should close the toolbox', function () { + cy.get('@editorInstance').then(async function (editor) { + editor.toolbar.toggleToolbox(true); + + isToolboxVisible(); + + editor.toolbar.toggleToolbox(false); + isToolboxNotVisible(); + }); + }); + it('should toggle the toolbox', function () { + cy.get('@editorInstance').then(async function (editor) { + editor.toolbar.toggleToolbox(); + isToolboxVisible(); + + editor.toolbar.toggleToolbox(); + isToolboxNotVisible(); + }); + }); + }); +}); diff --git a/types/api/toolbar.d.ts b/types/api/toolbar.d.ts index 0c029004..8e6eefb5 100644 --- a/types/api/toolbar.d.ts +++ b/types/api/toolbar.d.ts @@ -17,4 +17,10 @@ export interface Toolbar { * @param {boolean} openingState — opening state of Block Setting */ toggleBlockSettings(openingState?: boolean): void; + + /** + * Toggle toolbox + * @param {boolean} openingState — opening state of the toolbox + */ + toggleToolbox(openingState?: boolean): void; }