@operato/data-grist 10.29.6 → 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 +18 -0
- package/dist/src/data-grid/data-grid-body-style.js +2 -10
- package/dist/src/data-grid/data-grid-body-style.js.map +1 -1
- package/dist/src/data-grid/data-grid-body.d.ts +1 -0
- package/dist/src/data-grid/data-grid-body.js +35 -12
- package/dist/src/data-grid/data-grid-body.js.map +1 -1
- package/dist/src/data-grid/data-grid-header.js +5 -10
- package/dist/src/data-grid/data-grid-header.js.map +1 -1
- package/dist/src/data-grid/data-grid.d.ts +2 -1
- package/dist/src/data-grid/data-grid.js +74 -21
- package/dist/src/data-grid/data-grid.js.map +1 -1
- package/dist/test/accessible-name.test.js +6 -4
- package/dist/test/accessible-name.test.js.map +1 -1
- package/dist/test/field-contains-content.test.js +8 -5
- package/dist/test/field-contains-content.test.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/test/grid-single-scroller.test.d.ts +1 -0
- package/dist/test/grid-single-scroller.test.js +107 -0
- package/dist/test/grid-single-scroller.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/test/accessible-name.test.ts +6 -4
- package/test/field-contains-content.test.ts +10 -5
- package/test/first-click-stays.test.ts +101 -0
- package/test/grid-single-scroller.test.ts +150 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accessible-name.test.js","sourceRoot":"","sources":["../../test/accessible-name.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, fixture } from '@open-wc/testing'\nimport { html } from 'lit'\n\nimport '../src/data-grid/data-grid.js'\nimport '../src/data-grid/data-grid-body.js'\nimport { buildColumn } from '../src/configure/column-builder.js'\nimport { columnText } from '../src/utils/column-text.js'\nimport { ZERO_CONFIG, ZERO_DATA } from '../src/configure/zero-config.js'\n\n/**\n * Accessible names on the inputs inside the grid.\n *\n * ## Why this is tested\n *\n * Several inputs here had no name: the row-select checkboxes, the header filter boxes, and the IME\n * buffer that holds focus. Position carries the meaning for a sighted reader — a narrow leftmost\n * column means row select, a box under a header name filters that column — but position is a\n * picture, not a relationship, so nothing of it reaches a screen reader.\n *\n * ## What has to hold\n *\n * The name has one source. Editing `header` must change what is announced, which means callers\n * cannot spell the name out again. `columnText()` is that source.\n *\n * `buildColumn` turns a string header into `() => header`, and that function returns a lit template\n * the name cannot be read back out of. The name was disappearing right there.\n */\n\ndescribe('column name has one source', () => {\n it('keeps the plain text after a string header becomes a function', () => {\n const column = buildColumn({ type: 'string', name: 'palletId', header: '파렛트 번호' })\n\n expect(columnText(column)).to.equal('파렛트 번호')\n })\n\n it('keeps it when the string arrives as header.renderer', () => {\n const column = buildColumn({ type: 'string', name: 'palletId', header: { renderer: '파렛트 번호' } })\n\n expect(columnText(column)).to.equal('파렛트 번호')\n })\n\n it('lets label: true inherit the header name', () => {\n const column = buildColumn({ type: 'string', name: 'palletId', header: '파렛트 번호', label: true })\n\n expect(columnText(column)).to.equal('파렛트 번호')\n })\n\n it('falls back to column.name when the header is drawn by a function', () => {\n const column = buildColumn({ type: 'string', name: 'palletId', header: { renderer: () => html`<i>x</i>` } })\n\n expect(columnText(column)).to.equal('palletId')\n })\n\n it('invents no name when there is no column', () => {\n expect(columnText(undefined)).to.equal('')\n expect(columnText(null)).to.equal('')\n })\n})\n\ndescribe('row-select boxes are named', () => {\n const columns = [\n { type: 'gutter', gutterName: 'row-selector', name: '__selected__', multiple: true },\n { type: 'string', name: 'palletId', header: '파렛트 번호' }\n ].map(buildColumn)\n\n it('says which row each checkbox selects', async () => {\n const body: any = await fixture(html`\n <ox-grid-body\n .config=${{ ...ZERO_CONFIG, columns }}\n .columns=${columns}\n .data=${{ ...ZERO_DATA, records: [{ palletId: 'P-0001' }, { palletId: 'P-0002' }] }}\n ></ox-grid-body>\n `)\n\n await body.updateComplete\n\n /* The checkboxes live one shadow root deeper, inside each ox-grid-field. */\n const fields = Array.from(body.renderRoot.querySelectorAll('ox-grid-field')) as any[]\n\n await Promise.all(fields.map(field => field.updateComplete))\n\n const boxes = fields.flatMap(field =>\n Array.from(field.renderRoot?.querySelectorAll('input[type=checkbox], input[type=radio]') || [])\n ) as HTMLInputElement[]\n\n expect(boxes.length, 'found no row-select box').to.be.greaterThan(0)\n boxes.forEach(box =>\n expect(box.getAttribute('aria-label'), 'an unnamed checkbox is left').to.be.a('string').and.not.equal('')\n )\n })\n})\n\ndescribe('IME buffer names the cell it stands in for', () => {\n const columns = [\n { type: 'string', name: 'palletId', header: '파렛트 번호' },\n { type: 'string', name: 'location', header: '보관 위치' }\n ].map(buildColumn)\n\n async function bodyFocusedAt(column: number) {\n const body: any = await fixture(html`\n <ox-grid-body\n .config=${{ ...ZERO_CONFIG, columns }}\n .columns=${columns}\n .data=${{ ...ZERO_DATA, records: [{ palletId: 'P-0001', location: 'A-01' }] }}\n .focused=${{ row: 0, column }}\n ></ox-grid-body>\n `)\n\n await body.updateComplete\n\n return body.renderRoot.querySelector('#ime-buffer') as HTMLInputElement\n }\n\n it('reads the first column while focus sits there', async () => {\n expect((await bodyFocusedAt(0)).getAttribute('aria-label')).to.contain('파렛트 번호')\n })\n\n it('changes what it reads when focus moves a column over', async () => {\n expect((await bodyFocusedAt(1)).getAttribute('aria-label')).to.contain('보관 위치')\n })\n\n it('stays visible to assistive tech — it is where focus lands', async () => {\n expect((await bodyFocusedAt(0)).getAttribute('aria-hidden')).to.be.null\n })\n})\n\n/**\n * Table semantics.\n *\n * ## Why this is tested\n *\n * The grid is drawn with CSS grid: cells sit flat and there is no row element. Rows are a picture\n * made of equal offsetTop, so a screen reader saw a pile of inputs rather than a table — no \"this\n * is a table\", no \"row 3 column 3\", no \"40 rows in all\".\n *\n * Adding row wrappers can break two things at once:\n *\n * ```\n * semantics grid / row / columnheader / gridcell have to nest correctly\n * layout display: contents must generate no box; if it does, the columns collapse\n * ```\n *\n * The second one is why geometry is asserted: cells in a row must step right, and rows must step\n * down.\n */\ndescribe('grid declares itself a grid', () => {\n /* ox-grid takes already-compiled columns; compiling them is ox-grist's job. */\n const columns = [\n { type: 'gutter', gutterName: 'row-selector', name: '__selected__', multiple: true },\n { type: 'string', name: 'palletId', header: '파렛트 번호', sortable: true },\n { type: 'string', name: 'location', header: '보관 위치', sortable: true }\n ].map(buildColumn)\n\n async function grid(overrides: any = {}) {\n const el: any = await fixture(html`\n <ox-grid\n aria-label=\"입고 대기 목록\"\n .config=${{ ...ZERO_CONFIG, columns, rows: { ...ZERO_CONFIG.rows } }}\n .data=${{\n page: 1,\n limit: 20,\n total: 40,\n records: [\n { palletId: 'P-0001', location: 'A-01' },\n { palletId: 'P-0002', location: 'A-02' }\n ],\n ...overrides\n }}\n ></ox-grid>\n `)\n\n await el.updateComplete\n\n const header = el.renderRoot.querySelector('ox-grid-header')\n const body = el.renderRoot.querySelector('ox-grid-body')\n\n await header?.updateComplete\n await body?.updateComplete\n\n return { el, header, body }\n }\n\n it('nests grid, row and cell', async () => {\n const { el, header, body } = await grid()\n\n const grid_ = el.renderRoot.querySelector('[role=grid]')\n\n expect(grid_, 'no role=grid').to.exist\n expect(header.getAttribute('role')).to.equal('rowgroup')\n expect(body.getAttribute('role')).to.equal('rowgroup')\n\n expect(header.renderRoot.querySelectorAll('[role=row]').length).to.equal(1)\n expect(body.renderRoot.querySelectorAll('[role=row]').length).to.equal(2)\n expect(header.renderRoot.querySelectorAll('[role=columnheader]').length).to.equal(3)\n })\n\n it('counts the whole table, not the page on screen', async () => {\n const { el } = await grid()\n\n const grid_ = el.renderRoot.querySelector('[role=grid]')\n\n /* One header row plus 40 records. Two rows drawn is still a 40-row table. */\n expect(grid_.getAttribute('aria-rowcount')).to.equal('41')\n expect(grid_.getAttribute('aria-colcount')).to.equal('3')\n expect(grid_.getAttribute('aria-label')).to.equal('입고 대기 목록')\n })\n\n it('numbers page 2 from row 22, not back at 1', async () => {\n const { body } = await grid({ page: 2 })\n\n const rows = Array.from(body.renderRoot.querySelectorAll('[role=row]')) as HTMLElement[]\n\n /* One header row plus 20 records on page 1. */\n expect(rows[0].getAttribute('aria-rowindex')).to.equal('22')\n expect(rows[1].getAttribute('aria-rowindex')).to.equal('23')\n })\n\n it('numbers columns and leaves the width filler uncounted', async () => {\n const { body } = await grid()\n\n const row = body.renderRoot.querySelector('[role=row]') as HTMLElement\n const cells = Array.from(row.querySelectorAll('[role=gridcell]')) as HTMLElement[]\n\n expect(cells.map(cell => cell.getAttribute('aria-colindex'))).to.deep.equal(['1', '2', '3'])\n expect(row.querySelectorAll('[role=presentation]').length, 'the filler was counted as a cell').to.equal(1)\n })\n\n it('states sort direction in text, not only as an arrow', async () => {\n const el: any = await fixture(html`\n <ox-grid\n .config=${{ ...ZERO_CONFIG, columns, rows: { ...ZERO_CONFIG.rows } }}\n .sorters=${[{ name: 'palletId', desc: true }]}\n .data=${{ records: [{ palletId: 'P-0001', location: 'A-01' }] }}\n ></ox-grid>\n `)\n\n await el.updateComplete\n\n const header = el.renderRoot.querySelector('ox-grid-header')\n await header.updateComplete\n\n const headers = Array.from(header.renderRoot.querySelectorAll('[role=columnheader]')) as HTMLElement[]\n const sorts = headers.map(cell => cell.getAttribute('aria-sort'))\n\n /* A gutter cannot be sorted; claiming otherwise announces a control that is not there. */\n expect(sorts[0]).to.be.null\n expect(sorts[1], 'sorted descending').to.equal('descending')\n expect(sorts[2], 'sortable but not currently sorted').to.equal('none')\n })\n\n it('keeps the layout — a row wrapper that generates a box collapses the grid', async () => {\n const { body } = await grid()\n\n const rows = Array.from(body.renderRoot.querySelectorAll('[role=row]')) as HTMLElement[]\n const first = Array.from(rows[0].children) as HTMLElement[]\n\n expect(getComputedStyle(rows[0]).display).to.equal('contents')\n\n /* Cells step right; stacked at one x means the columns are gone. */\n const lefts = first.map(cell => cell.offsetLeft)\n expect(new Set(lefts).size, 'cells stacked at the same x').to.be.greaterThan(1)\n lefts.slice(1).forEach((left, index) => expect(left).to.be.greaterThan(lefts[index]))\n\n /* Rows step down. */\n const firstTop = (rows[0].children[0] as HTMLElement).offsetTop\n const secondTop = (rows[1].children[0] as HTMLElement).offsetTop\n expect(secondTop, 'two rows at the same y').to.be.greaterThan(firstTop)\n })\n})\n\n/**\n * Grouped headers.\n *\n * The header becomes two rows and ungrouped columns span both (`.span-both`). Placement runs\n * through CSS `grid-row` / `grid-column`, which makes this the riskiest spot for a row wrapper.\n */\ndescribe('grouped header spans two rows', () => {\n const columns = [\n { type: 'string', name: 'palletId', header: '파렛트 번호' },\n { type: 'string', name: 'width', header: { renderer: '폭', group: '치수' } },\n { type: 'string', name: 'height', header: { renderer: '높이', group: '치수' } }\n ].map(buildColumn)\n\n async function grouped() {\n const el: any = await fixture(html`\n <ox-grid\n .config=${{ ...ZERO_CONFIG, columns, rows: { ...ZERO_CONFIG.rows } }}\n .data=${{ total: 1, records: [{ palletId: 'P-0001', width: '1200', height: '900' }] }}\n ></ox-grid>\n `)\n\n await el.updateComplete\n\n const header = el.renderRoot.querySelector('ox-grid-header')\n const body = el.renderRoot.querySelector('ox-grid-body')\n\n await header.updateComplete\n await body.updateComplete\n\n return { el, header, body }\n }\n\n it('counts two header rows so the body starts at row 3', async () => {\n const { el, header, body } = await grouped()\n\n expect(header.renderRoot.querySelectorAll('[role=row]').length).to.equal(2)\n\n /* Two header rows plus one record. */\n expect(el.renderRoot.querySelector('[role=grid]').getAttribute('aria-rowcount')).to.equal('3')\n\n const rows = Array.from(body.renderRoot.querySelectorAll('[role=row]')) as HTMLElement[]\n expect(rows[0].getAttribute('aria-rowindex')).to.equal('3')\n })\n\n it('says how many columns a group covers', async () => {\n const { header } = await grouped()\n\n const cells = Array.from(header.renderRoot.querySelectorAll('[role=columnheader]')) as HTMLElement[]\n const first = cells[0]\n const group = cells.find(cell => cell.getAttribute('aria-colspan'))\n\n /* An ungrouped column spans both header rows. */\n expect(first.getAttribute('aria-rowspan')).to.equal('2')\n expect(first.getAttribute('aria-colindex')).to.equal('1')\n\n /* The group header covers columns 2 and 3. */\n expect(group, 'found no group header').to.exist\n expect(group!.getAttribute('aria-colindex')).to.equal('2')\n expect(group!.getAttribute('aria-colspan')).to.equal('2')\n })\n\n it('keeps two-row header placement — group sits above its leaf columns', async () => {\n const { header } = await grouped()\n\n const cells = Array.from(header.renderRoot.querySelectorAll('[role=columnheader]')) as HTMLElement[]\n const group = cells.find(cell => cell.getAttribute('aria-colspan'))!\n const leaf = cells.find(cell => !cell.getAttribute('aria-colspan') && cell !== cells[0])!\n\n expect(leaf.offsetTop, 'group header and its leaf column at the same height').to.be.greaterThan(group.offsetTop)\n expect(group.offsetWidth, 'group header does not cover two columns').to.be.greaterThan(leaf.offsetWidth)\n })\n})\n\n/**\n * The grid wrapper must not disturb the surrounding layout.\n *\n * `role=grid` admits only rows, so the settings-button slot and the pager moved outside the\n * wrapper. Two things then depend on this structure:\n *\n * ```\n * column layout the host is a flex column. A wrapper that generates a box swallows header\n * and body into one flex item, and the body's flex: 1 stops working\n * sibling selector \"show the settings button on header hover\" is an adjacent-sibling rule, so\n * the button has to sit directly after the wrapper\n * ```\n */\ndescribe('grid wrapper stays out of the layout', () => {\n const columns = [\n { type: 'string', name: 'palletId', header: '파렛트 번호' },\n { type: 'string', name: 'location', header: '보관 위치' }\n ].map(buildColumn)\n\n it('places the settings button after the grid, not inside it', async () => {\n const el: any = await fixture(html`\n <ox-grid\n .config=${{ ...ZERO_CONFIG, columns, rows: { ...ZERO_CONFIG.rows } }}\n .data=${{ total: 1, records: [{ palletId: 'P-0001', location: 'A-01' }] }}\n ></ox-grid>\n `)\n\n await el.updateComplete\n\n const grid = el.renderRoot.querySelector('[role=grid]') as HTMLElement\n const setting = el.renderRoot.querySelector('div[setting]') as HTMLElement\n\n expect(setting, 'no settings slot').to.exist\n expect(grid.contains(setting), 'settings button inside the grid breaks table reading').to.be.false\n expect(grid.nextElementSibling, 'adjacent-sibling rule no longer holds').to.equal(setting)\n })\n\n it('leaves header and body as flex items of the host', async () => {\n const el: any = await fixture(html`\n <div style=\"height: 300px; display: flex\">\n <ox-grid\n style=\"flex: 1\"\n .config=${{ ...ZERO_CONFIG, columns, rows: { ...ZERO_CONFIG.rows } }}\n .data=${{ total: 1, records: [{ palletId: 'P-0001', location: 'A-01' }] }}\n ></ox-grid>\n </div>\n `)\n\n const grid = el.querySelector('ox-grid') as any\n await grid.updateComplete\n\n const wrapper = grid.renderRoot.querySelector('[role=grid]') as HTMLElement\n const header = grid.renderRoot.querySelector('ox-grid-header') as HTMLElement\n const body = grid.renderRoot.querySelector('ox-grid-body') as HTMLElement\n\n expect(getComputedStyle(wrapper).display).to.equal('contents')\n\n /* The body takes the remaining height; a wrapper with a box shrinks it to header height. */\n expect(body.offsetHeight, 'body does not take the remaining height').to.be.greaterThan(100)\n expect(body.offsetTop, 'body is not below the header').to.be.greaterThan(0)\n expect(header.offsetTop).to.equal(0)\n })\n})\n"]}
|
|
1
|
+
{"version":3,"file":"accessible-name.test.js","sourceRoot":"","sources":["../../test/accessible-name.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, fixture } from '@open-wc/testing'\nimport { html } from 'lit'\n\nimport '../src/data-grid/data-grid.js'\nimport '../src/data-grid/data-grid-body.js'\nimport { buildColumn } from '../src/configure/column-builder.js'\nimport { columnText } from '../src/utils/column-text.js'\nimport { ZERO_CONFIG, ZERO_DATA } from '../src/configure/zero-config.js'\n\n/**\n * Accessible names on the inputs inside the grid.\n *\n * ## Why this is tested\n *\n * Several inputs here had no name: the row-select checkboxes, the header filter boxes, and the IME\n * buffer that holds focus. Position carries the meaning for a sighted reader — a narrow leftmost\n * column means row select, a box under a header name filters that column — but position is a\n * picture, not a relationship, so nothing of it reaches a screen reader.\n *\n * ## What has to hold\n *\n * The name has one source. Editing `header` must change what is announced, which means callers\n * cannot spell the name out again. `columnText()` is that source.\n *\n * `buildColumn` turns a string header into `() => header`, and that function returns a lit template\n * the name cannot be read back out of. The name was disappearing right there.\n */\n\ndescribe('column name has one source', () => {\n it('keeps the plain text after a string header becomes a function', () => {\n const column = buildColumn({ type: 'string', name: 'palletId', header: '파렛트 번호' })\n\n expect(columnText(column)).to.equal('파렛트 번호')\n })\n\n it('keeps it when the string arrives as header.renderer', () => {\n const column = buildColumn({ type: 'string', name: 'palletId', header: { renderer: '파렛트 번호' } })\n\n expect(columnText(column)).to.equal('파렛트 번호')\n })\n\n it('lets label: true inherit the header name', () => {\n const column = buildColumn({ type: 'string', name: 'palletId', header: '파렛트 번호', label: true })\n\n expect(columnText(column)).to.equal('파렛트 번호')\n })\n\n it('falls back to column.name when the header is drawn by a function', () => {\n const column = buildColumn({ type: 'string', name: 'palletId', header: { renderer: () => html`<i>x</i>` } })\n\n expect(columnText(column)).to.equal('palletId')\n })\n\n it('invents no name when there is no column', () => {\n expect(columnText(undefined)).to.equal('')\n expect(columnText(null)).to.equal('')\n })\n})\n\ndescribe('row-select boxes are named', () => {\n const columns = [\n { type: 'gutter', gutterName: 'row-selector', name: '__selected__', multiple: true },\n { type: 'string', name: 'palletId', header: '파렛트 번호' }\n ].map(buildColumn)\n\n it('says which row each checkbox selects', async () => {\n const body: any = await fixture(html`\n <ox-grid-body\n .config=${{ ...ZERO_CONFIG, columns }}\n .columns=${columns}\n .data=${{ ...ZERO_DATA, records: [{ palletId: 'P-0001' }, { palletId: 'P-0002' }] }}\n ></ox-grid-body>\n `)\n\n await body.updateComplete\n\n /* The checkboxes live one shadow root deeper, inside each ox-grid-field. */\n const fields = Array.from(body.renderRoot.querySelectorAll('ox-grid-field')) as any[]\n\n await Promise.all(fields.map(field => field.updateComplete))\n\n const boxes = fields.flatMap(field =>\n Array.from(field.renderRoot?.querySelectorAll('input[type=checkbox], input[type=radio]') || [])\n ) as HTMLInputElement[]\n\n expect(boxes.length, 'found no row-select box').to.be.greaterThan(0)\n boxes.forEach(box =>\n expect(box.getAttribute('aria-label'), 'an unnamed checkbox is left').to.be.a('string').and.not.equal('')\n )\n })\n})\n\ndescribe('IME buffer names the cell it stands in for', () => {\n const columns = [\n { type: 'string', name: 'palletId', header: '파렛트 번호' },\n { type: 'string', name: 'location', header: '보관 위치' }\n ].map(buildColumn)\n\n async function bodyFocusedAt(column: number) {\n const body: any = await fixture(html`\n <ox-grid-body\n .config=${{ ...ZERO_CONFIG, columns }}\n .columns=${columns}\n .data=${{ ...ZERO_DATA, records: [{ palletId: 'P-0001', location: 'A-01' }] }}\n .focused=${{ row: 0, column }}\n ></ox-grid-body>\n `)\n\n await body.updateComplete\n\n return body.renderRoot.querySelector('#ime-buffer') as HTMLInputElement\n }\n\n it('reads the first column while focus sits there', async () => {\n expect((await bodyFocusedAt(0)).getAttribute('aria-label')).to.contain('파렛트 번호')\n })\n\n it('changes what it reads when focus moves a column over', async () => {\n expect((await bodyFocusedAt(1)).getAttribute('aria-label')).to.contain('보관 위치')\n })\n\n it('stays visible to assistive tech — it is where focus lands', async () => {\n expect((await bodyFocusedAt(0)).getAttribute('aria-hidden')).to.be.null\n })\n})\n\n/**\n * Table semantics.\n *\n * ## Why this is tested\n *\n * The grid is drawn with CSS grid: cells sit flat and there is no row element. Rows are a picture\n * made of equal offsetTop, so a screen reader saw a pile of inputs rather than a table — no \"this\n * is a table\", no \"row 3 column 3\", no \"40 rows in all\".\n *\n * Adding row wrappers can break two things at once:\n *\n * ```\n * semantics grid / row / columnheader / gridcell have to nest correctly\n * layout display: contents must generate no box; if it does, the columns collapse\n * ```\n *\n * The second one is why geometry is asserted: cells in a row must step right, and rows must step\n * down.\n */\ndescribe('grid declares itself a grid', () => {\n /* ox-grid takes already-compiled columns; compiling them is ox-grist's job. */\n const columns = [\n { type: 'gutter', gutterName: 'row-selector', name: '__selected__', multiple: true },\n { type: 'string', name: 'palletId', header: '파렛트 번호', sortable: true },\n { type: 'string', name: 'location', header: '보관 위치', sortable: true }\n ].map(buildColumn)\n\n async function grid(overrides: any = {}) {\n const el: any = await fixture(html`\n <ox-grid\n aria-label=\"입고 대기 목록\"\n .config=${{ ...ZERO_CONFIG, columns, rows: { ...ZERO_CONFIG.rows } }}\n .data=${{\n page: 1,\n limit: 20,\n total: 40,\n records: [\n { palletId: 'P-0001', location: 'A-01' },\n { palletId: 'P-0002', location: 'A-02' }\n ],\n ...overrides\n }}\n ></ox-grid>\n `)\n\n await el.updateComplete\n\n const header = el.renderRoot.querySelector('ox-grid-header')\n const body = el.renderRoot.querySelector('ox-grid-body')\n\n await header?.updateComplete\n await body?.updateComplete\n\n return { el, header, body }\n }\n\n it('nests grid, row and cell', async () => {\n const { el, header, body } = await grid()\n\n const grid_ = el.renderRoot.querySelector('[role=grid]')\n\n expect(grid_, 'no role=grid').to.exist\n expect(header.getAttribute('role')).to.equal('rowgroup')\n expect(body.getAttribute('role')).to.equal('rowgroup')\n\n expect(header.renderRoot.querySelectorAll('[role=row]').length).to.equal(1)\n expect(body.renderRoot.querySelectorAll('[role=row]').length).to.equal(2)\n expect(header.renderRoot.querySelectorAll('[role=columnheader]').length).to.equal(3)\n })\n\n it('counts the whole table, not the page on screen', async () => {\n const { el } = await grid()\n\n const grid_ = el.renderRoot.querySelector('[role=grid]')\n\n /* One header row plus 40 records. Two rows drawn is still a 40-row table. */\n expect(grid_.getAttribute('aria-rowcount')).to.equal('41')\n expect(grid_.getAttribute('aria-colcount')).to.equal('3')\n expect(grid_.getAttribute('aria-label')).to.equal('입고 대기 목록')\n })\n\n it('numbers page 2 from row 22, not back at 1', async () => {\n const { body } = await grid({ page: 2 })\n\n const rows = Array.from(body.renderRoot.querySelectorAll('[role=row]')) as HTMLElement[]\n\n /* One header row plus 20 records on page 1. */\n expect(rows[0].getAttribute('aria-rowindex')).to.equal('22')\n expect(rows[1].getAttribute('aria-rowindex')).to.equal('23')\n })\n\n it('numbers columns and leaves the width filler uncounted', async () => {\n const { body } = await grid()\n\n const row = body.renderRoot.querySelector('[role=row]') as HTMLElement\n const cells = Array.from(row.querySelectorAll('[role=gridcell]')) as HTMLElement[]\n\n expect(cells.map(cell => cell.getAttribute('aria-colindex'))).to.deep.equal(['1', '2', '3'])\n expect(row.querySelectorAll('[role=presentation]').length, 'the filler was counted as a cell').to.equal(1)\n })\n\n it('states sort direction in text, not only as an arrow', async () => {\n const el: any = await fixture(html`\n <ox-grid\n .config=${{ ...ZERO_CONFIG, columns, rows: { ...ZERO_CONFIG.rows } }}\n .sorters=${[{ name: 'palletId', desc: true }]}\n .data=${{ records: [{ palletId: 'P-0001', location: 'A-01' }] }}\n ></ox-grid>\n `)\n\n await el.updateComplete\n\n const header = el.renderRoot.querySelector('ox-grid-header')\n await header.updateComplete\n\n const headers = Array.from(header.renderRoot.querySelectorAll('[role=columnheader]')) as HTMLElement[]\n const sorts = headers.map(cell => cell.getAttribute('aria-sort'))\n\n /* A gutter cannot be sorted; claiming otherwise announces a control that is not there. */\n expect(sorts[0]).to.be.null\n expect(sorts[1], 'sorted descending').to.equal('descending')\n expect(sorts[2], 'sortable but not currently sorted').to.equal('none')\n })\n\n it('keeps the layout — a row wrapper that generates a box collapses the grid', async () => {\n const { body } = await grid()\n\n const rows = Array.from(body.renderRoot.querySelectorAll('[role=row]')) as HTMLElement[]\n const first = Array.from(rows[0].children) as HTMLElement[]\n\n expect(getComputedStyle(rows[0]).display).to.equal('contents')\n\n /* Cells step right; stacked at one x means the columns are gone. */\n const lefts = first.map(cell => cell.offsetLeft)\n expect(new Set(lefts).size, 'cells stacked at the same x').to.be.greaterThan(1)\n lefts.slice(1).forEach((left, index) => expect(left).to.be.greaterThan(lefts[index]))\n\n /* Rows step down. */\n const firstTop = (rows[0].children[0] as HTMLElement).offsetTop\n const secondTop = (rows[1].children[0] as HTMLElement).offsetTop\n expect(secondTop, 'two rows at the same y').to.be.greaterThan(firstTop)\n })\n})\n\n/**\n * Grouped headers.\n *\n * The header becomes two rows and ungrouped columns span both (`.span-both`). Placement runs\n * through CSS `grid-row` / `grid-column`, which makes this the riskiest spot for a row wrapper.\n */\ndescribe('grouped header spans two rows', () => {\n const columns = [\n { type: 'string', name: 'palletId', header: '파렛트 번호' },\n { type: 'string', name: 'width', header: { renderer: '폭', group: '치수' } },\n { type: 'string', name: 'height', header: { renderer: '높이', group: '치수' } }\n ].map(buildColumn)\n\n async function grouped() {\n const el: any = await fixture(html`\n <ox-grid\n .config=${{ ...ZERO_CONFIG, columns, rows: { ...ZERO_CONFIG.rows } }}\n .data=${{ total: 1, records: [{ palletId: 'P-0001', width: '1200', height: '900' }] }}\n ></ox-grid>\n `)\n\n await el.updateComplete\n\n const header = el.renderRoot.querySelector('ox-grid-header')\n const body = el.renderRoot.querySelector('ox-grid-body')\n\n await header.updateComplete\n await body.updateComplete\n\n return { el, header, body }\n }\n\n it('counts two header rows so the body starts at row 3', async () => {\n const { el, header, body } = await grouped()\n\n expect(header.renderRoot.querySelectorAll('[role=row]').length).to.equal(2)\n\n /* Two header rows plus one record. */\n expect(el.renderRoot.querySelector('[role=grid]').getAttribute('aria-rowcount')).to.equal('3')\n\n const rows = Array.from(body.renderRoot.querySelectorAll('[role=row]')) as HTMLElement[]\n expect(rows[0].getAttribute('aria-rowindex')).to.equal('3')\n })\n\n it('says how many columns a group covers', async () => {\n const { header } = await grouped()\n\n const cells = Array.from(header.renderRoot.querySelectorAll('[role=columnheader]')) as HTMLElement[]\n const first = cells[0]\n const group = cells.find(cell => cell.getAttribute('aria-colspan'))\n\n /* An ungrouped column spans both header rows. */\n expect(first.getAttribute('aria-rowspan')).to.equal('2')\n expect(first.getAttribute('aria-colindex')).to.equal('1')\n\n /* The group header covers columns 2 and 3. */\n expect(group, 'found no group header').to.exist\n expect(group!.getAttribute('aria-colindex')).to.equal('2')\n expect(group!.getAttribute('aria-colspan')).to.equal('2')\n })\n\n it('keeps two-row header placement — group sits above its leaf columns', async () => {\n const { header } = await grouped()\n\n const cells = Array.from(header.renderRoot.querySelectorAll('[role=columnheader]')) as HTMLElement[]\n const group = cells.find(cell => cell.getAttribute('aria-colspan'))!\n const leaf = cells.find(cell => !cell.getAttribute('aria-colspan') && cell !== cells[0])!\n\n expect(leaf.offsetTop, 'group header and its leaf column at the same height').to.be.greaterThan(group.offsetTop)\n expect(group.offsetWidth, 'group header does not cover two columns').to.be.greaterThan(leaf.offsetWidth)\n })\n})\n\n/**\n * The grid wrapper must not disturb the surrounding layout.\n *\n * `role=grid` admits only rows, so the settings-button slot and the pager moved outside the\n * wrapper. Two things then depend on this structure:\n *\n * ```\n * column layout the host is a flex column. The wrapper is itself a flex column (it is the one\n * scroller that header and body share), so the body still takes the height\n * left under the header\n * sibling selector \"show the settings button on header hover\" is an adjacent-sibling rule, so\n * the button has to sit directly after the wrapper\n * ```\n */\ndescribe('grid wrapper stays out of the layout', () => {\n const columns = [\n { type: 'string', name: 'palletId', header: '파렛트 번호' },\n { type: 'string', name: 'location', header: '보관 위치' }\n ].map(buildColumn)\n\n it('places the settings button after the grid, not inside it', async () => {\n const el: any = await fixture(html`\n <ox-grid\n .config=${{ ...ZERO_CONFIG, columns, rows: { ...ZERO_CONFIG.rows } }}\n .data=${{ total: 1, records: [{ palletId: 'P-0001', location: 'A-01' }] }}\n ></ox-grid>\n `)\n\n await el.updateComplete\n\n const grid = el.renderRoot.querySelector('[role=grid]') as HTMLElement\n const setting = el.renderRoot.querySelector('div[setting]') as HTMLElement\n\n expect(setting, 'no settings slot').to.exist\n expect(grid.contains(setting), 'settings button inside the grid breaks table reading').to.be.false\n expect(grid.nextElementSibling, 'adjacent-sibling rule no longer holds').to.equal(setting)\n })\n\n it('lays header and body out as a column that fills the host', async () => {\n const el: any = await fixture(html`\n <div style=\"height: 300px; display: flex\">\n <ox-grid\n style=\"flex: 1\"\n .config=${{ ...ZERO_CONFIG, columns, rows: { ...ZERO_CONFIG.rows } }}\n .data=${{ total: 1, records: [{ palletId: 'P-0001', location: 'A-01' }] }}\n ></ox-grid>\n </div>\n `)\n\n const grid = el.querySelector('ox-grid') as any\n await grid.updateComplete\n\n const wrapper = grid.renderRoot.querySelector('[role=grid]') as HTMLElement\n const header = grid.renderRoot.querySelector('ox-grid-header') as HTMLElement\n const body = grid.renderRoot.querySelector('ox-grid-body') as HTMLElement\n\n expect(getComputedStyle(wrapper).display).to.equal('flex')\n expect(getComputedStyle(wrapper).flexDirection).to.equal('column')\n\n /* The body takes the remaining height; a wrapper with a box shrinks it to header height. */\n expect(body.offsetHeight, 'body does not take the remaining height').to.be.greaterThan(100)\n expect(body.offsetTop, 'body is not below the header').to.be.greaterThan(0)\n expect(header.offsetTop).to.equal(0)\n })\n})\n"]}
|
|
@@ -9,7 +9,8 @@ import '../src/data-grist.js';
|
|
|
9
9
|
* `span` and `pre` were clipped, so a long string — or an `<a>` — spilled past its track. The body's
|
|
10
10
|
* scrollWidth grew past the header's (the header is just the sum of the column widths): at the far
|
|
11
11
|
* right the header stopped while the body kept scrolling, and stray text showed where there were no
|
|
12
|
-
* columns.
|
|
12
|
+
* columns. Header and body now share one scroller, so the overflow shows as the grid scrolling past
|
|
13
|
+
* its last column instead.
|
|
13
14
|
*
|
|
14
15
|
* [measured] operato-office contract list — body 5503 / header 3830 (2026-10-04)
|
|
15
16
|
*
|
|
@@ -45,11 +46,12 @@ async function grid(renderer) {
|
|
|
45
46
|
await settle();
|
|
46
47
|
await el.updateComplete;
|
|
47
48
|
const grist = el.renderRoot.querySelector('#grist');
|
|
49
|
+
const scroller = grist.renderRoot.querySelector('div[grid]');
|
|
48
50
|
const header = grist.renderRoot.querySelector('ox-grid-header');
|
|
49
51
|
const body = grist.renderRoot.querySelector('ox-grid-body');
|
|
50
52
|
await body.updateComplete;
|
|
51
53
|
const notes = Array.from(body.renderRoot.querySelectorAll('ox-grid-field')).filter(f => { var _a; return ((_a = f.column) === null || _a === void 0 ? void 0 : _a.name) === 'note'; });
|
|
52
|
-
return { header, body, notes };
|
|
54
|
+
return { scroller, header, body, notes };
|
|
53
55
|
}
|
|
54
56
|
describe('a grid cell keeps its content inside its column', () => {
|
|
55
57
|
/* Resizing the grid body inside a fixture trips Chrome's benign "ResizeObserver loop" error. */
|
|
@@ -74,10 +76,11 @@ describe('a grid cell keeps its content inside its column', () => {
|
|
|
74
76
|
['an <a>', value => html `<a href="#">${value}</a>`]
|
|
75
77
|
];
|
|
76
78
|
for (const [kind, renderer] of renderers) {
|
|
77
|
-
it(`${kind}: the
|
|
78
|
-
const { header, body, notes } = await grid(renderer);
|
|
79
|
+
it(`${kind}: the grid scrolls exactly as far as its columns reach`, async () => {
|
|
80
|
+
const { scroller, header, body, notes } = await grid(renderer);
|
|
79
81
|
expect(notes.length, 'the long cells must be drawn, or this measures nothing').to.be.at.least(2);
|
|
80
|
-
expect(body.
|
|
82
|
+
expect(body.offsetWidth, 'header and body span the same width').to.equal(header.offsetWidth);
|
|
83
|
+
expect(scroller.scrollWidth, 'content past the last column scrolls on into empty space').to.equal(header.offsetWidth);
|
|
81
84
|
});
|
|
82
85
|
it(`${kind}: the cell is as wide as its column and clips what does not fit`, async () => {
|
|
83
86
|
const { notes } = await grid(renderer);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-contains-content.test.js","sourceRoot":"","sources":["../../test/field-contains-content.test.ts"],"names":[],"mappings":"AAAA,kIAAkI;AAClI,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAE1B,OAAO,sBAAsB,CAAA;AAE7B
|
|
1
|
+
{"version":3,"file":"field-contains-content.test.js","sourceRoot":"","sources":["../../test/field-contains-content.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* Elements are compared by presence, not by value: a failing element comparison makes chai render the DOM and hang the runner. */\nimport { expect, fixture } from '@open-wc/testing'\nimport { html } from 'lit'\n\nimport '../src/data-grist.js'\n\n/**\n * A cell keeps what its renderer draws inside its column.\n *\n * `FieldRenderer` may return a plain string, and the cell rendered it as a bare text node. Only\n * `span` and `pre` were clipped, so a long string — or an `<a>` — spilled past its track. The body's\n * scrollWidth grew past the header's (the header is just the sum of the column widths): at the far\n * right the header stopped while the body kept scrolling, and stray text showed where there were no\n * columns. Header and body now share one scroller, so the overflow shows as the grid scrolling past\n * its last column instead.\n *\n * [measured] operato-office contract list — body 5503 / header 3830 (2026-10-04)\n *\n * The long cells sit in the last column, because only content that runs past the last track widens\n * the body; in a middle column the next cell paints over it and the defect hides.\n */\n\nconst LONG = '긴 글자가 열 너비를 넘는다 '.repeat(40)\n\nconst settle = (ms = 150) => new Promise(resolve => setTimeout(resolve, ms))\n\ntype Root = HTMLElement & { renderRoot: ShadowRoot; updateComplete: Promise<unknown> }\n\nasync function grid(renderer: (value: unknown) => unknown) {\n const config = {\n columns: [\n { type: 'string', name: 'id', hidden: true },\n { type: 'string', name: 'name', header: 'name', width: 120 },\n { type: 'string', name: 'note', header: 'note', width: 160, record: { renderer } }\n ],\n pagination: { pages: [20] }\n }\n\n const el = (await fixture(html`\n <ox-grist\n style=\"width: 400px; height: 300px\"\n mode=\"GRID\"\n .config=${config}\n .fetchHandler=${async () => ({\n total: 2,\n records: [\n { id: '1', name: 'a', note: LONG },\n { id: '2', name: 'b', note: LONG }\n ]\n })}\n ></ox-grist>\n `)) as Root & { fetch(): Promise<void> }\n\n await el.fetch()\n await settle()\n await el.updateComplete\n\n const grist = el.renderRoot.querySelector('#grist') as Root\n const scroller = grist.renderRoot.querySelector('div[grid]') as HTMLElement\n const header = grist.renderRoot.querySelector('ox-grid-header') as Root\n const body = grist.renderRoot.querySelector('ox-grid-body') as Root\n await body.updateComplete\n\n const notes = Array.from(body.renderRoot.querySelectorAll('ox-grid-field')).filter(\n f => (f as any).column?.name === 'note'\n ) as Root[]\n\n return { scroller, header, body, notes }\n}\n\ndescribe('a grid cell keeps its content inside its column', () => {\n /* Resizing the grid body inside a fixture trips Chrome's benign \"ResizeObserver loop\" error. */\n const ignoreResizeLoop = (e: ErrorEvent) => {\n if (String(e.message).includes('ResizeObserver loop')) {\n e.stopImmediatePropagation()\n e.preventDefault()\n }\n }\n let previousOnError: OnErrorEventHandler = null\n before(() => {\n window.addEventListener('error', ignoreResizeLoop, true)\n previousOnError = window.onerror\n window.onerror = (message, ...rest) =>\n String(message).includes('ResizeObserver loop') ? true : previousOnError?.call(window, message, ...rest)\n })\n after(() => {\n window.removeEventListener('error', ignoreResizeLoop, true)\n window.onerror = previousOnError\n })\n\n const renderers: [string, (value: unknown) => unknown][] = [\n ['a plain string', value => String(value)],\n ['an <a>', value => html`<a href=\"#\">${value}</a>`]\n ]\n\n for (const [kind, renderer] of renderers) {\n it(`${kind}: the grid scrolls exactly as far as its columns reach`, async () => {\n const { scroller, header, body, notes } = await grid(renderer)\n\n expect(notes.length, 'the long cells must be drawn, or this measures nothing').to.be.at.least(2)\n expect(body.offsetWidth, 'header and body span the same width').to.equal(header.offsetWidth)\n expect(scroller.scrollWidth, 'content past the last column scrolls on into empty space').to.equal(\n header.offsetWidth\n )\n })\n\n it(`${kind}: the cell is as wide as its column and clips what does not fit`, async () => {\n const { notes } = await grid(renderer)\n\n for (const note of notes) {\n expect(Math.round(note.getBoundingClientRect().width)).to.equal(160)\n expect(getComputedStyle(note).overflowX).to.equal('hidden')\n }\n })\n }\n\n it('a plain string still ends in an ellipsis', async () => {\n const { notes } = await grid(value => String(value))\n\n const text = notes[0].renderRoot.querySelector('span') as HTMLElement | null\n expect(!!text, 'the string sits in a box that can take text-overflow').to.equal(true)\n expect(getComputedStyle(text!).textOverflow).to.equal('ellipsis')\n expect(text!.clientWidth).to.be.lessThan(160)\n })\n})\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '../src/data-grist.js';
|
|
@@ -0,0 +1,77 @@
|
|
|
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
|
+
import '../src/data-grist.js';
|
|
6
|
+
const settle = (ms = 150) => new Promise(resolve => setTimeout(resolve, ms));
|
|
7
|
+
describe('the first click on a scrolled grid', () => {
|
|
8
|
+
const ignoreResizeLoop = (e) => {
|
|
9
|
+
if (String(e.message).includes('ResizeObserver loop')) {
|
|
10
|
+
e.stopImmediatePropagation();
|
|
11
|
+
e.preventDefault();
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
let previousOnError = null;
|
|
15
|
+
before(() => {
|
|
16
|
+
window.addEventListener('error', ignoreResizeLoop, true);
|
|
17
|
+
previousOnError = window.onerror;
|
|
18
|
+
window.onerror = (message, ...rest) => String(message).includes('ResizeObserver loop') ? true : previousOnError === null || previousOnError === void 0 ? void 0 : previousOnError.call(window, message, ...rest);
|
|
19
|
+
});
|
|
20
|
+
after(async function () {
|
|
21
|
+
/* resetMouse is a round trip to the browser driver; under a full parallel run it takes seconds. */
|
|
22
|
+
this.timeout(10000);
|
|
23
|
+
/* Let the resize that the last layout queued arrive while the filter is still in place. */
|
|
24
|
+
await settle(300);
|
|
25
|
+
window.removeEventListener('error', ignoreResizeLoop, true);
|
|
26
|
+
window.onerror = previousOnError;
|
|
27
|
+
await resetMouse();
|
|
28
|
+
});
|
|
29
|
+
it('does not move the grid when the clicked cell is already in view', async function () {
|
|
30
|
+
this.timeout(10000);
|
|
31
|
+
const columns = [
|
|
32
|
+
{ type: 'gutter', gutterName: 'sequence' },
|
|
33
|
+
{ type: 'string', name: 'id', hidden: true },
|
|
34
|
+
{ type: 'string', name: 'code', header: 'code', width: 140, record: { editable: true } }
|
|
35
|
+
];
|
|
36
|
+
for (let i = 0; i < 30; i++) {
|
|
37
|
+
columns.push({ type: 'string', name: 'c' + i, header: 'col ' + i, width: 120, record: { editable: true } });
|
|
38
|
+
}
|
|
39
|
+
const records = Array.from({ length: 30 }, (_, r) => {
|
|
40
|
+
const record = { id: String(r), code: 'C-' + r };
|
|
41
|
+
for (let i = 0; i < 30; i++)
|
|
42
|
+
record['c' + i] = `v${r}-${i}`;
|
|
43
|
+
return record;
|
|
44
|
+
});
|
|
45
|
+
const el = (await fixture(html `
|
|
46
|
+
<ox-grist
|
|
47
|
+
style="display: flex; width: 700px; height: 360px"
|
|
48
|
+
mode="GRID"
|
|
49
|
+
.config=${{ columns, pagination: { pages: [100] } }}
|
|
50
|
+
.fetchHandler=${async () => ({ total: records.length, records })}
|
|
51
|
+
></ox-grist>
|
|
52
|
+
`));
|
|
53
|
+
await el.fetch();
|
|
54
|
+
await settle();
|
|
55
|
+
const grist = el.renderRoot.querySelector('#grist');
|
|
56
|
+
const scroller = grist.renderRoot.querySelector('div[grid]');
|
|
57
|
+
const body = grist.renderRoot.querySelector('ox-grid-body');
|
|
58
|
+
await body.updateComplete;
|
|
59
|
+
scroller.scrollLeft = 1000;
|
|
60
|
+
await settle(50);
|
|
61
|
+
expect(scroller.scrollLeft, 'the grid must scroll, or this measures nothing').to.equal(1000);
|
|
62
|
+
/* A cell in the middle of the view, in the third row. */
|
|
63
|
+
const row = body.renderRoot.querySelectorAll('div[grid-row]')[2];
|
|
64
|
+
const view = scroller.getBoundingClientRect();
|
|
65
|
+
const cell = Array.from(row.querySelectorAll('ox-grid-field')).find(f => {
|
|
66
|
+
const r = f.getBoundingClientRect();
|
|
67
|
+
return r.left > view.left + 200 && r.right < view.right - 200;
|
|
68
|
+
});
|
|
69
|
+
const before = cell.getBoundingClientRect();
|
|
70
|
+
await sendMouse({ type: 'click', position: [Math.round(before.left + 20), Math.round(before.top + before.height / 2)] });
|
|
71
|
+
await settle();
|
|
72
|
+
expect(cell.hasAttribute('focused'), 'the clicked cell takes the focus').to.equal(true);
|
|
73
|
+
expect(scroller.scrollLeft, 'the grid moved under the pointer').to.equal(1000);
|
|
74
|
+
expect(Math.round(cell.getBoundingClientRect().left)).to.equal(Math.round(before.left));
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=first-click-stays.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"first-click-stays.test.js","sourceRoot":"","sources":["../../test/first-click-stays.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* Elements are compared by presence, not by value: a failing element comparison makes chai render the DOM and hang the runner. */\nimport { expect, fixture } from '@open-wc/testing'\nimport { resetMouse, sendMouse } from '@web/test-runner-commands'\nimport { html } from 'lit'\n\nimport '../src/data-grist.js'\n\n/**\n * The first cell you click stays where you clicked it.\n *\n * Clicking a cell sets the new focus and calls focus() at once, before the body has drawn that\n * focus. The input buffer that takes the focus was still where it had never been placed (top left),\n * and the browser scrolled the grid to show it. Then the grid scrolled the focused cell back into\n * view — at the far edge. A cell clicked in the middle of a grid pushed 1000px to the right ended up\n * at the right edge (0, then 581). From the second click on the buffer sat near the last cell, so it\n * only showed the first time.\n *\n * The grid scrolls its own focus into view, so focusing the buffer must not scroll.\n */\n\ntype Root = HTMLElement & { renderRoot: ShadowRoot; updateComplete: Promise<unknown> }\n\nconst settle = (ms = 150) => new Promise(resolve => setTimeout(resolve, ms))\n\ndescribe('the first click on a scrolled grid', () => {\n const ignoreResizeLoop = (e: ErrorEvent) => {\n if (String(e.message).includes('ResizeObserver loop')) {\n e.stopImmediatePropagation()\n e.preventDefault()\n }\n }\n let previousOnError: OnErrorEventHandler = null\n before(() => {\n window.addEventListener('error', ignoreResizeLoop, true)\n previousOnError = window.onerror\n window.onerror = (message, ...rest) =>\n String(message).includes('ResizeObserver loop') ? true : previousOnError?.call(window, message, ...rest)\n })\n after(async function () {\n /* resetMouse is a round trip to the browser driver; under a full parallel run it takes seconds. */\n this.timeout(10000)\n /* Let the resize that the last layout queued arrive while the filter is still in place. */\n await settle(300)\n window.removeEventListener('error', ignoreResizeLoop, true)\n window.onerror = previousOnError\n await resetMouse()\n })\n\n it('does not move the grid when the clicked cell is already in view', async function () {\n this.timeout(10000)\n const columns: any[] = [\n { type: 'gutter', gutterName: 'sequence' },\n { type: 'string', name: 'id', hidden: true },\n { type: 'string', name: 'code', header: 'code', width: 140, record: { editable: true } }\n ]\n for (let i = 0; i < 30; i++) {\n columns.push({ type: 'string', name: 'c' + i, header: 'col ' + i, width: 120, record: { editable: true } })\n }\n const records = Array.from({ length: 30 }, (_, r) => {\n const record: any = { id: String(r), code: 'C-' + r }\n for (let i = 0; i < 30; i++) record['c' + i] = `v${r}-${i}`\n return record\n })\n\n const el = (await fixture(html`\n <ox-grist\n style=\"display: flex; width: 700px; height: 360px\"\n mode=\"GRID\"\n .config=${{ columns, pagination: { pages: [100] } }}\n .fetchHandler=${async () => ({ total: records.length, records })}\n ></ox-grist>\n `)) as Root & { fetch(): Promise<void> }\n await el.fetch()\n await settle()\n\n const grist = el.renderRoot.querySelector('#grist') as Root\n const scroller = grist.renderRoot.querySelector('div[grid]') as HTMLElement\n const body = grist.renderRoot.querySelector('ox-grid-body') as Root\n await body.updateComplete\n\n scroller.scrollLeft = 1000\n await settle(50)\n expect(scroller.scrollLeft, 'the grid must scroll, or this measures nothing').to.equal(1000)\n\n /* A cell in the middle of the view, in the third row. */\n const row = body.renderRoot.querySelectorAll('div[grid-row]')[2] as HTMLElement\n const view = scroller.getBoundingClientRect()\n const cell = (Array.from(row.querySelectorAll('ox-grid-field')) as HTMLElement[]).find(f => {\n const r = f.getBoundingClientRect()\n return r.left > view.left + 200 && r.right < view.right - 200\n })!\n const before = cell.getBoundingClientRect()\n\n await sendMouse({ type: 'click', position: [Math.round(before.left + 20), Math.round(before.top + before.height / 2)] })\n await settle()\n\n expect(cell.hasAttribute('focused'), 'the clicked cell takes the focus').to.equal(true)\n expect(scroller.scrollLeft, 'the grid moved under the pointer').to.equal(1000)\n expect(Math.round(cell.getBoundingClientRect().left)).to.equal(Math.round(before.left))\n })\n})\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '../src/data-grist.js';
|
|
@@ -0,0 +1,107 @@
|
|
|
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 { html } from 'lit';
|
|
4
|
+
import '../src/data-grist.js';
|
|
5
|
+
const settle = (ms = 150) => new Promise(resolve => setTimeout(resolve, ms));
|
|
6
|
+
async function grid() {
|
|
7
|
+
const columns = [
|
|
8
|
+
{ type: 'gutter', gutterName: 'sequence' },
|
|
9
|
+
{ type: 'string', name: 'id', hidden: true },
|
|
10
|
+
{ type: 'string', name: 'code', header: 'code', width: 120, fixed: true }
|
|
11
|
+
];
|
|
12
|
+
for (let i = 0; i < 12; i++) {
|
|
13
|
+
columns.push({ type: 'string', name: 'c' + i, header: 'col ' + i, width: 110 });
|
|
14
|
+
}
|
|
15
|
+
const records = Array.from({ length: 60 }, (_, r) => {
|
|
16
|
+
const record = { id: String(r), code: 'C-' + r };
|
|
17
|
+
for (let i = 0; i < 12; i++)
|
|
18
|
+
record['c' + i] = `v${r}-${i}`;
|
|
19
|
+
return record;
|
|
20
|
+
});
|
|
21
|
+
const el = (await fixture(html `
|
|
22
|
+
<ox-grist
|
|
23
|
+
style="width: 600px; height: 320px"
|
|
24
|
+
mode="GRID"
|
|
25
|
+
.config=${{ columns, pagination: { pages: [100] } }}
|
|
26
|
+
.fetchHandler=${async () => ({ total: records.length, records })}
|
|
27
|
+
></ox-grist>
|
|
28
|
+
`));
|
|
29
|
+
await el.fetch();
|
|
30
|
+
await settle();
|
|
31
|
+
await el.updateComplete;
|
|
32
|
+
const grist = el.renderRoot.querySelector('#grist');
|
|
33
|
+
const scroller = grist.renderRoot.querySelector('div[grid]');
|
|
34
|
+
const header = grist.renderRoot.querySelector('ox-grid-header');
|
|
35
|
+
const body = grist.renderRoot.querySelector('ox-grid-body');
|
|
36
|
+
await body.updateComplete;
|
|
37
|
+
return { grist, scroller, header, body };
|
|
38
|
+
}
|
|
39
|
+
/** The largest horizontal distance between a column's header cell and its cell in the first row. */
|
|
40
|
+
function misalignment(header, body) {
|
|
41
|
+
const heads = Array.from(header.renderRoot.querySelectorAll('[role=columnheader]'));
|
|
42
|
+
const row = body.renderRoot.querySelector('div[grid-row]');
|
|
43
|
+
const cells = Array.from(row.querySelectorAll('ox-grid-field'));
|
|
44
|
+
const n = Math.min(heads.length, cells.length);
|
|
45
|
+
let worst = 0;
|
|
46
|
+
for (let i = 0; i < n; i++) {
|
|
47
|
+
worst = Math.max(worst, Math.abs(heads[i].getBoundingClientRect().left - cells[i].getBoundingClientRect().left));
|
|
48
|
+
}
|
|
49
|
+
return { n, worst };
|
|
50
|
+
}
|
|
51
|
+
describe('grid header and body share one scroller', () => {
|
|
52
|
+
/* Resizing the grid body inside a fixture trips Chrome's benign "ResizeObserver loop" error. */
|
|
53
|
+
const ignoreResizeLoop = (e) => {
|
|
54
|
+
if (String(e.message).includes('ResizeObserver loop')) {
|
|
55
|
+
e.stopImmediatePropagation();
|
|
56
|
+
e.preventDefault();
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
let previousOnError = null;
|
|
60
|
+
before(() => {
|
|
61
|
+
window.addEventListener('error', ignoreResizeLoop, true);
|
|
62
|
+
previousOnError = window.onerror;
|
|
63
|
+
window.onerror = (message, ...rest) => String(message).includes('ResizeObserver loop') ? true : previousOnError === null || previousOnError === void 0 ? void 0 : previousOnError.call(window, message, ...rest);
|
|
64
|
+
});
|
|
65
|
+
after(() => {
|
|
66
|
+
window.removeEventListener('error', ignoreResizeLoop, true);
|
|
67
|
+
window.onerror = previousOnError;
|
|
68
|
+
});
|
|
69
|
+
it('neither the header nor the body scrolls on its own', async () => {
|
|
70
|
+
const { scroller, header, body } = await grid();
|
|
71
|
+
expect(scroller.scrollWidth, 'the grid must overflow, or this measures nothing').to.be.greaterThan(scroller.clientWidth);
|
|
72
|
+
expect(getComputedStyle(body).overflowX).to.equal('visible');
|
|
73
|
+
expect(getComputedStyle(header).overflowX).to.equal('visible');
|
|
74
|
+
expect(header.offsetWidth, 'header and body span the same width').to.equal(body.offsetWidth);
|
|
75
|
+
});
|
|
76
|
+
for (const where of ['start', 'middle', 'end']) {
|
|
77
|
+
it(`every column lines up with its header at the ${where}`, async () => {
|
|
78
|
+
const { scroller, header, body } = await grid();
|
|
79
|
+
const max = scroller.scrollWidth - scroller.clientWidth;
|
|
80
|
+
scroller.scrollLeft = where === 'start' ? 0 : where === 'middle' ? Math.round(max / 2) : max;
|
|
81
|
+
await settle(50);
|
|
82
|
+
const { n, worst } = misalignment(header, body);
|
|
83
|
+
expect(n, 'columns must be drawn, or this measures nothing').to.be.greaterThan(10);
|
|
84
|
+
expect(worst).to.equal(0);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
it('the header stays on top when the rows scroll', async () => {
|
|
88
|
+
const { scroller, header } = await grid();
|
|
89
|
+
scroller.scrollTop = 600;
|
|
90
|
+
await settle(50);
|
|
91
|
+
expect(scroller.scrollTop, 'the rows must scroll, or this measures nothing').to.be.greaterThan(0);
|
|
92
|
+
expect(header.getBoundingClientRect().top).to.equal(scroller.getBoundingClientRect().top);
|
|
93
|
+
});
|
|
94
|
+
it('a focused row that was under the header is brought out below it', async () => {
|
|
95
|
+
const { grist, scroller, header, body } = await grid();
|
|
96
|
+
scroller.scrollTop = 600;
|
|
97
|
+
await settle(50);
|
|
98
|
+
grist.focused = { row: 2, column: 3 };
|
|
99
|
+
await grist.updateComplete;
|
|
100
|
+
await body.updateComplete;
|
|
101
|
+
await settle(50);
|
|
102
|
+
const focused = body.renderRoot.querySelector('ox-grid-field[focused]');
|
|
103
|
+
expect(!!focused, 'a cell must take the focus').to.equal(true);
|
|
104
|
+
expect(focused.getBoundingClientRect().top).to.be.at.least(header.getBoundingClientRect().bottom - 1);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
//# sourceMappingURL=grid-single-scroller.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grid-single-scroller.test.js","sourceRoot":"","sources":["../../test/grid-single-scroller.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* Elements are compared by presence, not by value: a failing element comparison makes chai render the DOM and hang the runner. */\nimport { expect, fixture } from '@open-wc/testing'\nimport { html } from 'lit'\n\nimport '../src/data-grist.js'\n\n/**\n * Header and body move as one.\n *\n * The body used to be its own scroller, and the header a second scroller that copied the body's\n * scrollLeft from its scroll event (and the other way round). Three things went wrong:\n *\n * ```\n * gap the compositor moves the body at once; the header only moves after the main thread\n * handles the event, so on a busy screen it trails by several frames\n * shake the sync ran both ways, so a late header event put the body back one frame\n * the end when the two scroll widths differ, the header stops while the body goes on\n * ```\n *\n * Now the role=grid box is the only scroller. The header sticks to its top and the body does not\n * scroll. Nothing copies a position, so nothing can trail or pull back.\n */\n\ntype Root = HTMLElement & { renderRoot: ShadowRoot; updateComplete: Promise<unknown> }\n\nconst settle = (ms = 150) => new Promise(resolve => setTimeout(resolve, ms))\n\nasync function grid() {\n const columns: any[] = [\n { type: 'gutter', gutterName: 'sequence' },\n { type: 'string', name: 'id', hidden: true },\n { type: 'string', name: 'code', header: 'code', width: 120, fixed: true }\n ]\n for (let i = 0; i < 12; i++) {\n columns.push({ type: 'string', name: 'c' + i, header: 'col ' + i, width: 110 })\n }\n\n const records = Array.from({ length: 60 }, (_, r) => {\n const record: any = { id: String(r), code: 'C-' + r }\n for (let i = 0; i < 12; i++) record['c' + i] = `v${r}-${i}`\n return record\n })\n\n const el = (await fixture(html`\n <ox-grist\n style=\"width: 600px; height: 320px\"\n mode=\"GRID\"\n .config=${{ columns, pagination: { pages: [100] } }}\n .fetchHandler=${async () => ({ total: records.length, records })}\n ></ox-grist>\n `)) as Root & { fetch(): Promise<void> }\n\n await el.fetch()\n await settle()\n await el.updateComplete\n\n const grist = el.renderRoot.querySelector('#grist') as Root & { focused?: { row: number; column: number } }\n const scroller = grist.renderRoot.querySelector('div[grid]') as HTMLElement\n const header = grist.renderRoot.querySelector('ox-grid-header') as Root\n const body = grist.renderRoot.querySelector('ox-grid-body') as Root\n await body.updateComplete\n\n return { grist, scroller, header, body }\n}\n\n/** The largest horizontal distance between a column's header cell and its cell in the first row. */\nfunction misalignment(header: Root, body: Root) {\n const heads = Array.from(header.renderRoot.querySelectorAll('[role=columnheader]')) as HTMLElement[]\n const row = body.renderRoot.querySelector('div[grid-row]') as HTMLElement\n const cells = Array.from(row.querySelectorAll('ox-grid-field')) as HTMLElement[]\n const n = Math.min(heads.length, cells.length)\n\n let worst = 0\n for (let i = 0; i < n; i++) {\n worst = Math.max(worst, Math.abs(heads[i].getBoundingClientRect().left - cells[i].getBoundingClientRect().left))\n }\n return { n, worst }\n}\n\ndescribe('grid header and body share one scroller', () => {\n /* Resizing the grid body inside a fixture trips Chrome's benign \"ResizeObserver loop\" error. */\n const ignoreResizeLoop = (e: ErrorEvent) => {\n if (String(e.message).includes('ResizeObserver loop')) {\n e.stopImmediatePropagation()\n e.preventDefault()\n }\n }\n let previousOnError: OnErrorEventHandler = null\n before(() => {\n window.addEventListener('error', ignoreResizeLoop, true)\n previousOnError = window.onerror\n window.onerror = (message, ...rest) =>\n String(message).includes('ResizeObserver loop') ? true : previousOnError?.call(window, message, ...rest)\n })\n after(() => {\n window.removeEventListener('error', ignoreResizeLoop, true)\n window.onerror = previousOnError\n })\n\n it('neither the header nor the body scrolls on its own', async () => {\n const { scroller, header, body } = await grid()\n\n expect(scroller.scrollWidth, 'the grid must overflow, or this measures nothing').to.be.greaterThan(\n scroller.clientWidth\n )\n expect(getComputedStyle(body).overflowX).to.equal('visible')\n expect(getComputedStyle(header).overflowX).to.equal('visible')\n expect(header.offsetWidth, 'header and body span the same width').to.equal(body.offsetWidth)\n })\n\n for (const where of ['start', 'middle', 'end'] as const) {\n it(`every column lines up with its header at the ${where}`, async () => {\n const { scroller, header, body } = await grid()\n\n const max = scroller.scrollWidth - scroller.clientWidth\n scroller.scrollLeft = where === 'start' ? 0 : where === 'middle' ? Math.round(max / 2) : max\n await settle(50)\n\n const { n, worst } = misalignment(header, body)\n expect(n, 'columns must be drawn, or this measures nothing').to.be.greaterThan(10)\n expect(worst).to.equal(0)\n })\n }\n\n it('the header stays on top when the rows scroll', async () => {\n const { scroller, header } = await grid()\n\n scroller.scrollTop = 600\n await settle(50)\n\n expect(scroller.scrollTop, 'the rows must scroll, or this measures nothing').to.be.greaterThan(0)\n expect(header.getBoundingClientRect().top).to.equal(scroller.getBoundingClientRect().top)\n })\n\n it('a focused row that was under the header is brought out below it', async () => {\n const { grist, scroller, header, body } = await grid()\n\n scroller.scrollTop = 600\n await settle(50)\n\n grist.focused = { row: 2, column: 3 }\n await grist.updateComplete\n await body.updateComplete\n await settle(50)\n\n const focused = body.renderRoot.querySelector('ox-grid-field[focused]') as HTMLElement\n expect(!!focused, 'a cell must take the focus').to.equal(true)\n expect(focused.getBoundingClientRect().top).to.be.at.least(header.getBoundingClientRect().bottom - 1)\n })\n})\n"]}
|