-
Notifications
You must be signed in to change notification settings - Fork 879
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[labs/virtualizer] RangeChangedEvent and VisibilityChangedEvent no longer bubble up #3609
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@lit-labs/virtualizer': minor | ||
--- | ||
|
||
RangeChangedEvent and VisibilityChangedEvent both no longer bubble up. Listeners for these events must be placed on the lit-virtualizer or virtualize directive's host element. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,15 +7,17 @@ | |
import {array, ignoreBenignErrors, until} from '../helpers.js'; | ||
import {LitVirtualizer} from '../../lit-virtualizer.js'; | ||
import {virtualize} from '../../virtualize.js'; | ||
import {RangeChangedEvent, VisibilityChangedEvent} from '../../events.js'; | ||
import {css, LitElement} from 'lit'; | ||
import {customElement, property} from 'lit/decorators.js'; | ||
import {expect, html, fixture} from '@open-wc/testing'; | ||
|
||
abstract class TestElement extends LitElement { | ||
static styles = css` | ||
:host { | ||
display: block; | ||
height: 200px; | ||
.item { | ||
height: 50px; | ||
margin: 0; | ||
padding: 0; | ||
} | ||
`; | ||
|
||
|
@@ -24,29 +26,52 @@ abstract class TestElement extends LitElement { | |
|
||
@property({type: Array, attribute: false}) | ||
public items: Array<number> = []; | ||
|
||
@property({type: Array, attribute: false}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
public rangeChangedEvents: RangeChangedEvent[] = []; | ||
|
||
@property({type: Array, attribute: false}) | ||
public visibilityChangedEvents: VisibilityChangedEvent[] = []; | ||
|
||
recordRangeChangedEvent(event: RangeChangedEvent) { | ||
this.rangeChangedEvents.push(event); | ||
} | ||
|
||
recordVisibilityChangedEvent(event: VisibilityChangedEvent) { | ||
this.visibilityChangedEvents.push(event); | ||
} | ||
} | ||
|
||
@customElement('using-lit-virtualizer') | ||
class UsingLitVirtualizer extends TestElement { | ||
render() { | ||
return html` <lit-virtualizer | ||
@rangeChanged=${this.recordRangeChangedEvent} | ||
@visibilityChanged=${this.recordVisibilityChangedEvent} | ||
scroller | ||
.items=${this.items} | ||
.renderItem=${(n: number) => | ||
html`<div>${n}${this.selected.has(n) ? ' selected' : ''}</div>`} | ||
html`<div class="item"> | ||
[${n}${this.selected.has(n) ? ' selected' : ''}] | ||
</div>`} | ||
></lit-virtualizer>`; | ||
} | ||
} | ||
|
||
@customElement('using-virtualize-directive') | ||
class UsingVirtualizeDirective extends TestElement { | ||
render() { | ||
return html` <div> | ||
return html` <div | ||
@rangeChanged=${this.recordRangeChangedEvent} | ||
@visibilityChanged=${this.recordVisibilityChangedEvent} | ||
> | ||
${virtualize({ | ||
scroller: true, | ||
items: this.items, | ||
renderItem: (n) => | ||
html`<div>${n}${this.selected.has(n) ? ' selected' : ''}</div>`, | ||
html`<div class="item"> | ||
[${n}${this.selected.has(n) ? ' selected' : ''}] | ||
</div>`, | ||
})} | ||
</div>`; | ||
} | ||
|
@@ -81,6 +106,14 @@ describe('lit-virtualizer and virtualize directive', () => { | |
<using-lit-virtualizer></using-lit-virtualizer> | ||
<using-virtualize-directive></using-virtualize-directive> | ||
</div> | ||
<style> | ||
using-lit-virtualizer { | ||
height: 500px; | ||
} | ||
using-virtualize-directive { | ||
height: 500px; | ||
} | ||
</style> | ||
`); | ||
await until( | ||
() => | ||
|
@@ -96,45 +129,67 @@ describe('lit-virtualizer and virtualize directive', () => { | |
const ulv: UsingLitVirtualizer = example.querySelector( | ||
'using-lit-virtualizer' | ||
)!; | ||
const uvd: UsingVirtualizeDirective = example.querySelector( | ||
'using-virtualize-directive' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For my edification, do you know why we need to wait for these elements first with the I'm asking because the test is so long that any reduction in boilerplate will help new people read it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah this was how I was watching for upgrades from the outside. I didn't want to select the element until after the upgrade occurred, but I'll see if I can either eliminate the need for those, write a helper, or comment why it's necessary to explicitly await the upgrades for the elements when I do test clean ups in #2788 |
||
)!; | ||
|
||
ulv.items = [...items]; | ||
uvd.items = [...items]; | ||
|
||
ulv.items = items; | ||
ulv.selected = selected; | ||
uvd.selected = selected; | ||
|
||
await until(() => ulv.shadowRoot?.textContent?.includes('2 selected')); | ||
await until(() => ulv.shadowRoot?.textContent?.includes('[5 selected]')); | ||
await until(() => uvd.shadowRoot?.textContent?.includes('[5 selected]')); | ||
|
||
expect(ulv.shadowRoot?.textContent).to.include('2 selected'); | ||
expect(ulv.shadowRoot?.textContent).to.include('5 selected'); | ||
expect(ulv.shadowRoot?.textContent).to.include('[2 selected]'); | ||
expect(uvd.shadowRoot?.textContent).to.include('[2 selected]'); | ||
|
||
const uvd: UsingVirtualizeDirective = example.querySelector( | ||
'using-virtualize-directive' | ||
)!; | ||
expect(ulv.shadowRoot?.textContent).to.include('[5 selected]'); | ||
expect(uvd.shadowRoot?.textContent).to.include('[5 selected]'); | ||
|
||
uvd.items = items; | ||
uvd.selected = selected; | ||
// Changing selection doesn't trigger visibility changed or range changed events. | ||
ulv.selected = new Set([1, 3]); | ||
uvd.selected = new Set([1, 3]); | ||
|
||
await until(() => ulv.shadowRoot?.textContent?.includes('[3 selected]')); | ||
await until(() => uvd.shadowRoot?.textContent?.includes('[3 selected]')); | ||
|
||
expect(ulv.shadowRoot?.textContent).to.include('[1 selected]'); | ||
expect(uvd.shadowRoot?.textContent).to.include('[1 selected]'); | ||
|
||
await until(() => uvd.shadowRoot?.textContent?.includes('2 selected')); | ||
expect(ulv.shadowRoot?.textContent).to.include('[3 selected]'); | ||
expect(uvd.shadowRoot?.textContent).to.include('[3 selected]'); | ||
|
||
expect(uvd.shadowRoot?.textContent).to.include('2 selected'); | ||
expect(uvd.shadowRoot?.textContent).to.include('5 selected'); | ||
expect(ulv.shadowRoot?.textContent).not.to.include('[2 selected]'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe not now, but since the test is so long, it'd be great to see some comments break it up and describe the scenario, what the setup is doing, what the interaction is, expectations are checking, etc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair points. I'll add this when I do some overall test sprucing up in #2788 |
||
expect(uvd.shadowRoot?.textContent).not.to.include('[2 selected]'); | ||
|
||
const newSelected = new Set([1, 3]); | ||
expect(ulv.shadowRoot?.textContent).not.to.include('[5 selected]'); | ||
expect(uvd.shadowRoot?.textContent).not.to.include('[5 selected]'); | ||
|
||
ulv.selected = newSelected; | ||
// Clearing event arrays so we can watch for specific future events. | ||
ulv.rangeChangedEvents.splice(0); | ||
uvd.rangeChangedEvents.splice(0); | ||
ulv.visibilityChangedEvents.splice(0); | ||
uvd.visibilityChangedEvents.splice(0); | ||
|
||
await until(() => ulv.shadowRoot?.textContent?.includes('1 selected')); | ||
// Adding an item to the start of the list to trigger rangechanged and | ||
// visibilitychanged events. | ||
ulv.items = [-1, ...items]; | ||
uvd.items = [-1, ...items]; | ||
|
||
expect(ulv.shadowRoot?.textContent).to.include('1 selected'); | ||
expect(ulv.shadowRoot?.textContent).to.include('3 selected'); | ||
expect(ulv.shadowRoot?.textContent).not.to.include('2 selected'); | ||
expect(ulv.shadowRoot?.textContent).not.to.include('5 selected'); | ||
await until(() => ulv.shadowRoot?.textContent?.includes('[-1]')); | ||
await until(() => uvd.shadowRoot?.textContent?.includes('[-1]')); | ||
|
||
uvd.selected = newSelected; | ||
await until(() => ulv.rangeChangedEvents.length > 0); | ||
await until(() => uvd.rangeChangedEvents.length > 0); | ||
|
||
await until(() => uvd.shadowRoot?.textContent?.includes('1 selected')); | ||
expect(ulv.rangeChangedEvents.length).to.equal(1); | ||
expect(uvd.rangeChangedEvents.length).to.equal(1); | ||
|
||
expect(uvd.shadowRoot?.textContent).to.include('1 selected'); | ||
expect(uvd.shadowRoot?.textContent).to.include('3 selected'); | ||
expect(uvd.shadowRoot?.textContent).not.to.include('2 selected'); | ||
expect(uvd.shadowRoot?.textContent).not.to.include('5 selected'); | ||
// The indexes of visible items have not changed even though new item was | ||
// added to head of the array. So no visibilitychanged events are expected. | ||
expect(ulv.visibilityChangedEvents.length).to.equal(0); | ||
expect(uvd.visibilityChangedEvents.length).to.equal(0); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not for this PR, but can we get code comments on the event class and on
first
andlast
to document to users and maintainers what they're for? It can just be what's in the readme here: https://github.com/lit/lit/tree/main/packages/labs/virtualizer#visibilitychanged-event