@iyulab/data-components 0.7.0 → 0.8.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.
- package/CHANGELOG.md +168 -2
- package/README.md +36 -2
- package/dist/_virtual/{_@oxc-project_runtime@0.139.0 → _@oxc-project_runtime@0.142.0}/helpers/esm/decorate.js +1 -1
- package/dist/_virtual/{_@oxc-project_runtime@0.139.0 → _@oxc-project_runtime@0.142.0}/helpers/esm/decorateMetadata.js +1 -1
- package/dist/components/data-view/UDataView.js +4 -3
- package/dist/components/data-view/UDataView.styles.js +17 -90
- package/dist/components/simple-sheet/USimpleSheet.d.ts +2 -0
- package/dist/components/simple-sheet/USimpleSheet.js +5 -3
- package/dist/components/simple-sheet/USimpleSheet.styles.js +11 -107
- package/dist/components/u-rich-table/URichTable.d.ts +25 -0
- package/dist/components/u-rich-table/URichTable.js +53 -18
- package/dist/components/u-rich-table/styles.js +82 -196
- package/package.json +2 -2
|
@@ -9,6 +9,19 @@ export declare class URichTable extends LitElement {
|
|
|
9
9
|
currentPage: number;
|
|
10
10
|
loading: boolean;
|
|
11
11
|
emptyMessage: string;
|
|
12
|
+
/** 로딩 표시 문구 */
|
|
13
|
+
loadingMessage: string;
|
|
14
|
+
/** 필터 입력 placeholder */
|
|
15
|
+
filterPlaceholder: string;
|
|
16
|
+
/** 필터 select 의 "전체" 항목 문구 */
|
|
17
|
+
filterAllLabel: string;
|
|
18
|
+
/** 새 행 추가 버튼 문구 */
|
|
19
|
+
addRowLabel: string;
|
|
20
|
+
/**
|
|
21
|
+
* 페이지 정보 문구. (전체, 시작, 끝) 을 받아 문자열을 만든다.
|
|
22
|
+
* 언어마다 어순이 달라 템플릿 문자열이 아니라 함수로 연다.
|
|
23
|
+
*/
|
|
24
|
+
pageInfoFormatter: (total: number, start: number, end: number) => string;
|
|
12
25
|
selectable: boolean;
|
|
13
26
|
editable: boolean;
|
|
14
27
|
addable: boolean;
|
|
@@ -27,6 +40,18 @@ export declare class URichTable extends LitElement {
|
|
|
27
40
|
revertRow(_rowId: string): void;
|
|
28
41
|
setRowError(rowId: string, message: string): void;
|
|
29
42
|
clearRowError(rowId: string): void;
|
|
43
|
+
/**
|
|
44
|
+
* 행의 식별자. 선택·확장·행 오류 상태가 전부 이 값으로 추적된다.
|
|
45
|
+
*
|
|
46
|
+
* ⚠`_id` 는 이 컴포넌트가 **부여하지 않는다.** 소비자가 넣어 주지 않으면 모든 행의
|
|
47
|
+
* `_id` 가 `undefined` 가 되고, Set 은 그 하나만 담으므로 **한 행을 고르면 전부
|
|
48
|
+
* 골라진다.** 그래서 없을 때는 위치를 대신 쓴다 — 다만 위치 기반 식별은 데이터가
|
|
49
|
+
* 재정렬·재페이징되면 **선택이 다른 행으로 옮겨간다.** 정렬/필터/페이지가 소비자
|
|
50
|
+
* 책임인 컴포넌트이므로, 실제 사용에서는 `_id` 를 주는 것이 옳다.
|
|
51
|
+
*/
|
|
52
|
+
private _rowId;
|
|
53
|
+
private _warnedMissingRowId;
|
|
54
|
+
private _warnMissingRowId;
|
|
30
55
|
getSelectedRows(): Record<string, unknown>[];
|
|
31
56
|
render(): TemplateResult;
|
|
32
57
|
private _renderToolbar;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.142.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.142.0/helpers/esm/decorate.js";
|
|
3
3
|
import { richTableStyles } from "./styles.js";
|
|
4
4
|
import { parseTSV, toTSV } from "./utils/clipboard.js";
|
|
5
5
|
import { LitElement, html } from "lit";
|
|
@@ -15,6 +15,11 @@ var URichTable = class URichTable extends LitElement {
|
|
|
15
15
|
this.currentPage = 1;
|
|
16
16
|
this.loading = false;
|
|
17
17
|
this.emptyMessage = "데이터가 없습니다";
|
|
18
|
+
this.loadingMessage = "로딩 중...";
|
|
19
|
+
this.filterPlaceholder = "필터...";
|
|
20
|
+
this.filterAllLabel = "전체";
|
|
21
|
+
this.addRowLabel = "+ 새 행";
|
|
22
|
+
this.pageInfoFormatter = (total, start, end) => `전체 ${total.toLocaleString()}건 중 ${start}-${end} 표시`;
|
|
18
23
|
this.selectable = false;
|
|
19
24
|
this.editable = false;
|
|
20
25
|
this.addable = false;
|
|
@@ -29,6 +34,7 @@ var URichTable = class URichTable extends LitElement {
|
|
|
29
34
|
this.filters = {};
|
|
30
35
|
this.validationErrors = /* @__PURE__ */ new Map();
|
|
31
36
|
this.rowErrors = /* @__PURE__ */ new Map();
|
|
37
|
+
this._warnedMissingRowId = false;
|
|
32
38
|
this._lastSelectedIndex = -1;
|
|
33
39
|
this._onGlobalKeyDown = (e) => {
|
|
34
40
|
if (e.ctrlKey || e.metaKey) {
|
|
@@ -65,7 +71,8 @@ var URichTable = class URichTable extends LitElement {
|
|
|
65
71
|
}
|
|
66
72
|
if (e.key === " " && this.selectable) {
|
|
67
73
|
e.preventDefault();
|
|
68
|
-
const
|
|
74
|
+
const r = this.data[this.focusedCell.rowIndex];
|
|
75
|
+
const rowId = r ? this._rowId(r, this.focusedCell.rowIndex) : void 0;
|
|
69
76
|
if (rowId) this._onRowSelect(rowId);
|
|
70
77
|
}
|
|
71
78
|
if (e.key === "Delete" && this.selectedIds.size > 0) for (const row of this.getSelectedRows()) this.dispatchEvent(new CustomEvent("row-delete", {
|
|
@@ -88,8 +95,28 @@ var URichTable = class URichTable extends LitElement {
|
|
|
88
95
|
next.delete(rowId);
|
|
89
96
|
this.rowErrors = next;
|
|
90
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* 행의 식별자. 선택·확장·행 오류 상태가 전부 이 값으로 추적된다.
|
|
100
|
+
*
|
|
101
|
+
* ⚠`_id` 는 이 컴포넌트가 **부여하지 않는다.** 소비자가 넣어 주지 않으면 모든 행의
|
|
102
|
+
* `_id` 가 `undefined` 가 되고, Set 은 그 하나만 담으므로 **한 행을 고르면 전부
|
|
103
|
+
* 골라진다.** 그래서 없을 때는 위치를 대신 쓴다 — 다만 위치 기반 식별은 데이터가
|
|
104
|
+
* 재정렬·재페이징되면 **선택이 다른 행으로 옮겨간다.** 정렬/필터/페이지가 소비자
|
|
105
|
+
* 책임인 컴포넌트이므로, 실제 사용에서는 `_id` 를 주는 것이 옳다.
|
|
106
|
+
*/
|
|
107
|
+
_rowId(row, index) {
|
|
108
|
+
const id = row._id;
|
|
109
|
+
if (id !== void 0 && id !== null) return String(id);
|
|
110
|
+
this._warnMissingRowId();
|
|
111
|
+
return `#${index}`;
|
|
112
|
+
}
|
|
113
|
+
_warnMissingRowId() {
|
|
114
|
+
if (this._warnedMissingRowId) return;
|
|
115
|
+
this._warnedMissingRowId = true;
|
|
116
|
+
console.warn("[@iyulab/data-components] u-rich-table: 행에 `_id` 가 없어 **위치**로 식별합니다. 데이터가 재정렬·재페이징되면 선택 상태가 다른 행으로 옮겨갑니다. 각 행에 고유한 `_id` 를 부여하세요.");
|
|
117
|
+
}
|
|
91
118
|
getSelectedRows() {
|
|
92
|
-
return this.data.filter((row) => this.selectedIds.has(row
|
|
119
|
+
return this.data.filter((row, i) => this.selectedIds.has(this._rowId(row, i)));
|
|
93
120
|
}
|
|
94
121
|
render() {
|
|
95
122
|
return html`
|
|
@@ -122,7 +149,7 @@ var URichTable = class URichTable extends LitElement {
|
|
|
122
149
|
<div style="flex:1"></div>
|
|
123
150
|
<slot name="toolbar-end"></slot>
|
|
124
151
|
${this.addable ? html`
|
|
125
|
-
<button class="btn btn-success" @click=${this._onAddRowClick}
|
|
152
|
+
<button class="btn btn-success" @click=${this._onAddRowClick}>${this.addRowLabel}</button>
|
|
126
153
|
` : ""}
|
|
127
154
|
</div>
|
|
128
155
|
`;
|
|
@@ -157,10 +184,10 @@ var URichTable = class URichTable extends LitElement {
|
|
|
157
184
|
${this.columns.map((col) => html`
|
|
158
185
|
<td>
|
|
159
186
|
${col.filterable !== false ? col.filterType === "select" && col.options ? html`<select @change=${(e) => this._onFilterChange(col.key, e.target.value)}>
|
|
160
|
-
<option value=""
|
|
187
|
+
<option value="">${this.filterAllLabel}</option>
|
|
161
188
|
${col.options.map((o) => html`<option value=${o.value}>${o.label}</option>`)}
|
|
162
189
|
</select>` : html`<input
|
|
163
|
-
placeholder
|
|
190
|
+
placeholder=${this.filterPlaceholder}
|
|
164
191
|
@input=${(e) => this._onFilterChange(col.key, e.target.value)} />` : ""}
|
|
165
192
|
</td>
|
|
166
193
|
`)}
|
|
@@ -169,10 +196,10 @@ var URichTable = class URichTable extends LitElement {
|
|
|
169
196
|
`;
|
|
170
197
|
}
|
|
171
198
|
_renderBody() {
|
|
172
|
-
if (this.loading) return html`<tr><td colspan=${this._colSpan()}><div class="loading-overlay"
|
|
199
|
+
if (this.loading) return html`<tr><td colspan=${this._colSpan()}><div class="loading-overlay">${this.loadingMessage}</div></td></tr>`;
|
|
173
200
|
if (this.data.length === 0) return html`<tr><td colspan=${this._colSpan()}><div class="empty-message">${this.emptyMessage}</div></td></tr>`;
|
|
174
201
|
return this.data.map((row, rowIdx) => {
|
|
175
|
-
const rowId = row
|
|
202
|
+
const rowId = this._rowId(row, rowIdx);
|
|
176
203
|
const isSelected = this.selectedIds.has(rowId);
|
|
177
204
|
const isExpanded = this.expandedIds.has(rowId);
|
|
178
205
|
const hasError = this.rowErrors.has(rowId);
|
|
@@ -192,7 +219,7 @@ var URichTable = class URichTable extends LitElement {
|
|
|
192
219
|
` : ""}
|
|
193
220
|
${this.columns.map((col, colIdx) => this._renderCell(row, rowIdx, col, colIdx))}
|
|
194
221
|
<td class="actions-cell">
|
|
195
|
-
<span
|
|
222
|
+
<span class="row-menu" @click=${() => this._onRowMenu(row)}>⋯</span>
|
|
196
223
|
</td>
|
|
197
224
|
</tr>
|
|
198
225
|
${isExpanded && this.detailRenderer ? html`
|
|
@@ -201,7 +228,7 @@ var URichTable = class URichTable extends LitElement {
|
|
|
201
228
|
</tr>
|
|
202
229
|
` : ""}
|
|
203
230
|
${hasError ? html`
|
|
204
|
-
<tr><td colspan=${this._colSpan()}
|
|
231
|
+
<tr><td colspan=${this._colSpan()} class="row-error-cell">
|
|
205
232
|
${this.rowErrors.get(rowId)}
|
|
206
233
|
</td></tr>
|
|
207
234
|
` : ""}
|
|
@@ -253,7 +280,10 @@ var URichTable = class URichTable extends LitElement {
|
|
|
253
280
|
}
|
|
254
281
|
return String(value ?? "");
|
|
255
282
|
}
|
|
256
|
-
if (col.type === "badge" && col.badgeColors)
|
|
283
|
+
if (col.type === "badge" && col.badgeColors) {
|
|
284
|
+
const color = col.badgeColors[String(value)] ?? "#f3f4f6";
|
|
285
|
+
return html`<span class="badge" style="background:${color}">${this._getOptionLabel(col, value)}</span>`;
|
|
286
|
+
}
|
|
257
287
|
if (col.type === "select" && col.options) return this._getOptionLabel(col, value);
|
|
258
288
|
if (col.type === "number" && value != null) return Number(value).toLocaleString();
|
|
259
289
|
return String(value ?? "");
|
|
@@ -261,7 +291,7 @@ var URichTable = class URichTable extends LitElement {
|
|
|
261
291
|
_renderNewRow() {
|
|
262
292
|
return html`
|
|
263
293
|
<tr class="new-row">
|
|
264
|
-
${this.selectable ? html`<td class="checkbox-cell"><span
|
|
294
|
+
${this.selectable ? html`<td class="checkbox-cell"><span class="new-row-marker">+</span></td>` : ""}
|
|
265
295
|
${this.expandable ? html`<td></td>` : ""}
|
|
266
296
|
${this.columns.map((col, colIdx) => html`
|
|
267
297
|
<td>
|
|
@@ -284,7 +314,7 @@ var URichTable = class URichTable extends LitElement {
|
|
|
284
314
|
const end = Math.min(this.currentPage * this.pageSize, this.totalCount);
|
|
285
315
|
return html`
|
|
286
316
|
<div class="pagination">
|
|
287
|
-
<span
|
|
317
|
+
<span>${this.pageInfoFormatter(this.totalCount, start, end)}</span>
|
|
288
318
|
<div class="page-buttons">
|
|
289
319
|
<button ?disabled=${this.currentPage <= 1} @click=${() => this._onPageChange(this.currentPage - 1)}>◀</button>
|
|
290
320
|
${this._getPageNumbers(totalPages).map((p) => html`
|
|
@@ -303,7 +333,7 @@ var URichTable = class URichTable extends LitElement {
|
|
|
303
333
|
`;
|
|
304
334
|
}
|
|
305
335
|
_onSelectAll(e) {
|
|
306
|
-
if (e.target.checked) this.selectedIds = new Set(this.data.map((r) => r
|
|
336
|
+
if (e.target.checked) this.selectedIds = new Set(this.data.map((r, i) => this._rowId(r, i)));
|
|
307
337
|
else this.selectedIds = /* @__PURE__ */ new Set();
|
|
308
338
|
this._fireSelectionChange();
|
|
309
339
|
}
|
|
@@ -319,7 +349,7 @@ var URichTable = class URichTable extends LitElement {
|
|
|
319
349
|
const start = Math.min(this._lastSelectedIndex, rowIdx);
|
|
320
350
|
const end = Math.max(this._lastSelectedIndex, rowIdx);
|
|
321
351
|
const next = new Set(this.selectedIds);
|
|
322
|
-
for (let i = start; i <= end; i++) next.add(this.data[i]
|
|
352
|
+
for (let i = start; i <= end; i++) next.add(this._rowId(this.data[i], i));
|
|
323
353
|
this.selectedIds = next;
|
|
324
354
|
this._fireSelectionChange();
|
|
325
355
|
}
|
|
@@ -442,7 +472,7 @@ var URichTable = class URichTable extends LitElement {
|
|
|
442
472
|
this.expandedIds = next;
|
|
443
473
|
this.dispatchEvent(new CustomEvent("row-expand", {
|
|
444
474
|
detail: {
|
|
445
|
-
row: this.data.find((r) => r
|
|
475
|
+
row: this.data.find((r, i) => this._rowId(r, i) === rowId),
|
|
446
476
|
expanded
|
|
447
477
|
},
|
|
448
478
|
bubbles: true,
|
|
@@ -585,7 +615,7 @@ var URichTable = class URichTable extends LitElement {
|
|
|
585
615
|
};
|
|
586
616
|
}
|
|
587
617
|
_selectAll() {
|
|
588
|
-
this.selectedIds = new Set(this.data.map((r) => r
|
|
618
|
+
this.selectedIds = new Set(this.data.map((r, i) => this._rowId(r, i)));
|
|
589
619
|
this._fireSelectionChange();
|
|
590
620
|
}
|
|
591
621
|
static define(tagName = "u-rich-table") {
|
|
@@ -599,6 +629,11 @@ __decorate([property({ type: Number }), __decorateMetadata("design:type", Object
|
|
|
599
629
|
__decorate([property({ type: Number }), __decorateMetadata("design:type", Object)], URichTable.prototype, "currentPage", void 0);
|
|
600
630
|
__decorate([property({ type: Boolean }), __decorateMetadata("design:type", Object)], URichTable.prototype, "loading", void 0);
|
|
601
631
|
__decorate([property({ type: String }), __decorateMetadata("design:type", Object)], URichTable.prototype, "emptyMessage", void 0);
|
|
632
|
+
__decorate([property({ type: String }), __decorateMetadata("design:type", Object)], URichTable.prototype, "loadingMessage", void 0);
|
|
633
|
+
__decorate([property({ type: String }), __decorateMetadata("design:type", Object)], URichTable.prototype, "filterPlaceholder", void 0);
|
|
634
|
+
__decorate([property({ type: String }), __decorateMetadata("design:type", Object)], URichTable.prototype, "filterAllLabel", void 0);
|
|
635
|
+
__decorate([property({ type: String }), __decorateMetadata("design:type", Object)], URichTable.prototype, "addRowLabel", void 0);
|
|
636
|
+
__decorate([property({ attribute: false }), __decorateMetadata("design:type", Function)], URichTable.prototype, "pageInfoFormatter", void 0);
|
|
602
637
|
__decorate([property({ type: Boolean }), __decorateMetadata("design:type", Object)], URichTable.prototype, "selectable", void 0);
|
|
603
638
|
__decorate([property({ type: Boolean }), __decorateMetadata("design:type", Object)], URichTable.prototype, "editable", void 0);
|
|
604
639
|
__decorate([property({ type: Boolean }), __decorateMetadata("design:type", Object)], URichTable.prototype, "addable", void 0);
|