Improve item range selection.
This commit is contained in:
@@ -36,6 +36,13 @@ class TpTableItem extends BaseElement {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Rows are click targets in row-click/ctrl-click selection modes —
|
||||
a shift+click range gesture must not select their text. Checkbox
|
||||
tables keep text selectable (selection lives in the checkbox). */
|
||||
:host([data-selection-mode]) {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.wrap {
|
||||
display: grid;
|
||||
grid-template-columns: 0.5fr 3fr 0.5fr 0.5fr 0.5fr; /* Overridden by javascript */
|
||||
|
||||
+34
-5
@@ -187,6 +187,7 @@ export class TpTable extends DomQuery(LitElement) {
|
||||
${this.renderTableHeader(columns, showCheckboxColumn)}
|
||||
<div class="list"
|
||||
@row-selection-changed=${(e) => this._selectionChanged(e)}
|
||||
@mousedown=${(e) => this._listMousedown(e)}
|
||||
@click=${(e) => this._handleRowClick(e)}>
|
||||
${!Array.isArray(items) || items.length === 0 ? html`
|
||||
<div class="empty-message">
|
||||
@@ -311,6 +312,7 @@ export class TpTable extends DomQuery(LitElement) {
|
||||
super();
|
||||
this._selItems = new Map();
|
||||
this._lastSelectedId = null;
|
||||
this._shiftDownItem = null;
|
||||
this.selectionMode = 'checkbox';
|
||||
}
|
||||
|
||||
@@ -632,18 +634,42 @@ export class TpTable extends DomQuery(LitElement) {
|
||||
}
|
||||
}
|
||||
|
||||
// Text selection starts on MOUSEDOWN — preventing it at click is too
|
||||
// late: the browser has already selected and the click may even retarget
|
||||
// to a common ancestor instead of the row. Shift/ctrl/meta clicks are
|
||||
// selection gestures in row-click mode, so the browser must not start a
|
||||
// text selection from them.
|
||||
_listMousedown(e) {
|
||||
if (this.selectionMode !== 'row-click' || !this.selectable) return;
|
||||
|
||||
if (e.shiftKey || e.ctrlKey || e.metaKey) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
// Remember the row the shift gesture started on: if the click
|
||||
// retargets (row re-rendered between mousedown and mouseup), its
|
||||
// composed path no longer contains a row and the range would
|
||||
// silently collapse to the previously selected rows.
|
||||
this._shiftDownItem = e.shiftKey
|
||||
? e.composedPath().find(n => n?.hasAttribute && n.hasAttribute('item')) || null
|
||||
: null;
|
||||
}
|
||||
|
||||
_handleRowClick(e) {
|
||||
if (this.selectionMode !== 'row-click' || !this.selectable) return;
|
||||
|
||||
// Prevent the browser's native shift+click text selection since we're
|
||||
// using shift+click for range selection.
|
||||
e.preventDefault();
|
||||
|
||||
// Walk through composedPath to find the <tp-table-item> host, since
|
||||
// lit-virtualizer puts rows in a shadow tree.
|
||||
const itemEl = e.composedPath().find(
|
||||
let itemEl = e.composedPath().find(
|
||||
n => n?.hasAttribute && n.hasAttribute('item')
|
||||
);
|
||||
|
||||
if (!itemEl && e.shiftKey && this._shiftDownItem) {
|
||||
itemEl = this._shiftDownItem;
|
||||
}
|
||||
|
||||
this._shiftDownItem = null;
|
||||
|
||||
if (!itemEl || !itemEl.item) return;
|
||||
|
||||
const id = this.getItemId(itemEl.item);
|
||||
@@ -661,6 +687,9 @@ export class TpTable extends DomQuery(LitElement) {
|
||||
const it = items[i];
|
||||
this._selItems.set(this.getItemId(it), it);
|
||||
}
|
||||
|
||||
// Stray text selection from before the gesture must not survive.
|
||||
window.getSelection?.()?.removeAllRanges?.();
|
||||
}
|
||||
} else if (e.ctrlKey || e.metaKey) {
|
||||
// Toggle individual row.
|
||||
|
||||
Reference in New Issue
Block a user