@iyulab/flex-table 0.10.0 → 0.10.2
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/clipboard/clipboard.d.ts +12 -0
- package/dist/clipboard/clipboard.test.d.ts +1 -0
- package/dist/core/editing.d.ts +15 -0
- package/dist/core/filtering.d.ts +28 -0
- package/dist/core/filtering.test.d.ts +1 -0
- package/dist/core/row-selection.d.ts +23 -0
- package/dist/core/selection.d.ts +55 -0
- package/dist/core/selection.test.d.ts +1 -0
- package/dist/core/sorting.d.ts +27 -0
- package/dist/core/sorting.test.d.ts +1 -0
- package/dist/core/undo.d.ts +45 -0
- package/dist/core/undo.test.d.ts +1 -0
- package/dist/export/export.d.ts +12 -0
- package/dist/export/export.test.d.ts +1 -0
- package/dist/{flex-table-C0CCHc1F.js → flex-table-DNBCgorV.js} +17 -17
- package/dist/flex-table.d.ts +238 -0
- package/dist/flex-table.js +1 -1
- package/dist/flex-table.test.d.ts +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/models/types.d.ts +65 -0
- package/dist/odata/index.d.ts +2 -0
- package/dist/odata/index.js +33 -33
- package/dist/odata/types.d.ts +19 -0
- package/dist/odata/use-odata-source.d.ts +6 -0
- package/dist/react.d.ts +29 -0
- package/dist/react.js +1 -1
- package/dist/renderers/cell-renderer.d.ts +5 -0
- package/dist/styles/flex-table.styles.d.ts +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CellRange } from '../core/selection.js';
|
|
2
|
+
import type { ColumnDefinition, DataRow } from '../models/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Copy selected range to clipboard as TSV.
|
|
5
|
+
*/
|
|
6
|
+
export declare function copyToClipboard(data: DataRow[], columns: ColumnDefinition[], range: CellRange): string;
|
|
7
|
+
/**
|
|
8
|
+
* Parse TSV/CSV clipboard text into a 2D array of strings.
|
|
9
|
+
* Handles RFC 4180 quoted fields: double-quote escaping, embedded tabs/newlines.
|
|
10
|
+
*/
|
|
11
|
+
export declare function parseClipboardText(text: string): string[][];
|
|
12
|
+
export declare function parseValueForColumn(raw: string, col: ColumnDefinition): unknown;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CellPosition } from './selection.js';
|
|
2
|
+
export interface EditState {
|
|
3
|
+
position: CellPosition;
|
|
4
|
+
originalValue: unknown;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Manages cell editing state.
|
|
8
|
+
*/
|
|
9
|
+
export declare class EditingState {
|
|
10
|
+
current: EditState | null;
|
|
11
|
+
start(position: CellPosition, originalValue: unknown): void;
|
|
12
|
+
isEditing(row: number, col: number): boolean;
|
|
13
|
+
cancel(): EditState | null;
|
|
14
|
+
commit(): EditState | null;
|
|
15
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { DataRow } from '../models/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Filter predicate function.
|
|
4
|
+
* Receives the cell value and the full row.
|
|
5
|
+
*/
|
|
6
|
+
export type FilterPredicate = (value: unknown, row: DataRow) => boolean;
|
|
7
|
+
/**
|
|
8
|
+
* A filter applied to a specific column.
|
|
9
|
+
*/
|
|
10
|
+
export interface ColumnFilter {
|
|
11
|
+
/** Column key this filter applies to */
|
|
12
|
+
key: string;
|
|
13
|
+
/** Filter predicate */
|
|
14
|
+
predicate: FilterPredicate;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Callback invoked when a filter predicate throws an error.
|
|
18
|
+
*/
|
|
19
|
+
export type FilterErrorCallback = (error: unknown, row: DataRow, filter: ColumnFilter) => void;
|
|
20
|
+
/**
|
|
21
|
+
* Compute filtered indices.
|
|
22
|
+
* Returns data indices that pass ALL filters (AND logic).
|
|
23
|
+
* Original data is never mutated.
|
|
24
|
+
*
|
|
25
|
+
* If a filter predicate throws, the row is included (fail-open)
|
|
26
|
+
* and the optional `onError` callback is invoked.
|
|
27
|
+
*/
|
|
28
|
+
export declare function computeFilteredIndices(data: DataRow[], filters: ColumnFilter[], onError?: FilterErrorCallback): number[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { SelectionMode } from '../models/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Manages row-level selection state (checkbox-based).
|
|
4
|
+
* Separate from cell-level SelectionState.
|
|
5
|
+
*/
|
|
6
|
+
export declare class RowSelectionState {
|
|
7
|
+
private _selected;
|
|
8
|
+
private _mode;
|
|
9
|
+
private _rowCount;
|
|
10
|
+
get mode(): SelectionMode;
|
|
11
|
+
set mode(value: SelectionMode);
|
|
12
|
+
setRowCount(count: number): void;
|
|
13
|
+
get selectedIndices(): number[];
|
|
14
|
+
get selectedCount(): number;
|
|
15
|
+
get isAllSelected(): boolean;
|
|
16
|
+
get isSomeSelected(): boolean;
|
|
17
|
+
isSelected(index: number): boolean;
|
|
18
|
+
toggle(index: number): void;
|
|
19
|
+
select(index: number): void;
|
|
20
|
+
deselect(index: number): void;
|
|
21
|
+
selectAll(): void;
|
|
22
|
+
deselectAll(): void;
|
|
23
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents the active cell position.
|
|
3
|
+
*/
|
|
4
|
+
export interface CellPosition {
|
|
5
|
+
row: number;
|
|
6
|
+
col: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A rectangular range of cells.
|
|
10
|
+
*/
|
|
11
|
+
export interface CellRange {
|
|
12
|
+
startRow: number;
|
|
13
|
+
startCol: number;
|
|
14
|
+
endRow: number;
|
|
15
|
+
endCol: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Returns normalized range (start <= end).
|
|
19
|
+
*/
|
|
20
|
+
export declare function normalizeRange(range: CellRange): CellRange;
|
|
21
|
+
/**
|
|
22
|
+
* Manages active cell state and range selection.
|
|
23
|
+
*/
|
|
24
|
+
export declare class SelectionState {
|
|
25
|
+
activeCell: CellPosition | null;
|
|
26
|
+
/** Anchor cell for range selection (Shift+Arrow/Click) */
|
|
27
|
+
rangeAnchor: CellPosition | null;
|
|
28
|
+
/** Current range end (the active cell is the range end during Shift selection) */
|
|
29
|
+
range: CellRange | null;
|
|
30
|
+
private _rowCount;
|
|
31
|
+
private _colCount;
|
|
32
|
+
setDimensions(rowCount: number, colCount: number): void;
|
|
33
|
+
setActive(row: number, col: number): CellPosition | null;
|
|
34
|
+
/** Set active cell and extend range from anchor */
|
|
35
|
+
setActiveWithRange(row: number, col: number): CellPosition | null;
|
|
36
|
+
/** Check if a cell is within the current selection range */
|
|
37
|
+
isInRange(row: number, col: number): boolean;
|
|
38
|
+
/** Get the effective range: either the explicit range or just the active cell */
|
|
39
|
+
getEffectiveRange(): CellRange | null;
|
|
40
|
+
clear(): void;
|
|
41
|
+
moveUp(): CellPosition | null;
|
|
42
|
+
moveDown(): CellPosition | null;
|
|
43
|
+
moveLeft(): CellPosition | null;
|
|
44
|
+
moveRight(): CellPosition | null;
|
|
45
|
+
moveNext(): CellPosition | null;
|
|
46
|
+
movePrev(): CellPosition | null;
|
|
47
|
+
moveToStart(): CellPosition | null;
|
|
48
|
+
moveToEnd(): CellPosition | null;
|
|
49
|
+
moveToRowStart(): CellPosition | null;
|
|
50
|
+
moveToRowEnd(): CellPosition | null;
|
|
51
|
+
shiftMoveUp(): CellPosition | null;
|
|
52
|
+
shiftMoveDown(): CellPosition | null;
|
|
53
|
+
shiftMoveLeft(): CellPosition | null;
|
|
54
|
+
shiftMoveRight(): CellPosition | null;
|
|
55
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ColumnDefinition, DataRow } from '../models/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Sort direction.
|
|
4
|
+
*/
|
|
5
|
+
export type SortDirection = 'asc' | 'desc';
|
|
6
|
+
/**
|
|
7
|
+
* A single sort criterion.
|
|
8
|
+
*/
|
|
9
|
+
export interface SortCriteria {
|
|
10
|
+
/** Column key to sort by */
|
|
11
|
+
key: string;
|
|
12
|
+
/** Sort direction */
|
|
13
|
+
direction: SortDirection;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Compute sorted index mapping.
|
|
17
|
+
* Returns an array where result[visualIndex] = dataIndex.
|
|
18
|
+
* Original data is never mutated.
|
|
19
|
+
*/
|
|
20
|
+
export declare function computeSortedIndices(data: DataRow[], criteria: SortCriteria[], columns: ColumnDefinition[]): number[];
|
|
21
|
+
/**
|
|
22
|
+
* Toggle sort for a column key in the criteria array.
|
|
23
|
+
* Cycle: none → asc → desc → none.
|
|
24
|
+
* If multi is true (Shift+click), add as secondary sort.
|
|
25
|
+
* If multi is false, replace all criteria with this column.
|
|
26
|
+
*/
|
|
27
|
+
export declare function toggleSort(criteria: SortCriteria[], key: string, multi: boolean): SortCriteria[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A single undoable action.
|
|
3
|
+
*/
|
|
4
|
+
export interface UndoAction {
|
|
5
|
+
/** Human-readable label for debugging */
|
|
6
|
+
label: string;
|
|
7
|
+
/** Revert the action */
|
|
8
|
+
undo: () => void;
|
|
9
|
+
/** Re-apply the action */
|
|
10
|
+
redo: () => void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Manages undo/redo history.
|
|
14
|
+
*/
|
|
15
|
+
export declare class UndoStack {
|
|
16
|
+
private _undoStack;
|
|
17
|
+
private _redoStack;
|
|
18
|
+
private _maxSize;
|
|
19
|
+
/** Get/set the maximum number of undo actions stored. */
|
|
20
|
+
get maxSize(): number;
|
|
21
|
+
set maxSize(value: number);
|
|
22
|
+
get canUndo(): boolean;
|
|
23
|
+
get canRedo(): boolean;
|
|
24
|
+
get undoCount(): number;
|
|
25
|
+
get redoCount(): number;
|
|
26
|
+
/**
|
|
27
|
+
* Push a new action onto the undo stack.
|
|
28
|
+
* Clears the redo stack (new action invalidates redo history).
|
|
29
|
+
*/
|
|
30
|
+
push(action: UndoAction): void;
|
|
31
|
+
/**
|
|
32
|
+
* Undo the most recent action.
|
|
33
|
+
* Returns the action label, or null if nothing to undo.
|
|
34
|
+
*/
|
|
35
|
+
undo(): string | null;
|
|
36
|
+
/**
|
|
37
|
+
* Redo the most recently undone action.
|
|
38
|
+
* Returns the action label, or null if nothing to redo.
|
|
39
|
+
*/
|
|
40
|
+
redo(): string | null;
|
|
41
|
+
/**
|
|
42
|
+
* Clear all undo/redo history.
|
|
43
|
+
*/
|
|
44
|
+
clear(): void;
|
|
45
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ColumnDefinition, DataRow } from '../models/types.js';
|
|
2
|
+
export type ExportFormat = 'csv' | 'tsv' | 'json';
|
|
3
|
+
/**
|
|
4
|
+
* Export data to the specified format.
|
|
5
|
+
*/
|
|
6
|
+
export declare function exportData(data: DataRow[], columns: ColumnDefinition[], format: ExportFormat): string;
|
|
7
|
+
/**
|
|
8
|
+
* Trigger a file download in the browser.
|
|
9
|
+
*/
|
|
10
|
+
export declare function downloadFile(content: string, filename: string, mimeType: string): void;
|
|
11
|
+
export declare function getExportMimeType(format: ExportFormat): string;
|
|
12
|
+
export declare function getExportExtension(format: ExportFormat): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -762,7 +762,7 @@ function it(t) {
|
|
|
762
762
|
}
|
|
763
763
|
return i;
|
|
764
764
|
}
|
|
765
|
-
function
|
|
765
|
+
function z(t, e) {
|
|
766
766
|
if (t === "") return null;
|
|
767
767
|
switch (e.type) {
|
|
768
768
|
case "number": {
|
|
@@ -775,7 +775,7 @@ function A(t, e) {
|
|
|
775
775
|
return t;
|
|
776
776
|
}
|
|
777
777
|
}
|
|
778
|
-
function
|
|
778
|
+
function A(t, e, i) {
|
|
779
779
|
switch (i) {
|
|
780
780
|
case "csv":
|
|
781
781
|
return U(t, e, ",");
|
|
@@ -837,10 +837,10 @@ var ht = Object.defineProperty, dt = Object.getOwnPropertyDescriptor, v = (t, e,
|
|
|
837
837
|
(n = t[r]) && (o = (s ? n(e, i, o) : n(o)) || o);
|
|
838
838
|
return s && o && ht(e, i, o), o;
|
|
839
839
|
};
|
|
840
|
-
const S = 120, E = 40, ut = 32,
|
|
840
|
+
const S = 120, E = 40, ut = 32, R = 5;
|
|
841
841
|
let _ = class extends T {
|
|
842
842
|
constructor() {
|
|
843
|
-
super(...arguments), this.columns = [], this.data = [], this.rowHeight = ut, this.showRowNumbers = !1, this.theme = void 0, this.maxRows = 0, this.editable = !0, this.showFilters = !1, this.selectable = !1, this.dataMode = "client", this.footerData = null, this._scrollTop = 0, this._scrollLeft = 0, this._viewportHeight = 0, this._viewportWidth = 0, this._colLeftOffsets = [], this._totalRowWidth = 0, this._activeCell = null, this._editingCell = null, this._sortCriteria = [], this._selection = new j(), this._editing = new B(), this._rowSelection = new X(), this._undo = new tt(), this._filters = [], this._filteredIndices = [], this._sortedIndices = [], this._openFilterKey = null, this._rowSelectionVersion = 0, this._viewDirty = !0, this._resizing = null, this._resizeCleanup = null, this._columnWidths = /* @__PURE__ */ new Map(), this._invalidCells = /* @__PURE__ */ new Map(), this._textFilterState = /* @__PURE__ */ new Map(), this._numberFilterState = /* @__PURE__ */ new Map(), this._dateFilterState = /* @__PURE__ */ new Map();
|
|
843
|
+
super(...arguments), this.columns = [], this.data = [], this.rowHeight = ut, this.showRowNumbers = !1, this.theme = void 0, this.maxRows = 0, this.editable = !0, this.showFilters = !1, this.selectable = !1, this.dataMode = "client", this.footerData = null, this._scrollTop = 0, this._scrollLeft = 0, this._viewportHeight = 0, this._viewportWidth = 0, this._colLeftOffsets = [], this._totalRowWidth = 0, this._activeCell = null, this._editingCell = null, this._sortCriteria = [], this._selection = new j(), this._editing = new B(), this._rowSelection = new X(), this._undo = new tt(), this._filters = [], this._filteredIndices = [], this._sortedIndices = [], this._openFilterKey = null, this._rowSelectionVersion = 0, this._viewDirty = !0, this._resizing = null, this._resizeCleanup = null, this._columnWidths = /* @__PURE__ */ new Map(), this._hostResizeObserver = null, this._invalidCells = /* @__PURE__ */ new Map(), this._textFilterState = /* @__PURE__ */ new Map(), this._numberFilterState = /* @__PURE__ */ new Map(), this._dateFilterState = /* @__PURE__ */ new Map();
|
|
844
844
|
}
|
|
845
845
|
set selectionMode(t) {
|
|
846
846
|
this._rowSelection.mode = t, this.requestUpdate();
|
|
@@ -1150,10 +1150,10 @@ let _ = class extends T {
|
|
|
1150
1150
|
const o = this.visibleColumns.slice(s.startCol, s.endCol + 1), r = [];
|
|
1151
1151
|
for (let n = s.startRow; n <= s.endRow; n++)
|
|
1152
1152
|
r.push(this.data[this._toDataIndex(n)]);
|
|
1153
|
-
return
|
|
1153
|
+
return A(r, o, t);
|
|
1154
1154
|
}
|
|
1155
1155
|
const i = this._sortedIndices.map((s) => this.data[s]);
|
|
1156
|
-
return
|
|
1156
|
+
return A(i, this.visibleColumns, t);
|
|
1157
1157
|
}
|
|
1158
1158
|
/**
|
|
1159
1159
|
* Export table data and trigger file download.
|
|
@@ -1191,14 +1191,14 @@ let _ = class extends T {
|
|
|
1191
1191
|
return this._visibleRowCount * this.rowHeight;
|
|
1192
1192
|
}
|
|
1193
1193
|
get visibleRange() {
|
|
1194
|
-
const t = Math.max(0, this._scrollTop - this.headerHeight), e = Math.max(0, Math.floor(t / this.rowHeight) -
|
|
1194
|
+
const t = Math.max(0, this._scrollTop - this.headerHeight), e = Math.max(0, Math.floor(t / this.rowHeight) - R), i = Math.ceil(this._viewportHeight / this.rowHeight), s = Math.min(this._visibleRowCount, Math.floor(t / this.rowHeight) + i + R);
|
|
1195
1195
|
return { start: e, end: s };
|
|
1196
1196
|
}
|
|
1197
1197
|
connectedCallback() {
|
|
1198
|
-
super.connectedCallback(), this._onScroll = this._onScroll.bind(this), this._onKeyDown = this._onKeyDown.bind(this), this._onDocumentClick = this._onDocumentClick.bind(this), this._onContextMenu = this._onContextMenu.bind(this), this.addEventListener("scroll", this._onScroll, { passive: !0 }), this.addEventListener("keydown", this._onKeyDown), this.addEventListener("contextmenu", this._onContextMenu), this.hasAttribute("tabindex") || this.setAttribute("tabindex", "0"), this.setAttribute("role", "grid");
|
|
1198
|
+
super.connectedCallback(), this._onScroll = this._onScroll.bind(this), this._onKeyDown = this._onKeyDown.bind(this), this._onDocumentClick = this._onDocumentClick.bind(this), this._onContextMenu = this._onContextMenu.bind(this), this.addEventListener("scroll", this._onScroll, { passive: !0 }), this.addEventListener("keydown", this._onKeyDown), this.addEventListener("contextmenu", this._onContextMenu), this.hasAttribute("tabindex") || this.setAttribute("tabindex", "0"), this.setAttribute("role", "grid"), typeof ResizeObserver < "u" && (this._hostResizeObserver = new ResizeObserver(() => this._measureViewport()), this._hostResizeObserver.observe(this));
|
|
1199
1199
|
}
|
|
1200
1200
|
disconnectedCallback() {
|
|
1201
|
-
super.disconnectedCallback(), this.removeEventListener("scroll", this._onScroll), this.removeEventListener("keydown", this._onKeyDown), this.removeEventListener("contextmenu", this._onContextMenu), document.removeEventListener("click", this._onDocumentClick), this._resizeCleanup && (this._resizeCleanup(), this._resizeCleanup = null);
|
|
1201
|
+
super.disconnectedCallback(), this.removeEventListener("scroll", this._onScroll), this.removeEventListener("keydown", this._onKeyDown), this.removeEventListener("contextmenu", this._onContextMenu), document.removeEventListener("click", this._onDocumentClick), this._resizeCleanup && (this._resizeCleanup(), this._resizeCleanup = null), this._hostResizeObserver && (this._hostResizeObserver.disconnect(), this._hostResizeObserver = null);
|
|
1202
1202
|
}
|
|
1203
1203
|
firstUpdated() {
|
|
1204
1204
|
this._measureViewport();
|
|
@@ -1222,20 +1222,20 @@ let _ = class extends T {
|
|
|
1222
1222
|
o = n;
|
|
1223
1223
|
break;
|
|
1224
1224
|
}
|
|
1225
|
-
o = Math.max(0, o -
|
|
1225
|
+
o = Math.max(0, o - R);
|
|
1226
1226
|
let r = t.length;
|
|
1227
1227
|
for (let n = o; n < e.length; n++)
|
|
1228
1228
|
if (e[n] > s) {
|
|
1229
1229
|
r = n;
|
|
1230
1230
|
break;
|
|
1231
1231
|
}
|
|
1232
|
-
return r = Math.min(t.length, r +
|
|
1232
|
+
return r = Math.min(t.length, r + R), { start: o, end: r };
|
|
1233
1233
|
}
|
|
1234
1234
|
willUpdate(t) {
|
|
1235
1235
|
(!(t.size <= 2 && !t.has("data") && !t.has("columns") && !t.has("_openFilterKey") && !t.has("_editingCell") && !t.has("_activeCell") && (t.has("_scrollTop") || t.has("_scrollLeft"))) || this._viewDirty) && (this._recomputeView(), this._viewDirty = !1), this._updateColOffsets(), this._selection.setDimensions(this._visibleRowCount, this.visibleColumns.length), this._rowSelection.setRowCount(this._visibleRowCount);
|
|
1236
1236
|
}
|
|
1237
1237
|
updated() {
|
|
1238
|
-
this.
|
|
1238
|
+
this._focusEditor(), this._adjustFilterDropdown(), this.setAttribute("aria-rowcount", String(this._visibleRowCount)), this.setAttribute("aria-colcount", String(this.visibleColumns.length));
|
|
1239
1239
|
}
|
|
1240
1240
|
/** Recompute filter → sort pipeline. */
|
|
1241
1241
|
_recomputeView() {
|
|
@@ -1340,7 +1340,7 @@ let _ = class extends T {
|
|
|
1340
1340
|
if (!this._editing.current) return;
|
|
1341
1341
|
const t = (e = this.shadowRoot) == null ? void 0 : e.querySelector(".ft-editor");
|
|
1342
1342
|
if (t) {
|
|
1343
|
-
const i = this.visibleColumns[this._editing.current.position.col], s =
|
|
1343
|
+
const i = this.visibleColumns[this._editing.current.position.col], s = z(t.value, i);
|
|
1344
1344
|
this._applyEdit(s);
|
|
1345
1345
|
} else
|
|
1346
1346
|
this._cancelEdit();
|
|
@@ -1546,7 +1546,7 @@ let _ = class extends T {
|
|
|
1546
1546
|
for (let l = 0; l < e[o].length; l++) {
|
|
1547
1547
|
const a = t.col + l;
|
|
1548
1548
|
if (a >= i.length) break;
|
|
1549
|
-
const d = i[a], f = this.data[n][d.key], h =
|
|
1549
|
+
const d = i[a], f = this.data[n][d.key], h = z(e[o][l], d);
|
|
1550
1550
|
this.data[n][d.key] = h, s.push({ row: n, col: a, key: d.key, oldValue: f, newValue: h });
|
|
1551
1551
|
}
|
|
1552
1552
|
}
|
|
@@ -1967,8 +1967,8 @@ let _ = class extends T {
|
|
|
1967
1967
|
`;
|
|
1968
1968
|
}
|
|
1969
1969
|
_renderCell(t, e, i, s) {
|
|
1970
|
-
var x,
|
|
1971
|
-
const o = ((x = this._activeCell) == null ? void 0 : x.row) === i && ((
|
|
1970
|
+
var x, $, D, F;
|
|
1971
|
+
const o = ((x = this._activeCell) == null ? void 0 : x.row) === i && (($ = this._activeCell) == null ? void 0 : $.col) === s, r = ((D = this._editingCell) == null ? void 0 : D.row) === i && ((F = this._editingCell) == null ? void 0 : F.col) === s, n = this._selection.isInRange(i, s), l = e.pinned === "left", a = e.pinned === "right", d = l || a, f = this._getColWidth(e), h = this.rowHeight, g = this._colLeftOffsets[s] ?? 0;
|
|
1972
1972
|
let p;
|
|
1973
1973
|
l ? p = `position: absolute; top: 0; left: ${this._scrollLeft + this._getPinnedLeft(s)}px; width: ${f}px; height: ${h}px; z-index: 2;` : a ? p = `position: absolute; top: 0; right: ${-this._scrollLeft + this._getPinnedRight(s)}px; width: ${f}px; height: ${h}px; z-index: 2;` : p = `left: ${g}px; width: ${f}px; height: ${h}px;`;
|
|
1974
1974
|
const c = !this._isCellEditable(e);
|
|
@@ -2132,6 +2132,6 @@ export {
|
|
|
2132
2132
|
_ as F,
|
|
2133
2133
|
X as R,
|
|
2134
2134
|
tt as U,
|
|
2135
|
-
|
|
2135
|
+
A as e,
|
|
2136
2136
|
H as r
|
|
2137
2137
|
};
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
import type { ExportFormat } from './export/export.js';
|
|
3
|
+
import type { CellPosition } from './core/selection.js';
|
|
4
|
+
import type { SortCriteria } from './core/sorting.js';
|
|
5
|
+
import type { FilterPredicate } from './core/filtering.js';
|
|
6
|
+
import type { ColumnDefinition, DataRow, SelectionMode, DataMode } from './models/types.js';
|
|
7
|
+
import type { TemplateResult } from 'lit';
|
|
8
|
+
export declare class FlexTable extends LitElement {
|
|
9
|
+
static styles: import("lit").CSSResult;
|
|
10
|
+
columns: ColumnDefinition[];
|
|
11
|
+
data: DataRow[];
|
|
12
|
+
rowHeight: number;
|
|
13
|
+
showRowNumbers: boolean;
|
|
14
|
+
theme: 'light' | 'dark' | undefined;
|
|
15
|
+
maxRows: number;
|
|
16
|
+
editable: boolean;
|
|
17
|
+
showFilters: boolean;
|
|
18
|
+
/** Enable row-level checkbox selection. */
|
|
19
|
+
selectable: boolean;
|
|
20
|
+
/** Row selection mode: 'single' or 'multi' (default: 'multi'). */
|
|
21
|
+
set selectionMode(value: SelectionMode);
|
|
22
|
+
get selectionMode(): SelectionMode;
|
|
23
|
+
/** Data processing mode: 'client' (default) or 'server'. */
|
|
24
|
+
dataMode: DataMode;
|
|
25
|
+
/** Footer/summary row data. Keys match column keys; values are display strings. */
|
|
26
|
+
footerData: Record<string, string | TemplateResult> | null;
|
|
27
|
+
set maxUndoSize(value: number);
|
|
28
|
+
get maxUndoSize(): number;
|
|
29
|
+
private _scrollTop;
|
|
30
|
+
private _scrollLeft;
|
|
31
|
+
private _viewportHeight;
|
|
32
|
+
private _viewportWidth;
|
|
33
|
+
private _colLeftOffsets;
|
|
34
|
+
private _totalRowWidth;
|
|
35
|
+
private _activeCell;
|
|
36
|
+
private _editingCell;
|
|
37
|
+
private _sortCriteria;
|
|
38
|
+
private _selection;
|
|
39
|
+
private _editing;
|
|
40
|
+
private _rowSelection;
|
|
41
|
+
private _undo;
|
|
42
|
+
private _filters;
|
|
43
|
+
private _filteredIndices;
|
|
44
|
+
private _sortedIndices;
|
|
45
|
+
private _openFilterKey;
|
|
46
|
+
private _rowSelectionVersion;
|
|
47
|
+
private _viewDirty;
|
|
48
|
+
private _resizing;
|
|
49
|
+
private _resizeCleanup;
|
|
50
|
+
private _columnWidths;
|
|
51
|
+
private _hostResizeObserver;
|
|
52
|
+
get visibleColumns(): ColumnDefinition[];
|
|
53
|
+
private get _prefixWidth();
|
|
54
|
+
/** Whether an undo operation is available. */
|
|
55
|
+
get canUndo(): boolean;
|
|
56
|
+
/** Whether a redo operation is available. */
|
|
57
|
+
get canRedo(): boolean;
|
|
58
|
+
get activeCell(): CellPosition | null;
|
|
59
|
+
get editingCell(): CellPosition | null;
|
|
60
|
+
get sortCriteria(): SortCriteria[];
|
|
61
|
+
/** Number of rows after filtering (before pagination). */
|
|
62
|
+
get filteredRowCount(): number;
|
|
63
|
+
/** Get data indices of currently selected rows. */
|
|
64
|
+
getSelectedRows(): {
|
|
65
|
+
selectedIndices: number[];
|
|
66
|
+
selectedRows: DataRow[];
|
|
67
|
+
};
|
|
68
|
+
/** Select all visible rows (multi mode only). */
|
|
69
|
+
selectAll(): void;
|
|
70
|
+
/** Deselect all rows. */
|
|
71
|
+
deselectAll(): void;
|
|
72
|
+
private _dispatchRowSelectionEvent;
|
|
73
|
+
/**
|
|
74
|
+
* Set a filter for a column. Replaces any existing filter on the same key.
|
|
75
|
+
*/
|
|
76
|
+
setFilter(key: string, predicate: FilterPredicate): void;
|
|
77
|
+
/**
|
|
78
|
+
* Remove the filter for a column.
|
|
79
|
+
*/
|
|
80
|
+
removeFilter(key: string): void;
|
|
81
|
+
/**
|
|
82
|
+
* Remove all filters.
|
|
83
|
+
*/
|
|
84
|
+
clearFilters(): void;
|
|
85
|
+
/**
|
|
86
|
+
* Get current active filter keys.
|
|
87
|
+
*/
|
|
88
|
+
get filterKeys(): string[];
|
|
89
|
+
/**
|
|
90
|
+
* Explicitly request a re-render after external data mutations.
|
|
91
|
+
* Useful when `data` array contents are mutated in-place without reassignment.
|
|
92
|
+
*/
|
|
93
|
+
refreshData(): void;
|
|
94
|
+
private _dispatchUndoStateEvent;
|
|
95
|
+
private _dispatchFilterEvent;
|
|
96
|
+
/**
|
|
97
|
+
* Add a column at the specified index (default: end).
|
|
98
|
+
* Returns the added column definition.
|
|
99
|
+
*/
|
|
100
|
+
addColumn(def: ColumnDefinition, index?: number): ColumnDefinition;
|
|
101
|
+
/**
|
|
102
|
+
* Delete a column by its key.
|
|
103
|
+
* Removes related filters, sort criteria, and column width overrides.
|
|
104
|
+
*/
|
|
105
|
+
deleteColumn(key: string): void;
|
|
106
|
+
/**
|
|
107
|
+
* Move a column to a new position.
|
|
108
|
+
* @param key Column key to move.
|
|
109
|
+
* @param newIndex Target index in the columns array.
|
|
110
|
+
*/
|
|
111
|
+
moveColumn(key: string, newIndex: number): void;
|
|
112
|
+
/**
|
|
113
|
+
* Add a row at the specified index (default: end).
|
|
114
|
+
* Returns the new row.
|
|
115
|
+
*/
|
|
116
|
+
addRow(row?: DataRow, index?: number): DataRow | null;
|
|
117
|
+
/**
|
|
118
|
+
* Delete rows at the specified data indices.
|
|
119
|
+
* If no indices provided, deletes the currently selected rows.
|
|
120
|
+
*/
|
|
121
|
+
deleteRows(indices?: number[]): void;
|
|
122
|
+
/**
|
|
123
|
+
* Apply multiple cell changes as a single undo-able operation.
|
|
124
|
+
* @param changes Array of { row (data index), key, value } objects.
|
|
125
|
+
*/
|
|
126
|
+
updateRows(changes: Array<{
|
|
127
|
+
row: number;
|
|
128
|
+
key: string;
|
|
129
|
+
value: unknown;
|
|
130
|
+
}>): void;
|
|
131
|
+
private _createEmptyRow;
|
|
132
|
+
/**
|
|
133
|
+
* Export table data to string in the specified format.
|
|
134
|
+
* @param options.selectionOnly - Export only the currently selected range
|
|
135
|
+
*/
|
|
136
|
+
exportToString(format: ExportFormat, options?: {
|
|
137
|
+
selectionOnly?: boolean;
|
|
138
|
+
}): string;
|
|
139
|
+
/**
|
|
140
|
+
* Export table data and trigger file download.
|
|
141
|
+
*/
|
|
142
|
+
exportToFile(format: ExportFormat, filename?: string): void;
|
|
143
|
+
private _getSelectedDataRows;
|
|
144
|
+
/**
|
|
145
|
+
* Get the effective width for a column, checking internal overrides first.
|
|
146
|
+
*/
|
|
147
|
+
getColumnWidth(key: string): number | undefined;
|
|
148
|
+
private _getColWidth;
|
|
149
|
+
private get headerHeight();
|
|
150
|
+
/** Number of rows visible after filter + sort. */
|
|
151
|
+
private get _visibleRowCount();
|
|
152
|
+
private get totalBodyHeight();
|
|
153
|
+
private get visibleRange();
|
|
154
|
+
connectedCallback(): void;
|
|
155
|
+
disconnectedCallback(): void;
|
|
156
|
+
protected firstUpdated(): void;
|
|
157
|
+
private _updateColOffsets;
|
|
158
|
+
private get visibleColRange();
|
|
159
|
+
protected willUpdate(changedProperties: Map<string, unknown>): void;
|
|
160
|
+
protected updated(): void;
|
|
161
|
+
/** Recompute filter → sort pipeline. */
|
|
162
|
+
private _recomputeView;
|
|
163
|
+
/** Map visual row index to data row index */
|
|
164
|
+
private _toDataIndex;
|
|
165
|
+
private _focusEditor;
|
|
166
|
+
private _measureViewport;
|
|
167
|
+
private _onScroll;
|
|
168
|
+
private _onDocumentClick;
|
|
169
|
+
private _onContextMenu;
|
|
170
|
+
private _onCellClickEvent;
|
|
171
|
+
private _onRowNumberClick;
|
|
172
|
+
private _onCellDblClick;
|
|
173
|
+
/** Check if a column is editable based on global + per-column settings */
|
|
174
|
+
private _isCellEditable;
|
|
175
|
+
private _startEdit;
|
|
176
|
+
private _commitEdit;
|
|
177
|
+
private _applyEdit;
|
|
178
|
+
private _cancelEdit;
|
|
179
|
+
private _onEditorKeyDown;
|
|
180
|
+
private _syncActiveCell;
|
|
181
|
+
private _onKeyDown;
|
|
182
|
+
private _handleCtrlKey;
|
|
183
|
+
private _handleAltKey;
|
|
184
|
+
private _handleNavigation;
|
|
185
|
+
private _handleCopy;
|
|
186
|
+
private _handlePaste;
|
|
187
|
+
private _readClipboardText;
|
|
188
|
+
private _expandRowsForPaste;
|
|
189
|
+
private _applyPasteData;
|
|
190
|
+
private _handleDelete;
|
|
191
|
+
private _clearRange;
|
|
192
|
+
private _scrollToActiveCell;
|
|
193
|
+
private _dispatchSelectionEvent;
|
|
194
|
+
private _onHeaderClick;
|
|
195
|
+
private _selectColumn;
|
|
196
|
+
/** Public API: select an entire column by index. */
|
|
197
|
+
selectColumn(colIndex: number): void;
|
|
198
|
+
/** Calculate cumulative left offset for a left-pinned column */
|
|
199
|
+
private _getPinnedLeft;
|
|
200
|
+
/** Calculate cumulative right offset for a right-pinned column */
|
|
201
|
+
private _getPinnedRight;
|
|
202
|
+
private _renderHeaderCell;
|
|
203
|
+
private _adjustFilterDropdown;
|
|
204
|
+
private _onFilterBtnClick;
|
|
205
|
+
private _renderFilterDropdown;
|
|
206
|
+
private _renderTextFilter;
|
|
207
|
+
private _renderNumberFilter;
|
|
208
|
+
private _invalidCells;
|
|
209
|
+
private _cellKey;
|
|
210
|
+
private _markCellInvalid;
|
|
211
|
+
private _isCellInvalid;
|
|
212
|
+
private _textFilterState;
|
|
213
|
+
private _numberFilterState;
|
|
214
|
+
private _dateFilterState;
|
|
215
|
+
private _applyNumberFilter;
|
|
216
|
+
private _renderDateFilter;
|
|
217
|
+
private _applyDateFilter;
|
|
218
|
+
private _renderBooleanFilter;
|
|
219
|
+
private _clearColumnFilter;
|
|
220
|
+
private _onResizeAutoFit;
|
|
221
|
+
private _onResizeStart;
|
|
222
|
+
render(): TemplateResult<1>;
|
|
223
|
+
private _onSelectAllChange;
|
|
224
|
+
private _onRowCheckboxChange;
|
|
225
|
+
private _renderFooter;
|
|
226
|
+
private _renderRow;
|
|
227
|
+
private _renderCell;
|
|
228
|
+
private _renderEditor;
|
|
229
|
+
/** Convert value to YYYY-MM-DD for date input (local timezone) */
|
|
230
|
+
private _toDateInputValue;
|
|
231
|
+
/** Convert value to YYYY-MM-DDTHH:mm for datetime-local input (local timezone) */
|
|
232
|
+
private _toDateTimeInputValue;
|
|
233
|
+
}
|
|
234
|
+
declare global {
|
|
235
|
+
interface HTMLElementTagNameMap {
|
|
236
|
+
'flex-table': FlexTable;
|
|
237
|
+
}
|
|
238
|
+
}
|
package/dist/flex-table.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import './flex-table.js';
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { FlexTable } from './flex-table.js';
|
|
2
|
+
export type { ColumnDefinition, ColumnType, DataRow, CellRenderer, CellEditor, CellValidator, SelectionMode, DataMode } from './models/types.js';
|
|
3
|
+
export type { CellPosition, CellRange } from './core/selection.js';
|
|
4
|
+
export type { SortCriteria, SortDirection } from './core/sorting.js';
|
|
5
|
+
export type { ColumnFilter, FilterPredicate, FilterErrorCallback } from './core/filtering.js';
|
|
6
|
+
export { RowSelectionState } from './core/row-selection.js';
|
|
7
|
+
export { UndoStack } from './core/undo.js';
|
|
8
|
+
export type { UndoAction } from './core/undo.js';
|
|
9
|
+
export type { ExportFormat } from './export/export.js';
|
|
10
|
+
export { exportData } from './export/export.js';
|
|
11
|
+
export { renderCell } from './renderers/cell-renderer.js';
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { TemplateResult } from 'lit';
|
|
2
|
+
/**
|
|
3
|
+
* Built-in column data types for rendering and editing.
|
|
4
|
+
* Any string is accepted as a type — unknown types fall back to 'text' behavior.
|
|
5
|
+
*/
|
|
6
|
+
export type ColumnType = 'text' | 'number' | 'boolean' | 'date' | 'datetime' | (string & {});
|
|
7
|
+
/**
|
|
8
|
+
* Custom cell renderer function.
|
|
9
|
+
* Receives the cell value, the full row data, and the column definition.
|
|
10
|
+
* Returns either a Lit TemplateResult or a plain string.
|
|
11
|
+
*/
|
|
12
|
+
export type CellRenderer = (value: unknown, row: DataRow, col: ColumnDefinition) => TemplateResult | string;
|
|
13
|
+
/**
|
|
14
|
+
* Custom cell editor function.
|
|
15
|
+
* Receives the cell value, the full row data, and the column definition.
|
|
16
|
+
* Should return a Lit TemplateResult containing an input element with class "ft-editor".
|
|
17
|
+
*/
|
|
18
|
+
export type CellEditor = (value: unknown, row: DataRow, col: ColumnDefinition) => TemplateResult;
|
|
19
|
+
/**
|
|
20
|
+
* Cell validator function. Returns null/undefined if valid, or an error message string.
|
|
21
|
+
*/
|
|
22
|
+
export type CellValidator = (value: unknown, row: DataRow, col: ColumnDefinition) => string | null | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Row selection mode.
|
|
25
|
+
*/
|
|
26
|
+
export type SelectionMode = 'single' | 'multi';
|
|
27
|
+
/**
|
|
28
|
+
* Data processing mode.
|
|
29
|
+
* - 'client': flex-table performs sorting/filtering locally (default).
|
|
30
|
+
* - 'server': flex-table only dispatches events; consumer provides pre-sorted/filtered data.
|
|
31
|
+
*/
|
|
32
|
+
export type DataMode = 'client' | 'server';
|
|
33
|
+
/**
|
|
34
|
+
* Definition of a single column in the table.
|
|
35
|
+
*/
|
|
36
|
+
export interface ColumnDefinition {
|
|
37
|
+
/** Unique key matching data property names */
|
|
38
|
+
key: string;
|
|
39
|
+
/** Display header text */
|
|
40
|
+
header: string;
|
|
41
|
+
/** Data type for rendering/editing (default: 'text'). Unknown types fall back to 'text'. */
|
|
42
|
+
type?: ColumnType;
|
|
43
|
+
/** Column width in pixels (default: auto) */
|
|
44
|
+
width?: number;
|
|
45
|
+
/** Minimum column width in pixels (default: 40) */
|
|
46
|
+
minWidth?: number;
|
|
47
|
+
/** Whether the column is hidden */
|
|
48
|
+
hidden?: boolean;
|
|
49
|
+
/** Whether the column is sortable (default: true) */
|
|
50
|
+
sortable?: boolean;
|
|
51
|
+
/** Custom cell renderer — overrides built-in type rendering */
|
|
52
|
+
renderer?: CellRenderer;
|
|
53
|
+
/** Whether the column is editable (default: true — follows global editable setting) */
|
|
54
|
+
editable?: boolean;
|
|
55
|
+
/** Custom cell editor — overrides built-in type editing */
|
|
56
|
+
editor?: CellEditor;
|
|
57
|
+
/** Pin the column to one side during horizontal scroll */
|
|
58
|
+
pinned?: 'left' | 'right';
|
|
59
|
+
/** Cell validator — called before committing edits */
|
|
60
|
+
validator?: CellValidator;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* A single data row — schema-agnostic key-value map.
|
|
64
|
+
*/
|
|
65
|
+
export type DataRow = Record<string, unknown>;
|
package/dist/odata/index.js
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
import { useState as r, useRef as
|
|
1
|
+
import { useState as r, useRef as z, useCallback as m, useEffect as K } from "react";
|
|
2
2
|
import Q from "odata-query";
|
|
3
|
-
function I(
|
|
4
|
-
const { pageSize: a = 20, defaultOrderBy:
|
|
5
|
-
|
|
6
|
-
}, []),
|
|
7
|
-
|
|
8
|
-
}, []),
|
|
9
|
-
var
|
|
10
|
-
const
|
|
11
|
-
|
|
3
|
+
function I(c, d = {}) {
|
|
4
|
+
const { pageSize: a = 20, defaultOrderBy: n, fixedFilter: l } = d, x = l ? JSON.stringify(l) : "", [O, S] = r([]), [B, b] = r(0), [E, C] = r(!1), [R, g] = r(null), [h, p] = r(0), [u, T] = r(() => n ? U(n) : []), [f, q] = r(""), [A, D] = r(0), k = z(null), F = m(() => {
|
|
5
|
+
D((e) => e + 1);
|
|
6
|
+
}, []), J = m((e) => {
|
|
7
|
+
q(e), p(0);
|
|
8
|
+
}, []), L = m((e) => {
|
|
9
|
+
var o;
|
|
10
|
+
const i = (o = e.detail) == null ? void 0 : o.criteria;
|
|
11
|
+
i && (T(i), p(0));
|
|
12
12
|
}, []);
|
|
13
|
-
return
|
|
13
|
+
return K(() => {
|
|
14
14
|
var w;
|
|
15
15
|
(w = k.current) == null || w.abort();
|
|
16
16
|
const e = new AbortController();
|
|
17
17
|
k.current = e, C(!0), g(null);
|
|
18
|
-
const
|
|
18
|
+
const i = u.length > 0 ? u.map((t) => `${t.key} ${t.direction}`).join(", ") : n, o = {
|
|
19
19
|
top: a,
|
|
20
20
|
skip: h * a,
|
|
21
21
|
count: !0
|
|
22
22
|
};
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
return fetch(
|
|
23
|
+
i && (o.orderBy = i), l && (o.filter = l), f && (o.search = f);
|
|
24
|
+
const N = Q(o), P = `${window.location.origin}${c}${N}`;
|
|
25
|
+
return fetch(P, { signal: e.signal }).then(async (t) => {
|
|
26
26
|
var $;
|
|
27
27
|
if (!t.ok) {
|
|
28
|
-
const
|
|
29
|
-
let
|
|
28
|
+
const v = await t.text().catch(() => "");
|
|
29
|
+
let y = `요청 실패 (${t.status})`;
|
|
30
30
|
try {
|
|
31
|
-
const s = JSON.parse(
|
|
32
|
-
|
|
31
|
+
const s = JSON.parse(v);
|
|
32
|
+
y = (($ = s == null ? void 0 : s.error) == null ? void 0 : $.message) ?? (s == null ? void 0 : s.message) ?? y;
|
|
33
33
|
} catch {
|
|
34
34
|
}
|
|
35
|
-
throw new Error(
|
|
35
|
+
throw new Error(y);
|
|
36
36
|
}
|
|
37
37
|
return t.json();
|
|
38
38
|
}).then((t) => {
|
|
@@ -42,27 +42,27 @@ function I(i, f = {}) {
|
|
|
42
42
|
}).finally(() => {
|
|
43
43
|
e.signal.aborted || C(!1);
|
|
44
44
|
}), () => e.abort();
|
|
45
|
-
}, [
|
|
46
|
-
data:
|
|
45
|
+
}, [c, h, a, u, f, x, n, A]), {
|
|
46
|
+
data: O,
|
|
47
47
|
totalCount: B,
|
|
48
48
|
loading: E,
|
|
49
|
-
error:
|
|
49
|
+
error: R,
|
|
50
50
|
page: h,
|
|
51
51
|
setPage: p,
|
|
52
|
-
sortCriteria:
|
|
53
|
-
onSortChange:
|
|
54
|
-
search:
|
|
55
|
-
setSearch:
|
|
56
|
-
refresh:
|
|
52
|
+
sortCriteria: u,
|
|
53
|
+
onSortChange: L,
|
|
54
|
+
search: f,
|
|
55
|
+
setSearch: J,
|
|
56
|
+
refresh: F
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
-
function U(
|
|
60
|
-
return
|
|
61
|
-
var
|
|
62
|
-
const a =
|
|
59
|
+
function U(c) {
|
|
60
|
+
return c.split(",").map((d) => {
|
|
61
|
+
var n;
|
|
62
|
+
const a = d.trim().split(/\s+/);
|
|
63
63
|
return {
|
|
64
64
|
key: a[0],
|
|
65
|
-
direction: ((
|
|
65
|
+
direction: ((n = a[1]) == null ? void 0 : n.toLowerCase()) === "desc" ? "desc" : "asc"
|
|
66
66
|
};
|
|
67
67
|
});
|
|
68
68
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { SortCriteria } from '../core/sorting.js';
|
|
2
|
+
export interface UseODataSourceOptions {
|
|
3
|
+
pageSize?: number;
|
|
4
|
+
defaultOrderBy?: string;
|
|
5
|
+
fixedFilter?: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
export interface UseODataSourceResult<T> {
|
|
8
|
+
data: T[];
|
|
9
|
+
totalCount: number;
|
|
10
|
+
loading: boolean;
|
|
11
|
+
error: string | null;
|
|
12
|
+
page: number;
|
|
13
|
+
setPage: (page: number) => void;
|
|
14
|
+
sortCriteria: SortCriteria[];
|
|
15
|
+
onSortChange: (e: CustomEvent) => void;
|
|
16
|
+
setSearch: (term: string) => void;
|
|
17
|
+
search: string;
|
|
18
|
+
refresh: () => void;
|
|
19
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { UseODataSourceOptions, UseODataSourceResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* OData v4 서버 사이드 데이터소스 React 훅.
|
|
4
|
+
* flex-table의 dataMode="server"와 함께 사용한다.
|
|
5
|
+
*/
|
|
6
|
+
export declare function useODataSource<T = Record<string, unknown>>(url: string, options?: UseODataSourceOptions): UseODataSourceResult<T>;
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type EventName } from '@lit/react';
|
|
2
|
+
import { FlexTable } from './flex-table.js';
|
|
3
|
+
export declare const FlexTableReact: import("@lit/react").ReactWebComponent<FlexTable, {
|
|
4
|
+
onCellSelect: EventName<CustomEvent>;
|
|
5
|
+
onCellEditCommit: EventName<CustomEvent>;
|
|
6
|
+
onCellEditCancel: EventName<CustomEvent>;
|
|
7
|
+
onCellEditStart: EventName<CustomEvent>;
|
|
8
|
+
onSortChange: EventName<CustomEvent>;
|
|
9
|
+
onFilterChange: EventName<CustomEvent>;
|
|
10
|
+
onRowAdd: EventName<CustomEvent>;
|
|
11
|
+
onRowDelete: EventName<CustomEvent>;
|
|
12
|
+
onColumnResize: EventName<CustomEvent>;
|
|
13
|
+
onColumnSelect: EventName<CustomEvent>;
|
|
14
|
+
onColumnAdd: EventName<CustomEvent>;
|
|
15
|
+
onColumnDelete: EventName<CustomEvent>;
|
|
16
|
+
onColumnReorder: EventName<CustomEvent>;
|
|
17
|
+
onSelectionChange: EventName<CustomEvent>;
|
|
18
|
+
onClipboardCopy: EventName<CustomEvent>;
|
|
19
|
+
onClipboardCut: EventName<CustomEvent>;
|
|
20
|
+
onClipboardPaste: EventName<CustomEvent>;
|
|
21
|
+
onClipboardError: EventName<CustomEvent>;
|
|
22
|
+
onUndoStateChange: EventName<CustomEvent>;
|
|
23
|
+
onValidationError: EventName<CustomEvent>;
|
|
24
|
+
onBatchUpdate: EventName<CustomEvent>;
|
|
25
|
+
onContextMenu: EventName<CustomEvent>;
|
|
26
|
+
onFilterError: EventName<CustomEvent>;
|
|
27
|
+
}>;
|
|
28
|
+
export type { FlexTable };
|
|
29
|
+
export type { ColumnDefinition, DataRow, ColumnType, CellRenderer, CellEditor, CellValidator, SelectionMode, DataMode } from './models/types.js';
|
package/dist/react.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const flexTableStyles: import("lit").CSSResult;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iyulab/flex-table",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.2",
|
|
4
4
|
"description": "A minimalist, input-centric data grid web component",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/flex-table.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
],
|
|
26
26
|
"scripts": {
|
|
27
27
|
"dev": "vite serve demo",
|
|
28
|
-
"build": "
|
|
28
|
+
"build": "vite build && tsc --emitDeclarationOnly",
|
|
29
29
|
"build:demo": "vite build --config vite.config.demo.ts",
|
|
30
30
|
"typecheck": "tsc --noEmit",
|
|
31
31
|
"test": "vitest run",
|