@iyulab/data-components 0.1.0 → 0.1.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/CHANGELOG.md +3 -3
- package/README.md +89 -89
- package/dist/components/data-grid/UDataGrid.d.ts +1 -1
- package/dist/components/data-grid/UDataGrid.js +6 -4
- package/dist/components/data-grid/UDataGrid.types.d.ts +3 -0
- package/dist/components/data-view/UDataView.component.d.ts +39 -50
- package/dist/components/data-view/UDataView.component.js +162 -237
- package/dist/components/data-view/UDataView.d.ts +1 -1
- package/dist/components/data-view/UDataView.styles.js +126 -229
- package/dist/components/simple-sheet/USimpleSheet.component.d.ts +138 -0
- package/dist/components/simple-sheet/USimpleSheet.component.js +855 -0
- package/dist/components/simple-sheet/USimpleSheet.d.ts +8 -0
- package/dist/components/simple-sheet/USimpleSheet.styles.d.ts +1 -0
- package/dist/components/simple-sheet/USimpleSheet.styles.js +245 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +1 -3
- package/package.json +75 -75
- package/dist/components/data-view/UDataView.js +0 -5
- package/dist/components/index.d.ts +0 -3
- package/dist/styles/devextreme-overrides.css.js +0 -3
- package/dist/utils/devExtremeCssInjection.js +0 -164
- package/dist/utils/index.d.ts +0 -2
- package/dist/utils/shadowDomProtection.js +0 -82
- /package/dist/{utils → utilities}/devExtremeCssInjection.d.ts +0 -0
- /package/dist/{utils → utilities}/shadowDomProtection.d.ts +0 -0
|
@@ -6,277 +6,174 @@ const styles = css`
|
|
|
6
6
|
width: 100%;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
.
|
|
10
|
-
|
|
9
|
+
.data-view {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
gap: 1rem;
|
|
13
|
+
height: 100%;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/* Toolbar */
|
|
17
|
+
.toolbar {
|
|
18
|
+
display: flex;
|
|
19
|
+
align-items: center;
|
|
20
|
+
justify-content: space-between;
|
|
21
|
+
padding: 0.75rem;
|
|
22
|
+
background: var(--u-bg-color);
|
|
23
|
+
border: 1px solid var(--u-border-color);
|
|
24
|
+
border-radius: 8px;
|
|
11
25
|
}
|
|
12
26
|
|
|
13
|
-
.
|
|
27
|
+
.view-toggles {
|
|
14
28
|
display: flex;
|
|
15
|
-
|
|
16
|
-
|
|
29
|
+
gap: 0.25rem;
|
|
30
|
+
}
|
|
17
31
|
|
|
18
|
-
|
|
19
|
-
|
|
32
|
+
.view-toggles u-button[active] {
|
|
33
|
+
background: var(--u-blue-600);
|
|
34
|
+
color: var(--u-neutral-0);
|
|
35
|
+
}
|
|
20
36
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
37
|
+
.info {
|
|
38
|
+
font-size: 0.875rem;
|
|
39
|
+
color: var(--u-txt-color-weak);
|
|
40
|
+
font-weight: 500;
|
|
25
41
|
}
|
|
26
42
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
43
|
+
/* Grid Layout */
|
|
44
|
+
.grid {
|
|
45
|
+
display: grid;
|
|
46
|
+
grid-template-columns: repeat(auto-fill, minmax(var(--min-width, 200px), 1fr));
|
|
47
|
+
gap: var(--gap, 1rem);
|
|
48
|
+
}
|
|
33
49
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
50
|
+
/* List Layout */
|
|
51
|
+
.list {
|
|
52
|
+
display: flex;
|
|
53
|
+
flex-direction: column;
|
|
54
|
+
gap: var(--gap, 1rem);
|
|
39
55
|
}
|
|
40
56
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
57
|
+
/* Card Styles */
|
|
58
|
+
.card {
|
|
59
|
+
background: var(--u-bg-color);
|
|
60
|
+
border: 1px solid var(--u-border-color);
|
|
44
61
|
border-radius: 8px;
|
|
45
|
-
padding:
|
|
62
|
+
padding: 1.25rem;
|
|
46
63
|
cursor: pointer;
|
|
47
|
-
transition: all 0.
|
|
64
|
+
transition: all 0.15s ease;
|
|
65
|
+
}
|
|
48
66
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
67
|
+
.card:hover {
|
|
68
|
+
border-color: var(--u-blue-600);
|
|
69
|
+
box-shadow: 0 4px 12px var(--u-shadow-color-weak);
|
|
70
|
+
transform: translateY(-2px);
|
|
71
|
+
}
|
|
52
72
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
73
|
+
.card.selected {
|
|
74
|
+
border-color: var(--u-blue-600);
|
|
75
|
+
background: var(--u-bg-color-active);
|
|
76
|
+
box-shadow: 0 0 0 3px var(--u-blue-200);
|
|
57
77
|
}
|
|
58
78
|
|
|
59
|
-
.
|
|
79
|
+
.card-content {
|
|
60
80
|
display: flex;
|
|
61
|
-
|
|
81
|
+
flex-direction: column;
|
|
82
|
+
gap: 0.75rem;
|
|
62
83
|
}
|
|
63
84
|
|
|
64
|
-
.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
min-width: 128px;
|
|
69
|
-
margin-right: 1rem;
|
|
70
|
-
margin-bottom: 0;
|
|
71
|
-
object-fit: cover;
|
|
85
|
+
.card-field {
|
|
86
|
+
display: flex;
|
|
87
|
+
gap: 0.5rem;
|
|
88
|
+
align-items: baseline;
|
|
72
89
|
}
|
|
73
90
|
|
|
74
|
-
.
|
|
75
|
-
|
|
91
|
+
.card-field .label {
|
|
92
|
+
font-size: 0.875rem;
|
|
93
|
+
font-weight: 600;
|
|
94
|
+
color: var(--u-txt-color-weak);
|
|
95
|
+
min-width: 80px;
|
|
96
|
+
flex-shrink: 0;
|
|
76
97
|
}
|
|
77
98
|
|
|
78
|
-
.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
margin-bottom: 1rem;
|
|
83
|
-
border-radius: 4px;
|
|
84
|
-
|
|
85
|
-
&.list-image {
|
|
86
|
-
width: 128px;
|
|
87
|
-
height: 128px;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
&.table-image {
|
|
91
|
-
width: 64px;
|
|
92
|
-
height: 64px;
|
|
93
|
-
margin-bottom: 0;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
&.placeholder-image {
|
|
97
|
-
display: flex;
|
|
98
|
-
align-items: center;
|
|
99
|
-
justify-content: center;
|
|
100
|
-
font-size: 2rem;
|
|
101
|
-
font-weight: bold;
|
|
102
|
-
text-transform: uppercase;
|
|
103
|
-
}
|
|
99
|
+
.card-field .value {
|
|
100
|
+
font-size: 0.9375rem;
|
|
101
|
+
color: var(--u-txt-color);
|
|
102
|
+
word-break: break-word;
|
|
104
103
|
}
|
|
105
104
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
align-items: center;
|
|
111
|
-
|
|
112
|
-
.field-title {
|
|
113
|
-
color: var(--u-neutral-600);
|
|
114
|
-
margin-right: 0.5rem;
|
|
115
|
-
flex: 0 0 30%;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
.field-value {
|
|
119
|
-
font-weight: bold;
|
|
120
|
-
flex: 1;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
105
|
+
/* List Card Override */
|
|
106
|
+
.list-card .card-content {
|
|
107
|
+
flex-direction: row;
|
|
108
|
+
flex-wrap: wrap;
|
|
123
109
|
}
|
|
124
110
|
|
|
125
|
-
.
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
th, td {
|
|
131
|
-
padding: 0.5em;
|
|
132
|
-
border: none;
|
|
133
|
-
border-bottom: 1px solid #eee;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
th {
|
|
137
|
-
background-color: #f8f9fa;
|
|
138
|
-
font-weight: bold;
|
|
139
|
-
text-align: left;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
.image-cell {
|
|
143
|
-
width: 64px;
|
|
144
|
-
height: 64px;
|
|
145
|
-
padding: 0;
|
|
146
|
-
position: relative;
|
|
147
|
-
|
|
148
|
-
img, .placeholder-image {
|
|
149
|
-
position: absolute;
|
|
150
|
-
top: 0;
|
|
151
|
-
left: 0;
|
|
152
|
-
width: 100%;
|
|
153
|
-
height: 100%;
|
|
154
|
-
object-fit: cover;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
.placeholder-image {
|
|
158
|
-
font-size: 1.5rem;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
tr {
|
|
163
|
-
transition: all 0.3s ease;
|
|
164
|
-
|
|
165
|
-
&:hover {
|
|
166
|
-
background-color: rgba(0, 123, 255, 0.05);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
&.selected {
|
|
170
|
-
background-color: rgba(0, 123, 255, 0.1);
|
|
171
|
-
box-shadow: 0 0 0 2px #007bff;
|
|
172
|
-
position: relative;
|
|
173
|
-
z-index: 1;
|
|
174
|
-
|
|
175
|
-
td:first-child {
|
|
176
|
-
border-top-left-radius: 8px;
|
|
177
|
-
border-bottom-left-radius: 8px;
|
|
178
|
-
}
|
|
111
|
+
.list-card .card-field {
|
|
112
|
+
flex: 1 1 calc(50% - 0.5rem);
|
|
113
|
+
min-width: 200px;
|
|
114
|
+
}
|
|
179
115
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
116
|
+
/* Table */
|
|
117
|
+
.table-wrapper {
|
|
118
|
+
overflow-x: auto;
|
|
119
|
+
border: 1px solid var(--u-border-color);
|
|
120
|
+
border-radius: 8px;
|
|
186
121
|
}
|
|
187
122
|
|
|
188
|
-
|
|
189
|
-
display: block;
|
|
123
|
+
table {
|
|
190
124
|
width: 100%;
|
|
191
|
-
|
|
192
|
-
background-color
|
|
193
|
-
border-radius: 4px;
|
|
194
|
-
overflow: hidden;
|
|
195
|
-
position: relative;
|
|
196
|
-
|
|
197
|
-
&::after {
|
|
198
|
-
content: "";
|
|
199
|
-
position: absolute;
|
|
200
|
-
top: 0;
|
|
201
|
-
left: 0;
|
|
202
|
-
width: 100%;
|
|
203
|
-
height: 100%;
|
|
204
|
-
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
|
|
205
|
-
animation: skeleton-loading 1.5s infinite;
|
|
206
|
-
}
|
|
125
|
+
border-collapse: collapse;
|
|
126
|
+
background: var(--u-bg-color);
|
|
207
127
|
}
|
|
208
128
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
transform: translateX(100%);
|
|
215
|
-
}
|
|
129
|
+
thead {
|
|
130
|
+
background: var(--u-neutral-50);
|
|
131
|
+
position: sticky;
|
|
132
|
+
top: 0;
|
|
133
|
+
z-index: 10;
|
|
216
134
|
}
|
|
217
135
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
display: flex;
|
|
228
|
-
align-items: flex-start;
|
|
229
|
-
|
|
230
|
-
.skeleton-image {
|
|
231
|
-
width: 128px;
|
|
232
|
-
height: 128px;
|
|
233
|
-
margin-right: 1rem;
|
|
234
|
-
margin-bottom: 0;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
.skeleton-fields {
|
|
238
|
-
flex: 1;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
.skeleton-field {
|
|
243
|
-
display: flex;
|
|
244
|
-
align-items: center;
|
|
245
|
-
margin-bottom: 0.5rem;
|
|
136
|
+
th {
|
|
137
|
+
padding: 0.875rem 1rem;
|
|
138
|
+
text-align: left;
|
|
139
|
+
font-size: 0.875rem;
|
|
140
|
+
font-weight: 600;
|
|
141
|
+
color: var(--u-txt-color-weak);
|
|
142
|
+
border-bottom: 2px solid var(--u-border-color);
|
|
143
|
+
white-space: nowrap;
|
|
144
|
+
}
|
|
246
145
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
}
|
|
146
|
+
tbody tr {
|
|
147
|
+
cursor: pointer;
|
|
148
|
+
transition: background 0.1s ease;
|
|
149
|
+
}
|
|
252
150
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
height: 1em;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
151
|
+
tbody tr:hover {
|
|
152
|
+
background: var(--u-bg-color-hover);
|
|
258
153
|
}
|
|
259
154
|
|
|
260
|
-
.
|
|
261
|
-
|
|
155
|
+
tbody tr.selected {
|
|
156
|
+
background: var(--u-bg-color-active);
|
|
157
|
+
}
|
|
262
158
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
padding: 0.5em 0;
|
|
159
|
+
tbody tr:not(:last-child) {
|
|
160
|
+
border-bottom: 1px solid var(--u-border-color-weak);
|
|
161
|
+
}
|
|
267
162
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
163
|
+
td {
|
|
164
|
+
padding: 0.875rem 1rem;
|
|
165
|
+
font-size: 0.9375rem;
|
|
166
|
+
color: var(--u-txt-color);
|
|
167
|
+
}
|
|
272
168
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
169
|
+
/* Empty State */
|
|
170
|
+
.empty {
|
|
171
|
+
display: flex;
|
|
172
|
+
align-items: center;
|
|
173
|
+
justify-content: center;
|
|
174
|
+
min-height: 300px;
|
|
175
|
+
color: var(--u-txt-color-weak);
|
|
176
|
+
font-size: 1rem;
|
|
280
177
|
}
|
|
281
178
|
`;
|
|
282
179
|
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { TemplateResult } from 'lit';
|
|
2
|
+
import { UElement } from '@iyulab/components/dist/components/UElement.js';
|
|
3
|
+
export interface SheetColumn {
|
|
4
|
+
/** 데이터 키 (getDataAsObjects() 반환시 객체 키로 사용) */
|
|
5
|
+
key?: string;
|
|
6
|
+
/** 헤더 표시 레이블 */
|
|
7
|
+
label?: string;
|
|
8
|
+
/** 열 너비 (px) */
|
|
9
|
+
width?: number;
|
|
10
|
+
/** 읽기 전용 열 */
|
|
11
|
+
readonly?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* USimpleSheet - 심플 스프레드시트 컴포넌트
|
|
15
|
+
*
|
|
16
|
+
* 편집 편의 기능:
|
|
17
|
+
* - Undo/Redo: Ctrl+Z / Ctrl+Y / Ctrl+Shift+Z
|
|
18
|
+
* - Ctrl+Enter: 편집 확정 후 현재 셀 유지
|
|
19
|
+
* - Shift+Enter: 위로 이동
|
|
20
|
+
* - Home/End: 행 처음/끝 (Ctrl+Home/End: 시트 처음/끝)
|
|
21
|
+
* - Page Up/Down: 10행 단위 이동
|
|
22
|
+
* - Ctrl+A: 전체 선택
|
|
23
|
+
* - Tab 사이클: 마지막 열 → 다음 행 첫 열
|
|
24
|
+
* - Ctrl+D: Fill Down (선택 영역 첫 행 값 아래로 채우기)
|
|
25
|
+
* - Ctrl+R: Fill Right (선택 영역 첫 열 값 오른쪽으로 채우기)
|
|
26
|
+
* - 행/열 헤더 클릭: 전체 행/열 선택
|
|
27
|
+
* - 엑셀 호환 Ctrl+C/V (TSV), Delete/Backspace
|
|
28
|
+
* - 다중 셀 선택: Shift+클릭, Shift+Arrow, 마우스 드래그
|
|
29
|
+
* - columns 미설정시 A, B, C... 자동 헤더
|
|
30
|
+
*/
|
|
31
|
+
export declare class USimpleSheet extends UElement {
|
|
32
|
+
static styles: import('lit').CSSResultGroup[];
|
|
33
|
+
/** 초기 데이터 (2D 문자열 배열) */
|
|
34
|
+
data: string[][];
|
|
35
|
+
/** 열 정의 (미설정시 A, B, C... 자동 헤더) */
|
|
36
|
+
columns?: SheetColumn[];
|
|
37
|
+
/** 초기 행 수 */
|
|
38
|
+
rows: number;
|
|
39
|
+
/** 초기 열 수 (columns 미설정시 사용) */
|
|
40
|
+
cols: number;
|
|
41
|
+
/** 읽기 전용 모드 */
|
|
42
|
+
readonly: boolean;
|
|
43
|
+
private _sel;
|
|
44
|
+
private _editing;
|
|
45
|
+
private _editVal;
|
|
46
|
+
private _replaceOnEdit;
|
|
47
|
+
private _data;
|
|
48
|
+
private _colWidths;
|
|
49
|
+
private _isMouseSelecting;
|
|
50
|
+
private _containerEl;
|
|
51
|
+
private _resizing;
|
|
52
|
+
private static readonly MIN_COL_WIDTH;
|
|
53
|
+
private static readonly DEFAULT_COL_WIDTH;
|
|
54
|
+
private _history;
|
|
55
|
+
private _historyIndex;
|
|
56
|
+
private static readonly HISTORY_LIMIT;
|
|
57
|
+
connectedCallback(): void;
|
|
58
|
+
disconnectedCallback(): void;
|
|
59
|
+
protected willUpdate(changed: Map<string, unknown>): void;
|
|
60
|
+
private _syncDataFromProps;
|
|
61
|
+
private _syncData;
|
|
62
|
+
private get _rowCount();
|
|
63
|
+
private get _colCount();
|
|
64
|
+
private _pushHistory;
|
|
65
|
+
private _undo;
|
|
66
|
+
private _redo;
|
|
67
|
+
/** 열 인덱스를 A, B, ..., Z, AA, AB, ... 형태로 변환 */
|
|
68
|
+
private _colLabel;
|
|
69
|
+
private _colWidthStyle;
|
|
70
|
+
private _inSel;
|
|
71
|
+
private _isAnchor;
|
|
72
|
+
private _isColSelected;
|
|
73
|
+
private _isRowSelected;
|
|
74
|
+
render(): TemplateResult<1>;
|
|
75
|
+
private _renderCell;
|
|
76
|
+
private _refContainer;
|
|
77
|
+
private _onContainerFocus;
|
|
78
|
+
private _onContainerKeyDown;
|
|
79
|
+
private _onInputChange;
|
|
80
|
+
private _onInputKeyDown;
|
|
81
|
+
private _onInputBlur;
|
|
82
|
+
private _onTableMouseDown;
|
|
83
|
+
private _onTableMouseOver;
|
|
84
|
+
private _onTableDblClick;
|
|
85
|
+
private _onDocMouseUp;
|
|
86
|
+
/** 열 너비 조절 시작 */
|
|
87
|
+
private _onResizeStart;
|
|
88
|
+
private _onResizeMove;
|
|
89
|
+
private _onResizeEnd;
|
|
90
|
+
/** 코너 클릭 → 전체 선택 */
|
|
91
|
+
private _onSelectAll;
|
|
92
|
+
/** 열 헤더 클릭 → 전체 열 선택 */
|
|
93
|
+
private _onColHeaderMouseDown;
|
|
94
|
+
/** 행 헤더 클릭 → 전체 행 선택 */
|
|
95
|
+
private _onRowHeaderMouseDown;
|
|
96
|
+
private _onCopy;
|
|
97
|
+
private _onPaste;
|
|
98
|
+
private _selectionToTSV;
|
|
99
|
+
private _pasteFromText;
|
|
100
|
+
/** Ctrl+D: 선택 영역 첫 행 값을 아래로 채우기 */
|
|
101
|
+
private _fillDown;
|
|
102
|
+
/** Ctrl+R: 선택 영역 첫 열 값을 오른쪽으로 채우기 */
|
|
103
|
+
private _fillRight;
|
|
104
|
+
/**
|
|
105
|
+
* @param typedChar - 타이핑으로 시작할 경우 첫 글자. 미제공시 기존 값 유지.
|
|
106
|
+
*/
|
|
107
|
+
private _startEdit;
|
|
108
|
+
private _commitEdit;
|
|
109
|
+
private _cancelEdit;
|
|
110
|
+
private _clearSelection;
|
|
111
|
+
private _select;
|
|
112
|
+
private _scrollCellIntoView;
|
|
113
|
+
private _getCellFromEvent;
|
|
114
|
+
private _isColReadonly;
|
|
115
|
+
private _emitChange;
|
|
116
|
+
/** 현재 데이터를 2D 배열로 반환 */
|
|
117
|
+
getData(): string[][];
|
|
118
|
+
/**
|
|
119
|
+
* 정의된 columns의 key를 기준으로 객체 배열로 반환.
|
|
120
|
+
* columns 미설정시 A, B, C... 키를 사용.
|
|
121
|
+
*/
|
|
122
|
+
getDataAsObjects(): Record<string, string>[];
|
|
123
|
+
/** 데이터를 직접 설정하고 재렌더링 */
|
|
124
|
+
setData(data: string[][]): void;
|
|
125
|
+
/** 특정 셀 값 설정 */
|
|
126
|
+
setCell(row: number, col: number, value: string): void;
|
|
127
|
+
/** 현재 선택 영역 반환 */
|
|
128
|
+
getSelection(): {
|
|
129
|
+
minRow: number;
|
|
130
|
+
maxRow: number;
|
|
131
|
+
minCol: number;
|
|
132
|
+
maxCol: number;
|
|
133
|
+
} | null;
|
|
134
|
+
/** Undo 가능 여부 */
|
|
135
|
+
get canUndo(): boolean;
|
|
136
|
+
/** Redo 가능 여부 */
|
|
137
|
+
get canRedo(): boolean;
|
|
138
|
+
}
|