import { BlockToolConstructorOptions } from '@editorjs/editorjs/types/tools';
import type { NestedListParams } from '@editorjs/nested-list';
import NestedList from '@editorjs/nested-list';
// copied from original code == start ==
type ListDataStyle = 'ordered' | 'unordered';
interface ListItem {
/**
* list item text content
*/
content: string;
/**
* sublist items
*/
items: ListItem[];
}
interface ListData {
/**
* list type 'ordered' or 'unordered'
*/
style: ListDataStyle;
/**
* list of first-level elements
*/
items: ListItem[];
}
interface NestedListConfig {
/**
* default list style: ordered or unordered
* default is unordered
*/
defaultStyle?: ListDataStyle;
}
// copied from original code == end ==
// this is also implemented in package but couldn't import from dist source, so I just copied it
function isHtmlElement(node: Node): boolean {
return node instanceof HTMLElement;
}
// interface for config,
interface NestedListCustomParams {
maxDepth?: number;
}
// extending constructor params
export type _NestedListParams = BlockToolConstructorOptions<
ListData,
NestedListConfig & NestedListCustomParams
>;
export default class LimitedNestedList extends NestedList {
constructor({ data, config: _config, api, readOnly }: _NestedListParams) {
const { maxDepth, ...config } = _config;
// need to cast to original NestedListParams interface
super({ data, config, api, readOnly } as NestedListParams);
if (!maxDepth || maxDepth < 1) {
// min : 1 (could nest like : 1.1, 1.2, 2.1, 2.2, ... )
// default : 2 (could nest like : 1.1.1, 1.2.3, ... )
this.maxDepth = 2;
return;
}
this.maxDepth = maxDepth;
}
private maxDepth: number;
addTab(event: KeyboardEvent): void {
// same as original code == start ==
event.stopPropagation();
event.preventDefault();
const currentItem = this.currentItem;
if (!currentItem) {
return;
}
const prevItem = currentItem.previousSibling;
if (!prevItem) {
return;
}
if (!isHtmlElement(prevItem)) {
return;
}
const isFirstChild = !prevItem;
if (isFirstChild) {
return;
}
// same as original code == end ==
// find until element class name is : `ce-block__content`
const maxHTMLDepth = 2 + 3 * (this.maxDepth - 1); // 0, 2, 5, 8, 11, ...
const rootName = 'ce-block__content';
let HTMLDepth = 0;
let element: Element | null = currentItem;
while (element?.className !== rootName) {
element = element?.parentElement || null;
HTMLDepth += 1;
if (HTMLDepth > maxHTMLDepth) return;
}
return super.addTab(event);
}
}
const nestedListTool = {
class: LimitedNestedList,
inlineToolbar: true,
config: {
defaultStyle: 'ordered',
},
};
....
const editorConfig = {
tools: {
list : nestedListTool
....
}
}
I tried to make as finding root element, or Block by using block data
but it was quite hard to override methods, and accessing private variables.
I tried to make as finding root element, or
Blockby using block databut it was quite hard to override methods, and accessing private variables.