Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Max level depth implementation #80

Open
ccppoo opened this issue Aug 11, 2024 · 1 comment · May be fixed by #104
Open

Max level depth implementation #80

ccppoo opened this issue Aug 11, 2024 · 1 comment · May be fixed by #104

Comments

@ccppoo
Copy link

ccppoo commented Aug 11, 2024

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.

@collimarco
Copy link

+1 for this feature: it would be really useful to limit user input to 1 or 2 levels at most

@e11sy e11sy linked a pull request Nov 3, 2024 that will close this issue
13 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants