Skip to content

Commit

Permalink
feat: grid-pro loading editor state (#8156)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomivirkki authored Nov 18, 2024
1 parent 13cb006 commit 6ef77b9
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 2 deletions.
27 changes: 27 additions & 0 deletions packages/grid-pro/src/vaadin-grid-pro-inline-editing-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@ import { animationFrame } from '@vaadin/component-base/src/async.js';
import { Debouncer } from '@vaadin/component-base/src/debounce.js';
import { get, set } from '@vaadin/component-base/src/path-utils.js';
import { iterateRowCells, updatePart } from '@vaadin/grid/src/vaadin-grid-helpers.js';
import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';

registerStyles(
'vaadin-grid-pro',
css`
:host([loading-editor]) [part~='focused-cell'] ::slotted(vaadin-grid-cell-content) {
opacity: 0;
pointer-events: none;
}
`,
{
moduleId: 'vaadin-grid-pro-styles',
},
);

/**
* @polymerMixin
Expand Down Expand Up @@ -80,6 +94,19 @@ export const InlineEditingMixin = (superClass) =>

/** @protected */
ready() {
this.addEventListener(
'keydown',
(e) => {
if (this.hasAttribute('loading-editor') && !['Tab', 'Escape', 'Enter'].includes(e.key)) {
// If an editor is focused while it's loading, prevent default keydown behavior
// to avoid user interaction with the editor before it's fully loaded
// Used by Flow GridPro
e.preventDefault();
e.stopPropagation();
}
},
true,
);
// Add listener before `vaadin-grid` interaction mode listener
this.addEventListener('keydown', (e) => {
switch (e.keyCode) {
Expand Down
77 changes: 75 additions & 2 deletions packages/grid-pro/test/keyboard-navigation.common.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import { expect } from '@vaadin/chai-plugins';
import { fixtureSync } from '@vaadin/testing-helpers';
import { fixtureSync, nextFrame } from '@vaadin/testing-helpers';
import { sendKeys } from '@web/test-runner-commands';
import sinon from 'sinon';
import { createItems, dblclick, dragAndDropOver, flushGrid, getCellEditor, getContainerCell } from './helpers.js';
import {
createItems,
dblclick,
dragAndDropOver,
flushGrid,
getCellEditor,
getContainerCell,
getContainerCellContent,
} from './helpers.js';

describe('keyboard navigation', () => {
let grid;
Expand Down Expand Up @@ -273,4 +281,69 @@ describe('keyboard navigation', () => {
expect(focusSpy.calledAfter(stopSpy)).to.be.true;
});
});

describe('loading-editor', () => {
beforeEach(() => {
grid.toggleAttribute('loading-editor', true);
});

it('should not allow typing while the editor is loading', async () => {
const firstCell = getContainerCell(grid.$.items, 0, 0);
dblclick(firstCell._content);

await sendKeys({ press: 'a' });
await sendKeys({ press: 'Enter' });

grid.toggleAttribute('loading-editor', false);

expect(getContainerCellContent(grid.$.items, 0, 0).textContent).to.equal('0 foo');
});

it('should not allow keyboard interactions while the editor is loading', async () => {
const firstCell = getContainerCell(grid.$.items, 0, 0);
dblclick(firstCell._content);
const spy = sinon.spy();

const editor = getCellEditor(firstCell);
editor.addEventListener('keydown', spy);

await sendKeys({ press: 'ArrowDown' });

expect(spy.called).to.be.false;
});

it('should not allow pointer events while the editor is loading', async () => {
const firstCell = getContainerCell(grid.$.items, 0, 0);
dblclick(firstCell._content);
await nextFrame();
const editor = getCellEditor(firstCell);
expect(getComputedStyle(editor).pointerEvents).to.equal('none');
});

it('should hide cell content while the editor is loading', async () => {
const firstCell = getContainerCell(grid.$.items, 0, 0);
dblclick(firstCell._content);
await nextFrame();
const container = getContainerCellContent(grid.$.items, 0, 0);
expect(getComputedStyle(container).opacity).to.equal('0');
});

it('should allow tabbing to another cell while the editor is loading', async () => {
const firstCell = getContainerCell(grid.$.items, 0, 0);
dblclick(firstCell._content);

await sendKeys({ press: 'Tab' });
const secondCellContent = getContainerCellContent(grid.$.items, 0, 1);
console.log(secondCellContent);
expect(secondCellContent.contains(document.activeElement)).to.be.true;
});

it('should allow escaping from edit mode while the editor is loading', async () => {
const firstCell = getContainerCell(grid.$.items, 0, 0);
dblclick(firstCell._content);

await sendKeys({ press: 'Escape' });
expect(getContainerCellContent(grid.$.items, 0, 0).textContent).to.equal('0 foo');
});
});
});
16 changes: 16 additions & 0 deletions packages/grid-pro/theme/lumo/vaadin-grid-pro-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@ registerStyles(
var(--lumo-contrast-5pct) 14px
);
}
/* Loading editor cell styles are used by Flow GridPro */
:host([loading-editor]) [part~='focused-cell']::before {
content: '';
position: absolute;
inset: 0;
pointer-events: none;
box-shadow: inset 0 0 0 var(--_focus-ring-width) transparent;
animation: vaadin-grid-pro-loading-editor 1.4s infinite;
}
@keyframes vaadin-grid-pro-loading-editor {
50% {
box-shadow: inset 0 0 0 var(--_focus-ring-width) var(--_focus-ring-color);
}
}
`,
{ moduleId: 'lumo-grid-pro' },
);

0 comments on commit 6ef77b9

Please sign in to comment.