@kanunilabs/datagrid-react 1.8.11 → 1.8.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { RefObject, ReactNode, FocusEvent, MouseEvent } from 'react';
3
- import { GridRowData, DataGridController, GridDataType, RowKey, LookupItem, GridDictionary, StateStoringConfig, RowNode, DataRowNode, CardField, RowSaveStatus, GridColumnDef, DataGridCoreConfig, FilterRenderContextBase, FilterNode, InferColumnsOptions, GridThemeName, GridPaletteName, DescribeFilterOptions, GridDensity, ToolbarOptions, PortalContainer, CardViewOptions, EditMode, RowChange, RowStatusSource, ColumnRuntime, ColumnLayout, SortDescriptor, ColumnLookup, ColumnModel, ColSpanPlan, SummaryDef, RemoteDistinctList, PortalKind, ToolbarSearchOptions, ToolbarIconName, ColumnState, BusyPhase, VirtualWindow, ChartBoxSpec, ChartBoxModel, ChartSpec, ChartModel, ChartXYSpec, ChartXYModel, CellRange, RangeSelectionEngine, ColumnSelectMode, EditingEngine, EditingApi, NewRowPosition, ValidationRule, CrudHandlers, EditingPermissions, CommitOn, RowEditSession, ColumnNumberFormat, LookupMatchMode, LookupMatchFold } from '@kanunilabs/datagrid-core';
3
+ import { GridRowData, DataGridController, GridDataType, RowKey, LookupItem, GridDictionary, StateStoringConfig, RowNode, DataRowNode, CardField, RowSaveStatus, GridColumnDef, DataGridCoreConfig, FilterRenderContextBase, FilterNode, InferColumnsOptions, GridThemeName, GridPaletteName, DescribeFilterOptions, GridDensity, ToolbarOptions, PortalContainer, CardViewOptions, EditMode, RowChange, RowStatusSource, ColumnRuntime, ColumnLayout, SortDescriptor, ColumnLookup, ColumnModel, ColSpanPlan, LookupMatchFold, SummaryDef, RemoteDistinctList, PortalKind, ToolbarSearchOptions, ToolbarIconName, ColumnState, BusyPhase, VirtualWindow, ChartBoxSpec, ChartBoxModel, ChartSpec, ChartModel, ChartXYSpec, ChartXYModel, CellRange, RangeSelectionEngine, ColumnSelectMode, EditingEngine, EditingApi, NewRowPosition, ValidationRule, CrudHandlers, EditingPermissions, CommitOn, RowEditSession, ColumnNumberFormat, LookupMatchMode, LookupListColumn } from '@kanunilabs/datagrid-core';
4
4
  export { BusyChangedEvent, BusyPhase, ChangesChangedEvent, ClientRowModel, ColumnLayout, ColumnLookup, ColumnModel, ColumnPin, ColumnRuntime, ColumnState, ColumnStateChangedEvent, CommitOn, ContentReadyEvent, CustomFilterOperator, CustomFilterOperatorId, DEFAULT_ROW_HEIGHT, DENSITY_ROW_HEIGHT, DataGridController, DataGridCoreConfig, DataRowNode, DataSource, EditingApi, FilterChangedEvent, FilterCondition, FilterGroupNode, FilterNode, FilterOperator, FocusedRowChangedEvent, GRID_COLOR_SCHEMES, GRID_PALETTES, GRID_THEMES, GridColorScheme, GridColumnDef, GridDataType, GridDensity, GridEventMap, GridPalette, GridPaletteName, GridRowData, GridStateStore, GridTheme, GridThemeName, GridViewState, GroupRowNode, GroupingConfig, HeaderBandCell, InferColumnsOptions, LoadOptions, LoadResult, LookupItem, NewRowPosition, PortalContainer, RowDropPosition, RowKey, RowNode, SUMMARY_TYPE_LABEL, SaveRejected, SaveRowError, ScrollingConfig, SelectionDescriptor, SortChangedEvent, SortDescriptor, SortDirection, StateStoringConfig, SummaryDef, SummaryType, THEME_ROW_HEIGHT, ToolbarOptions, ToolbarSearchOptions, ViewportChangedEvent, VirtualWindow, VirtualWindowEngine, allowedSummaryTypes, andFilters, attachStateStoring, bandDepth, bandPath, computeColumnLayout, computeHeaderBands, createRestDataSource, describeFilter, downloadBlob, fillText, filterInputFromNode, formatSummaryValue, humanizeField, importCsv, inferColumns, isDataRow, isDataSource, isFilterGroup, isGroupRow, isPackagedTheme, isSaveRejected, lookupLabel, moveRowInArray, parseCsv, parseFilterInput, sniffDelimiter, summaryKey, summaryLabel, summaryTypeLabels, themeClassName } from '@kanunilabs/datagrid-core';
5
5
 
6
6
  /** Formats an export menu can offer. */
@@ -427,8 +427,11 @@ interface EditorRowApi {
427
427
  * **Escape** cancels the editor (`cancel()`), and **Tab / Shift+Tab** walk
428
428
  * the focusable elements INSIDE the box (text box → "…" button) and only
429
429
  * past the last (first) one commit and move to the next (previous) cell —
430
- * `commit({ move: 'next' })`. Enter is left to the editor: call
431
- * `commit({ move: 'down' })` from it for the built-in behaviour. The
430
+ * `commit({ move: 'next' })`. **Enter** commits like the built-in editor
431
+ * (moves down, or stays with `editKeys.enter`; Shift+Enter stays) — except
432
+ * in a `<textarea>` or an editable region, where it types a new line. An
433
+ * editor that uses Enter itself (picking from its own list) calls
434
+ * `preventDefault()` in its handler. The
432
435
  * editor's own shortcuts (F4, Alt+ArrowDown for its "…" button) are never
433
436
  * taken by the grid.
434
437
  * - Events from OUTSIDE the grid's DOM — a dialog the editor opens in a
@@ -451,8 +454,17 @@ interface EditorRowApi {
451
454
  * to the scroller when the editor has closed.
452
455
  */
453
456
  interface EditorRenderContext<TRow = GridRowData> {
454
- /** Current (uncommitted) editor value. */
457
+ /**
458
+ * Current (uncommitted) editor value — what the built-in editor would show:
459
+ * the column's `valueGetter` result when it has one.
460
+ */
455
461
  value: unknown;
462
+ /**
463
+ * The column's `field` as stored in the row (pending edits applied), before
464
+ * any `valueGetter` — the bit set behind a "E;D;S" summary, say. Undefined
465
+ * when the column has no `field`.
466
+ */
467
+ rawValue: unknown;
456
468
  /** The row with pending edits applied — what a cascading list should read. */
457
469
  row: TRow;
458
470
  columnId: string;
@@ -1200,6 +1212,14 @@ interface DataGridProps<TRow = GridRowData> extends Omit<DataGridCoreConfig<TRow
1200
1212
  * the totals are the headline; the rows below are then the evidence for it.
1201
1213
  */
1202
1214
  footerPosition?: 'top' | 'bottom';
1215
+ /**
1216
+ * Keep the bottom totals row on the grid's bottom edge when there are too few
1217
+ * rows to reach it (Tekax B.3), as a desktop data grid does. Default false:
1218
+ * the row follows the last data row and sticks to the edge only once the rows
1219
+ * scroll. Rows pinned to the bottom (`pinnedBottomRows`) move down with it.
1220
+ * No effect with `footerPosition: 'top'`.
1221
+ */
1222
+ pinFooterToBottom?: boolean;
1203
1223
  /**
1204
1224
  * What to do with the column widths once the grid knows how much room it has
1205
1225
  * (gap analysis P2.5). Default `'none'` — the configured widths are used as
@@ -1739,6 +1759,8 @@ interface GridRowProps<TRow = GridRowData> {
1739
1759
  * when it does not, they do not.
1740
1760
  */
1741
1761
  searchNeedle?: string;
1762
+ /** The grid's `searchFold`: how `searchNeedle` was folded, and so the cell text. */
1763
+ searchFold?: LookupMatchFold;
1742
1764
  /**
1743
1765
  * The grid's cache of FUNCTION lookup lists (P-5.1): a closed cell shows the
1744
1766
  * label, not the raw code. One stable object per grid; when a list arrives
@@ -1778,7 +1800,7 @@ interface GridRowProps<TRow = GridRowData> {
1778
1800
  onCellPointerEnter?: (ctx: CellSlotContext<TRow>, event: React.MouseEvent) => void;
1779
1801
  onCellDoubleClick?: (ctx: CellSlotContext<TRow>) => void;
1780
1802
  }
1781
- declare function GridRowImpl<TRow = GridRowData>({ gridId, node, index, layout, columnModel, centerColumns, centerIndices, stickyInsets, leadingSpacer, trailingSpacer, striped, selected, ariaSelectable, selectable, groupSelection, onToggleGroupSelect, groupDisplay, focusedColumnId, rowFocused, renderRow, checkboxColumn, statusColumn, rowNumberColumn, rowNumber, getNote, getSpan, resolveColSpans, findKind, headerRowCount, onRowClick, onRowMouseDown, onRowDoubleClick, onToggleSelect, onCellMouseDown, onRowContextMenu, searchNeedle, lookupLabels, onToggleGroup, summaryDefs, detailColumn, detailExpanded, onToggleDetail, onToggleTreeRow, renderDetail, renderEditForm, renderRowMessage, renderCellContent, getCellClassName, onCellPointerDown, onCellPointerEnter, onCellDoubleClick, rowDrag, dropSide, rowStatus, rowStatusText, rowStatusTint, rowStatusStrike, rowClass, height, }: GridRowProps<TRow>): react.JSX.Element | null;
1803
+ declare function GridRowImpl<TRow = GridRowData>({ gridId, node, index, layout, columnModel, centerColumns, centerIndices, stickyInsets, leadingSpacer, trailingSpacer, striped, selected, ariaSelectable, selectable, groupSelection, onToggleGroupSelect, groupDisplay, focusedColumnId, rowFocused, renderRow, checkboxColumn, statusColumn, rowNumberColumn, rowNumber, getNote, getSpan, resolveColSpans, findKind, headerRowCount, onRowClick, onRowMouseDown, onRowDoubleClick, onToggleSelect, onCellMouseDown, onRowContextMenu, searchNeedle, searchFold, lookupLabels, onToggleGroup, summaryDefs, detailColumn, detailExpanded, onToggleDetail, onToggleTreeRow, renderDetail, renderEditForm, renderRowMessage, renderCellContent, getCellClassName, onCellPointerDown, onCellPointerEnter, onCellDoubleClick, rowDrag, dropSide, rowStatus, rowStatusText, rowStatusTint, rowStatusStrike, rowClass, height, }: GridRowProps<TRow>): react.JSX.Element | null;
1782
1804
  declare const GridRow: typeof GridRowImpl;
1783
1805
 
1784
1806
  interface GridFilterRowProps<TRow = GridRowData> {
@@ -2485,11 +2507,13 @@ interface GridSurfaceProviderProps {
2485
2507
  theme?: GridThemeName;
2486
2508
  density?: GridDensity;
2487
2509
  palette?: GridPaletteName;
2510
+ /** Dark tokens for the popups too (`LookupBox` `dark`, B.9.13). */
2511
+ dark?: boolean;
2488
2512
  /** Where popups are drawn (the grid's `portalContainer`). Default <body>. */
2489
2513
  portalContainer?: PortalContainer;
2490
2514
  children: ReactNode;
2491
2515
  }
2492
- declare function GridSurfaceProvider({ theme, density, palette, portalContainer, children, }: GridSurfaceProviderProps): react.JSX.Element;
2516
+ declare function GridSurfaceProvider({ theme, density, palette, dark, portalContainer, children, }: GridSurfaceProviderProps): react.JSX.Element;
2493
2517
  /**
2494
2518
  * The element a popup is portalled into, read when the popup opens: <body>,
2495
2519
  * or the host inside the grid's `portalContainer` (core `portalTarget`).
@@ -2738,11 +2762,12 @@ interface UseGridEditingResult<TRow = GridRowData> {
2738
2762
  /**
2739
2763
  * A custom editor's commit (`renderEditor`'s `ctx.commit`, P-4.2): `'none'`
2740
2764
  * stays on the cell, `'down'` moves down (whatever `editKeys.enter` says —
2741
- * the editor asked), `'next'` / `'previous'` walk to the adjacent editable
2765
+ * the editor asked), `'enter'` is the grid's own Enter (down unless
2766
+ * `editKeys.enter`), `'next'` / `'previous'` walk to the adjacent editable
2742
2767
  * cell like Tab, `'blur'` leaves focus where it is. False when a rule
2743
2768
  * refused the value.
2744
2769
  */
2745
- commitCustomEditor: (move: 'down' | 'next' | 'previous' | 'none' | 'blur') => boolean;
2770
+ commitCustomEditor: (move: 'down' | 'enter' | 'next' | 'previous' | 'none' | 'blur') => boolean;
2746
2771
  /**
2747
2772
  * `ctx.suspendBlurCommit` (P-4.1): while on, blur is not leaving the editor
2748
2773
  * (`ctx.commitOnBlur`, the `commitOn: 'row'` send). Turning it off puts focus
@@ -2966,6 +2991,13 @@ interface GridLookupEditorProps {
2966
2991
  * field would open its list at once.
2967
2992
  */
2968
2993
  openOnEdit?: boolean;
2994
+ /**
2995
+ * Focusing or clicking the box opens the list. Default false (Tekax B.9.3):
2996
+ * the list opens on typing, ▾, F4, Alt+Down, Space (`editKeys.space`) or,
2997
+ * with `openOnEdit`, when the editor starts — so a Tab into a form field or
2998
+ * an editor opened with Enter shows the value, not a list over the rows.
2999
+ */
3000
+ openOnFocus?: boolean;
2969
3001
  /**
2970
3002
  * The editor was opened by TYPING and `value` is that one character: the
2971
3003
  * box starts with it as the typed text (list filtered by it, caret after
@@ -2985,6 +3017,48 @@ interface GridLookupEditorProps {
2985
3017
  * highlighted item; no match picks nothing. Ignored with `allowCustom`.
2986
3018
  */
2987
3019
  typeAhead?: boolean;
3020
+ /** A grip on the open list's corner to resize it (`lookup.listResizable`, B.4.3). */
3021
+ listResizable?: boolean;
3022
+ /** The list as a table with a header row (`lookup.listColumns`, B.4.2). */
3023
+ listColumns?: readonly LookupListColumn[];
3024
+ /** A ▾ button that opens and closes the list (`lookup.dropButton`, B.4.2). */
3025
+ dropButton?: boolean;
3026
+ /**
3027
+ * What the box shows and completes against (`lookup.display`, B.9.1):
3028
+ * `'code'`, `'name'` or `'both'`. Default: `'code'` for a `linked` list, the
3029
+ * label otherwise.
3030
+ */
3031
+ display?: 'code' | 'name' | 'both';
3032
+ /**
3033
+ * Does the pointer over an item move the highlight (what Enter, Tab and
3034
+ * leaving write)? Default true. False (B.9.6, `LookupBox`'s default): the
3035
+ * pointer only marks the item it is over; the keyboard's highlight stays.
3036
+ */
3037
+ hoverHighlights?: boolean;
3038
+ /** `lookup.openHighlight`: `'current'` opens on the current item, or the first (Tekax, 2026-11-12). */
3039
+ openHighlight?: 'none' | 'current';
3040
+ /** Text emptied and left: the value becomes null (B.9.7, `LookupBox`). Default false. */
3041
+ clearable?: boolean;
3042
+ /**
3043
+ * The list is on its way (B.9.8): typing is not refused, Enter picks
3044
+ * nothing, the list says so; once it arrives the text is checked against it
3045
+ * (cut back to what still matches) and completed.
3046
+ */
3047
+ loading?: boolean;
3048
+ /** Keys the box does not use (Insert, Ctrl+Delete, F-keys) go on to the page (B.9.9, `LookupBox`). */
3049
+ passKeys?: boolean;
3050
+ /** The "…" button is a Tab stop; Enter, Space, F4 and Alt+Down on it open the picker (B.9.14). */
3051
+ pickerTabStop?: boolean;
3052
+ /** `'picker-first'`: [box][…][▾] (B.9.14). Default [box][▾][…]. */
3053
+ buttonOrder?: 'drop-first' | 'picker-first';
3054
+ /** The buttons' accessible names (B.9.14): default "Choose from the full list" and the field's name. */
3055
+ pickerLabel?: string;
3056
+ dropLabel?: string;
3057
+ /** On the BOX (B.9.11): its id (for `<label for>`), form name, required, described-by. */
3058
+ inputId?: string;
3059
+ name?: string;
3060
+ required?: boolean;
3061
+ describedBy?: string;
2988
3062
  /**
2989
3063
  * Complete typed text to the one item left / an exact label on leaving.
2990
3064
  * Default true. False: the "pick from the list" rule (K-3, see the top).
@@ -3003,6 +3077,8 @@ interface GridLookupEditorProps {
3003
3077
  */
3004
3078
  onPick?: (item: LookupItem) => boolean;
3005
3079
  invalid?: boolean;
3080
+ /** A read-only field (`LookupBox`): the box and its buttons do nothing. */
3081
+ disabled?: boolean;
3006
3082
  /**
3007
3083
  * Take focus on mount. True for a cell editor — it opened BECAUSE the user
3008
3084
  * asked to edit that one cell. False in `row` mode, where every editable cell
@@ -3032,6 +3108,22 @@ interface GridLookupEditorProps {
3032
3108
  * settles the typed text, as before.
3033
3109
  */
3034
3110
  onBlurCommit?: () => void;
3111
+ /**
3112
+ * `lookup.onPickerOpen` (Tekax B.4.1), bound to the row: a "…" button and
3113
+ * Ctrl+Enter open the app's picker; its item is picked like a list item.
3114
+ */
3115
+ onPickerOpen?: (text: string) => Promise<LookupItem | null> | LookupItem | null;
3116
+ /**
3117
+ * The grid's `suspendBlurCommit` (P-4.1): held while the picker is open, so
3118
+ * focus going to the app's dialog neither commits the cell nor sends the row.
3119
+ */
3120
+ suspendBlurCommit?: (on: boolean, restoreTo?: () => HTMLElement | null) => void;
3121
+ /**
3122
+ * The grid's `setEditFlusher` (B.12.5 / B.9.19): the editor registers its
3123
+ * leaving rule, so a commit the editor did not start (`stopEditing()`,
3124
+ * `ctx.commit()`, a press elsewhere) writes what Tab would.
3125
+ */
3126
+ registerFlush?: (flush: (() => boolean) | null) => void;
3035
3127
  }
3036
3128
  /**
3037
3129
  * The same match, as items. Kept for callers and tests that want the simple
@@ -3039,19 +3131,22 @@ interface GridLookupEditorProps {
3039
3131
  */
3040
3132
  declare function matchOptions(options: readonly LookupItem[], query: string, mode: LookupMatchMode): readonly LookupItem[];
3041
3133
  /** The editor's settings that come straight from a column's `lookup`. */
3042
- type LookupEditorSettings = Pick<GridLookupEditorProps, 'matchMode' | 'codeMatchMode' | 'linked' | 'allowCustom' | 'autoCompleteSingle' | 'onNoMatch' | 'matchFold' | 'openOnEdit' | 'restrictInput' | 'typeAhead'>;
3134
+ type LookupEditorSettings = Pick<GridLookupEditorProps, 'matchMode' | 'codeMatchMode' | 'linked' | 'allowCustom' | 'autoCompleteSingle' | 'onNoMatch' | 'matchFold' | 'openOnEdit' | 'restrictInput' | 'typeAhead' | 'listResizable' | 'listColumns' | 'dropButton' | 'display' | 'hoverHighlights' | 'openHighlight'>;
3043
3135
  /** `lookup` → the editor's props, one reading for the cell, row and form editors. */
3044
3136
  declare function lookupEditorSettings(lookup: ColumnLookup<never> | undefined): LookupEditorSettings;
3045
- /**
3046
- * What one pick writes to the row (P-5.2 / P-5.3): the column's own value,
3047
- * `linkedColumns`' code / name / id, then `map`. Null when the column has
3048
- * neither — a plain pick, one cell, as before.
3049
- */
3050
3137
  declare function lookupPickValues(lookup: ColumnLookup<never> | undefined, columnId: string, item: LookupItem): Record<string, unknown> | null;
3051
- declare function GridLookupEditor({ options, value, matchMode, codeMatchMode, matchFold, linked, allowCustom, openOnEdit, seeded, restrictInput, typeAhead, autoCompleteSingle, onNoMatch, onPick, invalid, autoFocus, testId, columnId, ariaLabel, onChange, onCommit, commitOnPick, onCancel, onTab, onBlurCommit, }: GridLookupEditorProps): react.JSX.Element;
3138
+ declare function GridLookupEditor({ options, value, matchMode, codeMatchMode, matchFold, linked, allowCustom, openOnEdit, seeded, restrictInput, typeAhead, listResizable, listColumns, dropButton, openOnFocus, display, hoverHighlights, openHighlight, clearable, loading, passKeys, pickerTabStop, buttonOrder, pickerLabel, dropLabel, inputId, name, required, describedBy, autoCompleteSingle, onNoMatch, onPick, invalid, disabled, autoFocus, testId, columnId, ariaLabel, onChange, onCommit, commitOnPick, onCancel, onTab, onBlurCommit, onPickerOpen, suspendBlurCommit, registerFlush, }: GridLookupEditorProps): react.JSX.Element;
3052
3139
 
3053
3140
  interface GridCellEditorProps {
3054
3141
  value: unknown;
3142
+ /** The column's lookup when it is `multiple` (Tekax B.6): the check-box editor. */
3143
+ multipleLookup?: ColumnLookup<never>;
3144
+ /** `lookup.onPickerOpen`, bound to this cell (Tekax B.4.1). */
3145
+ onPickerOpen?: GridLookupEditorProps['onPickerOpen'];
3146
+ /** The engine's `setEditFlusher` (B.12.5): lookup and date editors register their leaving rule. */
3147
+ registerFlush?: (flush: (() => boolean) | null) => void;
3148
+ /** The grid's `suspendBlurCommit`, held while that picker is open. */
3149
+ suspendBlurCommit?: GridLookupEditorProps['suspendBlurCommit'];
3055
3150
  dataType: GridDataType | undefined;
3056
3151
  /**
3057
3152
  * Choices for a lookup/select editor. `null` means the list is still being
@@ -3106,7 +3201,7 @@ interface GridCellEditorProps {
3106
3201
  onTab: (direction: 1 | -1) => void;
3107
3202
  onCancel: () => void;
3108
3203
  }
3109
- declare function GridCellEditor({ value, dataType, error, seeded, seedText, options, allowCustom, matchMode, lookupSettings, onPick, ariaLabel, dateFormat, numberFormat, numberLocale, onChange, onCommit, onTab, onCancel, }: GridCellEditorProps): react.JSX.Element;
3204
+ declare function GridCellEditor({ value, dataType, error, seeded, seedText, options, allowCustom, matchMode, lookupSettings, onPick, multipleLookup, onPickerOpen, suspendBlurCommit, registerFlush, ariaLabel, dateFormat, numberFormat, numberLocale, onChange, onCommit, onTab, onCancel, }: GridCellEditorProps): react.JSX.Element;
3110
3205
 
3111
3206
  interface GridDateEditorProps {
3112
3207
  value: unknown;
@@ -3137,13 +3232,15 @@ interface GridDateEditorProps {
3137
3232
  * only settles the typed text, as before.
3138
3233
  */
3139
3234
  onBlurCommit?: () => void;
3235
+ /** The grid's `setEditFlusher` (B.12.5): a commit from elsewhere writes the typed (or cleared) day first. */
3236
+ registerFlush?: (flush: (() => boolean) | null) => void;
3140
3237
  /**
3141
3238
  * Digits the box starts with — the editor was opened by typing one on the
3142
3239
  * cell (P-3.6). The caret goes after them instead of selecting.
3143
3240
  */
3144
3241
  seedDigits?: string;
3145
3242
  }
3146
- declare function GridDateEditor({ value, format, invalid, disabled, autoFocus, testId, columnId, ariaLabel, onChange, onCommit, onCancel, onTab, onBlurCommit, seedDigits, }: GridDateEditorProps): react.JSX.Element;
3243
+ declare function GridDateEditor({ value, format, invalid, disabled, autoFocus, testId, columnId, ariaLabel, onChange, onCommit, onCancel, onTab, onBlurCommit, registerFlush, seedDigits, }: GridDateEditorProps): react.JSX.Element;
3147
3244
 
3148
3245
  interface GridDialogProps {
3149
3246
  open: boolean;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import { RefObject, ReactNode, FocusEvent, MouseEvent } from 'react';
3
- import { GridRowData, DataGridController, GridDataType, RowKey, LookupItem, GridDictionary, StateStoringConfig, RowNode, DataRowNode, CardField, RowSaveStatus, GridColumnDef, DataGridCoreConfig, FilterRenderContextBase, FilterNode, InferColumnsOptions, GridThemeName, GridPaletteName, DescribeFilterOptions, GridDensity, ToolbarOptions, PortalContainer, CardViewOptions, EditMode, RowChange, RowStatusSource, ColumnRuntime, ColumnLayout, SortDescriptor, ColumnLookup, ColumnModel, ColSpanPlan, SummaryDef, RemoteDistinctList, PortalKind, ToolbarSearchOptions, ToolbarIconName, ColumnState, BusyPhase, VirtualWindow, ChartBoxSpec, ChartBoxModel, ChartSpec, ChartModel, ChartXYSpec, ChartXYModel, CellRange, RangeSelectionEngine, ColumnSelectMode, EditingEngine, EditingApi, NewRowPosition, ValidationRule, CrudHandlers, EditingPermissions, CommitOn, RowEditSession, ColumnNumberFormat, LookupMatchMode, LookupMatchFold } from '@kanunilabs/datagrid-core';
3
+ import { GridRowData, DataGridController, GridDataType, RowKey, LookupItem, GridDictionary, StateStoringConfig, RowNode, DataRowNode, CardField, RowSaveStatus, GridColumnDef, DataGridCoreConfig, FilterRenderContextBase, FilterNode, InferColumnsOptions, GridThemeName, GridPaletteName, DescribeFilterOptions, GridDensity, ToolbarOptions, PortalContainer, CardViewOptions, EditMode, RowChange, RowStatusSource, ColumnRuntime, ColumnLayout, SortDescriptor, ColumnLookup, ColumnModel, ColSpanPlan, LookupMatchFold, SummaryDef, RemoteDistinctList, PortalKind, ToolbarSearchOptions, ToolbarIconName, ColumnState, BusyPhase, VirtualWindow, ChartBoxSpec, ChartBoxModel, ChartSpec, ChartModel, ChartXYSpec, ChartXYModel, CellRange, RangeSelectionEngine, ColumnSelectMode, EditingEngine, EditingApi, NewRowPosition, ValidationRule, CrudHandlers, EditingPermissions, CommitOn, RowEditSession, ColumnNumberFormat, LookupMatchMode, LookupListColumn } from '@kanunilabs/datagrid-core';
4
4
  export { BusyChangedEvent, BusyPhase, ChangesChangedEvent, ClientRowModel, ColumnLayout, ColumnLookup, ColumnModel, ColumnPin, ColumnRuntime, ColumnState, ColumnStateChangedEvent, CommitOn, ContentReadyEvent, CustomFilterOperator, CustomFilterOperatorId, DEFAULT_ROW_HEIGHT, DENSITY_ROW_HEIGHT, DataGridController, DataGridCoreConfig, DataRowNode, DataSource, EditingApi, FilterChangedEvent, FilterCondition, FilterGroupNode, FilterNode, FilterOperator, FocusedRowChangedEvent, GRID_COLOR_SCHEMES, GRID_PALETTES, GRID_THEMES, GridColorScheme, GridColumnDef, GridDataType, GridDensity, GridEventMap, GridPalette, GridPaletteName, GridRowData, GridStateStore, GridTheme, GridThemeName, GridViewState, GroupRowNode, GroupingConfig, HeaderBandCell, InferColumnsOptions, LoadOptions, LoadResult, LookupItem, NewRowPosition, PortalContainer, RowDropPosition, RowKey, RowNode, SUMMARY_TYPE_LABEL, SaveRejected, SaveRowError, ScrollingConfig, SelectionDescriptor, SortChangedEvent, SortDescriptor, SortDirection, StateStoringConfig, SummaryDef, SummaryType, THEME_ROW_HEIGHT, ToolbarOptions, ToolbarSearchOptions, ViewportChangedEvent, VirtualWindow, VirtualWindowEngine, allowedSummaryTypes, andFilters, attachStateStoring, bandDepth, bandPath, computeColumnLayout, computeHeaderBands, createRestDataSource, describeFilter, downloadBlob, fillText, filterInputFromNode, formatSummaryValue, humanizeField, importCsv, inferColumns, isDataRow, isDataSource, isFilterGroup, isGroupRow, isPackagedTheme, isSaveRejected, lookupLabel, moveRowInArray, parseCsv, parseFilterInput, sniffDelimiter, summaryKey, summaryLabel, summaryTypeLabels, themeClassName } from '@kanunilabs/datagrid-core';
5
5
 
6
6
  /** Formats an export menu can offer. */
@@ -427,8 +427,11 @@ interface EditorRowApi {
427
427
  * **Escape** cancels the editor (`cancel()`), and **Tab / Shift+Tab** walk
428
428
  * the focusable elements INSIDE the box (text box → "…" button) and only
429
429
  * past the last (first) one commit and move to the next (previous) cell —
430
- * `commit({ move: 'next' })`. Enter is left to the editor: call
431
- * `commit({ move: 'down' })` from it for the built-in behaviour. The
430
+ * `commit({ move: 'next' })`. **Enter** commits like the built-in editor
431
+ * (moves down, or stays with `editKeys.enter`; Shift+Enter stays) — except
432
+ * in a `<textarea>` or an editable region, where it types a new line. An
433
+ * editor that uses Enter itself (picking from its own list) calls
434
+ * `preventDefault()` in its handler. The
432
435
  * editor's own shortcuts (F4, Alt+ArrowDown for its "…" button) are never
433
436
  * taken by the grid.
434
437
  * - Events from OUTSIDE the grid's DOM — a dialog the editor opens in a
@@ -451,8 +454,17 @@ interface EditorRowApi {
451
454
  * to the scroller when the editor has closed.
452
455
  */
453
456
  interface EditorRenderContext<TRow = GridRowData> {
454
- /** Current (uncommitted) editor value. */
457
+ /**
458
+ * Current (uncommitted) editor value — what the built-in editor would show:
459
+ * the column's `valueGetter` result when it has one.
460
+ */
455
461
  value: unknown;
462
+ /**
463
+ * The column's `field` as stored in the row (pending edits applied), before
464
+ * any `valueGetter` — the bit set behind a "E;D;S" summary, say. Undefined
465
+ * when the column has no `field`.
466
+ */
467
+ rawValue: unknown;
456
468
  /** The row with pending edits applied — what a cascading list should read. */
457
469
  row: TRow;
458
470
  columnId: string;
@@ -1200,6 +1212,14 @@ interface DataGridProps<TRow = GridRowData> extends Omit<DataGridCoreConfig<TRow
1200
1212
  * the totals are the headline; the rows below are then the evidence for it.
1201
1213
  */
1202
1214
  footerPosition?: 'top' | 'bottom';
1215
+ /**
1216
+ * Keep the bottom totals row on the grid's bottom edge when there are too few
1217
+ * rows to reach it (Tekax B.3), as a desktop data grid does. Default false:
1218
+ * the row follows the last data row and sticks to the edge only once the rows
1219
+ * scroll. Rows pinned to the bottom (`pinnedBottomRows`) move down with it.
1220
+ * No effect with `footerPosition: 'top'`.
1221
+ */
1222
+ pinFooterToBottom?: boolean;
1203
1223
  /**
1204
1224
  * What to do with the column widths once the grid knows how much room it has
1205
1225
  * (gap analysis P2.5). Default `'none'` — the configured widths are used as
@@ -1739,6 +1759,8 @@ interface GridRowProps<TRow = GridRowData> {
1739
1759
  * when it does not, they do not.
1740
1760
  */
1741
1761
  searchNeedle?: string;
1762
+ /** The grid's `searchFold`: how `searchNeedle` was folded, and so the cell text. */
1763
+ searchFold?: LookupMatchFold;
1742
1764
  /**
1743
1765
  * The grid's cache of FUNCTION lookup lists (P-5.1): a closed cell shows the
1744
1766
  * label, not the raw code. One stable object per grid; when a list arrives
@@ -1778,7 +1800,7 @@ interface GridRowProps<TRow = GridRowData> {
1778
1800
  onCellPointerEnter?: (ctx: CellSlotContext<TRow>, event: React.MouseEvent) => void;
1779
1801
  onCellDoubleClick?: (ctx: CellSlotContext<TRow>) => void;
1780
1802
  }
1781
- declare function GridRowImpl<TRow = GridRowData>({ gridId, node, index, layout, columnModel, centerColumns, centerIndices, stickyInsets, leadingSpacer, trailingSpacer, striped, selected, ariaSelectable, selectable, groupSelection, onToggleGroupSelect, groupDisplay, focusedColumnId, rowFocused, renderRow, checkboxColumn, statusColumn, rowNumberColumn, rowNumber, getNote, getSpan, resolveColSpans, findKind, headerRowCount, onRowClick, onRowMouseDown, onRowDoubleClick, onToggleSelect, onCellMouseDown, onRowContextMenu, searchNeedle, lookupLabels, onToggleGroup, summaryDefs, detailColumn, detailExpanded, onToggleDetail, onToggleTreeRow, renderDetail, renderEditForm, renderRowMessage, renderCellContent, getCellClassName, onCellPointerDown, onCellPointerEnter, onCellDoubleClick, rowDrag, dropSide, rowStatus, rowStatusText, rowStatusTint, rowStatusStrike, rowClass, height, }: GridRowProps<TRow>): react.JSX.Element | null;
1803
+ declare function GridRowImpl<TRow = GridRowData>({ gridId, node, index, layout, columnModel, centerColumns, centerIndices, stickyInsets, leadingSpacer, trailingSpacer, striped, selected, ariaSelectable, selectable, groupSelection, onToggleGroupSelect, groupDisplay, focusedColumnId, rowFocused, renderRow, checkboxColumn, statusColumn, rowNumberColumn, rowNumber, getNote, getSpan, resolveColSpans, findKind, headerRowCount, onRowClick, onRowMouseDown, onRowDoubleClick, onToggleSelect, onCellMouseDown, onRowContextMenu, searchNeedle, searchFold, lookupLabels, onToggleGroup, summaryDefs, detailColumn, detailExpanded, onToggleDetail, onToggleTreeRow, renderDetail, renderEditForm, renderRowMessage, renderCellContent, getCellClassName, onCellPointerDown, onCellPointerEnter, onCellDoubleClick, rowDrag, dropSide, rowStatus, rowStatusText, rowStatusTint, rowStatusStrike, rowClass, height, }: GridRowProps<TRow>): react.JSX.Element | null;
1782
1804
  declare const GridRow: typeof GridRowImpl;
1783
1805
 
1784
1806
  interface GridFilterRowProps<TRow = GridRowData> {
@@ -2485,11 +2507,13 @@ interface GridSurfaceProviderProps {
2485
2507
  theme?: GridThemeName;
2486
2508
  density?: GridDensity;
2487
2509
  palette?: GridPaletteName;
2510
+ /** Dark tokens for the popups too (`LookupBox` `dark`, B.9.13). */
2511
+ dark?: boolean;
2488
2512
  /** Where popups are drawn (the grid's `portalContainer`). Default <body>. */
2489
2513
  portalContainer?: PortalContainer;
2490
2514
  children: ReactNode;
2491
2515
  }
2492
- declare function GridSurfaceProvider({ theme, density, palette, portalContainer, children, }: GridSurfaceProviderProps): react.JSX.Element;
2516
+ declare function GridSurfaceProvider({ theme, density, palette, dark, portalContainer, children, }: GridSurfaceProviderProps): react.JSX.Element;
2493
2517
  /**
2494
2518
  * The element a popup is portalled into, read when the popup opens: <body>,
2495
2519
  * or the host inside the grid's `portalContainer` (core `portalTarget`).
@@ -2738,11 +2762,12 @@ interface UseGridEditingResult<TRow = GridRowData> {
2738
2762
  /**
2739
2763
  * A custom editor's commit (`renderEditor`'s `ctx.commit`, P-4.2): `'none'`
2740
2764
  * stays on the cell, `'down'` moves down (whatever `editKeys.enter` says —
2741
- * the editor asked), `'next'` / `'previous'` walk to the adjacent editable
2765
+ * the editor asked), `'enter'` is the grid's own Enter (down unless
2766
+ * `editKeys.enter`), `'next'` / `'previous'` walk to the adjacent editable
2742
2767
  * cell like Tab, `'blur'` leaves focus where it is. False when a rule
2743
2768
  * refused the value.
2744
2769
  */
2745
- commitCustomEditor: (move: 'down' | 'next' | 'previous' | 'none' | 'blur') => boolean;
2770
+ commitCustomEditor: (move: 'down' | 'enter' | 'next' | 'previous' | 'none' | 'blur') => boolean;
2746
2771
  /**
2747
2772
  * `ctx.suspendBlurCommit` (P-4.1): while on, blur is not leaving the editor
2748
2773
  * (`ctx.commitOnBlur`, the `commitOn: 'row'` send). Turning it off puts focus
@@ -2966,6 +2991,13 @@ interface GridLookupEditorProps {
2966
2991
  * field would open its list at once.
2967
2992
  */
2968
2993
  openOnEdit?: boolean;
2994
+ /**
2995
+ * Focusing or clicking the box opens the list. Default false (Tekax B.9.3):
2996
+ * the list opens on typing, ▾, F4, Alt+Down, Space (`editKeys.space`) or,
2997
+ * with `openOnEdit`, when the editor starts — so a Tab into a form field or
2998
+ * an editor opened with Enter shows the value, not a list over the rows.
2999
+ */
3000
+ openOnFocus?: boolean;
2969
3001
  /**
2970
3002
  * The editor was opened by TYPING and `value` is that one character: the
2971
3003
  * box starts with it as the typed text (list filtered by it, caret after
@@ -2985,6 +3017,48 @@ interface GridLookupEditorProps {
2985
3017
  * highlighted item; no match picks nothing. Ignored with `allowCustom`.
2986
3018
  */
2987
3019
  typeAhead?: boolean;
3020
+ /** A grip on the open list's corner to resize it (`lookup.listResizable`, B.4.3). */
3021
+ listResizable?: boolean;
3022
+ /** The list as a table with a header row (`lookup.listColumns`, B.4.2). */
3023
+ listColumns?: readonly LookupListColumn[];
3024
+ /** A ▾ button that opens and closes the list (`lookup.dropButton`, B.4.2). */
3025
+ dropButton?: boolean;
3026
+ /**
3027
+ * What the box shows and completes against (`lookup.display`, B.9.1):
3028
+ * `'code'`, `'name'` or `'both'`. Default: `'code'` for a `linked` list, the
3029
+ * label otherwise.
3030
+ */
3031
+ display?: 'code' | 'name' | 'both';
3032
+ /**
3033
+ * Does the pointer over an item move the highlight (what Enter, Tab and
3034
+ * leaving write)? Default true. False (B.9.6, `LookupBox`'s default): the
3035
+ * pointer only marks the item it is over; the keyboard's highlight stays.
3036
+ */
3037
+ hoverHighlights?: boolean;
3038
+ /** `lookup.openHighlight`: `'current'` opens on the current item, or the first (Tekax, 2026-11-12). */
3039
+ openHighlight?: 'none' | 'current';
3040
+ /** Text emptied and left: the value becomes null (B.9.7, `LookupBox`). Default false. */
3041
+ clearable?: boolean;
3042
+ /**
3043
+ * The list is on its way (B.9.8): typing is not refused, Enter picks
3044
+ * nothing, the list says so; once it arrives the text is checked against it
3045
+ * (cut back to what still matches) and completed.
3046
+ */
3047
+ loading?: boolean;
3048
+ /** Keys the box does not use (Insert, Ctrl+Delete, F-keys) go on to the page (B.9.9, `LookupBox`). */
3049
+ passKeys?: boolean;
3050
+ /** The "…" button is a Tab stop; Enter, Space, F4 and Alt+Down on it open the picker (B.9.14). */
3051
+ pickerTabStop?: boolean;
3052
+ /** `'picker-first'`: [box][…][▾] (B.9.14). Default [box][▾][…]. */
3053
+ buttonOrder?: 'drop-first' | 'picker-first';
3054
+ /** The buttons' accessible names (B.9.14): default "Choose from the full list" and the field's name. */
3055
+ pickerLabel?: string;
3056
+ dropLabel?: string;
3057
+ /** On the BOX (B.9.11): its id (for `<label for>`), form name, required, described-by. */
3058
+ inputId?: string;
3059
+ name?: string;
3060
+ required?: boolean;
3061
+ describedBy?: string;
2988
3062
  /**
2989
3063
  * Complete typed text to the one item left / an exact label on leaving.
2990
3064
  * Default true. False: the "pick from the list" rule (K-3, see the top).
@@ -3003,6 +3077,8 @@ interface GridLookupEditorProps {
3003
3077
  */
3004
3078
  onPick?: (item: LookupItem) => boolean;
3005
3079
  invalid?: boolean;
3080
+ /** A read-only field (`LookupBox`): the box and its buttons do nothing. */
3081
+ disabled?: boolean;
3006
3082
  /**
3007
3083
  * Take focus on mount. True for a cell editor — it opened BECAUSE the user
3008
3084
  * asked to edit that one cell. False in `row` mode, where every editable cell
@@ -3032,6 +3108,22 @@ interface GridLookupEditorProps {
3032
3108
  * settles the typed text, as before.
3033
3109
  */
3034
3110
  onBlurCommit?: () => void;
3111
+ /**
3112
+ * `lookup.onPickerOpen` (Tekax B.4.1), bound to the row: a "…" button and
3113
+ * Ctrl+Enter open the app's picker; its item is picked like a list item.
3114
+ */
3115
+ onPickerOpen?: (text: string) => Promise<LookupItem | null> | LookupItem | null;
3116
+ /**
3117
+ * The grid's `suspendBlurCommit` (P-4.1): held while the picker is open, so
3118
+ * focus going to the app's dialog neither commits the cell nor sends the row.
3119
+ */
3120
+ suspendBlurCommit?: (on: boolean, restoreTo?: () => HTMLElement | null) => void;
3121
+ /**
3122
+ * The grid's `setEditFlusher` (B.12.5 / B.9.19): the editor registers its
3123
+ * leaving rule, so a commit the editor did not start (`stopEditing()`,
3124
+ * `ctx.commit()`, a press elsewhere) writes what Tab would.
3125
+ */
3126
+ registerFlush?: (flush: (() => boolean) | null) => void;
3035
3127
  }
3036
3128
  /**
3037
3129
  * The same match, as items. Kept for callers and tests that want the simple
@@ -3039,19 +3131,22 @@ interface GridLookupEditorProps {
3039
3131
  */
3040
3132
  declare function matchOptions(options: readonly LookupItem[], query: string, mode: LookupMatchMode): readonly LookupItem[];
3041
3133
  /** The editor's settings that come straight from a column's `lookup`. */
3042
- type LookupEditorSettings = Pick<GridLookupEditorProps, 'matchMode' | 'codeMatchMode' | 'linked' | 'allowCustom' | 'autoCompleteSingle' | 'onNoMatch' | 'matchFold' | 'openOnEdit' | 'restrictInput' | 'typeAhead'>;
3134
+ type LookupEditorSettings = Pick<GridLookupEditorProps, 'matchMode' | 'codeMatchMode' | 'linked' | 'allowCustom' | 'autoCompleteSingle' | 'onNoMatch' | 'matchFold' | 'openOnEdit' | 'restrictInput' | 'typeAhead' | 'listResizable' | 'listColumns' | 'dropButton' | 'display' | 'hoverHighlights' | 'openHighlight'>;
3043
3135
  /** `lookup` → the editor's props, one reading for the cell, row and form editors. */
3044
3136
  declare function lookupEditorSettings(lookup: ColumnLookup<never> | undefined): LookupEditorSettings;
3045
- /**
3046
- * What one pick writes to the row (P-5.2 / P-5.3): the column's own value,
3047
- * `linkedColumns`' code / name / id, then `map`. Null when the column has
3048
- * neither — a plain pick, one cell, as before.
3049
- */
3050
3137
  declare function lookupPickValues(lookup: ColumnLookup<never> | undefined, columnId: string, item: LookupItem): Record<string, unknown> | null;
3051
- declare function GridLookupEditor({ options, value, matchMode, codeMatchMode, matchFold, linked, allowCustom, openOnEdit, seeded, restrictInput, typeAhead, autoCompleteSingle, onNoMatch, onPick, invalid, autoFocus, testId, columnId, ariaLabel, onChange, onCommit, commitOnPick, onCancel, onTab, onBlurCommit, }: GridLookupEditorProps): react.JSX.Element;
3138
+ declare function GridLookupEditor({ options, value, matchMode, codeMatchMode, matchFold, linked, allowCustom, openOnEdit, seeded, restrictInput, typeAhead, listResizable, listColumns, dropButton, openOnFocus, display, hoverHighlights, openHighlight, clearable, loading, passKeys, pickerTabStop, buttonOrder, pickerLabel, dropLabel, inputId, name, required, describedBy, autoCompleteSingle, onNoMatch, onPick, invalid, disabled, autoFocus, testId, columnId, ariaLabel, onChange, onCommit, commitOnPick, onCancel, onTab, onBlurCommit, onPickerOpen, suspendBlurCommit, registerFlush, }: GridLookupEditorProps): react.JSX.Element;
3052
3139
 
3053
3140
  interface GridCellEditorProps {
3054
3141
  value: unknown;
3142
+ /** The column's lookup when it is `multiple` (Tekax B.6): the check-box editor. */
3143
+ multipleLookup?: ColumnLookup<never>;
3144
+ /** `lookup.onPickerOpen`, bound to this cell (Tekax B.4.1). */
3145
+ onPickerOpen?: GridLookupEditorProps['onPickerOpen'];
3146
+ /** The engine's `setEditFlusher` (B.12.5): lookup and date editors register their leaving rule. */
3147
+ registerFlush?: (flush: (() => boolean) | null) => void;
3148
+ /** The grid's `suspendBlurCommit`, held while that picker is open. */
3149
+ suspendBlurCommit?: GridLookupEditorProps['suspendBlurCommit'];
3055
3150
  dataType: GridDataType | undefined;
3056
3151
  /**
3057
3152
  * Choices for a lookup/select editor. `null` means the list is still being
@@ -3106,7 +3201,7 @@ interface GridCellEditorProps {
3106
3201
  onTab: (direction: 1 | -1) => void;
3107
3202
  onCancel: () => void;
3108
3203
  }
3109
- declare function GridCellEditor({ value, dataType, error, seeded, seedText, options, allowCustom, matchMode, lookupSettings, onPick, ariaLabel, dateFormat, numberFormat, numberLocale, onChange, onCommit, onTab, onCancel, }: GridCellEditorProps): react.JSX.Element;
3204
+ declare function GridCellEditor({ value, dataType, error, seeded, seedText, options, allowCustom, matchMode, lookupSettings, onPick, multipleLookup, onPickerOpen, suspendBlurCommit, registerFlush, ariaLabel, dateFormat, numberFormat, numberLocale, onChange, onCommit, onTab, onCancel, }: GridCellEditorProps): react.JSX.Element;
3110
3205
 
3111
3206
  interface GridDateEditorProps {
3112
3207
  value: unknown;
@@ -3137,13 +3232,15 @@ interface GridDateEditorProps {
3137
3232
  * only settles the typed text, as before.
3138
3233
  */
3139
3234
  onBlurCommit?: () => void;
3235
+ /** The grid's `setEditFlusher` (B.12.5): a commit from elsewhere writes the typed (or cleared) day first. */
3236
+ registerFlush?: (flush: (() => boolean) | null) => void;
3140
3237
  /**
3141
3238
  * Digits the box starts with — the editor was opened by typing one on the
3142
3239
  * cell (P-3.6). The caret goes after them instead of selecting.
3143
3240
  */
3144
3241
  seedDigits?: string;
3145
3242
  }
3146
- declare function GridDateEditor({ value, format, invalid, disabled, autoFocus, testId, columnId, ariaLabel, onChange, onCommit, onCancel, onTab, onBlurCommit, seedDigits, }: GridDateEditorProps): react.JSX.Element;
3243
+ declare function GridDateEditor({ value, format, invalid, disabled, autoFocus, testId, columnId, ariaLabel, onChange, onCommit, onCancel, onTab, onBlurCommit, registerFlush, seedDigits, }: GridDateEditorProps): react.JSX.Element;
3147
3244
 
3148
3245
  interface GridDialogProps {
3149
3246
  open: boolean;