@operato/data-grist 10.29.7 → 10.29.8
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 +9 -0
- package/dist/src/data-grid/data-grid-body.js +15 -3
- package/dist/src/data-grid/data-grid-body.js.map +1 -1
- package/dist/src/data-grid/data-grid.js +2 -1
- package/dist/src/data-grid/data-grid.js.map +1 -1
- package/dist/test/first-click-stays.test.d.ts +1 -0
- package/dist/test/first-click-stays.test.js +77 -0
- package/dist/test/first-click-stays.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/test/first-click-stays.test.ts +101 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@operato/data-grist",
|
|
3
|
-
"version": "10.29.
|
|
3
|
+
"version": "10.29.8",
|
|
4
4
|
"description": "User interface for grid (desktop) and list (mobile)",
|
|
5
5
|
"author": "heartyoh",
|
|
6
6
|
"type": "module",
|
|
@@ -116,5 +116,5 @@
|
|
|
116
116
|
"prettier --write"
|
|
117
117
|
]
|
|
118
118
|
},
|
|
119
|
-
"gitHead": "
|
|
119
|
+
"gitHead": "7afbba99cf2119ccb709b6cb0cff8b58d447ef88"
|
|
120
120
|
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/* Elements are compared by presence, not by value: a failing element comparison makes chai render the DOM and hang the runner. */
|
|
2
|
+
import { expect, fixture } from '@open-wc/testing'
|
|
3
|
+
import { resetMouse, sendMouse } from '@web/test-runner-commands'
|
|
4
|
+
import { html } from 'lit'
|
|
5
|
+
|
|
6
|
+
import '../src/data-grist.js'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The first cell you click stays where you clicked it.
|
|
10
|
+
*
|
|
11
|
+
* Clicking a cell sets the new focus and calls focus() at once, before the body has drawn that
|
|
12
|
+
* focus. The input buffer that takes the focus was still where it had never been placed (top left),
|
|
13
|
+
* and the browser scrolled the grid to show it. Then the grid scrolled the focused cell back into
|
|
14
|
+
* view — at the far edge. A cell clicked in the middle of a grid pushed 1000px to the right ended up
|
|
15
|
+
* at the right edge (0, then 581). From the second click on the buffer sat near the last cell, so it
|
|
16
|
+
* only showed the first time.
|
|
17
|
+
*
|
|
18
|
+
* The grid scrolls its own focus into view, so focusing the buffer must not scroll.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
type Root = HTMLElement & { renderRoot: ShadowRoot; updateComplete: Promise<unknown> }
|
|
22
|
+
|
|
23
|
+
const settle = (ms = 150) => new Promise(resolve => setTimeout(resolve, ms))
|
|
24
|
+
|
|
25
|
+
describe('the first click on a scrolled grid', () => {
|
|
26
|
+
const ignoreResizeLoop = (e: ErrorEvent) => {
|
|
27
|
+
if (String(e.message).includes('ResizeObserver loop')) {
|
|
28
|
+
e.stopImmediatePropagation()
|
|
29
|
+
e.preventDefault()
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
let previousOnError: OnErrorEventHandler = null
|
|
33
|
+
before(() => {
|
|
34
|
+
window.addEventListener('error', ignoreResizeLoop, true)
|
|
35
|
+
previousOnError = window.onerror
|
|
36
|
+
window.onerror = (message, ...rest) =>
|
|
37
|
+
String(message).includes('ResizeObserver loop') ? true : previousOnError?.call(window, message, ...rest)
|
|
38
|
+
})
|
|
39
|
+
after(async function () {
|
|
40
|
+
/* resetMouse is a round trip to the browser driver; under a full parallel run it takes seconds. */
|
|
41
|
+
this.timeout(10000)
|
|
42
|
+
/* Let the resize that the last layout queued arrive while the filter is still in place. */
|
|
43
|
+
await settle(300)
|
|
44
|
+
window.removeEventListener('error', ignoreResizeLoop, true)
|
|
45
|
+
window.onerror = previousOnError
|
|
46
|
+
await resetMouse()
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('does not move the grid when the clicked cell is already in view', async function () {
|
|
50
|
+
this.timeout(10000)
|
|
51
|
+
const columns: any[] = [
|
|
52
|
+
{ type: 'gutter', gutterName: 'sequence' },
|
|
53
|
+
{ type: 'string', name: 'id', hidden: true },
|
|
54
|
+
{ type: 'string', name: 'code', header: 'code', width: 140, record: { editable: true } }
|
|
55
|
+
]
|
|
56
|
+
for (let i = 0; i < 30; i++) {
|
|
57
|
+
columns.push({ type: 'string', name: 'c' + i, header: 'col ' + i, width: 120, record: { editable: true } })
|
|
58
|
+
}
|
|
59
|
+
const records = Array.from({ length: 30 }, (_, r) => {
|
|
60
|
+
const record: any = { id: String(r), code: 'C-' + r }
|
|
61
|
+
for (let i = 0; i < 30; i++) record['c' + i] = `v${r}-${i}`
|
|
62
|
+
return record
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
const el = (await fixture(html`
|
|
66
|
+
<ox-grist
|
|
67
|
+
style="display: flex; width: 700px; height: 360px"
|
|
68
|
+
mode="GRID"
|
|
69
|
+
.config=${{ columns, pagination: { pages: [100] } }}
|
|
70
|
+
.fetchHandler=${async () => ({ total: records.length, records })}
|
|
71
|
+
></ox-grist>
|
|
72
|
+
`)) as Root & { fetch(): Promise<void> }
|
|
73
|
+
await el.fetch()
|
|
74
|
+
await settle()
|
|
75
|
+
|
|
76
|
+
const grist = el.renderRoot.querySelector('#grist') as Root
|
|
77
|
+
const scroller = grist.renderRoot.querySelector('div[grid]') as HTMLElement
|
|
78
|
+
const body = grist.renderRoot.querySelector('ox-grid-body') as Root
|
|
79
|
+
await body.updateComplete
|
|
80
|
+
|
|
81
|
+
scroller.scrollLeft = 1000
|
|
82
|
+
await settle(50)
|
|
83
|
+
expect(scroller.scrollLeft, 'the grid must scroll, or this measures nothing').to.equal(1000)
|
|
84
|
+
|
|
85
|
+
/* A cell in the middle of the view, in the third row. */
|
|
86
|
+
const row = body.renderRoot.querySelectorAll('div[grid-row]')[2] as HTMLElement
|
|
87
|
+
const view = scroller.getBoundingClientRect()
|
|
88
|
+
const cell = (Array.from(row.querySelectorAll('ox-grid-field')) as HTMLElement[]).find(f => {
|
|
89
|
+
const r = f.getBoundingClientRect()
|
|
90
|
+
return r.left > view.left + 200 && r.right < view.right - 200
|
|
91
|
+
})!
|
|
92
|
+
const before = cell.getBoundingClientRect()
|
|
93
|
+
|
|
94
|
+
await sendMouse({ type: 'click', position: [Math.round(before.left + 20), Math.round(before.top + before.height / 2)] })
|
|
95
|
+
await settle()
|
|
96
|
+
|
|
97
|
+
expect(cell.hasAttribute('focused'), 'the clicked cell takes the focus').to.equal(true)
|
|
98
|
+
expect(scroller.scrollLeft, 'the grid moved under the pointer').to.equal(1000)
|
|
99
|
+
expect(Math.round(cell.getBoundingClientRect().left)).to.equal(Math.round(before.left))
|
|
100
|
+
})
|
|
101
|
+
})
|