diff --git a/.changeset/shiny-eyes-follow.md b/.changeset/shiny-eyes-follow.md new file mode 100644 index 0000000000..2c7dab0fa3 --- /dev/null +++ b/.changeset/shiny-eyes-follow.md @@ -0,0 +1,9 @@ +--- +"@lynx-js/web-elements": patch +--- + +fix: x-list should observe property list-type change. + +Before this commit, list-type only works when it was first assigned. + +use `requestAnimationFrame` instead of `queueMicrotask` to layoutListItem, this is because it may cause crashes in webkit. diff --git a/packages/web-platform/web-elements/src/XList/XListAttributes.ts b/packages/web-platform/web-elements/src/XList/XListAttributes.ts index f299520e0f..8d91ce96f5 100644 --- a/packages/web-platform/web-elements/src/XList/XListAttributes.ts +++ b/packages/web-platform/web-elements/src/XList/XListAttributes.ts @@ -11,8 +11,6 @@ import { } from '@lynx-js/web-elements-reactive'; import type { XList } from './XList.js'; -const WATERFALL_SLOT = 'waterfall-slot'; - export class XListAttributes implements InstanceType> { diff --git a/packages/web-platform/web-elements/src/XList/XListWaterfall.ts b/packages/web-platform/web-elements/src/XList/XListWaterfall.ts index fd9a55fdc3..7eb40a131e 100644 --- a/packages/web-platform/web-elements/src/XList/XListWaterfall.ts +++ b/packages/web-platform/web-elements/src/XList/XListWaterfall.ts @@ -4,8 +4,8 @@ // LICENSE file in the root directory of this source tree. */ import { - boostedQueueMicrotask, genDomGetter, + registerAttributeHandler, type AttributeReactiveClass, } from '@lynx-js/web-elements-reactive'; import type { XList } from './XList.js'; @@ -16,7 +16,7 @@ const WATERFALL_STYLE = 'waterfall-style'; export class XListWaterfall implements InstanceType> { - static observedAttributes = []; + static observedAttributes = ['list-type']; #dom: XList; #getListContainer = genDomGetter(() => this.#dom.shadowRoot!, '#content'); @@ -182,7 +182,7 @@ export class XListWaterfall this.#resizeObserver = new ResizeObserver(() => { // may cause: Resizeobserver loop completed with undelivered notifications // https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver#observation_errors - boostedQueueMicrotask(() => { + requestAnimationFrame(() => { this.#layoutListItem( spanCount, isScrollVertical, @@ -194,8 +194,9 @@ export class XListWaterfall }); }; - connectedCallback() { - if (this.#dom.getAttribute('list-type') === 'waterfall') { + @registerAttributeHandler('list-type', true) + #handlerListType(newVal: string | null) { + if (newVal === 'waterfall') { const spanCount = parseFloat( this.#dom.getAttribute('span-count') || this.#dom.getAttribute('column-count') @@ -227,6 +228,17 @@ export class XListWaterfall childList: true, }); } + } else { + this.#resizeObserver?.disconnect(); + this.#resizeObserver = undefined; + this.#childrenObserver?.disconnect(); + this.#childrenObserver = undefined; + for (let i = 0; i < this.#dom.children.length; i++) { + const listItem = this.#dom.children[i] as HTMLElement; + listItem.removeAttribute('slot'); + } + this.#dom.shadowRoot?.querySelector(`slot[name=${WATERFALL_SLOT}]`) + ?.remove(); } } } diff --git a/packages/web-platform/web-elements/src/XList/x-list.css b/packages/web-platform/web-elements/src/XList/x-list.css index fab0e4241f..65efa7d210 100644 --- a/packages/web-platform/web-elements/src/XList/x-list.css +++ b/packages/web-platform/web-elements/src/XList/x-list.css @@ -59,6 +59,7 @@ list-item { display: none; content-visibility: auto; flex: 0 0 auto !important; + position: static; } x-list > list-item, x-list > lynx-wrapper > list-item { diff --git a/packages/web-platform/web-tests/tests/web-elements.spec.ts b/packages/web-platform/web-tests/tests/web-elements.spec.ts index 324d876fb5..6f4a974226 100644 --- a/packages/web-platform/web-tests/tests/web-elements.spec.ts +++ b/packages/web-platform/web-tests/tests/web-elements.spec.ts @@ -2351,6 +2351,34 @@ test.describe('web-elements test suite', () => { await gotoWebComponentPage(page, title); await diffScreenShot(page, title, 'index'); }); + test('list-type-change', async ({ page }) => { + await gotoWebComponentPage(page, 'x-list/basic-waterfall'); + await diffScreenShot(page, 'x-list/list-type-change', 'index'); + await page.evaluate(() => { + document.querySelector('x-list')?.setAttribute( + 'list-type', + 'single', + ); + }); + await wait(100); + await diffScreenShot(page, 'x-list/list-type-change', 'single'); + await page.evaluate(() => { + document.querySelector('x-list')?.setAttribute( + 'list-type', + 'flow', + ); + }); + await wait(100); + await diffScreenShot(page, 'x-list/list-type-change', 'flow'); + await page.evaluate(() => { + document.querySelector('x-list')?.setAttribute( + 'list-type', + 'waterfall', + ); + }); + await wait(100); + await diffScreenShot(page, 'x-list/list-type-change', 'waterfall'); + }); }); test.describe('x-input', () => { test('placeholder', async ({ page }, { titlePath }) => { diff --git a/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/flow-chromium-linux.png b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/flow-chromium-linux.png new file mode 100644 index 0000000000..6c2d74d597 Binary files /dev/null and b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/flow-chromium-linux.png differ diff --git a/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/flow-firefox-linux.png b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/flow-firefox-linux.png new file mode 100644 index 0000000000..a634455b5b Binary files /dev/null and b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/flow-firefox-linux.png differ diff --git a/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/flow-webkit-linux.png b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/flow-webkit-linux.png new file mode 100644 index 0000000000..7dcd188916 Binary files /dev/null and b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/flow-webkit-linux.png differ diff --git a/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/index-chromium-linux.png b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/index-chromium-linux.png new file mode 100644 index 0000000000..ab63e8db70 Binary files /dev/null and b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/index-chromium-linux.png differ diff --git a/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/index-firefox-linux.png b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/index-firefox-linux.png new file mode 100644 index 0000000000..4bfd42f94a Binary files /dev/null and b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/index-firefox-linux.png differ diff --git a/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/index-webkit-linux.png b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/index-webkit-linux.png new file mode 100644 index 0000000000..6f0f59cb36 Binary files /dev/null and b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/index-webkit-linux.png differ diff --git a/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/single-chromium-linux.png b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/single-chromium-linux.png new file mode 100644 index 0000000000..5f5adddcf2 Binary files /dev/null and b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/single-chromium-linux.png differ diff --git a/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/single-firefox-linux.png b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/single-firefox-linux.png new file mode 100644 index 0000000000..5948552a04 Binary files /dev/null and b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/single-firefox-linux.png differ diff --git a/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/single-webkit-linux.png b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/single-webkit-linux.png new file mode 100644 index 0000000000..b6d01b1f97 Binary files /dev/null and b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/single-webkit-linux.png differ diff --git a/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/waterfall-chromium-linux.png b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/waterfall-chromium-linux.png new file mode 100644 index 0000000000..ab63e8db70 Binary files /dev/null and b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/waterfall-chromium-linux.png differ diff --git a/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/waterfall-firefox-linux.png b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/waterfall-firefox-linux.png new file mode 100644 index 0000000000..4bfd42f94a Binary files /dev/null and b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/waterfall-firefox-linux.png differ diff --git a/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/waterfall-webkit-linux.png b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/waterfall-webkit-linux.png new file mode 100644 index 0000000000..6f0f59cb36 Binary files /dev/null and b/packages/web-platform/web-tests/tests/web-elements.spec.ts-snapshots/x-list/list-type-change/waterfall-webkit-linux.png differ