UNPKG

wunderbaum

Version:

JavaScript tree/grid/treegrid control.

1,347 lines (1,260 loc) 43.7 kB
/*! * Wunderbaum - types * Copyright (c) 2021-2025, Martin Wendt. Released under the MIT license. * @VERSION, @DATE (https://github.com/mar10/wunderbaum) */ import { WunderbaumNode } from "./wb_node"; import { Wunderbaum } from "./wunderbaum"; import { WunderbaumOptions } from "./wb_options"; /** A value that can either be true, false, or undefined. */ export type TristateType = boolean | undefined; /** Show/hide checkbox or display a radiobutton icon instead. */ export type CheckboxOption = boolean | "radio"; /** A value that can either be true, false, or undefined. */ export type SortOrderType = "asc" | "desc" | undefined; /** An icon may either be * a string-tag that references an entry in the `iconMap` (e.g. `"folderOpen"`)), * an HTML string that contains a `<` and is used as-is, * an image URL string that contains a `.` or `/` and is rendered as `<img src='...'>`, * a class string such as `"bi bi-folder"`, * or a boolean value that indicates if the default icon should be used or hidden. */ export type IconOption = boolean | string; /** Show/hide default tooltip or display a string. */ export type TooltipOption = boolean | string; /* * `source` can be a url, an array of nodes, or an object with `url`, ... */ export interface SourceAjaxType { url: string; params?: any; body?: any; options?: RequestInit; } export type SourceListType = Array<WbNodeData>; export interface SourceObjectType { _format?: "nested" | "flat"; _version?: number; types?: NodeTypeDefinitionMap; columns?: ColumnDefinitionList; children: SourceListType; _keyMap?: { [key: string]: string }; _positional?: Array<string>; // _typeList?: Array<string>; _valueMap?: { [key: string]: Array<string> }; } /** Possible initilization for tree nodes. */ export type SourceType = | string | SourceListType | SourceAjaxType | SourceObjectType; /** Passed to `find...()` methods. Should return true if node matches. */ export type MatcherCallback = (node: WunderbaumNode) => boolean; /** Used for `tree.iconBadge` event. */ export type WbIconBadgeCallback = ( e: WbIconBadgeEventType ) => WbIconBadgeEventResultType; /** Passed to `sortChildren()` methods. Should return -1, 0, or 1. */ export type SortCallback = (a: WunderbaumNode, b: WunderbaumNode) => number; /** When set as option, called when the value is needed (e.g. `colspan` type definition). */ export type BoolOptionResolver = (node: WunderbaumNode) => boolean; /** When set as option, called when the value is needed (e.g. `icon` type definition). */ export type BoolOrStringOptionResolver = ( node: WunderbaumNode ) => boolean | string; /** A callback that receives a node instance and returns an arbitrary value type. */ export type NodeAnyCallback = (node: WunderbaumNode) => any; /** A callback that receives a node instance and returns a string value. */ export type NodeStringCallback = (node: WunderbaumNode) => string; /** A callback that receives a node instance and property name returns a value. */ export type NodePropertyGetterCallback = ( node: WunderbaumNode, propName: string ) => any; /** A callback that receives a node instance and returns an iteration modifier. */ export type NodeVisitCallback = (node: WunderbaumNode) => NodeVisitResponse; /** * Returned by `NodeVisitCallback` to control iteration. * `false` stops iteration, `skip` skips descendants but continues. * All other values continue iteration. */ export type NodeVisitResponse = "skip" | boolean | void; /** * A callback that receives a node-data dictionary and a node instance and * returns an iteration modifier. */ export type NodeToDictCallback = ( dict: WbNodeData, node: WunderbaumNode ) => NodeVisitResponse; /** * A callback that receives a node instance and may returnsa `false` to prevent * (de)selection. */ export type NodeSelectCallback = (node: WunderbaumNode) => boolean | void; /** * See also {@link WunderbaumNode.getOption|WunderbaumNode.getOption()} * to evaluate `node.NAME` setting and `tree.types[node.type].NAME`. */ export type DynamicBoolOption = boolean | BoolOptionResolver; export type DynamicStringOption = string | BoolOptionResolver; export type DynamicBoolOrStringOption = | boolean | string | BoolOrStringOptionResolver; export type DynamicCheckboxOption = CheckboxOption | BoolOrStringOptionResolver; export type DynamicIconOption = IconOption | BoolOrStringOptionResolver; export type DynamicTooltipOption = TooltipOption | BoolOrStringOptionResolver; // type WithWildcards<T> = T & { [key: string]: unknown }; /** A plain object (dictionary) that represents a node instance. */ export interface WbNodeData { /** Defines if the `selected` state is displayed as checkbox, radio button, * or hidden. * Defaults to {@link WunderbaumOptions.checkbox}. */ checkbox?: CheckboxOption; /** Optional list of child nodes. * If `children` is an empty array, the node is considered a leaf. * If `lazy` is true and `children is undefined or null, the node, is * considered unloaded. Otherwise, the node is considered a leaf. */ children?: Array<WbNodeData>; /** Additional classes that are added to `<div class='wb-row'>`. */ classes?: string; /** Only show title in a single, merged column. */ colspan?: boolean; /** Expand this node. */ expanded?: boolean; /** Defaults to standard icons (doc, folder, folderOpen, ...) * from {@link WunderbaumOptions.iconMap}. * Can be overridden by {@link WunderbaumOptions.icon}. */ icon?: IconOption; /** Tooltip for the node icon only. Defaults to {@link WunderbaumOptions.iconTooltip}. */ iconTooltip?: TooltipOption; /** The node's key. Must be unique for the whole tree. Defaults to a sequence number. */ key?: string; /** If true (and children are undefined or null), the node is considered lazy * and {@link WunderbaumOptions.lazyLoad} is called when expanded. */ lazy?: boolean; /** Make child nodes single-select radio buttons. */ radiogroup?: boolean; /** Node's reference key. Unlike {@link WunderbaumNode.key}, this value * may be non-unique. Nodes within the tree that share the same refKey are considered * clones. */ refKey?: string; /** The node's selection status, typically displayed as a checkbox. */ selected?: boolean; /** The node's status, typically displayed as merged single row. * @see {@link Wunderbaum.setStatus} */ statusNodeType?: NodeStatusType; /** The node's title. Will be html escaped to prevent XSS. */ title: string; /** Pass true to set node tooltip to the node's title. Defaults to {@link WunderbaumOptions.tooltip}. */ tooltip?: TooltipOption; /** Inherit shared settings from the matching entry in {@link WunderbaumOptions.types}. */ type?: string; /** Set to `true` to prevent selection. Defaults to {@link WunderbaumOptions.unselectable}. */ unselectable?: boolean; /** @internal */ _treeId?: string; /** Other data is passed to `node.data` and can be accessed via `node.data.NAME` */ [key: string]: unknown; } /** A plain object (dictionary) that defines node icons. */ export interface IconMapType { error: string; loading: string; noData: string; expanderExpanded: string; expanderCollapsed: string; expanderLazy: string; checkChecked: string; checkUnchecked: string; checkUnknown: string; radioChecked: string; radioUnchecked: string; radioUnknown: string; folder: string; folderOpen: string; folderLazy: string; doc: string; colSortable: string; colSortAsc: string; colSortDesc: string; colFilter: string; colFilterActive: string; colMenu: string; [key: string]: string; } /* ----------------------------------------------------------------------------- * EVENT CALLBACK TYPES * ---------------------------------------------------------------------------*/ /** A callback that receives a node instance and returns a string value. */ export type WbCancelableEventResultType = false | void; export interface WbTreeEventType { /** Name of the event. */ type: string; /** The affected tree instance. */ tree: Wunderbaum; /** Exposed utility module methods * (see [API docs](https://mar10.github.io/wunderbaum/api/modules/util.html)). */ util: any; /** Originating HTML event if any (e.g. `click`). */ event?: Event; // [key: string]: unknown; } export interface WbNodeEventType extends WbTreeEventType { /** The affected target node. */ node: WunderbaumNode; /** * Contains the node's type information, i.e. `tree.types[node.type]` if * defined. Set to `{}` otherwise. @see {@link Wunderbaum.types} */ typeInfo: NodeTypeDefinition; } export interface WbActivateEventType extends WbNodeEventType { prevNode: WunderbaumNode; /** The original event. */ event: Event; } export interface WbChangeEventType extends WbNodeEventType { /** Additional information derived from the original change event. */ info: WbEventInfo; /** The embedded element that fired the change event. */ inputElem: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement; /** The new value of the embedded element, depending on the input element type. */ inputValue: any; /** Result of `inputElem.checkValidity()`. */ inputValid: boolean; } export interface WbClickEventType extends WbTreeEventType { /** The original event. */ event: MouseEvent; /** The clicked node if any. */ node: WunderbaumNode; /** Additional information derived from the original mouse event. */ info: WbEventInfo; } export interface WbDeactivateEventType extends WbNodeEventType { nextNode: WunderbaumNode; /** The original event. */ event: Event; } export interface WbEditApplyEventType extends WbNodeEventType { /** Additional information derived from the original change event. */ info: WbEventInfo; /** The input element of the node title that fired the change event. */ inputElem: HTMLInputElement; /** The previous node title. */ oldValue: string; /** The new node title. */ newValue: string; /** Result of `inputElem.checkValidity()`. */ inputValid: boolean; } export interface WbEditEditEventType extends WbNodeEventType { /** The input element of the node title that was just created. */ inputElem: HTMLInputElement; } // export interface WbEnhanceTitleEventType extends WbNodeEventType { // titleSpan: HTMLSpanElement; // } export interface WbErrorEventType extends WbNodeEventType { error: any; } export interface WbExpandEventType extends WbNodeEventType { flag: boolean; } export interface WbFocusEventType extends WbTreeEventType { /** The original event. */ event: FocusEvent; /** True if `focusin`, false if `focusout`. */ flag: boolean; } export interface WbIconBadgeEventType extends WbNodeEventType { iconSpan: HTMLElement; } export interface WbIconBadgeEventResultType { /** Content of the badge `<span class='wb-badge'>` if any. */ badge: string | number | HTMLSpanElement | null | false; /** Additional class name(s), separate with space. */ badgeClass?: string; /** Tooltip for the badge. */ badgeTooltip?: string; } export interface WbInitEventType extends WbTreeEventType { error?: any; } export interface WbKeydownEventType extends WbTreeEventType { /** The original event. */ event: KeyboardEvent; node: WunderbaumNode; /** Additional information derived from the original keyboard event. */ info: WbEventInfo; } export interface WbModifyChildEventType extends WbNodeEventType { /** Type of change: 'add', 'remove', 'rename', 'move', 'data', ... */ operation: string; child: WunderbaumNode; } export interface WbReceiveEventType extends WbNodeEventType { response: any; } export interface WbSelectEventType extends WbNodeEventType { flag: boolean; } export interface WbButtonClickEventType extends WbTreeEventType { info: WbEventInfo; /** The associated command, e.g. 'menu', 'sort', 'filter', ... */ command: string; } export interface WbRenderEventType extends WbNodeEventType { /** * True if the node's markup was not yet created. In this case the render * event should create embedded input controls (in addition to update the * values according to to current node data). <br> * False if the node's markup was already created. In this case the render * event should only update the values according to to current node data. */ isNew: boolean; /** The node's `<span class='wb-node'>` element. */ nodeElem: HTMLSpanElement; /** True if the node only displays the title and is stretched over all remaining columns. */ isColspan: boolean; /** * Array of node's `<span class='wb-col'>` elements. * The first element is `<span class='wb-node wb-col'>`, which contains the * node title and icon (`idx: 0`, id: '*'`). */ allColInfosById: ColumnEventInfoMap; /** * Array of node's `<span class='wb-node'>` elements, * *that should be rendered by the event handler*. * In contrast to `allColInfosById`, the node title is not part of this array. * If node.isColspan() is true, this array is empty (`[]`). * This allows to iterate over all relevant in a simple loop: * ``` * for (const col of Object.values(e.renderColInfosById)) { * switch (col.id) { * default: * // Assumption: we named column.id === node.data.NAME * col.elem.textContent = node.data[col.id]; * break; * } * } */ renderColInfosById: ColumnEventInfoMap; } /** * Contains the node's type information, i.e. `tree.types[node.type]` if * defined. * @see {@link Wunderbaum.types} and {@link WunderbaumNode.getOption|WunderbaumNode.getOption()} * to evaluate `node.NAME` setting and `tree.types[node.type].NAME`. */ export interface NodeTypeDefinition { /** En/disable checkbox for matching nodes. */ checkbox?: CheckboxOption; /** Optional class names that are added to all `div.wb-row` elements of matching nodes. */ classes?: string; /** Only show title and hide other columns if any. */ colspan?: boolean; /** Default icon for matching nodes. */ icon?: IconOption; /** Default icon tooltip for matching nodes. */ iconTooltip?: TooltipOption; // and more [key: string]: unknown; } /* ----------------------------------------------------------------------------- * DATA TYPES * ---------------------------------------------------------------------------*/ export type NodeTypeDefinitionMap = { [type: string]: NodeTypeDefinition }; /** * Column type definitions. * @see {@link Wunderbaum.columns} */ export interface ColumnDefinition { /** Column ID as defined in `tree.columns` definition ("*" for title column). */ id: string; /** Column header (defaults to id) */ title: string; /** Column header tooltip (optional) */ tooltip?: string; /** Column width or weight. * Either an absolute pixel value (e.g. `"50px"`) or a relative weight (e.g. `1`) * that is used to calculate the width inside the remaining available space. * Default: `"*"`, which is interpreted as `1`. */ width?: string | number; /** Only used for columns with a relative weight. * Default: `4px`. */ minWidth?: string | number; /** Allow user to resize the column. * @default false (or global tree option `columnsSortable`) * @see {@link WunderbaumOptions.columnsResizable}. * @since 0.10.0 */ resizable?: boolean; /** Optional custom column width when user resized by mouse drag. * Default: unset. */ customWidthPx?: number; /** Display a 'filter' button in the column header. Default: false. <br> * Note: The actual filtering must be implemented in the `buttonClick()` event. * @default false (or global tree option `columnsFilterable`) * @since 0.11.0 */ filterable?: boolean; /** . * Default: inactive. <br> * Note: The actual filtering must be implemented in the `buttonClick()` event. */ filterActive?: boolean; /** Display a 'sort' button in the column header. Default: false. <br> * Note: The actual sorting must be implemented in the `buttonClick()` event. * @default false (or global tree option `columnsSortable`) * @see {@link WunderbaumOptions.columnsSortable}. * @since 0.11.0 */ sortable?: boolean; /** Optional custom column sort orde when user clicked the sort icon. * Default: unset, e.g. not sorted. <br> * Note: The actual sorting must be implemented in the `buttonClick()` event. * @since 0.11.0 */ sortOrder?: SortOrderType; /** Display a menu icon that may open a context menu for this column. * Note: The actual functionality must be implemented in the `buttonClick()` event. * @default false (or global tree option `columnsMenu`) * @see {@link WunderbaumOptions.columnsMenu}. * @since 0.11.0 */ menu?: boolean; /** Optional class names that are added to all `span.wb-col` header AND data * elements of that column. Separate multiple classes with space. */ classes?: string; /** If `headerClasses` is a set, it will be used for the header element only * (unlike `classes`, which is used for body and header cells). * Separate multiple classes with space. */ headerClasses?: string; // /** A list of icon definitions added to the column header. // */ // headerIcons?: string; /** Optional HTML content that is rendered into all `span.wb-col` elements of that column.*/ html?: string; /** @internal */ _weight?: number; /** @internal */ _widthPx?: number; /** @internal */ _ofsPx?: number; // ... and more [key: string]: unknown; } export type ColumnDefinitionList = Array<ColumnDefinition>; /** * Used by {@link Wunderbaum.getState} and {@link Wunderbaum.setState}. */ export interface TreeStateDefinition { /** The active node's key if any. */ activeKey: string | null; /** The active column index if any. */ activeColIdx: number | null; /** List of selected node's keys. */ selectedKeys: Array<string> | undefined; /** List of expanded node's keys. */ expandedKeys: Array<string> | undefined; /** List of checked node's keys. */ } /** * Column information (passed to the `render` event). */ export interface ColumnEventInfo { /** Column ID as defined in `tree.columns` definition ("*" for title column). */ id: string; /** Column index (0: leftmost title column). */ idx: number; /** The cell's `<span class='wb-col'>` element (null for plain trees). */ elem: HTMLSpanElement | null; /** The value of `tree.columns[]` for the current index. */ info: ColumnDefinition; } export type ColumnEventInfoMap = { [colId: string]: ColumnEventInfo }; /** * Additional information derived from mouse or keyboard events. * @see {@link Wunderbaum.getEventInfo} */ export interface WbEventInfo { /** The original HTTP Event.*/ event: MouseEvent | KeyboardEvent; /** Canonical descriptive string of the event type including modifiers, * e.g. `Ctrl+Down`. @see {@link util.eventToString} */ canonicalName: string; /** The tree instance. */ tree: Wunderbaum; /** The affected node instance instance if any. */ node: WunderbaumNode | null; /** The affected part of the node span (e.g. title, expander, ...). */ region: NodeRegion; /** The definition of the affected column if any. */ colDef?: ColumnDefinition; /** The index of affected column or -1. */ colIdx: number; /** The column definition ID of affected column if any. */ colId?: string; /** The affected column's span tag if any. */ colElem?: HTMLSpanElement; } // export type WbTreeCallbackType = (e: WbTreeEventType) => any; // export type WbNodeCallbackType = (e: WbNodeEventType) => any; // export type WbRenderCallbackType = (e: WbRenderEventType) => void; export type FilterModeType = null | "mark" | "dim" | "hide"; export type SelectModeType = "single" | "multi" | "hier"; export type NavigationType = | "down" | "first" | "firstCol" | "last" | "lastCol" | "left" | "nextMatch" | "pageDown" | "pageUp" | "parent" | "prevMatch" | "right" | "up"; export type ApplyCommandType = | NavigationType | "addChild" | "addSibling" | "collapse" | "collapseAll" | "copy" | "cut" | "edit" | "expand" | "expandAll" | "indent" | "moveDown" | "moveUp" | "outdent" | "paste" | "remove" | "rename" | "toggleSelect"; export type NodeFilterResponse = "skip" | "branch" | boolean | void; export type NodeFilterCallback = (node: WunderbaumNode) => NodeFilterResponse; /** * Possible values for {@link WunderbaumNode.update} and {@link Wunderbaum.update}. */ export enum ChangeType { /** Re-render the whole viewport, headers, and all rows. */ any = "any", /** A node's title, icon, columns, or status have changed. Update the existing row markup. */ data = "data", /** The `tree.columns` definition has changed beyond simple width adjustments. */ colStructure = "colStructure", /** The viewport/window was resized. Adjust layout attributes for all elements. */ resize = "resize", /** A node's definition has changed beyond status and data. Re-render the whole row's markup. */ row = "row", /** Nodes have been added, removed, etc. Update markup. */ structure = "structure", /** A node's status has changed. Update current row's classes, to reflect active, selected, ... */ status = "status", /** Vertical scroll event. Update the 'top' property of all rows. */ scroll = "scroll", } /** @internal */ export enum RenderFlag { clearMarkup = "clearMarkup", header = "header", redraw = "redraw", scroll = "scroll", } /** Possible values for {@link WunderbaumNode.setStatus}. */ export enum NodeStatusType { ok = "ok", loading = "loading", error = "error", noData = "noData", paging = "paging", } /** Define the subregion of a node, where an event occurred. */ export enum NodeRegion { unknown = "", checkbox = "checkbox", column = "column", expander = "expander", icon = "icon", prefix = "prefix", title = "title", } /** Initial navigation mode and possible transition. */ export enum NavModeEnum { /** Start with row mode, but allow cell-nav mode */ startRow = "startRow", /** Cell-nav mode only */ cell = "cell", /** Start in cell-nav mode, but allow row mode */ startCell = "startCell", /** Row mode only */ row = "row", } /** Translatable strings. */ export type TranslationsType = { /** @default "Loading..." */ loading: string; /** @default "Error" */ loadError: string; /** @default "No data" */ noData: string; /** @default " » " */ breadcrumbDelimiter: string; /** @default "Found ${matches} of ${count}" */ queryResult: string; /** @default "No result" */ noMatch: string; /** @default "${match} of ${matches}" */ matchIndex: string; }; /* ----------------------------------------------------------------------------- * METHOD OPTIONS TYPES * ---------------------------------------------------------------------------*/ /** Possible values for {@link WunderbaumNode.addChildren}. */ export interface AddChildrenOptions { /** Insert children before this node (or index) * @default undefined or null: append as last child */ before?: WunderbaumNode | number | null; /** * Set `node.expanded = true` according to tree.options.minExpandLevel. * This does *not* load lazy nodes. * @default true */ applyMinExpanLevel?: boolean; /** (@internal Internal use, do not set! ) */ _level?: number; } /** Possible values for {@link Wunderbaum.applyCommand} and {@link WunderbaumNode.applyCommand}. */ export interface ApplyCommandOptions { [key: string]: unknown; } /** Possible values for {@link Wunderbaum.expandAll} and {@link WunderbaumNode.expandAll}. */ export interface ExpandAllOptions { /** Expand and load lazy nodes @default false */ loadLazy?: boolean; /** Unload lazily loaded children if any (if collapsing). @default false */ resetLazy?: boolean; /** Ignore tree's `minExpandLevel` option @default false */ force?: boolean; /** Restrict expand level. * Pass 0 to make only toplevel nodes visible, 1 to expand one level deeper, etc. * @default unset (unlimited) */ depth?: number; /** * Also collapse child nodes beyond the `depth` level. * Otherwise only the `depth` level is collapsed and the expand state of the * descendants is retained. * Only in combination with collapse and `depth`. * Expanding with `deep` option is not supported as recursion depth implied by * the `depth` option. However a `deep` option will be considered if * `collapseOthers` is set. * @default false */ deep?: boolean; /** * Expand up to level=depth and collapse all other branches. * Only in combination with `flag == true`, `depth > 0`. * @default false */ collapseOthers?: boolean; /** Keep active node visible @default true */ keepActiveNodeVisible?: boolean; } /** * Possible option values for {@link Wunderbaum.filterNodes}. * The defaults are inherited from the tree instances ´tree.options.filter` * settings (see also {@link FilterOptionsType}). */ export interface FilterNodesOptions { /** Expand all branches that contain matches while filtered @default false */ autoExpand?: boolean; /** Whether to implicitly match all children of matched nodes @default false */ matchBranch?: boolean; /** Match single characters in order, e.g. 'fb' will match 'FooBar' @default false */ fuzzy?: boolean; /**Hide expanders if all child nodes are hidden by filter @default false */ hideExpanders?: boolean; /** Highlight matches by wrapping inside `<mark>` tags. * Does not work for filter callbacks. * @default true */ highlight?: boolean; /** Match end nodes only @default false */ leavesOnly?: boolean; /** Grayout unmatched nodes (pass 'hide' to remove instead) @default 'dim' */ mode?: FilterModeType; /** Display a 'no data' status node if result is empty @default true */ noData?: boolean | string; } /** Possible values for {@link Wunderbaum.getState}. */ export interface GetStateOptions { // /** Include the activated key. @default true */ // activeKey?: boolean; /** Include the expanded keys. @default true */ expandedKeys?: boolean; /** Include the selected keys. @default true */ selectedKeys?: boolean; } /** Possible values for {@link Wunderbaum.setState}. */ export interface SetStateOptions { /** Recursively load lazy nodes as needed. @default false */ expandLazy?: boolean; } /** Possible values for {@link WunderbaumNode.makeVisible}. */ export interface MakeVisibleOptions { /** Do not animate expand (currently not implemented). @default false */ noAnimation?: boolean; /** Scroll node into visible viewport area if required. @default true */ scrollIntoView?: boolean; /** Do not send events. @default false */ noEvents?: boolean; } /** Possible values for {@link WunderbaumNode.navigate}. */ export interface NavigateOptions { /** Activate the new node (otherwise focus only). @default true */ activate?: boolean; /** Originating event (e.g. KeyboardEvent) if any. */ event?: Event; } /** Possible values for {@link WunderbaumNode._render}. */ export interface RenderOptions { /** Which parts need update? @default ChangeType.data */ change?: ChangeType; /** Where to append a new node. @default 'last' */ after?: any; /** @internal. @default false */ isNew?: boolean; /** @internal. @default false */ preventScroll?: boolean; /** @internal. @default false */ isDataChange?: boolean; /** @internal. @default false */ top?: number; /** @internal. @default true */ resizeCols?: boolean; } /** Possible values for {@link WunderbaumNode.scrollIntoView} `options` argument. */ export interface ScrollIntoViewOptions { /** Do not animate (currently not implemented). @default false */ noAnimation?: boolean; /** Do not send events. @default false */ noEvents?: boolean; /** Keep this node visible at the top in any case. */ topNode?: WunderbaumNode; /** Add N pixel offset at top. */ ofsY?: number; } /** Possible values for {@link Wunderbaum.scrollTo} `options` argument. */ export interface ScrollToOptions extends ScrollIntoViewOptions { /** Which node to scroll into the viewport.*/ node: WunderbaumNode; } /** Possible values for {@link WunderbaumNode.setActive} `options` argument. */ export interface SetActiveOptions { /** Generate (de)activate event, even if node already has this status (@default: false). */ retrigger?: boolean; /** Do not generate (de)activate event (@default: false). */ noEvents?: boolean; // /** Mark node as focused node (default: true). // * Combine with `focusTree: true` to set keyboard focus to tree container. // */ // focusNode?: boolean; /** Call `tree.setFocus()` to acquire keyboard focus (@default: false). */ focusTree?: boolean; /** Optional original event that will be passed to the (de)activate handler. */ event?: Event; /** Also call {@link Wunderbaum.setColumn}. */ colIdx?: number | string; /** * Focus embedded input control of the grid cell if any (requires colIdx >= 0). * If colIdx is 0 or '*', the node title is put into edit mode. * Implies `focusTree: true`, requires `colIdx`. */ edit?: boolean; } /** Possible values for {@link Wunderbaum.setColumn} `options` argument. */ export interface SetColumnOptions { /** * Focus embedded input control of the grid cell if any . * If colIdx is 0 or '*', the node title is put into edit mode. * @default false */ edit?: boolean; /** Horizontically scroll into view. @default: true */ scrollIntoView?: boolean; } /** Possible values for {@link WunderbaumNode.setExpanded} `options` argument. */ export interface SetExpandedOptions { /** Ignore {@link WunderbaumOptions}.minExpandLevel. @default false */ force?: boolean; /** Immediately update viewport (async otherwise). @default false */ immediate?: boolean; /** Do not animate expand (currently not implemented). @default false */ noAnimation?: boolean; /** Do not send events. @default false */ noEvents?: boolean; /** Unload lazily loaded children if any (if collapsing). @default false */ resetLazy?: boolean; /** Scroll up to bring expanded nodes into viewport. @default false */ scrollIntoView?: boolean; } /** Possible values for {@link WunderbaumNode.update} `options` argument. */ export interface UpdateOptions { /** Force immediate redraw instead of throttled/async mode. @default false */ immediate?: boolean; // /** Remove HTML markup of all rendered nodes before redraw. @default false */ // removeMarkup?: boolean; } /** Possible values for {@link WunderbaumNode.setSelected} `options` argument. */ export interface SetSelectedOptions { /** Ignore restrictions, e.g. (`unselectable`). @default false */ force?: boolean; /** Do not send `beforeSelect` or `select` events. @default false */ noEvents?: boolean; /** Apply to all descendant nodes (only for `selectMode: 'multi'`). @default false */ propagateDown?: boolean; // /** Apply to all ancestor nodes. @default false */ // propagateUp?: boolean; /** Called for every node. May return false to prevent action. @default null */ callback?: NodeSelectCallback; } /** Possible values for {@link WunderbaumNode.setStatus} `options` argument. */ export interface SetStatusOptions { /** Displayed as status node title. */ message?: string; /** Used as tooltip. */ details?: string; } /** * Possible values for {@link WunderbaumNode.sortByProperty} `options` argument. */ export interface ResetOrderOptions { /** Sort descendants recursively. @default true */ recursive?: boolean; /** The name of the node property that will be renumbered. * @default `_nativeIndex`. */ propName?: string; } /** * Possible values for {@link WunderbaumNode.sortByProperty} `options` argument. */ export interface SortByPropertyOptions { /** Column ID as defined in `tree.columns` definition. Required if updateColInfo is true.*/ colId?: string; /** The name of the node property that will be used for sorting. * @default use the `colId` as property name. */ propName?: string; // /** If defined, this callback is used to extract the value to be sorted. */ // vallueGetter?: NodePropertyGetterCallback; /** Sort order. @default Use value from column definition (rotated).*/ order?: SortOrderType; /** * Sort by this property if order is `undefined`. * See also {@link WunderbaumNode.resetNativeChildOrder}. * @default `_nativeIndex`. */ nativeOrderPropName?: string; /** Sort string values case insensitive. @default false */ caseInsensitive?: boolean; /** Sort descendants recursively. @default true */ deep?: boolean; // /** Rotate sort order (asc -> desc -> none) before sorting. @default false */ // rotateOrder?: boolean; /** * Rotate sort order (asc -> desc -> none) before sorting. * Update the sort icons in the column header * Note: * Sorting is done in-place. There is no 'unsorted' state, but we can * call `setCurrentSortOrder()` to renumber the `node._sortIdx` property, * which will be used as sort key, when `order` is `undefined`. * @default false */ updateColInfo?: boolean; } /** Options passed to {@link Wunderbaum.visitRows}. */ export interface VisitRowsOptions { /** Skip filtered nodes and children of collapsed nodes. @default false */ includeHidden?: boolean; /** Return the start node as first result. @default true */ includeSelf?: boolean; /** Traverse in opposite direction, i.e. bottom up. @default false */ reverse?: boolean; /** Start traversal at this node @default first (topmost) tree node */ start?: WunderbaumNode | null; /** Wrap around at last node and continue at the top, * until the start node is reached again @default false */ wrap?: boolean; } /* ----------------------------------------------------------------------------- * wb_ext_filter * ---------------------------------------------------------------------------*/ /** * Passed as tree option.filer.connect to configure automatic integration of * filter UI controls. @experimental */ export interface FilterConnectType { inputElem: string | HTMLInputElement | null; modeButton?: string | HTMLButtonElement | null; nextButton?: string | HTMLButtonElement | HTMLAnchorElement | null; prevButton?: string | HTMLButtonElement | HTMLAnchorElement | null; matchInfoElem?: string | HTMLElement | null; } /** * Passed as tree options to configure default filtering behavior. * * @see {@link Wunderbaum.filterNodes} * @see {@link FilterNodesOptions} */ export type FilterOptionsType = { /** * Element or selector of input controls and buttons for filter query strings. * @experimental * @since 0.13 * @default null */ connect?: null | FilterConnectType; /** * Re-apply last filter if lazy data is loaded * @default true */ autoApply?: boolean; } & FilterNodesOptions; /* ----------------------------------------------------------------------------- * wb_ext_edit * ---------------------------------------------------------------------------*/ /** * Note: <br> * This options are used for renaming node titles. <br> * There is also the `tree.change` event to handle modifying node data from * input controls that are embedded in grid cells. */ export type EditOptionsType = { /** * Used to debounce the `change` event handler for grid cells [ms]. * @default 100 */ debounce?: number; /** * Minimum number of characters required for node title input field. * @default 1 */ minlength?: number; /** * Maximum number of characters allowed for node title input field. * @default null; */ maxlength?: null | number; /** * Array of strings to determine which user input should trigger edit mode. * E.g. `["clickActive", "F2", "macEnter"]`: <br> * 'clickActive': single click on active node title <br> * 'F2': press F2 key <br> * 'macEnter': press Enter (on macOS only) <br> * Pass an empty array to disable edit mode. * @default [] */ trigger?: string[]; /** * Trim whitespace before saving a node title. * @default true */ trim?: boolean; /** * Select all text of a node title, so it can be overwritten by typing. * @default true */ select?: boolean; /** * Handle 'clickActive' only if last click is less than this ms old (0: always) * @default 1000 */ slowClickDelay?: number; /** * Permanently apply node title input validations (CSS and tooltip) on keydown. * @default true */ validity?: boolean; // --- Events --- /** * `beforeEdit(e)` may return an input HTML string. Otherwise use a default. * @category Callback */ beforeEdit?: null | ((e: WbNodeEventType) => boolean) | string; /** * * @category Callback */ edit?: | null | ((e: WbNodeEventType & { inputElem: HTMLInputElement }) => void); /** * * @category Callback */ apply?: | null | ((e: WbNodeEventType & { inputElem: HTMLInputElement }) => any) | Promise<any>; }; /* ----------------------------------------------------------------------------- * wb_ext_dnd * ---------------------------------------------------------------------------*/ export type InsertNodeType = | "before" | "after" | "prependChild" | "appendChild"; export type DropEffectType = "none" | "copy" | "link" | "move"; export type DropEffectAllowedType = | "none" | "copy" | "copyLink" | "copyMove" | "link" | "linkMove" | "move" | "all"; export type DropRegionType = "over" | "before" | "after"; export type DropRegionTypeSet = Set<DropRegionType>; // type AllowedDropRegionType = // | "after" // | "afterBefore" // // | "afterBeforeOver" // == all == true // | "afterOver" // | "all" // == true // | "before" // | "beforeOver" // | "none" // == false == "" == null // | "over"; // == "child" export interface DragEventType extends WbNodeEventType { /** The original event. */ event: DragEvent; /** The source node. */ node: WunderbaumNode; } export interface DropEventType extends WbNodeEventType { /** The original event. */ event: DragEvent; /** The target node. */ node: WunderbaumNode; /** The source node if any. */ sourceNode: WunderbaumNode; } export type DndOptionsType = { /** * Expand nodes after n milliseconds of hovering * @default 1500 */ autoExpandMS?: 1500; // /** // * Additional offset for drop-marker with hitMode = "before"/"after" // * @default // */ // dropMarkerInsertOffsetX: -16; // /** // * Absolute position offset for .fancytree-drop-marker relatively to ..fancytree-title (icon/img near a node accepting drop) // * @default // */ // dropMarkerOffsetX: -24; // /** // * Root Container used for drop marker (could be a shadow root) // * (#1021 `document.body` is not available yet) // * @default // */ // dropMarkerParent: "body"; /** * true: Drag multiple (i.e. selected) nodes. Also a callback() is allowed * @default false */ multiSource?: false; /** * Restrict the possible cursor shapes and modifier operations * (can also be set in the dragStart event) * @default "all" */ effectAllowed?: DropEffectAllowedType; /** * Default dropEffect ('copy', 'link', or 'move') when no modifier is pressed. * Overidable in the dragEnter or dragOver event. * @default "move" */ dropEffectDefault?: DropEffectType; /** * Use opinionated heuristics to determine the dropEffect ('copy', 'link', or 'move') * based on `effectAllowed`, `dropEffectDefault`, and modifier keys. * This is recalculated before each dragEnter and dragOver event and can be * overridden there. * * @default true */ guessDropEffect: boolean; /** * Prevent dropping nodes from different Wunderbaum trees * @default false */ preventForeignNodes?: boolean; /** * Prevent dropping items on unloaded lazy Wunderbaum tree nodes * @default true */ preventLazyParents?: boolean; /** * Prevent dropping items other than Wunderbaum tree nodes * @default false */ preventNonNodes?: boolean; /** * Prevent dropping nodes on own descendants * @default true */ preventRecursion?: boolean; /** * Prevent dropping nodes under same direct parent * @default false */ preventSameParent?: boolean; /** * Prevent dropping nodes 'before self', etc. (move only) * @default true */ preventVoidMoves?: boolean; /** * Serialize Node Data to datatransfer object * @default true */ serializeClipboardData?: | boolean | ((nodeData: WbNodeData, node: WunderbaumNode) => string); /** * Enable auto-scrolling while dragging * @default true */ scroll?: boolean; /** * Active top/bottom margin in pixel * @default 20 */ scrollSensitivity?: 20; // /** // * Scroll events every N microseconds // * @default 50 // */ // scrollnterval: 50; /** * Pixel per event * @default 5 */ scrollSpeed?: 5; // /** // * Allow dragging of nodes to different IE windows // * @default false // */ // setTextTypeJson: boolean; /** * Optional callback passed to `toDict` on dragStart * @default null * @category Callback */ sourceCopyHook?: null; // Events (drag support) /** * Callback(sourceNode, data), return true, to enable dnd drag * @default null * @category Callback */ dragStart?: null | ((e: DragEventType) => boolean); /** * Callback(sourceNode, data) * @default null * @category Callback */ drag?: null | ((e: DragEventType) => void); /** * Callback(sourceNode, data) * @default null * @category Callback */ dragEnd?: null | ((e: DragEventType) => void); // Events (drop support) /** * Callback(targetNode, data), return true, to enable dnd drop * @default null * @category Callback */ dragEnter?: | null | ((e: DropEventType) => DropRegionType | DropRegionTypeSet | boolean); /** * Callback(targetNode, data) * @default null * @category Callback */ dragOver?: null | ((e: DropEventType) => void); /** * Callback(targetNode, data), return false to prevent autoExpand * @default null * @category Callback */ dragExpand?: null | ((e: DropEventType) => boolean); /** * Callback(targetNode, data) * @default null * @category Callback */ drop?: | null | (( e: WbNodeEventType & { event: DragEvent; region: DropRegionType; suggestedDropMode: InsertNodeType; suggestedDropEffect: DropEffectType; sourceNode: WunderbaumNode; sourceNodeData: WbNodeData | null; } ) => void); /** * Callback(targetNode, data) * @default null * @category Callback */ dragLeave?: null | ((e: DropEventType) => void); }; /* ----------------------------------------------------------------------------- * wb_ext_grid * ---------------------------------------------------------------------------*/ export type GridOptionsType = object; /* ----------------------------------------------------------------------------- * wb_ext_keynav * ---------------------------------------------------------------------------*/ export type KeynavOptionsType = object; /* ----------------------------------------------------------------------------- * wb_ext_loger * ---------------------------------------------------------------------------*/ export type LoggerOptionsType = object;