mirror of
https://github.com/codex-team/editor.js
synced 2024-06-10 01:42:29 +02:00
Remove customcontent parameter from popover
This commit is contained in:
parent
392ff54843
commit
0d506c2941
|
@ -617,22 +617,22 @@ export default class Block extends EventsDispatcher<BlockEvents> {
|
|||
public getTunes(): {
|
||||
toolTunes: PopoverItemParams[];
|
||||
commonTunes: PopoverItemParams[];
|
||||
customHtmlTunes: HTMLElement
|
||||
} {
|
||||
const customHtmlTunesContainer = document.createElement('div');
|
||||
const toolTunesPopoverParams: TunesMenuConfigItem[] = [];
|
||||
const commonTunesPopoverParams: TunesMenuConfigItem[] = [];
|
||||
|
||||
/** Tool's tunes: may be defined as return value of optional renderSettings method */
|
||||
const tunesDefinedInTool = typeof this.toolInstance.renderSettings === 'function' ? this.toolInstance.renderSettings() : [];
|
||||
|
||||
/** Separate custom html from Popover items params for tool's tunes */
|
||||
const {
|
||||
items: toolTunesPopoverParams,
|
||||
htmlElement: toolTunesHtmlElement,
|
||||
} = this.getTunesDataSegregated(tunesDefinedInTool);
|
||||
|
||||
if (toolTunesHtmlElement !== undefined) {
|
||||
customHtmlTunesContainer.appendChild(toolTunesHtmlElement);
|
||||
if ($.isElement(tunesDefinedInTool)) {
|
||||
toolTunesPopoverParams.push({
|
||||
type: 'custom',
|
||||
element: tunesDefinedInTool,
|
||||
});
|
||||
} else if (Array.isArray(tunesDefinedInTool)) {
|
||||
toolTunesPopoverParams.push(...tunesDefinedInTool);
|
||||
} else {
|
||||
toolTunesPopoverParams.push(tunesDefinedInTool);
|
||||
}
|
||||
|
||||
/** Common tunes: combination of default tunes (move up, move down, delete) and third-party tunes connected via tunes api */
|
||||
|
@ -643,24 +643,21 @@ export default class Block extends EventsDispatcher<BlockEvents> {
|
|||
|
||||
/** Separate custom html from Popover items params for common tunes */
|
||||
commonTunes.forEach(tuneConfig => {
|
||||
const {
|
||||
items,
|
||||
htmlElement,
|
||||
} = this.getTunesDataSegregated(tuneConfig);
|
||||
|
||||
if (htmlElement !== undefined) {
|
||||
customHtmlTunesContainer.appendChild(htmlElement);
|
||||
}
|
||||
|
||||
if (items !== undefined) {
|
||||
commonTunesPopoverParams.push(...items);
|
||||
if ($.isElement(tuneConfig)) {
|
||||
commonTunesPopoverParams.push({
|
||||
type: 'custom',
|
||||
element: tuneConfig,
|
||||
});
|
||||
} else if (Array.isArray(tuneConfig)) {
|
||||
commonTunesPopoverParams.push(...tuneConfig);
|
||||
} else {
|
||||
commonTunesPopoverParams.push(tuneConfig);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
toolTunes: toolTunesPopoverParams,
|
||||
commonTunes: commonTunesPopoverParams,
|
||||
customHtmlTunes: customHtmlTunesContainer,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ export default class BlockSettings extends Module<BlockSettingsNodes> {
|
|||
this.Editor.BlockSelection.clearCache();
|
||||
|
||||
/** Get tool's settings data */
|
||||
const { toolTunes, commonTunes, customHtmlTunes } = targetBlock.getTunes();
|
||||
const { toolTunes, commonTunes } = targetBlock.getTunes();
|
||||
|
||||
/** Tell to subscribers that block settings is opened */
|
||||
this.eventsDispatcher.emit(this.events.opened);
|
||||
|
@ -134,8 +134,6 @@ export default class BlockSettings extends Module<BlockSettingsNodes> {
|
|||
this.popover = new PopoverClass({
|
||||
searchable: true,
|
||||
items: await this.getTunesItems(targetBlock, commonTunes, toolTunes),
|
||||
customContent: customHtmlTunes,
|
||||
customContentFlippableItems: this.getControls(customHtmlTunes),
|
||||
scopeElement: this.Editor.API.methods.ui.nodes.redactor,
|
||||
messages: {
|
||||
nothingFound: I18n.ui(I18nInternalNS.ui.popover, 'Nothing found'),
|
||||
|
|
|
@ -3,7 +3,7 @@ import { BlockToolAPI } from '../block';
|
|||
import Shortcuts from '../utils/shortcuts';
|
||||
import BlockTool from '../tools/block';
|
||||
import ToolsCollection from '../tools/collection';
|
||||
import { API, BlockToolData, ToolboxConfigEntry, PopoverItem, BlockAPI } from '../../../types';
|
||||
import { API, BlockToolData, ToolboxConfigEntry, PopoverItemParams, BlockAPI } from '../../../types';
|
||||
import EventsDispatcher from '../utils/events';
|
||||
import I18n from '../i18n';
|
||||
import { I18nInternalNS } from '../i18n/namespace-internal';
|
||||
|
@ -303,11 +303,11 @@ export default class Toolbox extends EventsDispatcher<ToolboxEventMap> {
|
|||
* Returns list of items that will be displayed in toolbox
|
||||
*/
|
||||
@_.cacheable
|
||||
private get toolboxItemsToBeDisplayed(): PopoverItem[] {
|
||||
private get toolboxItemsToBeDisplayed(): PopoverItemParams[] {
|
||||
/**
|
||||
* Maps tool data to popover item structure
|
||||
*/
|
||||
const toPopoverItem = (toolboxItem: ToolboxConfigEntry, tool: BlockTool): PopoverItem => {
|
||||
const toPopoverItem = (toolboxItem: ToolboxConfigEntry, tool: BlockTool): PopoverItemParams => {
|
||||
return {
|
||||
icon: toolboxItem.icon,
|
||||
title: I18n.t(I18nInternalNS.toolNames, toolboxItem.title || _.capitalize(tool.name)),
|
||||
|
@ -320,7 +320,7 @@ export default class Toolbox extends EventsDispatcher<ToolboxEventMap> {
|
|||
};
|
||||
|
||||
return this.toolsToBeDisplayed
|
||||
.reduce<PopoverItem[]>((result, tool) => {
|
||||
.reduce<PopoverItemParams[]>((result, tool) => {
|
||||
if (Array.isArray(tool.toolbox)) {
|
||||
tool.toolbox.forEach(item => {
|
||||
result.push(toPopoverItem(item, tool));
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { PopoverItem } from '../popover-item';
|
||||
import { PopoverItemCustomParams } from '../popover-item.types';
|
||||
import { css } from './popover-item-custom.const';
|
||||
import Dom from '../../../../../dom';
|
||||
|
||||
/**
|
||||
* Represents popover item with custom html content
|
||||
|
@ -20,8 +21,10 @@ export class PopoverItemCustom extends PopoverItem {
|
|||
super();
|
||||
|
||||
this.nodes = {
|
||||
root: params.element,
|
||||
root: Dom.make('div', css.root),
|
||||
};
|
||||
|
||||
this.nodes.root.appendChild(params.element);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -39,4 +42,16 @@ export class PopoverItemCustom extends PopoverItem {
|
|||
public toggleHidden(isHidden: boolean): void {
|
||||
this.nodes.root?.classList.toggle(css.hidden, isHidden);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of buttons and inputs inside custom content
|
||||
*/
|
||||
public getControls(): HTMLElement[] {
|
||||
/** Query buttons and inputs inside custom html */
|
||||
const controls = this.nodes.root.querySelectorAll<HTMLElement>(
|
||||
`button, ${Dom.allInputsSelector}`
|
||||
);
|
||||
|
||||
return Array.from(controls);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,10 +28,9 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
|
|||
protected nodes: Nodes;
|
||||
|
||||
/**
|
||||
* List of usual interactive popover items that can be clicked, hovered, etc.
|
||||
* (excluding separators)
|
||||
* List of default popover items that can are searchable and may have confirmation state
|
||||
*/
|
||||
protected get itemsInteractive(): PopoverItemDefault[] {
|
||||
protected get itemsDefault(): PopoverItemDefault[] {
|
||||
return this.items.filter(item => item instanceof PopoverItemDefault) as PopoverItemDefault[];
|
||||
}
|
||||
|
||||
|
@ -98,10 +97,6 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
|
|||
|
||||
this.nodes.popover.appendChild(this.nodes.popoverContainer);
|
||||
|
||||
if (params.customContent) {
|
||||
this.addCustomContent(params.customContent);
|
||||
}
|
||||
|
||||
if (params.searchable) {
|
||||
this.addSearch();
|
||||
}
|
||||
|
@ -132,7 +127,7 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
|
|||
this.nodes.popover.classList.remove(css.popoverOpened);
|
||||
this.nodes.popover.classList.remove(css.popoverOpenTop);
|
||||
|
||||
this.itemsInteractive.forEach(item => item.reset());
|
||||
this.itemsDefault.forEach(item => item.reset());
|
||||
|
||||
if (this.search !== undefined) {
|
||||
this.search.clear();
|
||||
|
@ -172,7 +167,7 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
|
|||
* @param event - event to retrieve popover item from
|
||||
*/
|
||||
protected getTargetItem(event: Event): PopoverItemDefault | undefined {
|
||||
return this.itemsInteractive.find(el => {
|
||||
return this.itemsDefault.find(el => {
|
||||
const itemEl = el.getElement();
|
||||
|
||||
if (itemEl === null) {
|
||||
|
@ -207,7 +202,6 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
|
|||
item.toggleHidden(isHidden);
|
||||
});
|
||||
this.toggleNothingFoundMessage(isNothingFound);
|
||||
this.toggleCustomContent(isEmptyQuery);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -215,7 +209,7 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
|
|||
*/
|
||||
private addSearch(): void {
|
||||
this.search = new SearchInput({
|
||||
items: this.itemsInteractive,
|
||||
items: this.itemsDefault,
|
||||
placeholder: this.messages.search,
|
||||
});
|
||||
|
||||
|
@ -228,17 +222,6 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
|
|||
this.nodes.popoverContainer.insertBefore(searchElement, this.nodes.popoverContainer.firstChild);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds custom html content to the popover
|
||||
*
|
||||
* @param content - html content to append
|
||||
*/
|
||||
private addCustomContent(content: HTMLElement): void {
|
||||
this.nodes.customContent = content;
|
||||
this.nodes.customContent.classList.add(css.customContent);
|
||||
this.nodes.popoverContainer.insertBefore(content, this.nodes.popoverContainer.firstChild);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles clicks inside popover
|
||||
*
|
||||
|
@ -262,7 +245,7 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
|
|||
}
|
||||
|
||||
/** Cleanup other items state */
|
||||
this.itemsInteractive.filter(x => x !== item).forEach(x => x.reset());
|
||||
this.itemsDefault.filter(x => x !== item).forEach(x => x.reset());
|
||||
|
||||
item.handleClick();
|
||||
|
||||
|
@ -282,15 +265,6 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
|
|||
this.nodes.nothingFoundMessage.classList.toggle(css.nothingFoundMessageDisplayed, isDisplayed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles custom content visibility
|
||||
*
|
||||
* @param isDisplayed - true if custom content should be displayed
|
||||
*/
|
||||
private toggleCustomContent(isDisplayed: boolean): void {
|
||||
this.nodes.customContent?.classList.toggle(css.customContentHidden, isDisplayed);
|
||||
}
|
||||
|
||||
/**
|
||||
* - Toggles item active state, if clicked popover item has property 'toggle' set to true.
|
||||
*
|
||||
|
@ -305,7 +279,7 @@ export abstract class PopoverAbstract<Nodes extends PopoverNodes = PopoverNodes>
|
|||
}
|
||||
|
||||
if (typeof clickedItem.toggle === 'string') {
|
||||
const itemsInToggleGroup = this.itemsInteractive.filter(item => item.toggle === clickedItem.toggle);
|
||||
const itemsInToggleGroup = this.itemsDefault.filter(item => item.toggle === clickedItem.toggle);
|
||||
|
||||
/** If there's only one item in toggle group, toggle it */
|
||||
if (itemsInToggleGroup.length === 1) {
|
||||
|
|
|
@ -7,6 +7,7 @@ import { css } from './popover.const';
|
|||
import { SearchInputEvent, SearchableItem } from './components/search-input';
|
||||
import { cacheable } from '../../utils';
|
||||
import { PopoverItemDefault } from './components/popover-item';
|
||||
import { PopoverItemCustom } from './components/popover-item/popover-item-custom/popover-item-custom';
|
||||
|
||||
/**
|
||||
* Desktop popover.
|
||||
|
@ -18,11 +19,6 @@ export class PopoverDesktop extends PopoverAbstract {
|
|||
*/
|
||||
public flipper: Flipper;
|
||||
|
||||
/**
|
||||
* List of html elements inside custom content area that should be available for keyboard navigation
|
||||
*/
|
||||
private customContentFlippableItems: HTMLElement[] | undefined;
|
||||
|
||||
/**
|
||||
* Reference to nested popover if exists.
|
||||
* Undefined by default, PopoverDesktop when exists and null after destroyed.
|
||||
|
@ -63,10 +59,6 @@ export class PopoverDesktop extends PopoverAbstract {
|
|||
this.nodes.popover.classList.add(css.popoverNested);
|
||||
}
|
||||
|
||||
if (params.customContentFlippableItems) {
|
||||
this.customContentFlippableItems = params.customContentFlippableItems;
|
||||
}
|
||||
|
||||
if (params.scopeElement !== undefined) {
|
||||
this.scopeElement = params.scopeElement;
|
||||
}
|
||||
|
@ -283,23 +275,28 @@ export class PopoverDesktop extends PopoverAbstract {
|
|||
|
||||
/**
|
||||
* Returns list of elements available for keyboard navigation.
|
||||
* Contains both usual popover items elements and custom html content.
|
||||
*/
|
||||
private get flippableElements(): HTMLElement[] {
|
||||
const popoverItemsElements = this.itemsInteractive.map(item => item.getElement());
|
||||
const customContentControlsElements = this.customContentFlippableItems || [];
|
||||
const result = this.items
|
||||
.map(item => {
|
||||
if (item instanceof PopoverItemDefault) {
|
||||
return item.getElement();
|
||||
}
|
||||
if (item instanceof PopoverItemCustom) {
|
||||
return item.getControls();
|
||||
}
|
||||
})
|
||||
.flat()
|
||||
.filter(item => item !== undefined && item !== null);
|
||||
|
||||
/**
|
||||
* Combine elements inside custom content area with popover items elements
|
||||
*/
|
||||
return customContentControlsElements.concat(popoverItemsElements as HTMLElement[]);
|
||||
return result as HTMLElement[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on flipper navigation
|
||||
*/
|
||||
private onFlip = (): void => {
|
||||
const focusedItem = this.itemsInteractive.find(item => item.isFocused);
|
||||
const focusedItem = this.itemsDefault.find(item => item.isFocused);
|
||||
|
||||
focusedItem?.onFocus();
|
||||
};
|
||||
|
|
|
@ -15,16 +15,6 @@ export interface PopoverParams {
|
|||
*/
|
||||
scopeElement?: HTMLElement;
|
||||
|
||||
/**
|
||||
* Arbitrary html element to be inserted before items list
|
||||
*/
|
||||
customContent?: HTMLElement;
|
||||
|
||||
/**
|
||||
* List of html elements inside custom content area that should be available for keyboard navigation
|
||||
*/
|
||||
customContentFlippableItems?: HTMLElement[];
|
||||
|
||||
/**
|
||||
* True if popover should contain search field
|
||||
*/
|
||||
|
@ -92,9 +82,6 @@ export interface PopoverNodes {
|
|||
|
||||
/** Popover items wrapper */
|
||||
items: HTMLElement;
|
||||
|
||||
/** Custom html content area */
|
||||
customContent: HTMLElement | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
9
types/tools/tool-settings.d.ts
vendored
9
types/tools/tool-settings.d.ts
vendored
|
@ -1,6 +1,6 @@
|
|||
import { ToolConfig } from './tool-config';
|
||||
import { ToolConstructable, BlockToolData } from './index';
|
||||
import { PopoverItemDefaultParams, PopoverItemSeparatorParams, PopoverItemParams } from '../configs';
|
||||
import { PopoverItemDefaultParams, PopoverItemSeparatorParams, PopoverItemParams, PopoverItemCustomParams } from '../configs';
|
||||
|
||||
/**
|
||||
* Tool may specify its toolbox configuration
|
||||
|
@ -57,10 +57,15 @@ export type TunesMenuConfigDefaultItem = PopoverItemDefaultParams & {
|
|||
*/
|
||||
export type TunesMenuConfigSeparatorItem = PopoverItemSeparatorParams;
|
||||
|
||||
/**
|
||||
* Represents single Tunes Menu item with custom HTML contect
|
||||
*/
|
||||
export type TunesMenuConfigCustomItem = PopoverItemCustomParams;
|
||||
|
||||
/**
|
||||
* Union of all Tunes Menu item types
|
||||
*/
|
||||
export type TunesMenuConfigItem = TunesMenuConfigDefaultItem | TunesMenuConfigSeparatorItem;
|
||||
export type TunesMenuConfigItem = TunesMenuConfigDefaultItem | TunesMenuConfigSeparatorItem | TunesMenuConfigCustomItem;
|
||||
|
||||
/**
|
||||
* Tool may specify its tunes configuration
|
||||
|
|
Loading…
Reference in a new issue