@iyulab/flex-table 0.41.2 → 0.42.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 +16 -0
- package/README.md +13 -0
- package/dist/{flex-table-CZPubYVD.js → flex-table-BdnkC234.js} +27 -4
- package/dist/flex-table.js +1 -1
- package/dist/models/types.d.ts +9 -0
- package/dist/react.js +1 -1
- package/package.json +1 -1
- package/skills/iyulab-flex-table/SKILL.md +0 -1
- package/skills/iyulab-flex-table/references/api.md +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.42.0] - 2026-10-04
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`reveal: 'hover'` column option** — the column's content shows only while its row is hovered,
|
|
8
|
+
holds focus or is selected; for a row-actions column, so a list does not repeat the same buttons
|
|
9
|
+
on every row. The content stays focusable (Tab reveals it), touch screens always show it, and it
|
|
10
|
+
is not printed.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **The virtual scroll renders only the rows it needs above the view.** The first row in view was
|
|
15
|
+
computed as if the header and the frozen rows scrolled away with the body, so up to
|
|
16
|
+
(header + frozen rows) ÷ row height extra rows were rendered above the view — ten with eight frozen
|
|
17
|
+
rows. What is visible does not change.
|
|
18
|
+
|
|
3
19
|
## [0.41.2] - 2026-10-03
|
|
4
20
|
|
|
5
21
|
### Fixed
|
package/README.md
CHANGED
|
@@ -151,6 +151,7 @@ interface ColumnDefinition {
|
|
|
151
151
|
validator?: CellValidator; // Validate before commit: (value, row, col) => string | null
|
|
152
152
|
conditionalRules?: ConditionalRule[]; // Per-cell style rules, see below
|
|
153
153
|
mergeRepeated?: boolean | ((row, previousRow, col) => boolean); // Merge runs of repeated values, see below
|
|
154
|
+
reveal?: 'always' | 'hover'; // 'hover': show only while the row is hovered, focused or selected (row actions)
|
|
154
155
|
}
|
|
155
156
|
```
|
|
156
157
|
|
|
@@ -198,6 +199,18 @@ const columns: ColumnDefinition<Order>[] = [
|
|
|
198
199
|
|
|
199
200
|
Rules are evaluated in order and combined; later matching rules override earlier ones for overlapping style properties.
|
|
200
201
|
|
|
202
|
+
### Row actions that appear on hover
|
|
203
|
+
|
|
204
|
+
A column of row actions (edit, a "more" menu) repeated on every row turns a list into a wall of
|
|
205
|
+
buttons. `reveal: 'hover'` shows that column's content only while its row is hovered, holds focus or
|
|
206
|
+
is selected. The controls stay in the DOM and focusable — Tab reveals them — touch screens (no
|
|
207
|
+
hover) always show them, and they are not printed.
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
{ key: 'actions', label: '', width: 72, editable: false, reveal: 'hover',
|
|
211
|
+
render: (_, row) => html`<u-button size="sm" variant="ghost" aria-label="Edit">…</u-button>` }
|
|
212
|
+
```
|
|
213
|
+
|
|
201
214
|
### Merging Repeated Values
|
|
202
215
|
|
|
203
216
|
A list of child rows under a parent — order lines under an order, boxes under a shipment — repeats the parent's columns on every line. `mergeRepeated` draws each run of repeated values as one merged cell: the value shows once, on the run's first row, and the lines between the run's rows are dropped.
|
|
@@ -918,6 +918,28 @@ var y = r`
|
|
|
918
918
|
outline: 2px solid var(--ft-find-color);
|
|
919
919
|
outline-offset: -2px;
|
|
920
920
|
}
|
|
921
|
+
|
|
922
|
+
/* reveal: 'hover' — a row-actions column shows while the row is hovered, focused or selected.
|
|
923
|
+
opacity (not display/visibility) keeps the controls focusable, so Tab reveals them. */
|
|
924
|
+
.ft-cell.ft-reveal-hover > * {
|
|
925
|
+
opacity: 0;
|
|
926
|
+
transition: opacity var(--u-duration-fast, 140ms) ease-out;
|
|
927
|
+
}
|
|
928
|
+
.ft-row:hover .ft-cell.ft-reveal-hover > *,
|
|
929
|
+
.ft-row:focus-within .ft-cell.ft-reveal-hover > *,
|
|
930
|
+
.ft-row-selected .ft-cell.ft-reveal-hover > *,
|
|
931
|
+
.ft-cell.ft-reveal-hover.ft-active > * {
|
|
932
|
+
opacity: 1;
|
|
933
|
+
}
|
|
934
|
+
@media (hover: none) {
|
|
935
|
+
.ft-cell.ft-reveal-hover > * { opacity: 1; }
|
|
936
|
+
}
|
|
937
|
+
@media (prefers-reduced-motion: reduce) {
|
|
938
|
+
.ft-cell.ft-reveal-hover > * { transition: none; }
|
|
939
|
+
}
|
|
940
|
+
@media print {
|
|
941
|
+
.ft-cell.ft-reveal-hover > * { visibility: hidden; }
|
|
942
|
+
}
|
|
921
943
|
`;
|
|
922
944
|
//#endregion
|
|
923
945
|
//#region src/renderers/format.ts
|
|
@@ -2270,10 +2292,10 @@ var q = {
|
|
|
2270
2292
|
return Math.max(0, this._visibleRowCount - this._frozenRowCount) * this.rowHeight;
|
|
2271
2293
|
}
|
|
2272
2294
|
get visibleRange() {
|
|
2273
|
-
let e = this._frozenRowCount, t = Math.max(0, this._scrollTop
|
|
2295
|
+
let e = this._frozenRowCount, t = e + Math.floor(Math.max(0, this._scrollTop) / this.rowHeight), n = Math.max(e, t - Q), r = Math.max(0, this._viewportHeight - this.headerHeight - this.frozenRowsHeight), i = Math.ceil(r / this.rowHeight) + 1;
|
|
2274
2296
|
return {
|
|
2275
|
-
start:
|
|
2276
|
-
end: Math.min(this._visibleRowCount,
|
|
2297
|
+
start: n,
|
|
2298
|
+
end: Math.min(this._visibleRowCount, t + i + Q)
|
|
2277
2299
|
};
|
|
2278
2300
|
}
|
|
2279
2301
|
connectedCallback() {
|
|
@@ -4232,7 +4254,8 @@ var q = {
|
|
|
4232
4254
|
S ? "ft-find-current" : x ? "ft-find-match" : "",
|
|
4233
4255
|
o ? `ft-merge-${o.headParity}` : "",
|
|
4234
4256
|
o?.continues ? "ft-merge-continued" : "",
|
|
4235
|
-
o?.opensDown ? "ft-merge-open" : ""
|
|
4257
|
+
o?.opensDown ? "ft-merge-open" : "",
|
|
4258
|
+
t.reveal === "hover" ? "ft-reveal-hover" : ""
|
|
4236
4259
|
].filter(Boolean).join(" "), T = this._toDataIndex(n), E = this._comments.get(T)?.get(t.key) ?? null, D = E !== null, O = D ? i`<div class="ft-comment-indicator" title=${E}></div>` : a;
|
|
4237
4260
|
return i`
|
|
4238
4261
|
<div class=${D ? C + " ft-has-comment" : C}
|
package/dist/flex-table.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "./flex-table-
|
|
1
|
+
import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "./flex-table-BdnkC234.js";
|
|
2
2
|
export { o as FlexTable, e as RowSelectionState, t as UndoStack, n as effectiveAlign, i as exportData, r as flexTableLocale, a as renderCell };
|
package/dist/models/types.d.ts
CHANGED
|
@@ -115,6 +115,15 @@ export interface ColumnDefinition<T = DataRow> {
|
|
|
115
115
|
* the top of the scrolled view and below frozen rows, so it never scrolls out of sight.
|
|
116
116
|
*/
|
|
117
117
|
mergeRepeated?: boolean | ((row: T, previousRow: T, col: ColumnDefinition<T>) => boolean);
|
|
118
|
+
/**
|
|
119
|
+
* When the column's content shows.
|
|
120
|
+
* - `'always'` (default)
|
|
121
|
+
* - `'hover'`: only while the row is hovered, holds focus, or is selected — for a row-actions
|
|
122
|
+
* column (edit, a "more" menu), so a list does not repeat the same buttons on every row. The
|
|
123
|
+
* content stays in the DOM and keyboard focus reveals it; on touch screens (no hover) it is
|
|
124
|
+
* always shown, and it is not printed.
|
|
125
|
+
*/
|
|
126
|
+
reveal?: 'always' | 'hover';
|
|
118
127
|
}
|
|
119
128
|
/** Style applied to a cell by a conditional formatting rule */
|
|
120
129
|
export interface CellStyle {
|
package/dist/react.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as e } from "./flex-table-
|
|
1
|
+
import { t as e } from "./flex-table-BdnkC234.js";
|
|
2
2
|
import { i as t, t as n } from "./query-Dw4iO0ir.js";
|
|
3
3
|
import { t as r } from "./view-DiLr-TdY.js";
|
|
4
4
|
import i, { useCallback as a, useEffect as o, useMemo as s, useRef as c, useState as l } from "react";
|
package/package.json
CHANGED
|
@@ -66,6 +66,7 @@ Replacing `data` with the same array reference does not trigger the clear-on-cha
|
|
|
66
66
|
| `validator` | `CellValidator<T>` | `(value, row, col) => string \| null \| undefined` |
|
|
67
67
|
| `conditionalRules` | `ConditionalRule<T>[]` | `{ when(value, row, col): boolean, style: CellStyle }` |
|
|
68
68
|
| `mergeRepeated` | `boolean \| (row, previousRow, col) => boolean` | Draw a run of repeated values as one merged cell; values, sort, filter and export are unchanged |
|
|
69
|
+
| `reveal` | `'always' \| 'hover'` | `'hover'`: content shows only while the row is hovered, focused or selected — for a row-actions column; stays focusable, always shown without hover, not printed |
|
|
69
70
|
|
|
70
71
|
`CellStyle` = `{ background?, color?, fontWeight?: 'bold' | 'normal', fontStyle?: 'italic' | 'normal' }`.
|
|
71
72
|
|