@iyulab/data-components 0.13.0 → 0.14.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 +51 -0
- package/dist/_virtual/{_@oxc-project_runtime@0.142.0 → _@oxc-project_runtime@0.143.0}/helpers/esm/decorate.js +1 -1
- package/dist/_virtual/{_@oxc-project_runtime@0.142.0 → _@oxc-project_runtime@0.143.0}/helpers/esm/decorateMetadata.js +1 -1
- package/dist/components/data-view/UDataView.js +2 -2
- package/dist/components/simple-sheet/USimpleSheet.js +17 -12
- package/dist/components/u-rich-table/URichTable.d.ts +6 -0
- package/dist/components/u-rich-table/URichTable.js +39 -17
- package/dist/components/u-rich-table/styles.js +31 -3
- package/dist/components/u-rich-table/types.d.ts +10 -0
- package/dist/react.d.ts +5 -0
- package/dist/react.js +1 -0
- package/package.json +10 -6
- package/skills/iyulab-data-components/references/components/rich-table.md +20 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,56 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.14.0] - 2026-08-07
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`u-rich-table` gained a `row-activate` event** — the most common grid interaction, "click a
|
|
8
|
+
row to see its detail," had no way to reach the app. `selection-change` is checkbox-only and
|
|
9
|
+
conflating it with "the row being viewed" breaks multi-select screens; `row-expand` announces
|
|
10
|
+
that a detail row opened but gives the app no slot to render into. Clicking a cell now always
|
|
11
|
+
fires `row-activate` (`editable` columns included — a single click never enters edit mode, only
|
|
12
|
+
`dblclick` does), and so does `Enter` on a focused cell in a non-`editable` column (an
|
|
13
|
+
`editable` column's `Enter` still starts editing, unchanged). `detail: { row, id, via: 'click' |
|
|
14
|
+
'keyboard' }`. Purely additive — no existing behavior changes.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- 🔴**`u-rich-table`: giving the host a height made the pagination unreachable.** The component
|
|
19
|
+
declared no vertical layout, so under a height constraint the content overflowed at its natural
|
|
20
|
+
size while `:host` clipped with `overflow: hidden` — and because the pagination is the last child,
|
|
21
|
+
it was the first thing to disappear. It stayed in the DOM; it was simply neither visible nor
|
|
22
|
+
scrollable to. *The table rendered, but page 2 could not be reached.*
|
|
23
|
+
|
|
24
|
+
That left consumers with two options, both of which cost something the grid is for: constrain the
|
|
25
|
+
height and lose paging, or leave it unconstrained and let 50 rows become a 2,000px document whose
|
|
26
|
+
header scrolls away.
|
|
27
|
+
|
|
28
|
+
The host is now a column flex container: the toolbar and pagination hold their positions and only
|
|
29
|
+
the row area scrolls. The header row is `sticky`, so column names stay put while rows scroll —
|
|
30
|
+
the boundary line under it is drawn with an inset `box-shadow` rather than `border-bottom`,
|
|
31
|
+
because under `border-collapse: collapse` cell borders belong to the table and do not follow a
|
|
32
|
+
stuck header.
|
|
33
|
+
|
|
34
|
+
**Unconstrained use is unchanged**: with no height, `flex: 1 1 auto` follows content height and
|
|
35
|
+
`overflow: auto` adds no scrollbar. Verified in a real browser at both sizes.
|
|
36
|
+
|
|
37
|
+
- 🔴**`sideEffects` omitted this package's own entry barrel, so bundlers dropped every element
|
|
38
|
+
registration.** The barrel that `exports["."]` resolves to exists solely to register the custom
|
|
39
|
+
elements, but it was not in the `sideEffects` allowlist. A consumer writing
|
|
40
|
+
`import '@iyulab/data-components'` — the form this package's own documentation recommends — had the module
|
|
41
|
+
elided entirely in a production build. The failure is silent: the build succeeds with no warning,
|
|
42
|
+
the tags remain in the DOM, and an unregistered custom element renders nothing.
|
|
43
|
+
|
|
44
|
+
Registration modules were already listed correctly. That was not enough: a dropped barrel means
|
|
45
|
+
they are never reached.
|
|
46
|
+
|
|
47
|
+
The `./react` subpath entry had the same gap. This also explains a second symptom:
|
|
48
|
+
`querySelector` still returns an element for an unregistered tag, so consumer code calling a
|
|
49
|
+
component method on it fails with `is not a function` rather than returning null.
|
|
50
|
+
|
|
51
|
+
Both the source-resolved and published-artifact forms of every affected entry point are now
|
|
52
|
+
declared, so workspace consumers and installed consumers get the same guarantee.
|
|
53
|
+
|
|
3
54
|
## [0.13.0] - 2026-08-05
|
|
4
55
|
|
|
5
56
|
### Added
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region \0@oxc-project+runtime@0.
|
|
1
|
+
//#region \0@oxc-project+runtime@0.143.0/helpers/esm/decorate.js
|
|
2
2
|
function __decorate(decorators, target, key, desc) {
|
|
3
3
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
4
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region \0@oxc-project+runtime@0.
|
|
1
|
+
//#region \0@oxc-project+runtime@0.143.0/helpers/esm/decorateMetadata.js
|
|
2
2
|
function __decorateMetadata(k, v) {
|
|
3
3
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
4
4
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { styles } from "./UDataView.styles.js";
|
|
2
|
-
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.
|
|
3
|
-
import __decorate from "../../_virtual/_@oxc-project_runtime@0.
|
|
2
|
+
import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorateMetadata.js";
|
|
3
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
|
|
4
4
|
import { html } from "lit";
|
|
5
5
|
import { customElement, property } from "lit/decorators.js";
|
|
6
6
|
import "@iyulab/components/dist/components/icon/UIcon.js";
|
|
@@ -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.143.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
|
|
3
3
|
import { messages } from "../../utilities/messages.js";
|
|
4
4
|
import { styles } from "./USimpleSheet.styles.js";
|
|
5
5
|
import { html } from "lit";
|
|
@@ -56,8 +56,10 @@ var USimpleSheet = class USimpleSheet extends UElement {
|
|
|
56
56
|
if (e.ctrlKey || e.metaKey) {
|
|
57
57
|
if (e.key === "z" || e.key === "Z") {
|
|
58
58
|
e.preventDefault();
|
|
59
|
-
if (!this.readonly)
|
|
60
|
-
|
|
59
|
+
if (!this.readonly) {
|
|
60
|
+
if (e.shiftKey) this._redo();
|
|
61
|
+
else this._undo();
|
|
62
|
+
}
|
|
61
63
|
return;
|
|
62
64
|
}
|
|
63
65
|
if (e.key === "y" || e.key === "Y") {
|
|
@@ -109,9 +111,10 @@ var USimpleSheet = class USimpleSheet extends UElement {
|
|
|
109
111
|
}
|
|
110
112
|
if (e.key === "Tab") {
|
|
111
113
|
e.preventDefault();
|
|
112
|
-
if (e.shiftKey)
|
|
113
|
-
|
|
114
|
-
|
|
114
|
+
if (e.shiftKey) {
|
|
115
|
+
if (anchor.col === 0 && anchor.row > 0) this._select(anchor.row - 1, this._colCount - 1);
|
|
116
|
+
else this._select(anchor.row, Math.max(0, anchor.col - 1));
|
|
117
|
+
} else if (anchor.col === this._colCount - 1) {
|
|
115
118
|
if (anchor.row < this._rowCount - 1) this._select(anchor.row + 1, 0);
|
|
116
119
|
} else this._select(anchor.row, anchor.col + 1);
|
|
117
120
|
return;
|
|
@@ -220,11 +223,13 @@ var USimpleSheet = class USimpleSheet extends UElement {
|
|
|
220
223
|
e.preventDefault();
|
|
221
224
|
const pos = this._editing;
|
|
222
225
|
this._commitEdit();
|
|
223
|
-
if (e.shiftKey)
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
else
|
|
227
|
-
|
|
226
|
+
if (e.shiftKey) {
|
|
227
|
+
if (pos.col === 0 && pos.row > 0) this._select(pos.row - 1, this._colCount - 1);
|
|
228
|
+
else this._select(pos.row, Math.max(0, pos.col - 1));
|
|
229
|
+
} else if (pos.col === this._colCount - 1) {
|
|
230
|
+
if (pos.row < this._rowCount - 1) this._select(pos.row + 1, 0);
|
|
231
|
+
else this._select(pos.row, pos.col);
|
|
232
|
+
} else this._select(pos.row, pos.col + 1);
|
|
228
233
|
return;
|
|
229
234
|
}
|
|
230
235
|
if (e.key === "ArrowUp") {
|
|
@@ -131,6 +131,12 @@ export declare class URichTable extends LitElement {
|
|
|
131
131
|
private _onSortClick;
|
|
132
132
|
private _onFilterChange;
|
|
133
133
|
private _onCellClick;
|
|
134
|
+
/**
|
|
135
|
+
* 「선택」(체크박스)과 별개로 「보고 있는 행」을 앱에 알린다. 셀 단일 클릭은
|
|
136
|
+
* `editable` 열에서도 편집에 들어가지 않으므로(dblclick만 진입) 항상 안전하게 낼 수 있다.
|
|
137
|
+
* 키보드 경로(Enter)는 `editable` 열에서 이미 편집 진입 신호이므로 그 경우는 내지 않는다.
|
|
138
|
+
*/
|
|
139
|
+
private _fireRowActivate;
|
|
134
140
|
private _onCellDblClick;
|
|
135
141
|
private _onEditKeyDown;
|
|
136
142
|
private _onCellEditConfirm;
|
|
@@ -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.143.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import __decorate from "../../_virtual/_@oxc-project_runtime@0.143.0/helpers/esm/decorate.js";
|
|
3
3
|
import { messages } from "../../utilities/messages.js";
|
|
4
4
|
import { richTableStyles } from "./styles.js";
|
|
5
5
|
import { parseTSV, toTSV } from "./utils/clipboard.js";
|
|
@@ -73,7 +73,7 @@ var URichTable = class URichTable extends LitElement {
|
|
|
73
73
|
if (col?.editable) {
|
|
74
74
|
const value = this.data[this.focusedCell.rowIndex]?.[col.key];
|
|
75
75
|
this._onCellDblClick(this.focusedCell.rowIndex, this.focusedCell.colIndex, value);
|
|
76
|
-
}
|
|
76
|
+
} else this._fireRowActivate(this.focusedCell.rowIndex, "keyboard");
|
|
77
77
|
}
|
|
78
78
|
if (e.key === " " && this.selectable) {
|
|
79
79
|
e.preventDefault();
|
|
@@ -178,14 +178,16 @@ var URichTable = class URichTable extends LitElement {
|
|
|
178
178
|
render() {
|
|
179
179
|
return html`
|
|
180
180
|
${this._renderToolbar()}
|
|
181
|
-
<table>
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
181
|
+
<div class="table-wrap">
|
|
182
|
+
<table>
|
|
183
|
+
${this._renderHeader()}
|
|
184
|
+
<tbody>
|
|
185
|
+
${this.filterable ? this._renderFilterRow() : ""}
|
|
186
|
+
${this._renderBody()}
|
|
187
|
+
${this.addable ? this._renderNewRow() : ""}
|
|
188
|
+
</tbody>
|
|
189
|
+
</table>
|
|
190
|
+
</div>
|
|
189
191
|
${this._renderPagination()}
|
|
190
192
|
`;
|
|
191
193
|
}
|
|
@@ -452,12 +454,13 @@ var URichTable = class URichTable extends LitElement {
|
|
|
452
454
|
this._fireSelectionChange();
|
|
453
455
|
}
|
|
454
456
|
_onSortClick(field) {
|
|
455
|
-
if (this.sort?.field === field)
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
457
|
+
if (this.sort?.field === field) {
|
|
458
|
+
if (this.sort.direction === "asc") this.sort = {
|
|
459
|
+
field,
|
|
460
|
+
direction: "desc"
|
|
461
|
+
};
|
|
462
|
+
else this.sort = null;
|
|
463
|
+
} else this.sort = {
|
|
461
464
|
field,
|
|
462
465
|
direction: "asc"
|
|
463
466
|
};
|
|
@@ -494,6 +497,25 @@ var URichTable = class URichTable extends LitElement {
|
|
|
494
497
|
colIndex: colIdx
|
|
495
498
|
};
|
|
496
499
|
this._lastSelectedIndex = rowIdx;
|
|
500
|
+
this._fireRowActivate(rowIdx, "click");
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* 「선택」(체크박스)과 별개로 「보고 있는 행」을 앱에 알린다. 셀 단일 클릭은
|
|
504
|
+
* `editable` 열에서도 편집에 들어가지 않으므로(dblclick만 진입) 항상 안전하게 낼 수 있다.
|
|
505
|
+
* 키보드 경로(Enter)는 `editable` 열에서 이미 편집 진입 신호이므로 그 경우는 내지 않는다.
|
|
506
|
+
*/
|
|
507
|
+
_fireRowActivate(rowIdx, via) {
|
|
508
|
+
const row = this.data[rowIdx];
|
|
509
|
+
if (!row) return;
|
|
510
|
+
this.dispatchEvent(new CustomEvent("row-activate", {
|
|
511
|
+
detail: {
|
|
512
|
+
row,
|
|
513
|
+
id: this._rowId(row, rowIdx),
|
|
514
|
+
via
|
|
515
|
+
},
|
|
516
|
+
bubbles: true,
|
|
517
|
+
composed: true
|
|
518
|
+
}));
|
|
497
519
|
}
|
|
498
520
|
_onCellDblClick(rowIdx, colIdx, value) {
|
|
499
521
|
this.editingCell = {
|
|
@@ -16,7 +16,16 @@ var richTableStyles = css`
|
|
|
16
16
|
--dc-muted-color: var(--u-txt-color-weak, #757575); /* 보조 텍스트 · 라벨 */
|
|
17
17
|
--dc-icon-color: var(--u-txt-color-weak, #757575); /* 정렬 표시 · 확장 · 행 메뉴 */
|
|
18
18
|
--dc-empty-color: var(--u-txt-color-weak, #757575); /* 빈 상태 안내문 */
|
|
19
|
-
|
|
19
|
+
/* ── 세로 레이아웃 ──
|
|
20
|
+
🔴**높이 제약은 데이터 그리드의 기본 사용 형태다** — 「조회 조건 + 결과 목록」이 한 화면에
|
|
21
|
+
들어가야 하고, 결과가 몇 건이든 조건 영역과 페이지 이동은 항상 같은 자리에 있어야 한다.
|
|
22
|
+
종전에는 «display: block» 이라 호스트에 높이를 주면 내용이 자연 높이로 넘쳤고,
|
|
23
|
+
«overflow: hidden» 때문에 **넘친 부분에 도달할 방법이 없었다.** 페이지네이션이 마지막
|
|
24
|
+
자식이므로 **가장 먼저 사라진다** ⇒ *표는 그려지는데 2페이지로 갈 수 없었다.*
|
|
25
|
+
⚠**높이를 주지 않는 사용은 그대로다** — «flex: 1 1 auto» 는 제약이 없으면 내용 높이를
|
|
26
|
+
따르고 «overflow: auto» 는 넘치지 않으면 스크롤바를 만들지 않는다. */
|
|
27
|
+
display: flex;
|
|
28
|
+
flex-direction: column;
|
|
20
29
|
font-family: system-ui, -apple-system, sans-serif;
|
|
21
30
|
font-size: 13px;
|
|
22
31
|
color: var(--u-txt-color, #212121);
|
|
@@ -25,7 +34,15 @@ var richTableStyles = css`
|
|
|
25
34
|
overflow: hidden;
|
|
26
35
|
}
|
|
27
36
|
|
|
37
|
+
/* 행 영역만 스크롤한다 — 툴바와 페이지네이션은 자리를 지킨다. */
|
|
38
|
+
.table-wrap {
|
|
39
|
+
flex: 1 1 auto;
|
|
40
|
+
overflow: auto;
|
|
41
|
+
min-height: 0; /* ⚠flex 아이템의 기본 min-height:auto 는 «줄어들지 않음»이라 이것이 없으면 넘친다 */
|
|
42
|
+
}
|
|
43
|
+
|
|
28
44
|
.toolbar {
|
|
45
|
+
flex: 0 0 auto;
|
|
29
46
|
display: flex;
|
|
30
47
|
align-items: center;
|
|
31
48
|
gap: 8px;
|
|
@@ -79,9 +96,19 @@ var richTableStyles = css`
|
|
|
79
96
|
background: var(--u-bg-color-raised, #FAFAFA);
|
|
80
97
|
font-weight: 600;
|
|
81
98
|
text-align: left;
|
|
82
|
-
border-bottom: 2px solid var(--u-border-color, #E0E0E0);
|
|
83
99
|
user-select: none;
|
|
84
|
-
|
|
100
|
+
|
|
101
|
+
/* ⚠**아래 경계선을 «border-bottom» 으로 그리지 않는다.** «border-collapse: collapse» 에서
|
|
102
|
+
셀 테두리는 테이블이 소유하므로 **헤더만 sticky 로 띄우면 함께 따라오지 않는다** —
|
|
103
|
+
스크롤하는 순간 구분선이 사라지고 행이 헤더 밑으로 비쳐 지나간다. «box-shadow» 는
|
|
104
|
+
요소가 그리므로 sticky 를 따라온다. */
|
|
105
|
+
box-shadow: inset 0 -2px 0 var(--u-border-color, #E0E0E0);
|
|
106
|
+
|
|
107
|
+
/* 행 영역이 스크롤되는 동안 열 이름은 남는다 — 「어느 열이 무엇인지」가 이 컴포넌트의
|
|
108
|
+
스크롤 모델에서 잃으면 안 되는 것이다. */
|
|
109
|
+
position: sticky;
|
|
110
|
+
top: 0;
|
|
111
|
+
z-index: 1;
|
|
85
112
|
}
|
|
86
113
|
|
|
87
114
|
thead th.sortable {
|
|
@@ -222,6 +249,7 @@ var richTableStyles = css`
|
|
|
222
249
|
}
|
|
223
250
|
|
|
224
251
|
.pagination {
|
|
252
|
+
flex: 0 0 auto;
|
|
225
253
|
display: flex;
|
|
226
254
|
justify-content: space-between;
|
|
227
255
|
align-items: center;
|
|
@@ -66,6 +66,16 @@ export interface RichTableEventMap {
|
|
|
66
66
|
row: Record<string, unknown>;
|
|
67
67
|
expanded: boolean;
|
|
68
68
|
}>;
|
|
69
|
+
/**
|
|
70
|
+
* 사용자가 행을 "열었다" — 셀 클릭 또는 포커스된 행에서의 `Enter`. `selectable` 과 무관하다:
|
|
71
|
+
* 선택은 "무엇을 처리할까", 활성화는 "무엇을 볼까"이다. `editable` 열에서 `Enter` 는 이미
|
|
72
|
+
* 셀 편집 진입 신호이므로 그 경우는 내지 않는다(`via: 'keyboard'` 는 비-editable 열에서만 발생).
|
|
73
|
+
*/
|
|
74
|
+
'row-activate': CustomEvent<{
|
|
75
|
+
row: Record<string, unknown>;
|
|
76
|
+
id: string;
|
|
77
|
+
via: 'click' | 'keyboard';
|
|
78
|
+
}>;
|
|
69
79
|
'sort-change': CustomEvent<{
|
|
70
80
|
field: string;
|
|
71
81
|
direction: 'asc' | 'desc' | null;
|
package/dist/react.d.ts
CHANGED
|
@@ -36,6 +36,11 @@ export declare const URichTableReact: import('@lit/react').ReactWebComponent<URi
|
|
|
36
36
|
row: Record<string, unknown>;
|
|
37
37
|
expanded: boolean;
|
|
38
38
|
}>>;
|
|
39
|
+
readonly onRowActivate: EventName<CustomEvent<{
|
|
40
|
+
row: Record<string, unknown>;
|
|
41
|
+
id: string;
|
|
42
|
+
via: "click" | "keyboard";
|
|
43
|
+
}>>;
|
|
39
44
|
readonly onSortChange: EventName<CustomEvent<{
|
|
40
45
|
field: string;
|
|
41
46
|
direction: "asc" | "desc" | null;
|
package/dist/react.js
CHANGED
|
@@ -39,6 +39,7 @@ var URichTableReact = createComponent({
|
|
|
39
39
|
onRowUpdate: "row-update",
|
|
40
40
|
onRowDelete: "row-delete",
|
|
41
41
|
onRowExpand: "row-expand",
|
|
42
|
+
onRowActivate: "row-activate",
|
|
42
43
|
onSortChange: "sort-change",
|
|
43
44
|
onFilterChange: "filter-change",
|
|
44
45
|
onPageChange: "page-change",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iyulab/data-components",
|
|
3
3
|
"description": "iyulab data visualization components",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.14.0",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"iyulab",
|
|
7
7
|
"web-components",
|
|
@@ -42,16 +42,20 @@
|
|
|
42
42
|
"./u-rich-table": "./dist/components/u-rich-table/URichTable.js"
|
|
43
43
|
},
|
|
44
44
|
"sideEffects": [
|
|
45
|
-
"./
|
|
45
|
+
"./dist/components/data-view/UDataView.js",
|
|
46
46
|
"./src/components/data-view/UDataView.ts",
|
|
47
|
+
"./dist/components/simple-sheet/USimpleSheet.js",
|
|
47
48
|
"./src/components/simple-sheet/USimpleSheet.ts",
|
|
49
|
+
"./dist/components/u-rich-table/URichTable.js",
|
|
48
50
|
"./src/components/u-rich-table/URichTable.ts",
|
|
51
|
+
"./dist/index.js",
|
|
52
|
+
"./src/index.ts",
|
|
53
|
+
"./dist/init.js",
|
|
49
54
|
"./src/init.ts",
|
|
55
|
+
"./dist/react.js",
|
|
56
|
+
"./src/react.ts",
|
|
50
57
|
"./dist/utilities/shadowDomProtection.js",
|
|
51
|
-
"./
|
|
52
|
-
"./dist/components/simple-sheet/USimpleSheet.js",
|
|
53
|
-
"./dist/components/u-rich-table/URichTable.js",
|
|
54
|
-
"./dist/init.js"
|
|
58
|
+
"./src/utilities/shadowDomProtection.ts"
|
|
55
59
|
],
|
|
56
60
|
"scripts": {
|
|
57
61
|
"start": "vite",
|
|
@@ -57,6 +57,24 @@ table.addEventListener('filter-change', e => load({ filters: e.detail.filters })
|
|
|
57
57
|
`totalCount` is what the pager counts — not `data.length`. Setting `data` alone
|
|
58
58
|
produces a table that believes it holds every matching record.
|
|
59
59
|
|
|
60
|
+
## Sizing: give the host a height
|
|
61
|
+
|
|
62
|
+
The component manages its own vertical layout. Constrain the host and the row
|
|
63
|
+
area is what scrolls — the toolbar and the pager keep their positions, and the
|
|
64
|
+
header row stays visible while rows move under it:
|
|
65
|
+
|
|
66
|
+
```css
|
|
67
|
+
u-rich-table { height: calc(100vh - 280px); }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
That is the shape a query screen wants: filters above, the pager always in the
|
|
71
|
+
same place, and column names readable no matter how far down you are.
|
|
72
|
+
|
|
73
|
+
Leave the height off and the table grows to its content instead — no inner
|
|
74
|
+
scrollbar, the page scrolls. Both are supported; pick per screen. What you
|
|
75
|
+
should **not** do is wrap it in your own `overflow: auto` container, which puts
|
|
76
|
+
the header and toolbar back inside the scrolling region.
|
|
77
|
+
|
|
60
78
|
## Selection across pages
|
|
61
79
|
|
|
62
80
|
Two facts are deliberately separate, because in server paging they differ:
|
|
@@ -158,6 +176,7 @@ type SelectionChange = RichTableEventMap['selection-change'];
|
|
|
158
176
|
| `row-create` | `{ row }` | The add-row control produced a row |
|
|
159
177
|
| `row-delete` | `{ row }` | A row was deleted |
|
|
160
178
|
| `row-expand` | `{ row, expanded }` | A detail row was opened or closed |
|
|
179
|
+
| `row-activate` | `{ row, id, via }` | A row was clicked, or `Enter` was pressed on a focused non-editable cell (`via` is `'click'` or `'keyboard'`). Independent of `selectable` — selection is "what to act on", activation is "what to view" |
|
|
161
180
|
| `paste` | `{ rows }` | TSV was pasted into the grid |
|
|
162
181
|
|
|
163
182
|
## ColumnDef
|
|
@@ -193,7 +212,7 @@ type SelectionChange = RichTableEventMap['selection-change'];
|
|
|
193
212
|
| Keys | Action |
|
|
194
213
|
|---|---|
|
|
195
214
|
| Arrow keys | Move the focused cell |
|
|
196
|
-
| `Enter` |
|
|
215
|
+
| `Enter` | Editable cell: start editing / commit and move down. Non-editable cell: emit `row-activate` |
|
|
197
216
|
| `Escape` | Cancel editing |
|
|
198
217
|
| `Tab` | Commit and move to the next cell |
|
|
199
218
|
| `Space` | Toggle selection of the focused row (when `selectable`) |
|