@iyulab/flex-table 0.10.1 → 0.11.0

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.
@@ -1,6 +1,6 @@
1
1
  import { LitElement } from 'lit';
2
2
  import type { ExportFormat } from './export/export.js';
3
- import type { CellPosition } from './core/selection.js';
3
+ import type { CellPosition, CellRange } from './core/selection.js';
4
4
  import type { SortCriteria } from './core/sorting.js';
5
5
  import type { FilterPredicate } from './core/filtering.js';
6
6
  import type { ColumnDefinition, DataRow, SelectionMode, DataMode } from './models/types.js';
@@ -45,9 +45,18 @@ export declare class FlexTable extends LitElement {
45
45
  private _openFilterKey;
46
46
  private _rowSelectionVersion;
47
47
  private _viewDirty;
48
+ private _isDragging;
49
+ private _wasDrag;
48
50
  private _resizing;
49
51
  private _resizeCleanup;
52
+ private _colDrag;
53
+ private _colDragIndicatorLeft;
54
+ private _fillDrag;
55
+ private _rowDrag;
56
+ private _rowDragIndicatorY;
57
+ private _findState;
50
58
  private _columnWidths;
59
+ private _hostResizeObserver;
51
60
  get visibleColumns(): ColumnDefinition[];
52
61
  private get _prefixWidth();
53
62
  /** Whether an undo operation is available. */
@@ -167,6 +176,8 @@ export declare class FlexTable extends LitElement {
167
176
  private _onDocumentClick;
168
177
  private _onContextMenu;
169
178
  private _onCellClickEvent;
179
+ private _onCellMouseDown;
180
+ private _onCellMouseEnter;
170
181
  private _onRowNumberClick;
171
182
  private _onCellDblClick;
172
183
  /** Check if a column is editable based on global + per-column settings */
@@ -186,7 +197,10 @@ export declare class FlexTable extends LitElement {
186
197
  private _readClipboardText;
187
198
  private _expandRowsForPaste;
188
199
  private _applyPasteData;
200
+ private _handleFillDown;
201
+ private _handleFillRight;
189
202
  private _handleDelete;
203
+ private _clearRanges;
190
204
  private _clearRange;
191
205
  private _scrollToActiveCell;
192
206
  private _dispatchSelectionEvent;
@@ -218,6 +232,30 @@ export declare class FlexTable extends LitElement {
218
232
  private _clearColumnFilter;
219
233
  private _onResizeAutoFit;
220
234
  private _onResizeStart;
235
+ private _onHeaderMouseDown;
236
+ private _startColumnGhost;
237
+ private _updateColumnDrag;
238
+ private _finishColumnDrag;
239
+ private _onFillHandleMouseDown;
240
+ private _updateFillDrag;
241
+ _applyFillHandle(sourceRange: CellRange, targetRange: CellRange): void;
242
+ private _detectNumericSeries;
243
+ private _renderFillHandle;
244
+ private _renderFillPreview;
245
+ private _onRowNumMouseDown;
246
+ private _startRowGhost;
247
+ private _updateRowDrag;
248
+ private _finishRowDrag;
249
+ private _toggleFindPanel;
250
+ _openFindPanel(mode: 'find' | 'replace'): void;
251
+ private _closeFindPanel;
252
+ _findSearch(): void;
253
+ private _findGoTo;
254
+ private _findNext;
255
+ private _findPrev;
256
+ _replaceAll(): void;
257
+ private _replaceOne;
258
+ private _renderFindPanel;
221
259
  render(): TemplateResult<1>;
222
260
  private _onSelectAllChange;
223
261
  private _onRowCheckboxChange;
@@ -1,8 +1,2 @@
1
- import { F as t, R as o, U as r, e as l, r as s } from "./flex-table-C0CCHc1F.js";
2
- export {
3
- t as FlexTable,
4
- o as RowSelectionState,
5
- r as UndoStack,
6
- l as exportData,
7
- s as renderCell
8
- };
1
+ import { a as e, i as t, n, r, t as i } from "./flex-table-DJvbRtBl.js";
2
+ export { i as FlexTable, t as RowSelectionState, r as UndoStack, n as exportData, e as renderCell };
@@ -3,7 +3,12 @@ import type { TemplateResult } from 'lit';
3
3
  * Built-in column data types for rendering and editing.
4
4
  * Any string is accepted as a type — unknown types fall back to 'text' behavior.
5
5
  */
6
- export type ColumnType = 'text' | 'number' | 'boolean' | 'date' | 'datetime' | (string & {});
6
+ export type ColumnType = 'text' | 'number' | 'boolean' | 'date' | 'datetime' | 'select' | (string & {});
7
+ /** Option item for select columns */
8
+ export interface SelectOption {
9
+ label: string;
10
+ value: unknown;
11
+ }
7
12
  /**
8
13
  * Custom cell renderer function.
9
14
  * Receives the cell value, the full row data, and the column definition.
@@ -58,6 +63,8 @@ export interface ColumnDefinition {
58
63
  pinned?: 'left' | 'right';
59
64
  /** Cell validator — called before committing edits */
60
65
  validator?: CellValidator;
66
+ /** Allowed values for select columns (strings or label/value pairs) */
67
+ options?: string[] | SelectOption[];
61
68
  }
62
69
  /**
63
70
  * A single data row — schema-agnostic key-value map.
@@ -1,71 +1,74 @@
1
- import { useState as r, useRef as J, useCallback as y, useEffect as N } from "react";
2
- import Q from "odata-query";
3
- function I(i, f = {}) {
4
- const { pageSize: a = 20, defaultOrderBy: o, fixedFilter: d } = f, [x, S] = r([]), [B, b] = r(0), [E, C] = r(!1), [O, g] = r(null), [h, p] = r(0), [l, R] = r(() => o ? U(o) : []), [u, T] = r(""), [q, A] = r(0), k = J(null), D = y(() => {
5
- A((e) => e + 1);
6
- }, []), L = y((e) => {
7
- T(e), p(0);
8
- }, []), P = y((e) => {
9
- var n;
10
- const c = (n = e.detail) == null ? void 0 : n.criteria;
11
- c && (R(c), p(0));
12
- }, []);
13
- return N(() => {
14
- var w;
15
- (w = k.current) == null || w.abort();
16
- const e = new AbortController();
17
- k.current = e, C(!0), g(null);
18
- const c = l.length > 0 ? l.map((t) => `${t.key} ${t.direction}`).join(", ") : o, n = {
19
- top: a,
20
- skip: h * a,
21
- count: !0
22
- };
23
- c && (n.orderBy = c), d && (n.filter = d), u && (n.search = u);
24
- const v = Q(n), z = `${window.location.origin}${i}${v}`;
25
- return fetch(z, { signal: e.signal }).then(async (t) => {
26
- var $;
27
- if (!t.ok) {
28
- const F = await t.text().catch(() => "");
29
- let m = `요청 실패 (${t.status})`;
30
- try {
31
- const s = JSON.parse(F);
32
- m = (($ = s == null ? void 0 : s.error) == null ? void 0 : $.message) ?? (s == null ? void 0 : s.message) ?? m;
33
- } catch {
34
- }
35
- throw new Error(m);
36
- }
37
- return t.json();
38
- }).then((t) => {
39
- e.signal.aborted || (S(t.value ?? t), b(t["@odata.count"] ?? 0), g(null));
40
- }).catch((t) => {
41
- e.signal.aborted || t.name !== "AbortError" && (g(t.message), S([]), b(0));
42
- }).finally(() => {
43
- e.signal.aborted || C(!1);
44
- }), () => e.abort();
45
- }, [i, h, a, l, u, d, o, q]), {
46
- data: x,
47
- totalCount: B,
48
- loading: E,
49
- error: O,
50
- page: h,
51
- setPage: p,
52
- sortCriteria: l,
53
- onSortChange: P,
54
- search: u,
55
- setSearch: L,
56
- refresh: D
57
- };
1
+ import { useCallback as e, useEffect as t, useRef as n, useState as r } from "react";
2
+ import i from "odata-query";
3
+ //#region src/odata/use-odata-source.ts
4
+ function a(a, s = {}) {
5
+ let { pageSize: c = 20, defaultOrderBy: l, fixedFilter: u } = s, d = u ? JSON.stringify(u) : "", [f, p] = r([]), [m, h] = r(0), [g, _] = r(!1), [v, y] = r(null), [b, x] = r(0), [S, C] = r(() => l ? o(l) : []), [w, T] = r(""), [E, D] = r(0), O = n(null), k = e(() => {
6
+ D((e) => e + 1);
7
+ }, []), A = e((e) => {
8
+ T(e), x(0);
9
+ }, []), j = e((e) => {
10
+ let t = e.detail?.criteria;
11
+ t && (C(t), x(0));
12
+ }, []);
13
+ return t(() => {
14
+ O.current?.abort();
15
+ let e = new AbortController();
16
+ O.current = e, _(!0), y(null);
17
+ let t = S.length > 0 ? S.map((e) => `${e.key} ${e.direction}`).join(", ") : l, n = {
18
+ top: c,
19
+ skip: b * c,
20
+ count: !0
21
+ };
22
+ t && (n.orderBy = t), u && (n.filter = u), w && (n.search = w);
23
+ let r = i(n), o = `${window.location.origin}${a}${r}`;
24
+ return fetch(o, { signal: e.signal }).then(async (e) => {
25
+ if (!e.ok) {
26
+ let t = await e.text().catch(() => ""), n = `요청 실패 (${e.status})`;
27
+ try {
28
+ let e = JSON.parse(t);
29
+ n = e?.error?.message ?? e?.message ?? n;
30
+ } catch {}
31
+ throw Error(n);
32
+ }
33
+ return e.json();
34
+ }).then((t) => {
35
+ e.signal.aborted || (p(t.value ?? t), h(t["@odata.count"] ?? 0), y(null));
36
+ }).catch((t) => {
37
+ e.signal.aborted || t.name !== "AbortError" && (y(t.message), p([]), h(0));
38
+ }).finally(() => {
39
+ e.signal.aborted || _(!1);
40
+ }), () => e.abort();
41
+ }, [
42
+ a,
43
+ b,
44
+ c,
45
+ S,
46
+ w,
47
+ d,
48
+ l,
49
+ E
50
+ ]), {
51
+ data: f,
52
+ totalCount: m,
53
+ loading: g,
54
+ error: v,
55
+ page: b,
56
+ setPage: x,
57
+ sortCriteria: S,
58
+ onSortChange: j,
59
+ search: w,
60
+ setSearch: A,
61
+ refresh: k
62
+ };
58
63
  }
59
- function U(i) {
60
- return i.split(",").map((f) => {
61
- var o;
62
- const a = f.trim().split(/\s+/);
63
- return {
64
- key: a[0],
65
- direction: ((o = a[1]) == null ? void 0 : o.toLowerCase()) === "desc" ? "desc" : "asc"
66
- };
67
- });
64
+ function o(e) {
65
+ return e.split(",").map((e) => {
66
+ let t = e.trim().split(/\s+/);
67
+ return {
68
+ key: t[0],
69
+ direction: t[1]?.toLowerCase() === "desc" ? "desc" : "asc"
70
+ };
71
+ });
68
72
  }
69
- export {
70
- I as useODataSource
71
- };
73
+ //#endregion
74
+ export { a as useODataSource };
package/dist/react.js CHANGED
@@ -1,36 +1,36 @@
1
- import e from "react";
2
- import { createComponent as o } from "@lit/react";
3
- import { F as l } from "./flex-table-C0CCHc1F.js";
4
- const a = o({
5
- tagName: "flex-table",
6
- elementClass: l,
7
- react: e,
8
- events: {
9
- onCellSelect: "cell-select",
10
- onCellEditCommit: "cell-edit-commit",
11
- onCellEditCancel: "cell-edit-cancel",
12
- onCellEditStart: "cell-edit-start",
13
- onSortChange: "sort-change",
14
- onFilterChange: "filter-change",
15
- onRowAdd: "row-add",
16
- onRowDelete: "row-delete",
17
- onColumnResize: "column-resize",
18
- onColumnSelect: "column-select",
19
- onColumnAdd: "column-add",
20
- onColumnDelete: "column-delete",
21
- onColumnReorder: "column-reorder",
22
- onSelectionChange: "selection-change",
23
- onClipboardCopy: "clipboard-copy",
24
- onClipboardCut: "clipboard-cut",
25
- onClipboardPaste: "clipboard-paste",
26
- onClipboardError: "clipboard-error",
27
- onUndoStateChange: "undo-state-change",
28
- onValidationError: "validation-error",
29
- onBatchUpdate: "batch-update",
30
- onContextMenu: "context-menu",
31
- onFilterError: "filter-error"
32
- }
1
+ import { t as e } from "./flex-table-DJvbRtBl.js";
2
+ import t from "react";
3
+ import { createComponent as n } from "@lit/react";
4
+ //#region src/react.ts
5
+ var r = n({
6
+ tagName: "flex-table",
7
+ elementClass: e,
8
+ react: t,
9
+ events: {
10
+ onCellSelect: "cell-select",
11
+ onCellEditCommit: "cell-edit-commit",
12
+ onCellEditCancel: "cell-edit-cancel",
13
+ onCellEditStart: "cell-edit-start",
14
+ onSortChange: "sort-change",
15
+ onFilterChange: "filter-change",
16
+ onRowAdd: "row-add",
17
+ onRowDelete: "row-delete",
18
+ onColumnResize: "column-resize",
19
+ onColumnSelect: "column-select",
20
+ onColumnAdd: "column-add",
21
+ onColumnDelete: "column-delete",
22
+ onColumnReorder: "column-reorder",
23
+ onSelectionChange: "selection-change",
24
+ onClipboardCopy: "clipboard-copy",
25
+ onClipboardCut: "clipboard-cut",
26
+ onClipboardPaste: "clipboard-paste",
27
+ onClipboardError: "clipboard-error",
28
+ onUndoStateChange: "undo-state-change",
29
+ onValidationError: "validation-error",
30
+ onBatchUpdate: "batch-update",
31
+ onContextMenu: "context-menu",
32
+ onFilterError: "filter-error"
33
+ }
33
34
  });
34
- export {
35
- a as FlexTableReact
36
- };
35
+ //#endregion
36
+ export { r as FlexTableReact };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iyulab/flex-table",
3
- "version": "0.10.1",
3
+ "version": "0.11.0",
4
4
  "description": "A minimalist, input-centric data grid web component",
5
5
  "type": "module",
6
6
  "main": "./dist/flex-table.js",
@@ -52,7 +52,7 @@
52
52
  "url": "https://github.com/iyulab/flex-table/issues"
53
53
  },
54
54
  "dependencies": {
55
- "lit": "^3.2.0",
55
+ "lit": "^3.3.3",
56
56
  "odata-query": "^8.0.7"
57
57
  },
58
58
  "peerDependencies": {
@@ -70,16 +70,16 @@
70
70
  "devDependencies": {
71
71
  "@lit/react": "^1.0.8",
72
72
  "@types/react": "^19.2.14",
73
- "@typescript-eslint/eslint-plugin": "^8.58.0",
74
- "@typescript-eslint/parser": "^8.58.0",
73
+ "@typescript-eslint/eslint-plugin": "^8.59.3",
74
+ "@typescript-eslint/parser": "^8.59.3",
75
75
  "eslint": "^10.1.0",
76
- "eslint-plugin-lit": "^2.2.1",
77
- "jsdom": "^28.1.0",
76
+ "eslint-plugin-lit": "^2.3.1",
77
+ "jsdom": "^29.1.1",
78
78
  "loupe": "^3.2.1",
79
- "react": "^19.2.4",
79
+ "react": "^19.2.6",
80
80
  "strip-literal": "^3.1.0",
81
81
  "typescript": "~5.7.0",
82
- "vite": "^6.0.0",
83
- "vitest": "^3.0.0"
82
+ "vite": "^8.0.13",
83
+ "vitest": "^4.1.6"
84
84
  }
85
85
  }