mirror of
https://github.com/codex-team/editor.js
synced 2024-06-10 09:52:36 +02:00
fix(tunes): Make label an alias for title in tunes menu item (#2198)
* Make label an alias for title in tunes item
* Cleanup
* Update version and changelog
* Update changelog
* Move resolveAlias to utils
* Add fallback for popover item title
* Lint
* Lint
* Add fallback icon and title to popover
* Update version
* Lint
* Fix changelog
* Fallback to empty string
This reverts commit ae9d643557
.
* Fix changelog again
* Cleanup
* Add deprecated
This commit is contained in:
parent
c97f0842f5
commit
870e265af0
|
@ -1,5 +1,9 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
### 2.26.4
|
||||||
|
|
||||||
|
- `Improvement` — *Menu Config* — Property `label` renamed to `title`.
|
||||||
|
|
||||||
### 2.26.3
|
### 2.26.3
|
||||||
|
|
||||||
- `Fix` — *Paste Module* — fix for a problem with specifying of `pasteConfig().tags` in upper case [#2208](https://github.com/codex-team/editor.js/issues/2208).
|
- `Fix` — *Paste Module* — fix for a problem with specifying of `pasteConfig().tags` in upper case [#2208](https://github.com/codex-team/editor.js/issues/2208).
|
||||||
|
@ -9,6 +13,7 @@
|
||||||
- `Fix` — *Menu Config* — Installed tunes are rendered above default tunes again.
|
- `Fix` — *Menu Config* — Installed tunes are rendered above default tunes again.
|
||||||
|
|
||||||
### 2.26.1
|
### 2.26.1
|
||||||
|
|
||||||
- `Improvement` — *Menu Config* — Now it becomes possible to create toggle groups.
|
- `Improvement` — *Menu Config* — Now it becomes possible to create toggle groups.
|
||||||
|
|
||||||
### 2.26.0
|
### 2.26.0
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@editorjs/editorjs",
|
"name": "@editorjs/editorjs",
|
||||||
"version": "2.26.3",
|
"version": "2.26.4",
|
||||||
"description": "Editor.js — Native JS, based on API and Open Source",
|
"description": "Editor.js — Native JS, based on API and Open Source",
|
||||||
"main": "dist/editor.js",
|
"main": "dist/editor.js",
|
||||||
"types": "./types/index.d.ts",
|
"types": "./types/index.d.ts",
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
"url": "https://opencollective.com/editorjs"
|
"url": "https://opencollective.com/editorjs"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codexteam/icons": "^0.0.4",
|
"@codexteam/icons": "0.1.0",
|
||||||
"codex-notifier": "^1.1.2",
|
"codex-notifier": "^1.1.2",
|
||||||
"codex-tooltip": "^1.0.5",
|
"codex-tooltip": "^1.0.5",
|
||||||
"html-janitor": "^2.0.4",
|
"html-janitor": "^2.0.4",
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
* @classdesc Editor's default tune that moves up selected block
|
* @classdesc Editor's default tune that moves up selected block
|
||||||
* @copyright <CodeX Team> 2018
|
* @copyright <CodeX Team> 2018
|
||||||
*/
|
*/
|
||||||
import { API, BlockTune, PopoverItem } from '../../../types';
|
import { API, BlockTune } from '../../../types';
|
||||||
import { IconCross } from '@codexteam/icons';
|
import { IconCross } from '@codexteam/icons';
|
||||||
|
import { TunesMenuConfig } from '../../../types/tools';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -34,13 +35,13 @@ export default class DeleteTune implements BlockTune {
|
||||||
/**
|
/**
|
||||||
* Tune's appearance in block settings menu
|
* Tune's appearance in block settings menu
|
||||||
*/
|
*/
|
||||||
public render(): PopoverItem {
|
public render(): TunesMenuConfig {
|
||||||
return {
|
return {
|
||||||
icon: IconCross,
|
icon: IconCross,
|
||||||
label: this.api.i18n.t('Delete'),
|
title: this.api.i18n.t('Delete'),
|
||||||
name: 'delete',
|
name: 'delete',
|
||||||
confirmation: {
|
confirmation: {
|
||||||
label: this.api.i18n.t('Click to delete'),
|
title: this.api.i18n.t('Click to delete'),
|
||||||
onActivate: (): void => this.handleClick(),
|
onActivate: (): void => this.handleClick(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,9 +4,10 @@
|
||||||
* @copyright <CodeX Team> 2018
|
* @copyright <CodeX Team> 2018
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { API, BlockTune, PopoverItem } from '../../../types';
|
import { API, BlockTune } from '../../../types';
|
||||||
import Popover from '../utils/popover';
|
import Popover from '../utils/popover';
|
||||||
import { IconChevronDown } from '@codexteam/icons';
|
import { IconChevronDown } from '@codexteam/icons';
|
||||||
|
import { TunesMenuConfig } from '../../../types/tools';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,10 +45,10 @@ export default class MoveDownTune implements BlockTune {
|
||||||
/**
|
/**
|
||||||
* Tune's appearance in block settings menu
|
* Tune's appearance in block settings menu
|
||||||
*/
|
*/
|
||||||
public render(): PopoverItem {
|
public render(): TunesMenuConfig {
|
||||||
return {
|
return {
|
||||||
icon: IconChevronDown,
|
icon: IconChevronDown,
|
||||||
label: this.api.i18n.t('Move down'),
|
title: this.api.i18n.t('Move down'),
|
||||||
onActivate: (item, event): void => this.handleClick(event),
|
onActivate: (item, event): void => this.handleClick(event),
|
||||||
name: 'move-down',
|
name: 'move-down',
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
* @classdesc Editor's default tune that moves up selected block
|
* @classdesc Editor's default tune that moves up selected block
|
||||||
* @copyright <CodeX Team> 2018
|
* @copyright <CodeX Team> 2018
|
||||||
*/
|
*/
|
||||||
import { API, BlockTune, PopoverItem } from '../../../types';
|
import { API, BlockTune } from '../../../types';
|
||||||
import Popover from '../../components/utils/popover';
|
import Popover from '../../components/utils/popover';
|
||||||
import { IconChevronUp } from '@codexteam/icons';
|
import { IconChevronUp } from '@codexteam/icons';
|
||||||
|
import { TunesMenuConfig } from '../../../types/tools';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -42,10 +43,10 @@ export default class MoveUpTune implements BlockTune {
|
||||||
/**
|
/**
|
||||||
* Tune's appearance in block settings menu
|
* Tune's appearance in block settings menu
|
||||||
*/
|
*/
|
||||||
public render(): PopoverItem {
|
public render(): TunesMenuConfig {
|
||||||
return {
|
return {
|
||||||
icon: IconChevronUp,
|
icon: IconChevronUp,
|
||||||
label: this.api.i18n.t('Move up'),
|
title: this.api.i18n.t('Move up'),
|
||||||
onActivate: (item, e): void => this.handleClick(e),
|
onActivate: (item, e): void => this.handleClick(e),
|
||||||
name: 'move-up',
|
name: 'move-up',
|
||||||
};
|
};
|
||||||
|
|
|
@ -21,6 +21,7 @@ import BlockTune from '../tools/tune';
|
||||||
import { BlockTuneData } from '../../../types/block-tunes/block-tune-data';
|
import { BlockTuneData } from '../../../types/block-tunes/block-tune-data';
|
||||||
import ToolsCollection from '../tools/collection';
|
import ToolsCollection from '../tools/collection';
|
||||||
import EventsDispatcher from '../utils/events';
|
import EventsDispatcher from '../utils/events';
|
||||||
|
import { TunesMenuConfigItem } from '../../../types/tools';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface describes Block class constructor argument
|
* Interface describes Block class constructor argument
|
||||||
|
@ -646,7 +647,7 @@ export default class Block extends EventsDispatcher<BlockEvents> {
|
||||||
*/
|
*/
|
||||||
public getTunes(): [PopoverItem[], HTMLElement] {
|
public getTunes(): [PopoverItem[], HTMLElement] {
|
||||||
const customHtmlTunesContainer = document.createElement('div');
|
const customHtmlTunesContainer = document.createElement('div');
|
||||||
const tunesItems: PopoverItem[] = [];
|
const tunesItems: TunesMenuConfigItem[] = [];
|
||||||
|
|
||||||
/** Tool's tunes: may be defined as return value of optional renderSettings method */
|
/** Tool's tunes: may be defined as return value of optional renderSettings method */
|
||||||
const tunesDefinedInTool = typeof this.toolInstance.renderSettings === 'function' ? this.toolInstance.renderSettings() : [];
|
const tunesDefinedInTool = typeof this.toolInstance.renderSettings === 'function' ? this.toolInstance.renderSettings() : [];
|
||||||
|
|
|
@ -6,6 +6,8 @@ import Popover, { PopoverEvent } from '../../utils/popover';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import { I18nInternalNS } from '../../i18n/namespace-internal';
|
import { I18nInternalNS } from '../../i18n/namespace-internal';
|
||||||
import Flipper from '../../flipper';
|
import Flipper from '../../flipper';
|
||||||
|
import { TunesMenuConfigItem } from '../../../../types/tools';
|
||||||
|
import { resolveAliases } from '../../utils/resolve-aliases';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTML Elements that used for BlockSettings
|
* HTML Elements that used for BlockSettings
|
||||||
|
@ -114,7 +116,7 @@ export default class BlockSettings extends Module<BlockSettingsNodes> {
|
||||||
searchable: true,
|
searchable: true,
|
||||||
filterLabel: I18n.ui(I18nInternalNS.ui.popover, 'Filter'),
|
filterLabel: I18n.ui(I18nInternalNS.ui.popover, 'Filter'),
|
||||||
nothingFoundLabel: I18n.ui(I18nInternalNS.ui.popover, 'Nothing found'),
|
nothingFoundLabel: I18n.ui(I18nInternalNS.ui.popover, 'Nothing found'),
|
||||||
items: tunesItems,
|
items: tunesItems.map(tune => this.resolveTuneAliases(tune)),
|
||||||
customContent: customHtmlTunesContainer,
|
customContent: customHtmlTunesContainer,
|
||||||
customContentFlippableItems: this.getControls(customHtmlTunesContainer),
|
customContentFlippableItems: this.getControls(customHtmlTunesContainer),
|
||||||
scopeElement: this.Editor.API.methods.ui.nodes.redactor,
|
scopeElement: this.Editor.API.methods.ui.nodes.redactor,
|
||||||
|
@ -192,4 +194,19 @@ export default class BlockSettings extends Module<BlockSettingsNodes> {
|
||||||
private onOverlayClicked = (): void => {
|
private onOverlayClicked = (): void => {
|
||||||
this.close();
|
this.close();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves aliases in tunes menu items
|
||||||
|
*
|
||||||
|
* @param item - item with resolved aliases
|
||||||
|
*/
|
||||||
|
private resolveTuneAliases(item: TunesMenuConfigItem): TunesMenuConfigItem {
|
||||||
|
const result = resolveAliases(item, { label: 'title' });
|
||||||
|
|
||||||
|
if (item.confirmation) {
|
||||||
|
result.confirmation = this.resolveTuneAliases(item.confirmation);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,7 +243,7 @@ export default class Toolbox extends EventsDispatcher<ToolboxEvent> {
|
||||||
const toPopoverItem = (toolboxItem: ToolboxConfigEntry, tool: BlockTool): PopoverItem => {
|
const toPopoverItem = (toolboxItem: ToolboxConfigEntry, tool: BlockTool): PopoverItem => {
|
||||||
return {
|
return {
|
||||||
icon: toolboxItem.icon,
|
icon: toolboxItem.icon,
|
||||||
label: I18n.t(I18nInternalNS.toolNames, toolboxItem.title || _.capitalize(tool.name)),
|
title: I18n.t(I18nInternalNS.toolNames, toolboxItem.title || _.capitalize(tool.name)),
|
||||||
name: tool.name,
|
name: tool.name,
|
||||||
onActivate: (): void => {
|
onActivate: (): void => {
|
||||||
this.toolButtonActivated(tool.name, toolboxItem.data);
|
this.toolButtonActivated(tool.name, toolboxItem.data);
|
||||||
|
|
|
@ -6,6 +6,7 @@ import EventsDispatcher from './events';
|
||||||
import { isMobileScreen, keyCodes, cacheable } from '../utils';
|
import { isMobileScreen, keyCodes, cacheable } from '../utils';
|
||||||
import ScrollLocker from './scroll-locker';
|
import ScrollLocker from './scroll-locker';
|
||||||
import { PopoverItem, PopoverItemWithConfirmation } from '../../../types';
|
import { PopoverItem, PopoverItemWithConfirmation } from '../../../types';
|
||||||
|
import { IconDotCircle } from '@codexteam/icons';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event that can be triggered by the Popover
|
* Event that can be triggered by the Popover
|
||||||
|
@ -434,11 +435,11 @@ export default class Popover extends EventsDispatcher<PopoverEvent> {
|
||||||
el.dataset.itemName = item.name;
|
el.dataset.itemName = item.name;
|
||||||
}
|
}
|
||||||
const label = Dom.make('div', Popover.CSS.itemLabel, {
|
const label = Dom.make('div', Popover.CSS.itemLabel, {
|
||||||
innerHTML: item.label,
|
innerHTML: item.title || '',
|
||||||
});
|
});
|
||||||
|
|
||||||
el.appendChild(Dom.make('div', Popover.CSS.itemIcon, {
|
el.appendChild(Dom.make('div', Popover.CSS.itemIcon, {
|
||||||
innerHTML: item.icon || item.name.substring(0, 1).toUpperCase(),
|
innerHTML: item.icon || IconDotCircle,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
el.appendChild(label);
|
el.appendChild(label);
|
||||||
|
|
23
src/components/utils/resolve-aliases.ts
Normal file
23
src/components/utils/resolve-aliases.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/**
|
||||||
|
* Resolves aliases in specified object according to passed aliases info
|
||||||
|
*
|
||||||
|
* @example resolveAliases(obj, { label: 'title' })
|
||||||
|
* here 'label' is alias for 'title'
|
||||||
|
* @param obj - object with aliases to be resolved
|
||||||
|
* @param aliases - object with aliases info where key is an alias property name and value is an aliased property name
|
||||||
|
*/
|
||||||
|
export function resolveAliases<ObjectType>(obj: ObjectType, aliases: { [alias: string]: string }): ObjectType {
|
||||||
|
const result = {} as ObjectType;
|
||||||
|
|
||||||
|
Object.keys(obj).forEach(property => {
|
||||||
|
const aliasedProperty = aliases[property];
|
||||||
|
|
||||||
|
if (aliasedProperty !== undefined) {
|
||||||
|
result[aliasedProperty] = obj[property];
|
||||||
|
} else {
|
||||||
|
result[property] = obj[property];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ import { IconSearch } from '@codexteam/icons';
|
||||||
* Item that could be searched
|
* Item that could be searched
|
||||||
*/
|
*/
|
||||||
interface SearchableItem {
|
interface SearchableItem {
|
||||||
label: string;
|
title?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -145,7 +145,7 @@ export default class SearchInput {
|
||||||
* @param item - item to be checked
|
* @param item - item to be checked
|
||||||
*/
|
*/
|
||||||
private checkItem(item: SearchableItem): boolean {
|
private checkItem(item: SearchableItem): boolean {
|
||||||
const text = item.label.toLowerCase();
|
const text = item.title?.toLowerCase() || '';
|
||||||
const query = this.searchQuery.toLowerCase();
|
const query = this.searchQuery.toLowerCase();
|
||||||
|
|
||||||
return text.includes(query);
|
return text.includes(query);
|
||||||
|
|
|
@ -413,6 +413,87 @@ describe('Editor Tools Api', () => {
|
||||||
.get('.ce-popover')
|
.get('.ce-popover')
|
||||||
.should('contain.text', sampleText);
|
.should('contain.text', sampleText);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should support label alias', () => {
|
||||||
|
/** Tool with single tunes menu entry configured */
|
||||||
|
class TestTool {
|
||||||
|
/** Returns toolbox config as list of entries */
|
||||||
|
public static get toolbox(): ToolboxConfigEntry {
|
||||||
|
return {
|
||||||
|
title: 'Test tool',
|
||||||
|
icon: ICON,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns configuration for block tunes menu */
|
||||||
|
public renderSettings(): TunesMenuConfig {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
icon: ICON,
|
||||||
|
name: 'testToolTune1',
|
||||||
|
onActivate: (): void => {},
|
||||||
|
|
||||||
|
// Set text via title property
|
||||||
|
title: 'Test tool tune 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: ICON,
|
||||||
|
name: 'testToolTune2',
|
||||||
|
onActivate: (): void => {},
|
||||||
|
|
||||||
|
// Set test via label property
|
||||||
|
label: 'Test tool tune 2',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Save method stub */
|
||||||
|
public save(): void {}
|
||||||
|
|
||||||
|
/** Renders a block */
|
||||||
|
public render(): HTMLElement {
|
||||||
|
const element = document.createElement('div');
|
||||||
|
|
||||||
|
element.contentEditable = 'true';
|
||||||
|
element.setAttribute('data-name', 'testBlock');
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cy.createEditor({
|
||||||
|
tools: {
|
||||||
|
testTool: TestTool,
|
||||||
|
},
|
||||||
|
}).as('editorInstance');
|
||||||
|
|
||||||
|
cy.get('[data-cy=editorjs]')
|
||||||
|
.get('div.ce-block')
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.get('[data-cy=editorjs]')
|
||||||
|
.get('div.ce-toolbar__plus')
|
||||||
|
.click();
|
||||||
|
|
||||||
|
// Insert test tool block
|
||||||
|
cy.get('[data-cy=editorjs]')
|
||||||
|
.get(`[data-item-name="testTool"]`)
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.get('[data-cy=editorjs]')
|
||||||
|
.get('[data-name=testBlock]')
|
||||||
|
.type('some text')
|
||||||
|
.click();
|
||||||
|
|
||||||
|
// Open block tunes
|
||||||
|
cy.get('[data-cy=editorjs]')
|
||||||
|
.get('.ce-toolbar__settings-btn')
|
||||||
|
.click();
|
||||||
|
|
||||||
|
// Expect both tunes to have correct text
|
||||||
|
cy.get('[data-item-name=testToolTune1]').contains('Test tool tune 1');
|
||||||
|
cy.get('[data-item-name=testToolTune2]').contains('Test tool tune 2');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,7 +13,7 @@ describe('Editor Tunes Api', () => {
|
||||||
public render(): TunesMenuConfig {
|
public render(): TunesMenuConfig {
|
||||||
return {
|
return {
|
||||||
icon: 'ICON',
|
icon: 'ICON',
|
||||||
label: 'Test tune',
|
title: 'Test tune',
|
||||||
name: 'testTune',
|
name: 'testTune',
|
||||||
|
|
||||||
onActivate: (): void => { },
|
onActivate: (): void => { },
|
||||||
|
@ -54,13 +54,13 @@ describe('Editor Tunes Api', () => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
icon: 'ICON1',
|
icon: 'ICON1',
|
||||||
label: 'Tune entry 1',
|
title: 'Tune entry 1',
|
||||||
name: 'testTune1',
|
name: 'testTune1',
|
||||||
|
|
||||||
onActivate: (): void => { },
|
onActivate: (): void => { },
|
||||||
}, {
|
}, {
|
||||||
icon: 'ICON2',
|
icon: 'ICON2',
|
||||||
label: 'Tune entry 2',
|
title: 'Tune entry 2',
|
||||||
name: 'testTune2',
|
name: 'testTune2',
|
||||||
|
|
||||||
onActivate: (): void => { },
|
onActivate: (): void => { },
|
||||||
|
@ -134,6 +134,59 @@ describe('Editor Tunes Api', () => {
|
||||||
.should('contain.text', sampleText);
|
.should('contain.text', sampleText);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should support label alias', () => {
|
||||||
|
/** Test tune that should appear be rendered in block tunes menu */
|
||||||
|
class TestTune {
|
||||||
|
/** Set Tool is Tune */
|
||||||
|
public static readonly isTune = true;
|
||||||
|
|
||||||
|
/** Tune's appearance in block settings menu */
|
||||||
|
public render(): TunesMenuConfig {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
icon: 'ICON1',
|
||||||
|
name: 'testTune1',
|
||||||
|
onActivate: (): void => { },
|
||||||
|
|
||||||
|
// Set text via title property
|
||||||
|
title: 'Tune entry 1',
|
||||||
|
}, {
|
||||||
|
icon: 'ICON2',
|
||||||
|
name: 'testTune2',
|
||||||
|
onActivate: (): void => { },
|
||||||
|
|
||||||
|
// Set text via label property
|
||||||
|
label: 'Tune entry 2',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Save method stub */
|
||||||
|
public save(): void {}
|
||||||
|
}
|
||||||
|
|
||||||
|
cy.createEditor({
|
||||||
|
tools: {
|
||||||
|
testTune: TestTune,
|
||||||
|
},
|
||||||
|
tunes: [ 'testTune' ],
|
||||||
|
}).as('editorInstance');
|
||||||
|
|
||||||
|
cy.get('[data-cy=editorjs]')
|
||||||
|
.get('div.ce-block')
|
||||||
|
.type('some text')
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.get('[data-cy=editorjs]')
|
||||||
|
.get('.ce-toolbar__settings-btn')
|
||||||
|
.click();
|
||||||
|
|
||||||
|
|
||||||
|
/** Check both tunes have correct text */
|
||||||
|
cy.get('[data-item-name=testTune1]').contains('Tune entry 1');
|
||||||
|
cy.get('[data-item-name=testTune2]').contains('Tune entry 2');
|
||||||
|
});
|
||||||
|
|
||||||
it('should display installed tunes above default tunes', () => {
|
it('should display installed tunes above default tunes', () => {
|
||||||
/** Test tune that should appear be rendered in block tunes menu */
|
/** Test tune that should appear be rendered in block tunes menu */
|
||||||
class TestTune {
|
class TestTune {
|
||||||
|
|
|
@ -29,7 +29,7 @@ class SomePlugin {
|
||||||
public static get toolbox(): PopoverItem {
|
public static get toolbox(): PopoverItem {
|
||||||
return {
|
return {
|
||||||
icon: '₷',
|
icon: '₷',
|
||||||
label: 'Some tool',
|
title: 'Some tool',
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||||
onActivate: (): void => {},
|
onActivate: (): void => {},
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,9 +6,9 @@ import { PopoverItem } from '../../../../types';
|
||||||
describe('Popover', () => {
|
describe('Popover', () => {
|
||||||
it('should support confirmation chains', () => {
|
it('should support confirmation chains', () => {
|
||||||
const actionIcon = 'Icon 1';
|
const actionIcon = 'Icon 1';
|
||||||
const actionLabel = 'Action';
|
const actionTitle = 'Action';
|
||||||
const confirmActionIcon = 'Icon 2';
|
const confirmActionIcon = 'Icon 2';
|
||||||
const confirmActionLabel = 'Confirm action';
|
const confirmActionTitle = 'Confirm action';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Confirmation is moved to separate variable to be able to test it's callback execution.
|
* Confirmation is moved to separate variable to be able to test it's callback execution.
|
||||||
|
@ -16,14 +16,14 @@ describe('Popover', () => {
|
||||||
*/
|
*/
|
||||||
const confirmation = {
|
const confirmation = {
|
||||||
icon: confirmActionIcon,
|
icon: confirmActionIcon,
|
||||||
label: confirmActionLabel,
|
title: confirmActionTitle,
|
||||||
onActivate: cy.stub(),
|
onActivate: cy.stub(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const items: PopoverItem[] = [
|
const items: PopoverItem[] = [
|
||||||
{
|
{
|
||||||
icon: actionIcon,
|
icon: actionIcon,
|
||||||
label: actionLabel,
|
title: actionTitle,
|
||||||
name: 'testItem',
|
name: 'testItem',
|
||||||
confirmation,
|
confirmation,
|
||||||
},
|
},
|
||||||
|
@ -45,7 +45,7 @@ describe('Popover', () => {
|
||||||
|
|
||||||
cy.get('[data-item-name=testItem]')
|
cy.get('[data-item-name=testItem]')
|
||||||
.get('.ce-popover__item-label')
|
.get('.ce-popover__item-label')
|
||||||
.should('have.text', actionLabel);
|
.should('have.text', actionTitle);
|
||||||
|
|
||||||
// First click on item
|
// First click on item
|
||||||
cy.get('[data-item-name=testItem]').click();
|
cy.get('[data-item-name=testItem]').click();
|
||||||
|
@ -58,7 +58,7 @@ describe('Popover', () => {
|
||||||
// Check label has changed
|
// Check label has changed
|
||||||
cy.get('[data-item-name=testItem]')
|
cy.get('[data-item-name=testItem]')
|
||||||
.get('.ce-popover__item-label')
|
.get('.ce-popover__item-label')
|
||||||
.should('have.text', confirmActionLabel);
|
.should('have.text', confirmActionTitle);
|
||||||
|
|
||||||
// Second click
|
// Second click
|
||||||
cy.get('[data-item-name=testItem]')
|
cy.get('[data-item-name=testItem]')
|
||||||
|
@ -74,7 +74,7 @@ describe('Popover', () => {
|
||||||
const items: PopoverItem[] = [
|
const items: PopoverItem[] = [
|
||||||
{
|
{
|
||||||
icon: 'Icon',
|
icon: 'Icon',
|
||||||
label: 'Label',
|
title: 'Title',
|
||||||
isActive: true,
|
isActive: true,
|
||||||
name: 'testItem',
|
name: 'testItem',
|
||||||
onActivate: (): void => {},
|
onActivate: (): void => {},
|
||||||
|
@ -101,7 +101,7 @@ describe('Popover', () => {
|
||||||
const items: PopoverItem[] = [
|
const items: PopoverItem[] = [
|
||||||
{
|
{
|
||||||
icon: 'Icon',
|
icon: 'Icon',
|
||||||
label: 'Label',
|
title: 'Title',
|
||||||
isDisabled: true,
|
isDisabled: true,
|
||||||
name: 'testItem',
|
name: 'testItem',
|
||||||
onActivate: cy.stub(),
|
onActivate: cy.stub(),
|
||||||
|
@ -133,7 +133,7 @@ describe('Popover', () => {
|
||||||
const items: PopoverItem[] = [
|
const items: PopoverItem[] = [
|
||||||
{
|
{
|
||||||
icon: 'Icon',
|
icon: 'Icon',
|
||||||
label: 'Label',
|
title: 'Title',
|
||||||
closeOnActivate: true,
|
closeOnActivate: true,
|
||||||
name: 'testItem',
|
name: 'testItem',
|
||||||
onActivate: (): void => {},
|
onActivate: (): void => {},
|
||||||
|
@ -163,7 +163,7 @@ describe('Popover', () => {
|
||||||
const items: PopoverItem[] = [
|
const items: PopoverItem[] = [
|
||||||
{
|
{
|
||||||
icon: 'Icon',
|
icon: 'Icon',
|
||||||
label: 'Label',
|
title: 'Title',
|
||||||
toggle: true,
|
toggle: true,
|
||||||
name: 'testItem',
|
name: 'testItem',
|
||||||
onActivate: (): void => {},
|
onActivate: (): void => {},
|
||||||
|
@ -190,7 +190,7 @@ describe('Popover', () => {
|
||||||
const items: PopoverItem[] = [
|
const items: PopoverItem[] = [
|
||||||
{
|
{
|
||||||
icon: 'Icon 1',
|
icon: 'Icon 1',
|
||||||
label: 'Label 1',
|
title: 'Title 1',
|
||||||
toggle: 'group-name',
|
toggle: 'group-name',
|
||||||
name: 'testItem1',
|
name: 'testItem1',
|
||||||
isActive: true,
|
isActive: true,
|
||||||
|
@ -198,7 +198,7 @@ describe('Popover', () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: 'Icon 2',
|
icon: 'Icon 2',
|
||||||
label: 'Label 2',
|
title: 'Title 2',
|
||||||
toggle: 'group-name',
|
toggle: 'group-name',
|
||||||
name: 'testItem2',
|
name: 'testItem2',
|
||||||
onActivate: (): void => {},
|
onActivate: (): void => {},
|
||||||
|
@ -238,7 +238,7 @@ describe('Popover', () => {
|
||||||
const items: PopoverItem[] = [
|
const items: PopoverItem[] = [
|
||||||
{
|
{
|
||||||
icon: 'Icon',
|
icon: 'Icon',
|
||||||
label: 'Label',
|
title: 'Title',
|
||||||
toggle: 'key',
|
toggle: 'key',
|
||||||
name: 'testItem',
|
name: 'testItem',
|
||||||
onActivate: (): void => {},
|
onActivate: (): void => {},
|
||||||
|
|
4
types/configs/popover.d.ts
vendored
4
types/configs/popover.d.ts
vendored
|
@ -5,7 +5,7 @@ interface PopoverItemBase {
|
||||||
/**
|
/**
|
||||||
* Displayed text
|
* Displayed text
|
||||||
*/
|
*/
|
||||||
label: string;
|
title?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Item icon to be appeared near a title
|
* Item icon to be appeared near a title
|
||||||
|
@ -54,7 +54,7 @@ export interface PopoverItemWithConfirmation extends PopoverItemBase {
|
||||||
* Popover item parameters that should be applied on item activation.
|
* Popover item parameters that should be applied on item activation.
|
||||||
* May be used to ask user for confirmation before executing popover item activation handler.
|
* May be used to ask user for confirmation before executing popover item activation handler.
|
||||||
*/
|
*/
|
||||||
confirmation: Partial<PopoverItem>;
|
confirmation: PopoverItem;
|
||||||
|
|
||||||
onActivate?: never;
|
onActivate?: never;
|
||||||
}
|
}
|
||||||
|
|
27
types/tools/tool-settings.d.ts
vendored
27
types/tools/tool-settings.d.ts
vendored
|
@ -28,11 +28,36 @@ export interface ToolboxConfigEntry {
|
||||||
data?: BlockToolData
|
data?: BlockToolData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents single Tunes Menu item
|
||||||
|
*/
|
||||||
|
export type TunesMenuConfigItem = PopoverItem & {
|
||||||
|
/**
|
||||||
|
* Tune displayed text.
|
||||||
|
*/
|
||||||
|
title?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tune displayed text.
|
||||||
|
* Alias for title property
|
||||||
|
*
|
||||||
|
* @deprecated - use title property instead
|
||||||
|
*/
|
||||||
|
label?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Menu item parameters that should be applied on item activation.
|
||||||
|
* May be used to ask user for confirmation before executing menu item activation handler.
|
||||||
|
*/
|
||||||
|
confirmation?: TunesMenuConfigItem;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tool may specify its tunes configuration
|
* Tool may specify its tunes configuration
|
||||||
* that can contain either one or multiple entries
|
* that can contain either one or multiple entries
|
||||||
*/
|
*/
|
||||||
export type TunesMenuConfig = PopoverItem | PopoverItem[];
|
export type TunesMenuConfig = TunesMenuConfigItem | TunesMenuConfigItem[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object passed to the Tool's constructor by {@link EditorConfig#tools}
|
* Object passed to the Tool's constructor by {@link EditorConfig#tools}
|
||||||
|
|
|
@ -852,9 +852,10 @@
|
||||||
"@babel/helper-validator-identifier" "^7.19.1"
|
"@babel/helper-validator-identifier" "^7.19.1"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
"@codexteam/icons@^0.0.4":
|
"@codexteam/icons@0.1.0":
|
||||||
version "0.0.4"
|
version "0.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@codexteam/icons/-/icons-0.0.4.tgz#8b72dcd3f3a1b0d880bdceb2abebd74b46d3ae13"
|
resolved "https://registry.yarnpkg.com/@codexteam/icons/-/icons-0.1.0.tgz#a02885fe8699f69902d05b077b5f1cd48a2ca6b9"
|
||||||
|
integrity sha512-jW1fWnwtWzcP4FBGsaodbJY3s1ZaRU+IJy1pvJ7ygNQxkQinybJcwXoyt0a5mWwu/4w30A42EWhCrZn8lp4fdw==
|
||||||
|
|
||||||
"@codexteam/shortcuts@^1.1.1":
|
"@codexteam/shortcuts@^1.1.1":
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
|
|
Loading…
Reference in a new issue