open-grid 0.3.2 → 1.0.0-rc.1
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/README.md +3 -2
- package/dist/OpenGrid-C6SK6VeK.cjs +90 -0
- package/dist/OpenGrid-C6SK6VeK.cjs.map +1 -0
- package/dist/OpenGrid-D7EJOVi1.js +4864 -0
- package/dist/OpenGrid-D7EJOVi1.js.map +1 -0
- package/dist/open-grid-base.css +14 -0
- package/dist/open-grid-react.cjs +1 -1
- package/dist/open-grid-react.js +1 -1
- package/dist/open-grid-vue.cjs +1 -1
- package/dist/open-grid-vue.js +1 -1
- package/dist/open-grid.cjs +6 -6
- package/dist/open-grid.cjs.map +1 -1
- package/dist/open-grid.js +224 -172
- package/dist/open-grid.js.map +1 -1
- package/dist/types/core/CellEditManager.d.ts +2 -3
- package/dist/types/core/CellEventHandler.d.ts +4 -5
- package/dist/types/core/CellTypeRegistry.d.ts +1 -2
- package/dist/types/core/ColumnLayout.d.ts +1 -2
- package/dist/types/core/ContextMenu.d.ts +1 -2
- package/dist/types/core/CrossGridMapper.d.ts +21 -0
- package/dist/types/core/CrossGridRegistry.d.ts +12 -0
- package/dist/types/core/DataLayer.d.ts +4 -2
- package/dist/types/core/DragVisuals.d.ts +23 -0
- package/dist/types/core/ExportManager.d.ts +4 -3
- package/dist/types/core/FilterPanel.d.ts +1 -2
- package/dist/types/core/FilterSelect.d.ts +1 -2
- package/dist/types/core/FindBarManager.d.ts +4 -5
- package/dist/types/core/FooterManager.d.ts +2 -1
- package/dist/types/core/FormulaEngine.d.ts +1 -2
- package/dist/types/core/GridRenderer.d.ts +3 -2
- package/dist/types/core/GridShuttle.d.ts +24 -0
- package/dist/types/core/GroupEngine.d.ts +7 -4
- package/dist/types/core/GroupTreeManager.d.ts +6 -3
- package/dist/types/core/KeyboardManager.d.ts +4 -5
- package/dist/types/core/OpenGrid.d.ts +55 -4
- package/dist/types/core/OverrideKernel.d.ts +70 -0
- package/dist/types/core/PivotEngine.d.ts +1 -2
- package/dist/types/core/RowDragDrop.d.ts +25 -5
- package/dist/types/core/RowManager.d.ts +0 -1
- package/dist/types/core/SortFilterManager.d.ts +5 -6
- package/dist/types/core/TriggerManager.d.ts +1 -2
- package/dist/types/core/WorksheetManager.d.ts +1 -2
- package/dist/types/core/editors/CellEditor.d.ts +2 -3
- package/dist/types/core/editors/DateEditor.d.ts +2 -3
- package/dist/types/core/editors/SelectEditor.d.ts +2 -3
- package/dist/types/core/renderers/CellRenderer.d.ts +15 -4
- package/dist/types/core/types.d.ts +115 -0
- package/dist/types/index.d.ts +3 -1
- package/dist/types/react/OpenGrid.d.ts +3 -3
- package/dist/types/vue/types.d.ts +1 -2
- package/package.json +99 -102
- package/dist/OpenGrid-CzP1mcZW.cjs +0 -90
- package/dist/OpenGrid-CzP1mcZW.cjs.map +0 -1
- package/dist/OpenGrid-Dult64jp.js +0 -4401
- package/dist/OpenGrid-Dult64jp.js.map +0 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OverrideKernel — `grid.override()` 확장 커널 (94 최종 종합본 반영)
|
|
3
|
+
*
|
|
4
|
+
* 핵심 원칙(94 §1 F1~F4):
|
|
5
|
+
* - F2: FIFO 합성 = `reduce` 좌측폴드. 먼저 등록 = 안쪽(원본 근접), 나중 등록 = 바깥.
|
|
6
|
+
* `[fn1,fn2,fn3]` → 실행 시 fn3(최후등록)이 최외곽, orig() 호출이 안쪽으로 전파.
|
|
7
|
+
* - F3: 재진입 가드 = 깊이 제한(maxDepth 기본 32) + 호출경로 사이클 감지(_callPath, 동일 name
|
|
8
|
+
* 재출현 시 차단) + 명시적 { reentrant:true } 옵트인. 정당한 cascade는 깊이 내 허용.
|
|
9
|
+
* - F4: 에러 격리 = 기본 strict=true(예외 전파). { onError:'fallback' } 옵트인 시에만
|
|
10
|
+
* 경고 후 orig fallback(멱등 가정, 롤백 불가).
|
|
11
|
+
*
|
|
12
|
+
* 본 커널은 단독 클래스로, OpenGrid 인스턴스를 host 로 받아 프로토타입 메서드를
|
|
13
|
+
* 인스턴스 프로퍼티로 shadowing(순수 런타임 래핑, C1-clean) 한다. 소스 본문 0줄 수정.
|
|
14
|
+
*/
|
|
15
|
+
export interface OverrideKernelHost {
|
|
16
|
+
[name: string]: any;
|
|
17
|
+
}
|
|
18
|
+
/** override() 호출 시 레이어가 받는 함수 시그니처: 첫 인자는 안쪽(원본 근접) 함수. */
|
|
19
|
+
export type OverrideLayer = (orig: (...args: any[]) => any, ...args: any[]) => any;
|
|
20
|
+
export interface OverrideOptions {
|
|
21
|
+
/** 동일 name 재진입을 허용(정당한 재귀). 기본 false. */
|
|
22
|
+
reentrant?: boolean;
|
|
23
|
+
/** 'fallback' → 레이어 예외 시 경고 후 orig 실행(멱등 가정). 미지정 시 strict(전파). */
|
|
24
|
+
onError?: 'fallback';
|
|
25
|
+
}
|
|
26
|
+
export declare class OverrideKernel {
|
|
27
|
+
private _host;
|
|
28
|
+
/** name → this-bound 원본 함수 (최초 1회 보존) */
|
|
29
|
+
private _originals;
|
|
30
|
+
/** name → 최초 override 직전 host 가 own 프로퍼티로 메서드를 가졌는지(복구 방식 결정) */
|
|
31
|
+
private _hadOwn;
|
|
32
|
+
/** name → 레이어 목록(등록순, FIFO) */
|
|
33
|
+
private _stack;
|
|
34
|
+
/** slot → strategy 함수 */
|
|
35
|
+
private _strategies;
|
|
36
|
+
/** F3: 현재 호출 경로(메서드 name 스택) — 사이클 감지용 */
|
|
37
|
+
private _callPath;
|
|
38
|
+
/** F4: 기본 strict (예외 전파) */
|
|
39
|
+
private _strict;
|
|
40
|
+
/** F3: 재귀 깊이 제한 */
|
|
41
|
+
private _maxDepth;
|
|
42
|
+
constructor(host: OverrideKernelHost, opts?: {
|
|
43
|
+
strict?: boolean;
|
|
44
|
+
maxDepth?: number;
|
|
45
|
+
});
|
|
46
|
+
/**
|
|
47
|
+
* 메서드 override 등록.
|
|
48
|
+
* 1. 최초 1회 원본을 this-bound 로 보존.
|
|
49
|
+
* 2. 레이어 push (FIFO 등록순).
|
|
50
|
+
* 3. reduce 좌측폴드로 합성(나중 등록 = 최외곽).
|
|
51
|
+
* 4. 재진입 가드 + 에러 격리로 감싼 dispatcher 를 host[name] 인스턴스 프로퍼티에 할당.
|
|
52
|
+
*/
|
|
53
|
+
override(name: string, fn: OverrideLayer, opts?: OverrideOptions): OverrideKernelHost;
|
|
54
|
+
/** 합성된 dispatcher 생성. override/restore 시점마다 재구성. */
|
|
55
|
+
private _buildDispatcher;
|
|
56
|
+
/** strategy 슬롯 등록 (Phase 2 매니저 배선용 API). */
|
|
57
|
+
strategy(slot: string, fn: Function): OverrideKernelHost;
|
|
58
|
+
/** strategy 슬롯 조회 — 미등록 시 fallback 반환 (매니저 read API). */
|
|
59
|
+
getStrategy<F extends Function>(slot: string, fallback: F): F;
|
|
60
|
+
/** 슬롯 등록 여부. */
|
|
61
|
+
hasStrategy(slot: string): boolean;
|
|
62
|
+
/** 단일 메서드 원본 복구. 없으면 no-op. */
|
|
63
|
+
restore(name: string): OverrideKernelHost;
|
|
64
|
+
/** 전체 복구 + strategy clear. destroy 시 호출. */
|
|
65
|
+
restoreAll(): OverrideKernelHost;
|
|
66
|
+
/** override 등록 여부. */
|
|
67
|
+
hasOverride(name: string): boolean;
|
|
68
|
+
/** override 등록된 메서드 이름 목록. */
|
|
69
|
+
getOverrideNames(): string[];
|
|
70
|
+
}
|
|
@@ -1,14 +1,34 @@
|
|
|
1
1
|
export type RowDropCallback = (fromIndex: number, toIndex: number) => void;
|
|
2
|
+
/** 커서 좌표로 다른 그리드의 바디를 찾는 해석기 */
|
|
3
|
+
export interface CrossGridResolveResult {
|
|
4
|
+
bodyEl: HTMLElement;
|
|
5
|
+
rowHeight: number;
|
|
6
|
+
totalRows: number;
|
|
7
|
+
}
|
|
8
|
+
export interface CrossGridConfig {
|
|
9
|
+
/** 커서 위치(x,y)에 있는 다른(crossGrid 허용) 그리드 바디 정보 반환. 없으면 null */
|
|
10
|
+
resolveTarget: (clientX: number, clientY: number) => CrossGridResolveResult | null;
|
|
11
|
+
/** 다른 그리드로 드롭됐을 때 호출 (소스 fromIndex, 타깃 바디, 타깃 삽입 인덱스) */
|
|
12
|
+
onCrossDrop: (fromIndex: number, targetBodyEl: HTMLElement, targetIndex: number) => void;
|
|
13
|
+
}
|
|
2
14
|
/**
|
|
3
|
-
* 행 드래그앤드롭
|
|
4
|
-
* 행 DOM에 드래그 핸들을 심고,
|
|
15
|
+
* 행 드래그앤드롭 관리자 (순수 DnD).
|
|
16
|
+
* 행 DOM에 드래그 핸들을 심고, 고스트/인디케이터로 위치를 표시한 뒤 콜백으로 알림.
|
|
17
|
+
* 그리드 간 이동 판정(타깃 그리드 해석)은 주입된 CrossGridConfig 에 위임한다.
|
|
5
18
|
*/
|
|
6
19
|
export declare class RowDragDrop {
|
|
7
|
-
private _drag;
|
|
8
|
-
private _onDrop;
|
|
9
20
|
private _bodyEl;
|
|
10
21
|
private _rowHeight;
|
|
11
|
-
|
|
22
|
+
private _onDrop;
|
|
23
|
+
private _cross;
|
|
24
|
+
/** fromIndex 기준 함께 드래그할 행 수(멀티행 배지용). 기본 1 */
|
|
25
|
+
private _getDragCount;
|
|
26
|
+
private _drag;
|
|
27
|
+
private readonly _selfIndicator;
|
|
28
|
+
private readonly _crossIndicator;
|
|
29
|
+
constructor(_bodyEl: HTMLElement, _rowHeight: number, _onDrop: RowDropCallback, _cross?: CrossGridConfig | null,
|
|
30
|
+
/** fromIndex 기준 함께 드래그할 행 수(멀티행 배지용). 기본 1 */
|
|
31
|
+
_getDragCount?: (fromIndex: number) => number);
|
|
12
32
|
/** 행 엘리먼트에 드래그 핸들 삽입 */
|
|
13
33
|
attachHandle(rowEl: HTMLElement, rowIndex: number, totalRows: number): HTMLElement;
|
|
14
34
|
private _startDrag;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { DataLayer } from './DataLayer.js';
|
|
2
|
-
import { ColumnLayout } from './ColumnLayout.js';
|
|
3
|
-
import { VirtualScroll } from './VirtualScroll.js';
|
|
4
|
-
import { Pagination } from './Pagination.js';
|
|
5
|
-
import { SortItem, FilterItem } from './types.js';
|
|
6
|
-
|
|
1
|
+
import type { DataLayer } from './DataLayer.js';
|
|
2
|
+
import type { ColumnLayout } from './ColumnLayout.js';
|
|
3
|
+
import type { VirtualScroll } from './VirtualScroll.js';
|
|
4
|
+
import type { Pagination } from './Pagination.js';
|
|
5
|
+
import type { SortItem, FilterItem } from './types.js';
|
|
7
6
|
export interface SortFilterDeps<T extends Record<string, any>> {
|
|
8
7
|
getData: () => DataLayer<T>;
|
|
9
8
|
getColLayout: () => ColumnLayout<T>;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { TriggerContext, TriggerHandler, TriggerEvent } from './types.js';
|
|
2
|
-
|
|
1
|
+
import type { TriggerContext, TriggerHandler, TriggerEvent } from './types.js';
|
|
3
2
|
export declare class TriggerManager {
|
|
4
3
|
private _triggers;
|
|
5
4
|
add(event: TriggerEvent | string, handler: TriggerHandler): void;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { ColumnDef, WorksheetState } from './types.js';
|
|
2
|
-
|
|
1
|
+
import type { ColumnDef, WorksheetState } from './types.js';
|
|
3
2
|
export type SwitchCallback<T> = (name: string, state: WorksheetState<T>) => void;
|
|
4
3
|
export declare class WorksheetManager<T extends Record<string, any> = any> {
|
|
5
4
|
private _sheets;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { ColumnDef } from '../types.js';
|
|
2
|
-
import { RenderContext } from '../renderers/CellRenderer.js';
|
|
3
|
-
|
|
1
|
+
import type { ColumnDef } from '../types.js';
|
|
2
|
+
import type { RenderContext } from '../renderers/CellRenderer.js';
|
|
4
3
|
export { DateEditor } from './DateEditor.js';
|
|
5
4
|
export { SelectEditor } from './SelectEditor.js';
|
|
6
5
|
export interface EditorResult {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { CellEditor } from './CellEditor.js';
|
|
2
|
-
import { RenderContext } from '../renderers/CellRenderer.js';
|
|
3
|
-
|
|
1
|
+
import type { CellEditor } from './CellEditor.js';
|
|
2
|
+
import type { RenderContext } from '../renderers/CellRenderer.js';
|
|
4
3
|
export declare class DateEditor implements CellEditor {
|
|
5
4
|
private input;
|
|
6
5
|
private _container;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { CellEditor } from './CellEditor.js';
|
|
2
|
-
import { RenderContext } from '../renderers/CellRenderer.js';
|
|
3
|
-
|
|
1
|
+
import type { CellEditor } from './CellEditor.js';
|
|
2
|
+
import type { RenderContext } from '../renderers/CellRenderer.js';
|
|
4
3
|
export type SelectOption = string | {
|
|
5
4
|
label?: string;
|
|
6
5
|
text?: string;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { ColumnDef } from '../types.js';
|
|
2
|
-
|
|
1
|
+
import type { ColumnDef } from '../types.js';
|
|
3
2
|
export interface RenderContext<T = any> {
|
|
4
3
|
value: any;
|
|
5
4
|
row: T;
|
|
@@ -12,13 +11,25 @@ export interface RenderContext<T = any> {
|
|
|
12
11
|
export interface CellRenderer {
|
|
13
12
|
render(ctx: RenderContext): HTMLElement;
|
|
14
13
|
}
|
|
14
|
+
export declare function setDisplayFormatterResolver(resolver: ((value: any, field: string, row: any) => string | null) | null): void;
|
|
15
15
|
/**
|
|
16
16
|
* 컬럼에 formula가 있으면 OGDecimal로 평가해 표시값(string)을 반환.
|
|
17
17
|
* formula가 없으면 null 반환 → 기존 ctx.value 사용.
|
|
18
18
|
*/
|
|
19
19
|
export declare function resolveFormula(ctx: RenderContext): string | null;
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
/**
|
|
21
|
+
* 숫자 포맷.
|
|
22
|
+
* format 문자열:
|
|
23
|
+
* '#,##0' 천단위 콤마, 정수
|
|
24
|
+
* '#,##0.00' 천단위 콤마, 소수 2자리
|
|
25
|
+
* '₩#,##0' 통화 접두 (₩1,234)
|
|
26
|
+
* '$#,##0.00' 통화 접두 ($1,234.56)
|
|
27
|
+
* '#,##0원' 통화 접미 (1,234원)
|
|
28
|
+
* '$#,##0;($#,##0)' 양수;음수 패턴 — 음수를 괄호로 (회계식)
|
|
29
|
+
* currency: ISO 통화코드('KRW'|'USD'|'EUR'…) 지정 시 Intl.NumberFormat 로케일 통화 포맷 우선.
|
|
30
|
+
*/
|
|
31
|
+
export declare function formatNumber(value: any, format?: string, precision?: number, currency?: string, field?: string, row?: any): string;
|
|
32
|
+
export declare function formatDate(value: any, format?: string, field?: string, row?: any): string;
|
|
22
33
|
export declare class TextRenderer implements CellRenderer {
|
|
23
34
|
render(ctx: RenderContext): HTMLElement;
|
|
24
35
|
}
|
|
@@ -68,6 +68,36 @@ export interface DragDropEvent<T = any> {
|
|
|
68
68
|
targetIndex: number;
|
|
69
69
|
targetGridId?: string;
|
|
70
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* 그리드↔그리드 행 이동 이벤트.
|
|
73
|
+
* crossGrid:true 인 두 그리드 사이에서 행을 드래그·드롭할 때 3단계로 발생한다.
|
|
74
|
+
* - onGridDropBefore : 변경 직전(이동 전). false 반환 시 이동 취소.
|
|
75
|
+
* - onGridDropAfter : 양쪽 데이터 모델 이동 완료 후.
|
|
76
|
+
* - onGridDropComplete: 양쪽 재렌더까지 끝난 후.
|
|
77
|
+
*/
|
|
78
|
+
export interface GridDropEvent<T = any> {
|
|
79
|
+
/** 행을 보낸(드래그 시작) 그리드 */
|
|
80
|
+
sourceGrid: OpenGridInstance<T>;
|
|
81
|
+
/** 행을 받은(드롭 대상) 그리드 */
|
|
82
|
+
targetGrid: OpenGridInstance<T>;
|
|
83
|
+
/** 이동된 행 데이터 (내부 id 제외 복사본) */
|
|
84
|
+
rows: T[];
|
|
85
|
+
/** 소스 그리드에서의 원래 행 인덱스들 */
|
|
86
|
+
sourceIndexes: number[];
|
|
87
|
+
/** 타깃 그리드에서 삽입된 시작 인덱스 */
|
|
88
|
+
targetIndex: number;
|
|
89
|
+
/** before 단계에서 true 로 바꾸면 이동 취소 (onGridDropBefore가 false 반환한 것과 동일) */
|
|
90
|
+
cancel?: boolean;
|
|
91
|
+
}
|
|
92
|
+
/** 그리드↔그리드 필드 매핑 확정 이벤트 (interactive 모드에서 매핑 모달 확인 시) */
|
|
93
|
+
export interface GridMappingEvent<T = any> {
|
|
94
|
+
sourceGrid: OpenGridInstance<T>;
|
|
95
|
+
targetGrid: OpenGridInstance<T>;
|
|
96
|
+
/** 타깃필드 → 소스필드 매핑 */
|
|
97
|
+
mapping: Record<string, string>;
|
|
98
|
+
/** crossGridMapping 에 baking 할 수 있는 변환 함수 소스 */
|
|
99
|
+
script: string;
|
|
100
|
+
}
|
|
71
101
|
export interface SelectionEvent<T = any> {
|
|
72
102
|
rows: T[];
|
|
73
103
|
rowIndexes: number[];
|
|
@@ -105,7 +135,13 @@ export interface ColumnDef<T = any> {
|
|
|
105
135
|
maxWidth?: number;
|
|
106
136
|
flex?: number;
|
|
107
137
|
type?: DataType;
|
|
138
|
+
/**
|
|
139
|
+
* 숫자/날짜 포맷 문자열. 숫자는 통화 기호 접두·접미와 음수 패턴 지원:
|
|
140
|
+
* '#,##0' · '#,##0.00' · '₩#,##0' · '$#,##0.00' · '#,##0원' · '$#,##0;($#,##0)'(음수 괄호)
|
|
141
|
+
*/
|
|
108
142
|
format?: string;
|
|
143
|
+
/** ISO 통화코드('KRW'|'USD'|'EUR'…). 지정 시 Intl.NumberFormat 로케일 통화 포맷 (format 보다 우선) */
|
|
144
|
+
currency?: string;
|
|
109
145
|
valueMap?: Record<string, string>;
|
|
110
146
|
renderer?: RendererType | RendererDef;
|
|
111
147
|
editable?: boolean | ((row: T, rowIndex: number) => boolean);
|
|
@@ -121,6 +157,12 @@ export interface ColumnDef<T = any> {
|
|
|
121
157
|
frozen?: boolean;
|
|
122
158
|
/** 셀 줄바꿈: true 면 nowrap+ellipsis 대신 여러 줄로 표시(rowHeight 확대와 함께 사용) */
|
|
123
159
|
wrap?: boolean;
|
|
160
|
+
/**
|
|
161
|
+
* 헤더(컬럼 머리글) 줄바꿈: true 면 헤더 텍스트가 잘리지 않고 여러 줄로 줄바꿈된다.
|
|
162
|
+
* (셀 본문용 wrap 과 별개로 헤더에만 적용. header 문자열의 '\n' 은 headerWrap 여부와 무관하게 항상 줄바꿈됨)
|
|
163
|
+
* 줄바꿈된 헤더에 맞춰 헤더 행 높이가 자동으로 늘어난다.
|
|
164
|
+
*/
|
|
165
|
+
headerWrap?: boolean;
|
|
124
166
|
colSpan?: boolean | ((row: T, rowIndex: number) => boolean);
|
|
125
167
|
rowSpan?: boolean;
|
|
126
168
|
children?: ColumnDef<T>[];
|
|
@@ -255,6 +297,15 @@ export interface GridOptions<T = any> {
|
|
|
255
297
|
stateColumn?: boolean;
|
|
256
298
|
checkColumn?: boolean;
|
|
257
299
|
draggable?: boolean;
|
|
300
|
+
/** 그리드↔그리드 행 드래그 이동 허용 (draggable:true 와 함께 사용, 양쪽 그리드 모두 true 여야 이동) */
|
|
301
|
+
crossGrid?: boolean;
|
|
302
|
+
/**
|
|
303
|
+
* 크로스그리드 이동 시 소스→타깃 행 변환 방식.
|
|
304
|
+
* - 'auto'(기본): 필드명 그대로 복사
|
|
305
|
+
* - 'interactive': 소스/타깃 스키마가 다르면 매핑 모달을 띄워 개발자가 매칭 + 변환 스크립트 출력
|
|
306
|
+
* - 함수: (srcRow) => targetRow 로 직접 변환 (모달 없이 baking)
|
|
307
|
+
*/
|
|
308
|
+
crossGridMapping?: 'auto' | 'interactive' | ((srcRow: T) => Partial<T>);
|
|
258
309
|
mergeCells?: boolean;
|
|
259
310
|
groupBy?: string[];
|
|
260
311
|
summary?: SummaryOptions;
|
|
@@ -274,6 +325,7 @@ export interface GridOptions<T = any> {
|
|
|
274
325
|
worksheets?: WorksheetDef[];
|
|
275
326
|
calcPrecision?: number;
|
|
276
327
|
columnReorder?: boolean;
|
|
328
|
+
overrideStrict?: boolean;
|
|
277
329
|
onReady?: (grid: OpenGridInstance<T>) => void;
|
|
278
330
|
onCellClick?: (e: CellEvent<T>) => void;
|
|
279
331
|
onCellDblClick?: (e: CellEvent<T>) => void;
|
|
@@ -290,6 +342,14 @@ export interface GridOptions<T = any> {
|
|
|
290
342
|
fromIndex: number;
|
|
291
343
|
toIndex: number;
|
|
292
344
|
}) => void;
|
|
345
|
+
/** 변경전 — 이동 직전. false 반환 시 이동 취소 */
|
|
346
|
+
onGridDropBefore?: (e: GridDropEvent<T>) => boolean | void;
|
|
347
|
+
/** 변경후 — 양쪽 데이터 모델 이동 완료 */
|
|
348
|
+
onGridDropAfter?: (e: GridDropEvent<T>) => void;
|
|
349
|
+
/** 완료시 — 양쪽 재렌더까지 끝남 */
|
|
350
|
+
onGridDropComplete?: (e: GridDropEvent<T>) => void;
|
|
351
|
+
/** interactive 매핑 모달에서 매핑 확정 시 — 생성된 매핑/스크립트 수신 */
|
|
352
|
+
onGridDropMapping?: (e: GridMappingEvent<T>) => void;
|
|
293
353
|
onColumnReorder?: (e: {
|
|
294
354
|
fromIndex: number;
|
|
295
355
|
toIndex: number;
|
|
@@ -311,7 +371,58 @@ export interface GridOptions<T = any> {
|
|
|
311
371
|
onCellKeyUp?: (e: CellKeyEvent<T>) => void;
|
|
312
372
|
onCellKeyPress?: (e: CellKeyEvent<T>) => void;
|
|
313
373
|
}
|
|
374
|
+
/** override 레이어 함수: 첫 인자는 안쪽(원본 근접) 함수. orig(...) 호출이 super 처럼 동작. */
|
|
375
|
+
export type OverrideLayerFn = (orig: (...args: any[]) => any, ...args: any[]) => any;
|
|
376
|
+
export interface OverrideCallOptions {
|
|
377
|
+
/** 동일 메서드 재진입 허용(정당한 재귀). 기본 false. */
|
|
378
|
+
reentrant?: boolean;
|
|
379
|
+
/** 'fallback' → 레이어 예외 시 경고 후 원본 실행(멱등 가정, 롤백 불가). 미지정 시 strict. */
|
|
380
|
+
onError?: 'fallback';
|
|
381
|
+
}
|
|
382
|
+
/** 등록 가능한 알고리즘 슬롯 이름(6종). */
|
|
383
|
+
export type StrategySlot = 'sortComparator' | 'filterPredicate' | 'displayFormatter' | 'cellSerializer' | 'groupKeyFn' | 'summaryOp';
|
|
384
|
+
/** 단일키 정렬 비교자. dir 부호는 호출자(DataLayer)가 적용 — 슬롯은 비교만 반환. */
|
|
385
|
+
export type SortComparatorFn = (a: any, b: any, field: string, dir: 'asc' | 'desc') => number;
|
|
386
|
+
/** 필터 술어. true → 행 포함. */
|
|
387
|
+
export type FilterPredicateFn = (value: any, fi: FilterItem, field: string) => boolean;
|
|
388
|
+
/** 표시값 포맷. getDisplayValue(인스턴스 안전) + 렌더러(formatNumber/formatDate) 공유. */
|
|
389
|
+
export type DisplayFormatterFn = (value: any, field: string, row: any) => string;
|
|
390
|
+
/** export 셀 직렬화. */
|
|
391
|
+
export type CellSerializerFn = (value: any, col: any, row: any) => any;
|
|
392
|
+
/** 그룹 키 산출. remainingFields = 현재 깊이부터의 잔여 필드. */
|
|
393
|
+
export type GroupKeyFn = (row: any, remainingFields: string[]) => any;
|
|
394
|
+
/** 집계 연산. null 반환 시 기본 SUM/AVG/COUNT/MAX/MIN 분기로 폴백. */
|
|
395
|
+
export type SummaryOpFn = (op: string, nums: any[], field: string) => number | null;
|
|
396
|
+
/** 슬롯명 → 시그니처 매핑. */
|
|
397
|
+
export interface StrategyMap {
|
|
398
|
+
sortComparator: SortComparatorFn;
|
|
399
|
+
filterPredicate: FilterPredicateFn;
|
|
400
|
+
displayFormatter: DisplayFormatterFn;
|
|
401
|
+
cellSerializer: CellSerializerFn;
|
|
402
|
+
groupKeyFn: GroupKeyFn;
|
|
403
|
+
summaryOp: SummaryOpFn;
|
|
404
|
+
}
|
|
405
|
+
/** 호출가능 + .strategy 멤버를 가진 하이브리드 override API. */
|
|
406
|
+
export interface OverrideApi<T = any> {
|
|
407
|
+
/** 메서드 본문 무수정 런타임 래핑(C1-clean). 체이닝 위해 grid 인스턴스 반환. */
|
|
408
|
+
(name: string, fn: OverrideLayerFn, opts?: OverrideCallOptions): OpenGridInstance<T>;
|
|
409
|
+
/** 알고리즘 슬롯 등록(Phase 2 매니저 훅포인트). 체이닝 위해 grid 인스턴스 반환. */
|
|
410
|
+
strategy<K extends StrategySlot>(slot: K, fn: StrategyMap[K]): OpenGridInstance<T>;
|
|
411
|
+
strategy(slot: string, fn: Function): OpenGridInstance<T>;
|
|
412
|
+
}
|
|
314
413
|
export interface OpenGridInstance<T = any> {
|
|
414
|
+
/** 공개 메서드를 런타임 래핑하거나(.override) 알고리즘 슬롯을 등록(.strategy). */
|
|
415
|
+
override: OverrideApi<T>;
|
|
416
|
+
/** 단일 메서드 원본 복구. */
|
|
417
|
+
restore(name: string): OpenGridInstance<T>;
|
|
418
|
+
/** 전체 override + strategy 복구(destroy 시 자동). */
|
|
419
|
+
restoreAll(): OpenGridInstance<T>;
|
|
420
|
+
/** 해당 메서드가 override 되어 있는지. */
|
|
421
|
+
hasOverride(name: string): boolean;
|
|
422
|
+
/** override 등록된 메서드 이름 목록. */
|
|
423
|
+
getOverrideNames(): string[];
|
|
424
|
+
/** strategy 슬롯 조회(미등록 시 fallback 반환). 매니저 read API. */
|
|
425
|
+
getStrategy<F extends Function>(slot: string, fallback: F): F;
|
|
315
426
|
setData(data: T[]): void;
|
|
316
427
|
getData(): T[];
|
|
317
428
|
getSourceRows(): T[];
|
|
@@ -386,6 +497,10 @@ export interface OpenGridInstance<T = any> {
|
|
|
386
497
|
resetFilter(field?: string): void;
|
|
387
498
|
getFilterState(): Record<string, FilterItem[]>;
|
|
388
499
|
restoreFilter(state: Record<string, FilterItem[]>): void;
|
|
500
|
+
/** 지정 행들을 다른 그리드로 이동. 3단계 이벤트 + crossGridMapping 적용. */
|
|
501
|
+
moveRowsTo(target: OpenGridInstance<T>, sourceIndexes: number[], targetIndex?: number): Promise<boolean>;
|
|
502
|
+
/** 체크된 행을 다른 그리드로 이동 (화살표 셔틀용) */
|
|
503
|
+
moveCheckedTo(target: OpenGridInstance<T>): Promise<boolean>;
|
|
389
504
|
freeze(columnCount: number): void;
|
|
390
505
|
freezeRows(rowCount: number): void;
|
|
391
506
|
groupBy(fields: string[]): void;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import './styles/base.css';
|
|
2
2
|
export { OpenGrid } from './core/OpenGrid.js';
|
|
3
|
+
export { GridShuttle, createGridShuttle } from './core/GridShuttle.js';
|
|
4
|
+
export type { GridShuttleOptions } from './core/GridShuttle.js';
|
|
3
5
|
export { OrgChart } from './core/OrgChart.js';
|
|
4
6
|
export { XmlConverter } from './core/XmlConverter.js';
|
|
5
7
|
export type { OrgChartOptions, OrgChartColumnDef } from './core/OrgChart.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { GridOptions, ColumnDef, OpenGridInstance } from '../core/types.js';
|
|
3
|
-
|
|
1
|
+
import React, { CSSProperties } from 'react';
|
|
2
|
+
import type { GridOptions, ColumnDef, OpenGridInstance } from '../core/types.js';
|
|
3
|
+
import '../styles/base.css';
|
|
4
4
|
export interface OpenGridProps<T extends Record<string, any> = any> {
|
|
5
5
|
data?: T[];
|
|
6
6
|
columns: ColumnDef<T>[];
|
package/package.json
CHANGED
|
@@ -1,102 +1,99 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "open-grid",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "High-performance, framework-agnostic data grid with Vue 3 and React 18 support",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "dist/open-grid.cjs",
|
|
7
|
-
"module": "dist/open-grid.js",
|
|
8
|
-
"types": "dist/types/index.d.ts",
|
|
9
|
-
"exports": {
|
|
10
|
-
".": {
|
|
11
|
-
"import": "./dist/open-grid.js",
|
|
12
|
-
"require": "./dist/open-grid.cjs",
|
|
13
|
-
"types": "./dist/types/index.d.ts"
|
|
14
|
-
},
|
|
15
|
-
"./vue": {
|
|
16
|
-
"import": "./dist/open-grid-vue.js",
|
|
17
|
-
"require": "./dist/open-grid-vue.cjs",
|
|
18
|
-
"types": "./dist/types/vue/index.d.ts"
|
|
19
|
-
},
|
|
20
|
-
"./react": {
|
|
21
|
-
"import": "./dist/open-grid-react.js",
|
|
22
|
-
"require": "./dist/open-grid-react.cjs",
|
|
23
|
-
"types": "./dist/types/react/index.d.ts"
|
|
24
|
-
},
|
|
25
|
-
"./style.css": "./dist/style.css"
|
|
26
|
-
},
|
|
27
|
-
"files": [
|
|
28
|
-
"dist",
|
|
29
|
-
"README.md",
|
|
30
|
-
"LICENSE"
|
|
31
|
-
],
|
|
32
|
-
"scripts": {
|
|
33
|
-
"dev": "vite",
|
|
34
|
-
"build": "tsc && vite build",
|
|
35
|
-
"build:types": "tsc --emitDeclarationOnly",
|
|
36
|
-
"test": "vitest run",
|
|
37
|
-
"test:watch": "vitest",
|
|
38
|
-
"test:coverage": "vitest run --coverage",
|
|
39
|
-
"test:e2e": "playwright test",
|
|
40
|
-
"lint": "eslint src --ext .ts,.tsx,.vue",
|
|
41
|
-
"preview": "vite preview",
|
|
42
|
-
"build:deploy": "vite build --config vite.config.deploy.ts",
|
|
43
|
-
"obfuscate": "node scripts/obfuscate.mjs",
|
|
44
|
-
"deploy": "npm run build && npm run build:deploy && npm run obfuscate"
|
|
45
|
-
},
|
|
46
|
-
"peerDependencies": {
|
|
47
|
-
"react": ">=18.0.0",
|
|
48
|
-
"react-dom": ">=18.0.0",
|
|
49
|
-
"vue": ">=3.0.0"
|
|
50
|
-
},
|
|
51
|
-
"peerDependenciesMeta": {
|
|
52
|
-
"react": {
|
|
53
|
-
"optional": true
|
|
54
|
-
},
|
|
55
|
-
"react-dom": {
|
|
56
|
-
"optional": true
|
|
57
|
-
},
|
|
58
|
-
"vue": {
|
|
59
|
-
"optional": true
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
"devDependencies": {
|
|
63
|
-
"@playwright/test": "^1.44.0",
|
|
64
|
-
"@types/react": "^18.3.0",
|
|
65
|
-
"@types/react-dom": "^18.3.0",
|
|
66
|
-
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
|
67
|
-
"@typescript-eslint/parser": "^7.0.0",
|
|
68
|
-
"@vitejs/plugin-react": "^4.3.0",
|
|
69
|
-
"@vitejs/plugin-vue": "^5.0.0",
|
|
70
|
-
"@vitest/coverage-v8": "^1.6.1",
|
|
71
|
-
"eslint": "^9.0.0",
|
|
72
|
-
"javascript-obfuscator": "^5.4.3",
|
|
73
|
-
"jsdom": "^29.1.1",
|
|
74
|
-
"react": "^18.3.0",
|
|
75
|
-
"react-dom": "^18.3.0",
|
|
76
|
-
"typescript": "^5.4.0",
|
|
77
|
-
"vite": "^5.2.0",
|
|
78
|
-
"vite-plugin-dts": "^3.9.0",
|
|
79
|
-
"vitest": "^1.6.0",
|
|
80
|
-
"vue": "^3.4.0"
|
|
81
|
-
},
|
|
82
|
-
"dependencies": {
|
|
83
|
-
"xlsx": "^0.18.5",
|
|
84
|
-
"xlsx-js-style": "^1.2.0"
|
|
85
|
-
},
|
|
86
|
-
"keywords": [
|
|
87
|
-
"grid",
|
|
88
|
-
"datagrid",
|
|
89
|
-
"table",
|
|
90
|
-
"vue",
|
|
91
|
-
"react",
|
|
92
|
-
"typescript",
|
|
93
|
-
"virtual-scroll",
|
|
94
|
-
"editable"
|
|
95
|
-
],
|
|
96
|
-
"license": "MIT",
|
|
97
|
-
"author": "OPEN_GRID Contributors",
|
|
98
|
-
"
|
|
99
|
-
|
|
100
|
-
"url": "https://github.com/open-grid/open-grid"
|
|
101
|
-
}
|
|
102
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "open-grid",
|
|
3
|
+
"version": "1.0.0-rc.1",
|
|
4
|
+
"description": "High-performance, framework-agnostic data grid with Vue 3 and React 18 support",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/open-grid.cjs",
|
|
7
|
+
"module": "dist/open-grid.js",
|
|
8
|
+
"types": "dist/types/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/open-grid.js",
|
|
12
|
+
"require": "./dist/open-grid.cjs",
|
|
13
|
+
"types": "./dist/types/index.d.ts"
|
|
14
|
+
},
|
|
15
|
+
"./vue": {
|
|
16
|
+
"import": "./dist/open-grid-vue.js",
|
|
17
|
+
"require": "./dist/open-grid-vue.cjs",
|
|
18
|
+
"types": "./dist/types/vue/index.d.ts"
|
|
19
|
+
},
|
|
20
|
+
"./react": {
|
|
21
|
+
"import": "./dist/open-grid-react.js",
|
|
22
|
+
"require": "./dist/open-grid-react.cjs",
|
|
23
|
+
"types": "./dist/types/react/index.d.ts"
|
|
24
|
+
},
|
|
25
|
+
"./style.css": "./dist/style.css"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"README.md",
|
|
30
|
+
"LICENSE"
|
|
31
|
+
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"dev": "vite",
|
|
34
|
+
"build": "tsc && vite build",
|
|
35
|
+
"build:types": "tsc --emitDeclarationOnly",
|
|
36
|
+
"test": "vitest run",
|
|
37
|
+
"test:watch": "vitest",
|
|
38
|
+
"test:coverage": "vitest run --coverage",
|
|
39
|
+
"test:e2e": "playwright test",
|
|
40
|
+
"lint": "eslint src --ext .ts,.tsx,.vue",
|
|
41
|
+
"preview": "vite preview",
|
|
42
|
+
"build:deploy": "vite build --config vite.config.deploy.ts",
|
|
43
|
+
"obfuscate": "node scripts/obfuscate.mjs",
|
|
44
|
+
"deploy": "npm run build && npm run build:deploy && npm run obfuscate"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"react": ">=18.0.0",
|
|
48
|
+
"react-dom": ">=18.0.0",
|
|
49
|
+
"vue": ">=3.0.0"
|
|
50
|
+
},
|
|
51
|
+
"peerDependenciesMeta": {
|
|
52
|
+
"react": {
|
|
53
|
+
"optional": true
|
|
54
|
+
},
|
|
55
|
+
"react-dom": {
|
|
56
|
+
"optional": true
|
|
57
|
+
},
|
|
58
|
+
"vue": {
|
|
59
|
+
"optional": true
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@playwright/test": "^1.44.0",
|
|
64
|
+
"@types/react": "^18.3.0",
|
|
65
|
+
"@types/react-dom": "^18.3.0",
|
|
66
|
+
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
|
67
|
+
"@typescript-eslint/parser": "^7.0.0",
|
|
68
|
+
"@vitejs/plugin-react": "^4.3.0",
|
|
69
|
+
"@vitejs/plugin-vue": "^5.0.0",
|
|
70
|
+
"@vitest/coverage-v8": "^1.6.1",
|
|
71
|
+
"eslint": "^9.0.0",
|
|
72
|
+
"javascript-obfuscator": "^5.4.3",
|
|
73
|
+
"jsdom": "^29.1.1",
|
|
74
|
+
"react": "^18.3.0",
|
|
75
|
+
"react-dom": "^18.3.0",
|
|
76
|
+
"typescript": "^5.4.0",
|
|
77
|
+
"vite": "^5.2.0",
|
|
78
|
+
"vite-plugin-dts": "^3.9.0",
|
|
79
|
+
"vitest": "^1.6.0",
|
|
80
|
+
"vue": "^3.4.0"
|
|
81
|
+
},
|
|
82
|
+
"dependencies": {
|
|
83
|
+
"xlsx": "^0.18.5",
|
|
84
|
+
"xlsx-js-style": "^1.2.0"
|
|
85
|
+
},
|
|
86
|
+
"keywords": [
|
|
87
|
+
"grid",
|
|
88
|
+
"datagrid",
|
|
89
|
+
"table",
|
|
90
|
+
"vue",
|
|
91
|
+
"react",
|
|
92
|
+
"typescript",
|
|
93
|
+
"virtual-scroll",
|
|
94
|
+
"editable"
|
|
95
|
+
],
|
|
96
|
+
"license": "MIT",
|
|
97
|
+
"author": "OPEN_GRID Contributors",
|
|
98
|
+
"homepage": "https://foxnail.kr/open-grid/demo/v2/index.php"
|
|
99
|
+
}
|