mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-04 05:28:59 +01:00 
			
		
		
		
	chore(react/collections/table): set up context menu partially
This commit is contained in:
		
							parent
							
								
									9d877ec97a
								
							
						
					
					
						commit
						76e903a782
					
				@ -1,31 +1,35 @@
 | 
				
			|||||||
import { ColumnComponent, RowComponent, Tabulator } from "tabulator-tables";
 | 
					import { ColumnComponent, EventCallBackMethods, RowComponent, Tabulator } from "tabulator-tables";
 | 
				
			||||||
import contextMenu, { MenuItem } from "../../../menus/context_menu.js";
 | 
					import contextMenu, { MenuItem } from "../../../menus/context_menu.js";
 | 
				
			||||||
import { TableData } from "./rows.js";
 | 
					import FNote from "../../../entities/fnote.js";
 | 
				
			||||||
import branches from "../../../services/branches.js";
 | 
					 | 
				
			||||||
import { t } from "../../../services/i18n.js";
 | 
					import { t } from "../../../services/i18n.js";
 | 
				
			||||||
 | 
					import { TableData } from "./rows.js";
 | 
				
			||||||
import link_context_menu from "../../../menus/link_context_menu.js";
 | 
					import link_context_menu from "../../../menus/link_context_menu.js";
 | 
				
			||||||
import type FNote from "../../../entities/fnote.js";
 | 
					 | 
				
			||||||
import froca from "../../../services/froca.js";
 | 
					import froca from "../../../services/froca.js";
 | 
				
			||||||
import type Component from "../../../components/component.js";
 | 
					import branches from "../../../services/branches.js";
 | 
				
			||||||
 | 
					import Component from "../../../components/component.js";
 | 
				
			||||||
 | 
					import { RefObject } from "preact";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function setupContextMenu(tabulator: Tabulator, parentNote: FNote) {
 | 
					export function useContextMenu(parentNote: FNote, parentComponent: Component | null | undefined, tabulator: RefObject<Tabulator>): Partial<EventCallBackMethods> {
 | 
				
			||||||
    tabulator.on("rowContext", (e, row) => showRowContextMenu(e, row, parentNote, tabulator));
 | 
					    const events: Partial<EventCallBackMethods> = {};
 | 
				
			||||||
    tabulator.on("headerContext", (e, col) => showColumnContextMenu(e, col, parentNote, tabulator));
 | 
					    if (!tabulator || !parentComponent) return events;
 | 
				
			||||||
    tabulator.on("renderComplete", () => {
 | 
					 | 
				
			||||||
        const headerRow = tabulator.element.querySelector(".tabulator-header-contents");
 | 
					 | 
				
			||||||
        headerRow?.addEventListener("contextmenu", (e) => showHeaderContextMenu(e, tabulator));
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Pressing the expand button prevents bubbling and the context menu remains menu when it shouldn't.
 | 
					    events["rowContext"] = (e, row) => tabulator.current && showRowContextMenu(parentComponent, e as MouseEvent, row, parentNote, tabulator.current);
 | 
				
			||||||
    if (tabulator.options.dataTree) {
 | 
					    events["headerContext"] = (e, col) => tabulator.current && showColumnContextMenu(parentComponent, e as MouseEvent, col, parentNote, tabulator.current);
 | 
				
			||||||
        const dismissContextMenu = () => contextMenu.hide();
 | 
					    events["renderComplete"] = () => {
 | 
				
			||||||
        tabulator.on("dataTreeRowExpanded", dismissContextMenu);
 | 
					        const headerRow = tabulator.current?.element.querySelector(".tabulator-header-contents");
 | 
				
			||||||
        tabulator.on("dataTreeRowCollapsed", dismissContextMenu);
 | 
					        headerRow?.addEventListener("contextmenu", (e) => showHeaderContextMenu(parentComponent, e as MouseEvent, tabulator.current!));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    // Pressing the expand button prevents bubbling and the context menu remains menu when it shouldn't.
 | 
				
			||||||
 | 
					    if (tabulator.current?.options.dataTree) {
 | 
				
			||||||
 | 
					        const dismissContextMenu = () => contextMenu.hide();
 | 
				
			||||||
 | 
					        events["dataTreeRowExpanded"] = dismissContextMenu;
 | 
				
			||||||
 | 
					        events["dataTreeRowCollapsed"] = dismissContextMenu;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return events;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function showColumnContextMenu(_e: UIEvent, column: ColumnComponent, parentNote: FNote, tabulator: Tabulator) {
 | 
					function showColumnContextMenu(parentComponent: Component, e: MouseEvent, column: ColumnComponent, parentNote: FNote, tabulator: Tabulator) {
 | 
				
			||||||
    const e = _e as MouseEvent;
 | 
					 | 
				
			||||||
    const { title, field } = column.getDefinition();
 | 
					    const { title, field } = column.getDefinition();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const sorters = tabulator.getSorters();
 | 
					    const sorters = tabulator.getSorters();
 | 
				
			||||||
@ -87,16 +91,16 @@ function showColumnContextMenu(_e: UIEvent, column: ColumnComponent, parentNote:
 | 
				
			|||||||
                title: t("table_view.add-column-to-the-left"),
 | 
					                title: t("table_view.add-column-to-the-left"),
 | 
				
			||||||
                uiIcon: "bx bx-horizontal-left",
 | 
					                uiIcon: "bx bx-horizontal-left",
 | 
				
			||||||
                enabled: !column.getDefinition().frozen,
 | 
					                enabled: !column.getDefinition().frozen,
 | 
				
			||||||
                items: buildInsertSubmenu(e, column, "before"),
 | 
					                items: buildInsertSubmenu(parentComponent, column, "before"),
 | 
				
			||||||
                handler: () => getParentComponent(e)?.triggerCommand("addNewTableColumn", {
 | 
					                handler: () => parentComponent?.triggerCommand("addNewTableColumn", {
 | 
				
			||||||
                    referenceColumn: column
 | 
					                    referenceColumn: column
 | 
				
			||||||
                })
 | 
					                })
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                title: t("table_view.add-column-to-the-right"),
 | 
					                title: t("table_view.add-column-to-the-right"),
 | 
				
			||||||
                uiIcon: "bx bx-horizontal-right",
 | 
					                uiIcon: "bx bx-horizontal-right",
 | 
				
			||||||
                items: buildInsertSubmenu(e, column, "after"),
 | 
					                items: buildInsertSubmenu(parentComponent, column, "after"),
 | 
				
			||||||
                handler: () => getParentComponent(e)?.triggerCommand("addNewTableColumn", {
 | 
					                handler: () => parentComponent?.triggerCommand("addNewTableColumn", {
 | 
				
			||||||
                    referenceColumn: column,
 | 
					                    referenceColumn: column,
 | 
				
			||||||
                    direction: "after"
 | 
					                    direction: "after"
 | 
				
			||||||
                })
 | 
					                })
 | 
				
			||||||
@ -106,7 +110,7 @@ function showColumnContextMenu(_e: UIEvent, column: ColumnComponent, parentNote:
 | 
				
			|||||||
                title: t("table_view.edit-column"),
 | 
					                title: t("table_view.edit-column"),
 | 
				
			||||||
                uiIcon: "bx bxs-edit-alt",
 | 
					                uiIcon: "bx bxs-edit-alt",
 | 
				
			||||||
                enabled: isUserDefinedColumn,
 | 
					                enabled: isUserDefinedColumn,
 | 
				
			||||||
                handler: () => getParentComponent(e)?.triggerCommand("addNewTableColumn", {
 | 
					                handler: () => parentComponent?.triggerCommand("addNewTableColumn", {
 | 
				
			||||||
                    referenceColumn: column,
 | 
					                    referenceColumn: column,
 | 
				
			||||||
                    columnToEdit: column
 | 
					                    columnToEdit: column
 | 
				
			||||||
                })
 | 
					                })
 | 
				
			||||||
@ -115,7 +119,7 @@ function showColumnContextMenu(_e: UIEvent, column: ColumnComponent, parentNote:
 | 
				
			|||||||
                title: t("table_view.delete-column"),
 | 
					                title: t("table_view.delete-column"),
 | 
				
			||||||
                uiIcon: "bx bx-trash",
 | 
					                uiIcon: "bx bx-trash",
 | 
				
			||||||
                enabled: isUserDefinedColumn,
 | 
					                enabled: isUserDefinedColumn,
 | 
				
			||||||
                handler: () => getParentComponent(e)?.triggerCommand("deleteTableColumn", {
 | 
					                handler: () => parentComponent?.triggerCommand("deleteTableColumn", {
 | 
				
			||||||
                    columnToDelete: column
 | 
					                    columnToDelete: column
 | 
				
			||||||
                })
 | 
					                })
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -131,8 +135,7 @@ function showColumnContextMenu(_e: UIEvent, column: ColumnComponent, parentNote:
 | 
				
			|||||||
 * Shows a context menu which has options dedicated to the header area (the part where the columns are, but in the empty space).
 | 
					 * Shows a context menu which has options dedicated to the header area (the part where the columns are, but in the empty space).
 | 
				
			||||||
 * Provides generic options such as toggling columns.
 | 
					 * Provides generic options such as toggling columns.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
function showHeaderContextMenu(_e: Event, tabulator: Tabulator) {
 | 
					function showHeaderContextMenu(parentComponent: Component, e: MouseEvent, tabulator: Tabulator) {
 | 
				
			||||||
    const e = _e as MouseEvent;
 | 
					 | 
				
			||||||
    contextMenu.show({
 | 
					    contextMenu.show({
 | 
				
			||||||
        items: [
 | 
					        items: [
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@ -146,7 +149,7 @@ function showHeaderContextMenu(_e: Event, tabulator: Tabulator) {
 | 
				
			|||||||
                uiIcon: "bx bx-empty",
 | 
					                uiIcon: "bx bx-empty",
 | 
				
			||||||
                enabled: false
 | 
					                enabled: false
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            ...buildInsertSubmenu(e)
 | 
					            ...buildInsertSubmenu(parentComponent)
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        selectMenuItemHandler() {},
 | 
					        selectMenuItemHandler() {},
 | 
				
			||||||
        x: e.pageX,
 | 
					        x: e.pageX,
 | 
				
			||||||
@ -155,8 +158,7 @@ function showHeaderContextMenu(_e: Event, tabulator: Tabulator) {
 | 
				
			|||||||
    e.preventDefault();
 | 
					    e.preventDefault();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function showRowContextMenu(_e: UIEvent, row: RowComponent, parentNote: FNote, tabulator: Tabulator) {
 | 
					export function showRowContextMenu(parentComponent: Component, e: MouseEvent, row: RowComponent, parentNote: FNote, tabulator: Tabulator) {
 | 
				
			||||||
    const e = _e as MouseEvent;
 | 
					 | 
				
			||||||
    const rowData = row.getData() as TableData;
 | 
					    const rowData = row.getData() as TableData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let parentNoteId: string = parentNote.noteId;
 | 
					    let parentNoteId: string = parentNote.noteId;
 | 
				
			||||||
@ -175,7 +177,7 @@ export function showRowContextMenu(_e: UIEvent, row: RowComponent, parentNote: F
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                title: t("table_view.row-insert-above"),
 | 
					                title: t("table_view.row-insert-above"),
 | 
				
			||||||
                uiIcon: "bx bx-horizontal-left bx-rotate-90",
 | 
					                uiIcon: "bx bx-horizontal-left bx-rotate-90",
 | 
				
			||||||
                handler: () => getParentComponent(e)?.triggerCommand("addNewRow", {
 | 
					                handler: () => parentComponent?.triggerCommand("addNewRow", {
 | 
				
			||||||
                    parentNotePath: parentNoteId,
 | 
					                    parentNotePath: parentNoteId,
 | 
				
			||||||
                    customOpts: {
 | 
					                    customOpts: {
 | 
				
			||||||
                        target: "before",
 | 
					                        target: "before",
 | 
				
			||||||
@ -189,7 +191,7 @@ export function showRowContextMenu(_e: UIEvent, row: RowComponent, parentNote: F
 | 
				
			|||||||
                handler: async () => {
 | 
					                handler: async () => {
 | 
				
			||||||
                    const branchId = row.getData().branchId;
 | 
					                    const branchId = row.getData().branchId;
 | 
				
			||||||
                    const note = await froca.getBranch(branchId)?.getNote();
 | 
					                    const note = await froca.getBranch(branchId)?.getNote();
 | 
				
			||||||
                    getParentComponent(e)?.triggerCommand("addNewRow", {
 | 
					                    parentComponent?.triggerCommand("addNewRow", {
 | 
				
			||||||
                        parentNotePath: note?.noteId,
 | 
					                        parentNotePath: note?.noteId,
 | 
				
			||||||
                        customOpts: {
 | 
					                        customOpts: {
 | 
				
			||||||
                            target: "after",
 | 
					                            target: "after",
 | 
				
			||||||
@ -201,7 +203,7 @@ export function showRowContextMenu(_e: UIEvent, row: RowComponent, parentNote: F
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                title: t("table_view.row-insert-below"),
 | 
					                title: t("table_view.row-insert-below"),
 | 
				
			||||||
                uiIcon: "bx bx-horizontal-left bx-rotate-270",
 | 
					                uiIcon: "bx bx-horizontal-left bx-rotate-270",
 | 
				
			||||||
                handler: () => getParentComponent(e)?.triggerCommand("addNewRow", {
 | 
					                handler: () => parentComponent?.triggerCommand("addNewRow", {
 | 
				
			||||||
                    parentNotePath: parentNoteId,
 | 
					                    parentNotePath: parentNoteId,
 | 
				
			||||||
                    customOpts: {
 | 
					                    customOpts: {
 | 
				
			||||||
                        target: "after",
 | 
					                        target: "after",
 | 
				
			||||||
@ -223,16 +225,6 @@ export function showRowContextMenu(_e: UIEvent, row: RowComponent, parentNote: F
 | 
				
			|||||||
    e.preventDefault();
 | 
					    e.preventDefault();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getParentComponent(e: MouseEvent) {
 | 
					 | 
				
			||||||
    if (!e.target) {
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return $(e.target)
 | 
					 | 
				
			||||||
        .closest(".component")
 | 
					 | 
				
			||||||
        .prop("component") as Component;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function buildColumnItems(tabulator: Tabulator) {
 | 
					function buildColumnItems(tabulator: Tabulator) {
 | 
				
			||||||
    const items: MenuItem<unknown>[] = [];
 | 
					    const items: MenuItem<unknown>[] = [];
 | 
				
			||||||
    for (const column of tabulator.getColumns()) {
 | 
					    for (const column of tabulator.getColumns()) {
 | 
				
			||||||
@ -249,13 +241,13 @@ function buildColumnItems(tabulator: Tabulator) {
 | 
				
			|||||||
    return items;
 | 
					    return items;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function buildInsertSubmenu(e: MouseEvent, referenceColumn?: ColumnComponent, direction?: "before" | "after"): MenuItem<unknown>[] {
 | 
					function buildInsertSubmenu(parentComponent: Component, referenceColumn?: ColumnComponent, direction?: "before" | "after"): MenuItem<unknown>[] {
 | 
				
			||||||
    return [
 | 
					    return [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            title: t("table_view.new-column-label"),
 | 
					            title: t("table_view.new-column-label"),
 | 
				
			||||||
            uiIcon: "bx bx-hash",
 | 
					            uiIcon: "bx bx-hash",
 | 
				
			||||||
            handler: () => {
 | 
					            handler: () => {
 | 
				
			||||||
                getParentComponent(e)?.triggerCommand("addNewTableColumn", {
 | 
					                parentComponent?.triggerCommand("addNewTableColumn", {
 | 
				
			||||||
                    referenceColumn,
 | 
					                    referenceColumn,
 | 
				
			||||||
                    type: "label",
 | 
					                    type: "label",
 | 
				
			||||||
                    direction
 | 
					                    direction
 | 
				
			||||||
@ -266,7 +258,7 @@ function buildInsertSubmenu(e: MouseEvent, referenceColumn?: ColumnComponent, di
 | 
				
			|||||||
            title: t("table_view.new-column-relation"),
 | 
					            title: t("table_view.new-column-relation"),
 | 
				
			||||||
            uiIcon: "bx bx-transfer",
 | 
					            uiIcon: "bx bx-transfer",
 | 
				
			||||||
            handler: () => {
 | 
					            handler: () => {
 | 
				
			||||||
                getParentComponent(e)?.triggerCommand("addNewTableColumn", {
 | 
					                parentComponent?.triggerCommand("addNewTableColumn", {
 | 
				
			||||||
                    referenceColumn,
 | 
					                    referenceColumn,
 | 
				
			||||||
                    type: "relation",
 | 
					                    type: "relation",
 | 
				
			||||||
                    direction
 | 
					                    direction
 | 
				
			||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import { useEffect, useState } from "preact/hooks";
 | 
					import { useContext, useEffect, useRef, useState } from "preact/hooks";
 | 
				
			||||||
import { ViewModeProps } from "../interface";
 | 
					import { ViewModeProps } from "../interface";
 | 
				
			||||||
import "./index.css";
 | 
					import "./index.css";
 | 
				
			||||||
import { buildColumnDefinitions } from "./columns";
 | 
					import { buildColumnDefinitions } from "./columns";
 | 
				
			||||||
@ -6,8 +6,9 @@ import getAttributeDefinitionInformation, { buildRowDefinitions, TableData } fro
 | 
				
			|||||||
import { useNoteLabelInt } from "../../react/hooks";
 | 
					import { useNoteLabelInt } from "../../react/hooks";
 | 
				
			||||||
import { canReorderRows } from "../../view_widgets/table_view/dragging";
 | 
					import { canReorderRows } from "../../view_widgets/table_view/dragging";
 | 
				
			||||||
import Tabulator from "./tabulator";
 | 
					import Tabulator from "./tabulator";
 | 
				
			||||||
import {SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MoveRowsModule, ColumnDefinition, DataTreeModule} from 'tabulator-tables';
 | 
					import { Tabulator as VanillaTabulator, SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MoveRowsModule, ColumnDefinition, DataTreeModule} from 'tabulator-tables';
 | 
				
			||||||
 | 
					import { useContextMenu } from "./context_menu";
 | 
				
			||||||
 | 
					import { ParentComponent } from "../../react/react_utils";
 | 
				
			||||||
interface TableConfig {
 | 
					interface TableConfig {
 | 
				
			||||||
    tableData?: {
 | 
					    tableData?: {
 | 
				
			||||||
        columns?: ColumnDefinition[];
 | 
					        columns?: ColumnDefinition[];
 | 
				
			||||||
@ -18,6 +19,8 @@ export default function TableView({ note, viewConfig }: ViewModeProps<TableConfi
 | 
				
			|||||||
    const [ maxDepth ] = useNoteLabelInt(note, "maxNestingDepth") ?? -1;
 | 
					    const [ maxDepth ] = useNoteLabelInt(note, "maxNestingDepth") ?? -1;
 | 
				
			||||||
    const [ columnDefs, setColumnDefs ] = useState<ColumnDefinition[]>();
 | 
					    const [ columnDefs, setColumnDefs ] = useState<ColumnDefinition[]>();
 | 
				
			||||||
    const [ rowData, setRowData ] = useState<TableData[]>();
 | 
					    const [ rowData, setRowData ] = useState<TableData[]>();
 | 
				
			||||||
 | 
					    const tabulatorRef = useRef<VanillaTabulator>(null);
 | 
				
			||||||
 | 
					    const parentComponent = useContext(ParentComponent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    useEffect(() => {
 | 
					    useEffect(() => {
 | 
				
			||||||
        const info = getAttributeDefinitionInformation(note);
 | 
					        const info = getAttributeDefinitionInformation(note);
 | 
				
			||||||
@ -34,14 +37,18 @@ export default function TableView({ note, viewConfig }: ViewModeProps<TableConfi
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }, [ note ]);
 | 
					    }, [ note ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const contextMenuEvents = useContextMenu(note, parentComponent, tabulatorRef);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <div className="table-view">
 | 
					        <div className="table-view">
 | 
				
			||||||
            {columnDefs && (
 | 
					            {columnDefs && (
 | 
				
			||||||
                <Tabulator
 | 
					                <Tabulator
 | 
				
			||||||
 | 
					                    tabulatorRef={tabulatorRef}
 | 
				
			||||||
                    className="table-view-container"
 | 
					                    className="table-view-container"
 | 
				
			||||||
                    columns={columnDefs}
 | 
					                    columns={columnDefs}
 | 
				
			||||||
                    data={rowData}
 | 
					                    data={rowData}
 | 
				
			||||||
                    modules={[ SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MoveRowsModule, DataTreeModule ]}
 | 
					                    modules={[ SortModule, FormatModule, InteractionModule, EditModule, ResizeColumnsModule, FrozenColumnsModule, PersistenceModule, MoveColumnsModule, MoveRowsModule, DataTreeModule ]}
 | 
				
			||||||
 | 
					                    {...contextMenuEvents}
 | 
				
			||||||
                />
 | 
					                />
 | 
				
			||||||
            )}
 | 
					            )}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,27 +1,29 @@
 | 
				
			|||||||
import { useEffect, useRef } from "preact/hooks";
 | 
					import { useEffect, useLayoutEffect, useRef } from "preact/hooks";
 | 
				
			||||||
import { ColumnDefinition, Module, Tabulator as VanillaTabulator } from "tabulator-tables";
 | 
					import { ColumnDefinition, EventCallBackMethods, Module, Tabulator as VanillaTabulator } from "tabulator-tables";
 | 
				
			||||||
import "tabulator-tables/dist/css/tabulator.css";
 | 
					import "tabulator-tables/dist/css/tabulator.css";
 | 
				
			||||||
import "../../../../src/stylesheets/table.css";
 | 
					import "../../../../src/stylesheets/table.css";
 | 
				
			||||||
 | 
					import { RefObject } from "preact";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface TableProps<T> {
 | 
					interface TableProps<T> extends Partial<EventCallBackMethods> {
 | 
				
			||||||
 | 
					    tabulatorRef: RefObject<VanillaTabulator>;
 | 
				
			||||||
    className?: string;
 | 
					    className?: string;
 | 
				
			||||||
    columns: ColumnDefinition[];
 | 
					    columns: ColumnDefinition[];
 | 
				
			||||||
    data?: T[];
 | 
					    data?: T[];
 | 
				
			||||||
    modules?: (new (table: VanillaTabulator) => Module)[];
 | 
					    modules?: (new (table: VanillaTabulator) => Module)[];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function Tabulator<T>({ className, columns, data, modules }: TableProps<T>) {
 | 
					export default function Tabulator<T>({ className, columns, data, modules, tabulatorRef: externalTabulatorRef, ...events }: TableProps<T>) {
 | 
				
			||||||
    const containerRef = useRef<HTMLDivElement>(null);
 | 
					    const containerRef = useRef<HTMLDivElement>(null);
 | 
				
			||||||
    const tabulatorRef = useRef<VanillaTabulator>(null);
 | 
					    const tabulatorRef = useRef<VanillaTabulator>(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    useEffect(() => {
 | 
					    useLayoutEffect(() => {
 | 
				
			||||||
        if (!modules) return;
 | 
					        if (!modules) return;
 | 
				
			||||||
        for (const module of modules) {
 | 
					        for (const module of modules) {
 | 
				
			||||||
            VanillaTabulator.registerModule(module);
 | 
					            VanillaTabulator.registerModule(module);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }, [modules]);
 | 
					    }, [modules]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    useEffect(() => {
 | 
					    useLayoutEffect(() => {
 | 
				
			||||||
        if (!containerRef.current) return;
 | 
					        if (!containerRef.current) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const tabulator = new VanillaTabulator(containerRef.current, {
 | 
					        const tabulator = new VanillaTabulator(containerRef.current, {
 | 
				
			||||||
@ -30,10 +32,26 @@ export default function Tabulator<T>({ className, columns, data, modules }: Tabl
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        tabulatorRef.current = tabulator;
 | 
					        tabulatorRef.current = tabulator;
 | 
				
			||||||
 | 
					        externalTabulatorRef.current = tabulator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return () => tabulator.destroy();
 | 
					        return () => tabulator.destroy();
 | 
				
			||||||
    }, []);
 | 
					    }, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    useEffect(() => {
 | 
				
			||||||
 | 
					        const tabulator = tabulatorRef.current;
 | 
				
			||||||
 | 
					        if (!tabulator) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (const [ eventName, handler ] of Object.entries(events)) {
 | 
				
			||||||
 | 
					            tabulator.on(eventName as keyof EventCallBackMethods, handler);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return () => {
 | 
				
			||||||
 | 
					            for (const [ eventName, handler ] of Object.entries(events)) {
 | 
				
			||||||
 | 
					                tabulator.off(eventName as keyof EventCallBackMethods, handler);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }, Object.values(events));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <div ref={containerRef} className={className} />
 | 
					        <div ref={containerRef} className={className} />
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user