@iyulab/flex-table 0.50.0 → 0.50.2
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 +21 -0
- package/README.md +6 -3
- package/dist/{flex-table-B64ScsFY.js → flex-table-Hx-xTm0e.js} +44 -6
- package/dist/flex-table.d.ts +22 -0
- package/dist/flex-table.js +1 -1
- package/dist/react.js +1 -1
- package/package.json +1 -1
- package/skills/iyulab-flex-table/references/styling.md +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.50.2] - 2026-10-06
|
|
4
|
+
|
|
5
|
+
### Documentation
|
|
6
|
+
|
|
7
|
+
- Shift+F10 and the context-menu key on the active cell open the cell menu at that cell (and fire
|
|
8
|
+
`context-menu`) — documented and covered by a test. It works since 0.50.1, whose roving focus puts the
|
|
9
|
+
focus on the cell the browser opens the menu for.
|
|
10
|
+
|
|
11
|
+
## [0.50.1] - 2026-10-06
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **Screen readers hear the active cell.** The table kept the focus on itself and marked the active cell
|
|
16
|
+
with a class only, so assistive technology announced the grid and nothing as the arrow keys moved
|
|
17
|
+
(the host cannot point `aria-activedescendant` into its own shadow tree). The focus now sits on the
|
|
18
|
+
active cell — or the active header cell — while the table has it (roving focus): each move is announced
|
|
19
|
+
with the cell's row, column and content. `document.activeElement` is still the table.
|
|
20
|
+
- When scrolling moves the focused cell out of the rendered window, the focus waits on the table instead
|
|
21
|
+
of staying on a recycled cell that now shows another row; the next key brings it back onto the active
|
|
22
|
+
cell.
|
|
23
|
+
|
|
3
24
|
## [0.50.0] - 2026-10-06
|
|
4
25
|
|
|
5
26
|
### Fixed
|
package/README.md
CHANGED
|
@@ -65,9 +65,9 @@ npm install @iyulab/flex-table
|
|
|
65
65
|
- **Row Numbers** — Optional `show-row-numbers` attribute with sticky positioning
|
|
66
66
|
- **Footer Row** — Summary/aggregate row via `footer-data` property
|
|
67
67
|
- **Data Mode** — Client-side or server-side sorting/filtering (`dataMode`)
|
|
68
|
-
- **Context Menu** — `context-menu` event for custom right-click menus
|
|
68
|
+
- **Context Menu** — `context-menu` event for custom right-click menus; Shift+F10 or the context-menu key opens it on the active cell
|
|
69
69
|
- **React Wrapper** — `@iyulab/flex-table/react` subpath for idiomatic React usage
|
|
70
|
-
- **ARIA** — `role="grid"
|
|
70
|
+
- **ARIA** — `role="grid"` with roving focus (the focus sits on the active cell or header cell, so screen readers announce each move), `aria-sort`, `aria-selected`, `aria-readonly`, `aria-invalid`, `aria-rowcount`, `aria-colcount`, `aria-rowindex`, `aria-colindex`
|
|
71
71
|
|
|
72
72
|
## Sizing
|
|
73
73
|
|
|
@@ -351,7 +351,7 @@ type-checks without a cast. The React wrapper's `on*` props carry the same types
|
|
|
351
351
|
| Event | Detail | Description |
|
|
352
352
|
|-------|--------|-------------|
|
|
353
353
|
| `undo-state-change` | `{ canUndo, canRedo }` | Undo/redo availability changed |
|
|
354
|
-
| `context-menu` | `{ x, y, row, col, key, value, rowData }` | Right-click on cell. Cancelable — `preventDefault()` suppresses the built-in menu |
|
|
354
|
+
| `context-menu` | `{ x, y, row, col, key, value, rowData }` | Right-click on a cell, or Shift+F10 / the context-menu key on the active cell. Cancelable — `preventDefault()` suppresses the built-in menu |
|
|
355
355
|
|
|
356
356
|
## CSS Custom Properties
|
|
357
357
|
|
|
@@ -458,12 +458,15 @@ package dependency; CSS custom properties are resolved at render time, not impor
|
|
|
458
458
|
| ArrowLeft / ArrowRight / Home / End (header row) | Move along the header; ArrowDown returns to the first row |
|
|
459
459
|
| Enter / Space (header row) | Sort the column (ascending → descending → none); with Shift, add it to the sort |
|
|
460
460
|
| Alt+ArrowDown or the context-menu key (header row) | Open the column menu |
|
|
461
|
+
| Shift+F10 or the context-menu key (a body cell) | Open the cell menu (`show-context-menu`) at the active cell / fire `context-menu` |
|
|
461
462
|
| Enter / Space on a column menu button | Open the column menu |
|
|
462
463
|
| ArrowUp / ArrowDown / Home / End (column menu) | Move between menu items |
|
|
463
464
|
| Escape (column menu) | Close the menu and return focus to where it was opened from |
|
|
464
465
|
|
|
465
466
|
The table is one Tab stop: keyboard focus arriving on it activates the first cell (the first header cell
|
|
466
467
|
when there are no rows), and the column menu buttons and row checkboxes are reached by keys, not Tab.
|
|
468
|
+
While the table has the focus, the focus sits on the active cell (or header cell) itself — `document.activeElement`
|
|
469
|
+
is the table, and its `shadowRoot.activeElement` is that cell.
|
|
467
470
|
|
|
468
471
|
## Localization
|
|
469
472
|
|
|
@@ -1892,9 +1892,23 @@ var K = {
|
|
|
1892
1892
|
lte: "≤"
|
|
1893
1893
|
}, q = 120, J = 40, Y = 20, X = 32, Z = 5, Ze = 200, Q = class extends n {
|
|
1894
1894
|
constructor(...e) {
|
|
1895
|
-
super(...e), this.columns = [], this._data = [], this._inUndoRedo = !1, this.clearUndoOnDataChange = !1, this.clearSelectionOnDataChange = !1, this._rowHeightFromCss = X, this._targetFloor = 0, this.showRowNumbers = !1, this.theme = void 0, this.maxRows = 0, this.editable = !0, this.showFilters = !1, this.showContextMenu = !1, this.frozenRows = 0, this.emptyMessage = "No data", this.noMatchingMessage = "No matching data", this.loading = !1, this.importEnabled = !1, this.selectable = !1, this.dataMode = "client", this.footerData = null, this.stylesheets = [], this._scrollTop = 0, this._scrollLeft = 0, this._viewportHeight = 0, this._viewportWidth = 0, this._colLeftOffsets = [], this._totalRowWidth = 0, this._baseStyleSheets = [], this._activeCell = null, this._headerCol = null, this._editingCell = null, this._sortCriteria = [], this._selection = new oe(), this._editing = new se(), this._rowSelection = new A(), this._undo = new j(), this._filters = [], this._filteredIndices = [], this._sortedIndices = [], this._openFilterKey = null, this._rowSelectionVersion = 0, this._lastCheckboxRowIndex = null, this._checkboxShiftPending = !1, this._autocompleteState = null, this._headerMenu = null, this._bodyContextMenu = null, this._commentPopup = null, this._viewDirty = !0, this._isDragging = !1, this._wasDrag = !1, this._resizing = null, this._resizeCleanup = null, this._wasHeaderDrag = !1, this._wasRowDrag = !1, this._colDrag = null, this._colDragIndicatorLeft = null, this._fillDrag = null, this._rowDrag = null, this._rowDragIndicatorY = null, this._findState = null, this._columnWidths = /* @__PURE__ */ new Map(), this._hostResizeObserver = null, this._comments = /* @__PURE__ */ new Map(), this._isDragOver = !1, this._warnedUnconstrained = !1, this._onHostFocus = (e) => {
|
|
1895
|
+
super(...e), this.columns = [], this._data = [], this._inUndoRedo = !1, this.clearUndoOnDataChange = !1, this.clearSelectionOnDataChange = !1, this._rowHeightFromCss = X, this._targetFloor = 0, this.showRowNumbers = !1, this.theme = void 0, this.maxRows = 0, this.editable = !0, this.showFilters = !1, this.showContextMenu = !1, this.frozenRows = 0, this.emptyMessage = "No data", this.noMatchingMessage = "No matching data", this.loading = !1, this.importEnabled = !1, this.selectable = !1, this.dataMode = "client", this.footerData = null, this.stylesheets = [], this._scrollTop = 0, this._scrollLeft = 0, this._viewportHeight = 0, this._viewportWidth = 0, this._colLeftOffsets = [], this._totalRowWidth = 0, this._baseStyleSheets = [], this._activeCell = null, this._headerCol = null, this._focusedCellEl = null, this._editingCell = null, this._sortCriteria = [], this._selection = new oe(), this._editing = new se(), this._rowSelection = new A(), this._undo = new j(), this._filters = [], this._filteredIndices = [], this._sortedIndices = [], this._openFilterKey = null, this._rowSelectionVersion = 0, this._lastCheckboxRowIndex = null, this._checkboxShiftPending = !1, this._autocompleteState = null, this._headerMenu = null, this._bodyContextMenu = null, this._commentPopup = null, this._viewDirty = !0, this._isDragging = !1, this._wasDrag = !1, this._resizing = null, this._resizeCleanup = null, this._wasHeaderDrag = !1, this._wasRowDrag = !1, this._colDrag = null, this._colDragIndicatorLeft = null, this._fillDrag = null, this._rowDrag = null, this._rowDragIndicatorY = null, this._findState = null, this._columnWidths = /* @__PURE__ */ new Map(), this._hostResizeObserver = null, this._comments = /* @__PURE__ */ new Map(), this._isDragOver = !1, this._warnedUnconstrained = !1, this._onHostFocus = (e) => {
|
|
1896
1896
|
e.composedPath()[0] !== this || this._activeCell || this._headerCol !== null || this.visibleColumns.length !== 0 && this.matches(":focus-visible") && (this._visibleRowCount > 0 ? (this._selection.setActive(0, 0), this._syncActiveCell()) : this._headerCol = 0);
|
|
1897
|
-
}, this.
|
|
1897
|
+
}, this._onFocusIn = (e) => {
|
|
1898
|
+
let t = e.composedPath()[0];
|
|
1899
|
+
t !== this && this._isGridSurface(t) && (this._focusedCellEl = t, this.tabIndex === 0 && (this._hostTabIndexLowered = !0, this.tabIndex = -1));
|
|
1900
|
+
}, this._onFocusOut = (e) => {
|
|
1901
|
+
let t = e.relatedTarget;
|
|
1902
|
+
if (t && (t === this || this.contains(t) || this.shadowRoot?.contains(t))) return;
|
|
1903
|
+
let n = e.composedPath()[0];
|
|
1904
|
+
requestAnimationFrame(() => {
|
|
1905
|
+
if (n instanceof HTMLElement && n === this._focusedCellEl && !n.isConnected) {
|
|
1906
|
+
this._syncGridFocus();
|
|
1907
|
+
return;
|
|
1908
|
+
}
|
|
1909
|
+
document.activeElement !== this && (this._focusedCellEl = null, this._hostTabIndexLowered && (this._hostTabIndexLowered = !1, this.tabIndex = 0));
|
|
1910
|
+
});
|
|
1911
|
+
}, this._hostTabIndexLowered = !1, this._onCommentPopupOutsideClick = () => {
|
|
1898
1912
|
this._commitCommentPopup();
|
|
1899
1913
|
}, this._invalidCells = /* @__PURE__ */ new Map(), this._textFilterState = /* @__PURE__ */ new Map(), this._numberFilterState = /* @__PURE__ */ new Map(), this._dateFilterState = /* @__PURE__ */ new Map(), this._emptyFilterState = /* @__PURE__ */ new Map();
|
|
1900
1914
|
}
|
|
@@ -2425,10 +2439,10 @@ var K = {
|
|
|
2425
2439
|
};
|
|
2426
2440
|
}
|
|
2427
2441
|
connectedCallback() {
|
|
2428
|
-
super.connectedCallback(), this._onScroll = this._onScroll.bind(this), this._onKeyDown = this._onKeyDown.bind(this), this._onDocumentClick = this._onDocumentClick.bind(this), this._onContextMenu = this._onContextMenu.bind(this), this._onDragover = this._onDragover.bind(this), this._onDragleave = this._onDragleave.bind(this), this._onDrop = this._onDrop.bind(this), this.addEventListener("scroll", this._onScroll, { passive: !0 }), this.addEventListener("keydown", this._onKeyDown), this.addEventListener("focus", this._onHostFocus), this.addEventListener("contextmenu", this._onContextMenu), this.addEventListener("dragover", this._onDragover), this.addEventListener("dragleave", this._onDragleave), this.addEventListener("drop", this._onDrop), this.hasAttribute("tabindex") || this.setAttribute("tabindex", "0"), this.setAttribute("role", "grid"), typeof ResizeObserver < "u" && (this._hostResizeObserver = new ResizeObserver(() => this._measureViewport()), this._hostResizeObserver.observe(this));
|
|
2442
|
+
super.connectedCallback(), this._onScroll = this._onScroll.bind(this), this._onKeyDown = this._onKeyDown.bind(this), this._onDocumentClick = this._onDocumentClick.bind(this), this._onContextMenu = this._onContextMenu.bind(this), this._onDragover = this._onDragover.bind(this), this._onDragleave = this._onDragleave.bind(this), this._onDrop = this._onDrop.bind(this), this.addEventListener("scroll", this._onScroll, { passive: !0 }), this.addEventListener("keydown", this._onKeyDown), this.addEventListener("focus", this._onHostFocus), this.renderRoot.addEventListener("focusin", this._onFocusIn), this.renderRoot.addEventListener("focusout", this._onFocusOut), this.addEventListener("contextmenu", this._onContextMenu), this.addEventListener("dragover", this._onDragover), this.addEventListener("dragleave", this._onDragleave), this.addEventListener("drop", this._onDrop), this.hasAttribute("tabindex") || this.setAttribute("tabindex", "0"), this.setAttribute("role", "grid"), typeof ResizeObserver < "u" && (this._hostResizeObserver = new ResizeObserver(() => this._measureViewport()), this._hostResizeObserver.observe(this));
|
|
2429
2443
|
}
|
|
2430
2444
|
disconnectedCallback() {
|
|
2431
|
-
super.disconnectedCallback(), this.removeEventListener("scroll", this._onScroll), this.removeEventListener("keydown", this._onKeyDown), this.removeEventListener("focus", this._onHostFocus), this.removeEventListener("contextmenu", this._onContextMenu), this.removeEventListener("dragover", this._onDragover), this.removeEventListener("dragleave", this._onDragleave), this.removeEventListener("drop", this._onDrop), document.removeEventListener("click", this._onDocumentClick), document.removeEventListener("mousedown", this._onCommentPopupOutsideClick), this._isDragging = !1, this._wasDrag = !1, this._resizeCleanup &&= (this._resizeCleanup(), null), this._hostResizeObserver &&= (this._hostResizeObserver.disconnect(), null);
|
|
2445
|
+
super.disconnectedCallback(), this.removeEventListener("scroll", this._onScroll), this.removeEventListener("keydown", this._onKeyDown), this.removeEventListener("focus", this._onHostFocus), this.renderRoot.removeEventListener("focusin", this._onFocusIn), this.renderRoot.removeEventListener("focusout", this._onFocusOut), this.removeEventListener("contextmenu", this._onContextMenu), this.removeEventListener("dragover", this._onDragover), this.removeEventListener("dragleave", this._onDragleave), this.removeEventListener("drop", this._onDrop), document.removeEventListener("click", this._onDocumentClick), document.removeEventListener("mousedown", this._onCommentPopupOutsideClick), this._isDragging = !1, this._wasDrag = !1, this._resizeCleanup &&= (this._resizeCleanup(), null), this._hostResizeObserver &&= (this._hostResizeObserver.disconnect(), null);
|
|
2432
2446
|
}
|
|
2433
2447
|
firstUpdated() {
|
|
2434
2448
|
this._readDensityTokens(), this._measureViewport(), this.shadowRoot && Array.isArray(this.shadowRoot.adoptedStyleSheets) && (this._baseStyleSheets = [...this.shadowRoot.adoptedStyleSheets]), this._syncStylesheets();
|
|
@@ -2479,7 +2493,7 @@ var K = {
|
|
|
2479
2493
|
(!(e.size <= 2 && !e.has("data") && !e.has("columns") && !e.has("_openFilterKey") && !e.has("_editingCell") && !e.has("_activeCell") && (e.has("_scrollTop") || e.has("_scrollLeft"))) || this._viewDirty) && (this._recomputeView(), this._viewDirty = !1), this._updateColOffsets(), this._selection.setDimensions(this._visibleRowCount, this.visibleColumns.length), this._rowSelection.setRowCount(this._visibleRowCount);
|
|
2480
2494
|
}
|
|
2481
2495
|
updated(e) {
|
|
2482
|
-
this._focusEditor(), this._adjustFilterDropdown(), e.has("_headerMenu") && this._keepMenuInView(".ft-header-menu"), e.has("_bodyContextMenu") && this._bodyContextMenu && (this._keepMenuInView(".ft-body-context-menu"), this.shadowRoot?.querySelector(".ft-body-context-menu [role=\"menuitem\"]")?.focus()), e.has("stylesheets") && this._syncStylesheets();
|
|
2496
|
+
this._focusEditor(), this._syncGridFocus(), this._adjustFilterDropdown(), e.has("_headerMenu") && this._keepMenuInView(".ft-header-menu"), e.has("_bodyContextMenu") && this._bodyContextMenu && (this._keepMenuInView(".ft-body-context-menu"), this.shadowRoot?.querySelector(".ft-body-context-menu [role=\"menuitem\"]")?.focus()), e.has("stylesheets") && this._syncStylesheets();
|
|
2483
2497
|
let t = String(1 + this._visibleRowCount + +!!this.footerData), n = String(this.visibleColumns.length);
|
|
2484
2498
|
if (this.getAttribute("aria-rowcount") !== t && this.setAttribute("aria-rowcount", t), this.getAttribute("aria-colcount") !== n && this.setAttribute("aria-colcount", n), this.loading ? this.getAttribute("aria-busy") !== "true" && this.setAttribute("aria-busy", "true") : this.hasAttribute("aria-busy") && this.removeAttribute("aria-busy"), e.has("_commentPopup") && this._commentPopup) {
|
|
2485
2499
|
let e = this.shadowRoot?.querySelector(".ft-comment-popup textarea");
|
|
@@ -2802,7 +2816,7 @@ var K = {
|
|
|
2802
2816
|
"y"
|
|
2803
2817
|
].includes(t) && this._handleCtrlKey(e)) return;
|
|
2804
2818
|
}
|
|
2805
|
-
if (t.length !== 0 && (e.composedPath()[0]
|
|
2819
|
+
if (t.length !== 0 && (this._isGridSurface(e.composedPath()[0]) || e.ctrlKey || e.metaKey)) {
|
|
2806
2820
|
if (this._headerCol !== null) {
|
|
2807
2821
|
this._onHeaderKeyDown(e, t);
|
|
2808
2822
|
return;
|
|
@@ -2893,6 +2907,28 @@ var K = {
|
|
|
2893
2907
|
_enterHeader(e) {
|
|
2894
2908
|
this._selection.clear(), this._syncActiveCell(), this._headerCol = e, this._scrollColumnIntoView(e);
|
|
2895
2909
|
}
|
|
2910
|
+
_isGridSurface(e) {
|
|
2911
|
+
return e === this || e instanceof HTMLElement && (e.classList.contains("ft-cell") || e.classList.contains("ft-header-cell")) && !e.classList.contains("ft-editing");
|
|
2912
|
+
}
|
|
2913
|
+
_keyboardCellEl() {
|
|
2914
|
+
let e = this.shadowRoot;
|
|
2915
|
+
if (!e) return null;
|
|
2916
|
+
if (this._headerCol !== null) return e.querySelector(`.ft-header-cell[data-col-index="${this._headerCol}"]`);
|
|
2917
|
+
let t = this._activeCell;
|
|
2918
|
+
return t ? e.querySelector(`.ft-row[aria-rowindex="${t.row + 2}"] .ft-cell[data-col-index="${t.col}"]`) : null;
|
|
2919
|
+
}
|
|
2920
|
+
_syncGridFocus() {
|
|
2921
|
+
let e = this.shadowRoot;
|
|
2922
|
+
if (!e) return;
|
|
2923
|
+
let t = e.activeElement;
|
|
2924
|
+
if (document.activeElement !== this) {
|
|
2925
|
+
this._focusedCellEl && !this._focusedCellEl.isConnected && (document.activeElement === document.body || document.activeElement === null) && (this._focusedCellEl = null, (this._keyboardCellEl() ?? this).focus({ preventScroll: !0 }));
|
|
2926
|
+
return;
|
|
2927
|
+
}
|
|
2928
|
+
if (t && !this._isGridSurface(t)) return;
|
|
2929
|
+
let n = this._keyboardCellEl() ?? this;
|
|
2930
|
+
n !== (t ?? this) && n.focus({ preventScroll: !0 });
|
|
2931
|
+
}
|
|
2896
2932
|
_handleCtrlKey(e) {
|
|
2897
2933
|
if (!(e.ctrlKey || e.metaKey) || e.altKey) return !1;
|
|
2898
2934
|
switch (e.key.toLowerCase()) {
|
|
@@ -3240,6 +3276,7 @@ var K = {
|
|
|
3240
3276
|
return i`
|
|
3241
3277
|
<div class=${y}
|
|
3242
3278
|
role="columnheader"
|
|
3279
|
+
tabindex="-1"
|
|
3243
3280
|
aria-colindex=${t + 1}
|
|
3244
3281
|
data-col-index=${t}
|
|
3245
3282
|
style=${_}
|
|
@@ -4433,6 +4470,7 @@ var K = {
|
|
|
4433
4470
|
return i`
|
|
4434
4471
|
<div class=${E ? C + " ft-has-comment" : C}
|
|
4435
4472
|
role="gridcell"
|
|
4473
|
+
tabindex="-1"
|
|
4436
4474
|
aria-colindex=${r + 1}
|
|
4437
4475
|
data-col-index=${r}
|
|
4438
4476
|
aria-selected=${v ? "true" : "false"}
|
package/dist/flex-table.d.ts
CHANGED
|
@@ -113,6 +113,8 @@ export declare class FlexTable extends LitElement {
|
|
|
113
113
|
* it). Exclusive with an active body cell: entering one leaves the other.
|
|
114
114
|
*/
|
|
115
115
|
private _headerCol;
|
|
116
|
+
/** The cell (body or header) that last held the keyboard focus — to take it back if a re-render drops it. */
|
|
117
|
+
private _focusedCellEl;
|
|
116
118
|
private _editingCell;
|
|
117
119
|
private _sortCriteria;
|
|
118
120
|
private _selection;
|
|
@@ -413,6 +415,26 @@ export declare class FlexTable extends LitElement {
|
|
|
413
415
|
* pointer focus places the cell it pressed instead.
|
|
414
416
|
*/
|
|
415
417
|
private _onHostFocus;
|
|
418
|
+
/**
|
|
419
|
+
* The grid's own keyboard surface: the host, the active body cell, the active header cell. Keys on
|
|
420
|
+
* anything else inside it (an editor, a menu, a button a cell renders) belong to that control.
|
|
421
|
+
*/
|
|
422
|
+
private _isGridSurface;
|
|
423
|
+
/**
|
|
424
|
+
* The element the keyboard is on — the active header cell, else the active body cell — when it is
|
|
425
|
+
* rendered (the body scrolls it out of the virtual window), else `null`.
|
|
426
|
+
*/
|
|
427
|
+
private _keyboardCellEl;
|
|
428
|
+
/**
|
|
429
|
+
* Roving focus: while the grid holds the focus, the focus sits on the cell the keyboard is on, so
|
|
430
|
+
* assistive technology announces each move (the host cannot point `aria-activedescendant` into its
|
|
431
|
+
* own shadow tree). It moves only between the host and the grid's cells — never out of an editor,
|
|
432
|
+
* a menu or a control that holds it.
|
|
433
|
+
*/
|
|
434
|
+
private _syncGridFocus;
|
|
435
|
+
private _onFocusIn;
|
|
436
|
+
private _onFocusOut;
|
|
437
|
+
private _hostTabIndexLowered;
|
|
416
438
|
private _handleCtrlKey;
|
|
417
439
|
private _handleAltKey;
|
|
418
440
|
/** Widen (positive) or narrow (negative) a visible column by `delta` px, never below its minimum. */
|
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-Hx-xTm0e.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/react.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as e } from "./flex-table-
|
|
1
|
+
import { t as e } from "./flex-table-Hx-xTm0e.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
|
@@ -72,6 +72,7 @@ flex-table {
|
|
|
72
72
|
| ArrowUp on the first row | Move onto the header row (arrows / Home / End along it, ArrowDown back) |
|
|
73
73
|
| Enter / Space on a header cell | Sort (Shift adds to the sort) |
|
|
74
74
|
| Alt+ArrowDown or context-menu key on a header cell | Open the column menu |
|
|
75
|
+
| Shift+F10 or context-menu key on a body cell | Open the cell menu at the active cell (fires `context-menu`) |
|
|
75
76
|
| Home / End, Ctrl+Home / Ctrl+End | Row start/end, table start/end |
|
|
76
77
|
| Shift+Arrow, Shift+Click | Extend range selection |
|
|
77
78
|
| Shift+Space | Select / deselect the active cell's row (`selectable`; row checkboxes are not Tab stops) |
|
|
@@ -87,7 +88,8 @@ flex-table {
|
|
|
87
88
|
| Alt+ArrowLeft / Alt+ArrowRight | Resize current column |
|
|
88
89
|
| Enter / Space on a column menu button | Open the column menu (arrows, Home/End navigate; Escape closes) |
|
|
89
90
|
|
|
90
|
-
The table is one Tab stop —
|
|
91
|
+
The table is one Tab stop with roving focus — the focus sits on the active cell or header cell (screen
|
|
92
|
+
readers announce each move); keyboard focus arriving on it activates the first cell; the column menu
|
|
91
93
|
buttons are not Tab stops (the header row reaches them).
|
|
92
94
|
|
|
93
95
|
Ctrl also matches Cmd on macOS. Editing shortcuts are ignored when `editable` is `false`.
|