Cover Files keyboard row selection
This commit is contained in:
parent
d3dfa2d652
commit
b0d80e230f
|
|
@ -174,6 +174,29 @@ test.describe('G: Files Plugin', () => {
|
||||||
await expect(page.locator('[data-file-name="DragTwo.txt"]')).toBeVisible();
|
await expect(page.locator('[data-file-name="DragTwo.txt"]')).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('files explorer supports keyboard row selection and clearing selection', async ({ page }) => {
|
||||||
|
await page.locator('.wt-label').filter({ hasText: 'Project' }).click();
|
||||||
|
await openFilesTool(page);
|
||||||
|
await expect(page.locator('.files-breadcrumb')).toContainText('Project', { timeout: 10000 });
|
||||||
|
|
||||||
|
const rows = page.locator('.files-item');
|
||||||
|
await expect(rows.nth(1)).toBeVisible();
|
||||||
|
|
||||||
|
await rows.nth(0).click();
|
||||||
|
await expect(rows.nth(0)).toHaveClass(/selected/);
|
||||||
|
|
||||||
|
await page.locator('.files-root').focus();
|
||||||
|
await page.keyboard.press('ArrowDown');
|
||||||
|
await expect(rows.nth(1)).toHaveClass(/selected/);
|
||||||
|
await expect(rows.nth(0)).not.toHaveClass(/selected/);
|
||||||
|
|
||||||
|
await page.keyboard.press('ArrowUp');
|
||||||
|
await expect(rows.nth(0)).toHaveClass(/selected/);
|
||||||
|
|
||||||
|
await page.keyboard.press('Escape');
|
||||||
|
await expect(page.locator('.files-item.selected')).toHaveCount(0);
|
||||||
|
});
|
||||||
|
|
||||||
test('files history persists in workspace context and handles mouse back forward buttons', async ({ page }) => {
|
test('files history persists in workspace context and handles mouse back forward buttons', async ({ page }) => {
|
||||||
await page.locator('.wt-label').filter({ hasText: 'Project' }).click();
|
await page.locator('.wt-label').filter({ hasText: 'Project' }).click();
|
||||||
await openFilesTool(page);
|
await openFilesTool(page);
|
||||||
|
|
|
||||||
|
|
@ -979,11 +979,55 @@
|
||||||
window.addEventListener('auxclick', mouseHistory, true);
|
window.addEventListener('auxclick', mouseHistory, true);
|
||||||
window.addEventListener('keydown', keyHistory);
|
window.addEventListener('keydown', keyHistory);
|
||||||
c.addEventListener('keydown', function (ev) {
|
c.addEventListener('keydown', function (ev) {
|
||||||
|
if (ev.target && ['INPUT', 'SELECT', 'TEXTAREA', 'BUTTON'].indexOf(ev.target.tagName) !== -1) return;
|
||||||
var ctrl = ev.ctrlKey || ev.metaKey;
|
var ctrl = ev.ctrlKey || ev.metaKey;
|
||||||
if (ctrl && ev.key.toLowerCase() === 'a') { ev.preventDefault(); selected = {}; visible().forEach(function (item) { selected[item.relativePath] = true; }); render(); }
|
var key = ev.key || '';
|
||||||
if (ctrl && ev.key.toLowerCase() === 'x') { ev.preventDefault(); cutSelection(); }
|
|
||||||
if (ctrl && ev.key.toLowerCase() === 'c') { ev.preventDefault(); copySelection(); }
|
function currentIndex(shown) {
|
||||||
if (ctrl && ev.key.toLowerCase() === 'v') { ev.preventDefault(); paste(); }
|
if (lastClicked) {
|
||||||
|
for (var i = 0; i < shown.length; i++) {
|
||||||
|
if (shown[i].relativePath === lastClicked) return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var keys = Object.keys(selected);
|
||||||
|
if (keys.length) {
|
||||||
|
for (var j = 0; j < shown.length; j++) {
|
||||||
|
if (selected[shown[j].relativePath]) return j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveSelection(delta) {
|
||||||
|
var shown = visible();
|
||||||
|
if (!shown.length) return;
|
||||||
|
var index = currentIndex(shown) + delta;
|
||||||
|
if (index < 0) index = 0;
|
||||||
|
if (index >= shown.length) index = shown.length - 1;
|
||||||
|
selected = {};
|
||||||
|
selected[shown[index].relativePath] = true;
|
||||||
|
lastClicked = shown[index].relativePath;
|
||||||
|
render();
|
||||||
|
var rows = list.querySelectorAll('.files-item');
|
||||||
|
if (rows[index]) rows[index].scrollIntoView({ block: 'nearest' });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key === 'Escape') {
|
||||||
|
ev.preventDefault();
|
||||||
|
selected = {};
|
||||||
|
lastClicked = '';
|
||||||
|
render();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (key === 'ArrowDown' || key === 'ArrowUp') {
|
||||||
|
ev.preventDefault();
|
||||||
|
moveSelection(key === 'ArrowDown' ? 1 : -1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ctrl && key.toLowerCase() === 'a') { ev.preventDefault(); selected = {}; visible().forEach(function (item) { selected[item.relativePath] = true; }); render(); }
|
||||||
|
if (ctrl && key.toLowerCase() === 'x') { ev.preventDefault(); cutSelection(); }
|
||||||
|
if (ctrl && key.toLowerCase() === 'c') { ev.preventDefault(); copySelection(); }
|
||||||
|
if (ctrl && key.toLowerCase() === 'v') { ev.preventDefault(); paste(); }
|
||||||
});
|
});
|
||||||
c.__filesCleanup = function () {
|
c.__filesCleanup = function () {
|
||||||
window.removeEventListener('mousedown', mouseHistory, true);
|
window.removeEventListener('mousedown', mouseHistory, true);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue