-
Notifications
You must be signed in to change notification settings - Fork 939
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[lit-html] Add keyed directive (#2337)
- Loading branch information
1 parent
d319cf5
commit fcc2b3d
Showing
8 changed files
with
110 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
'lit': minor | ||
'lit-html': minor | ||
--- | ||
|
||
Add a `keyed(key, value)` directive that clears a part if the key changes. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import {nothing} from '../lit-html.js'; | ||
import { | ||
directive, | ||
Directive, | ||
ChildPart, | ||
DirectiveParameters, | ||
} from '../directive.js'; | ||
import {setCommittedValue} from '../directive-helpers.js'; | ||
|
||
class Keyed extends Directive { | ||
key: unknown = nothing; | ||
|
||
render(k: unknown, v: unknown) { | ||
this.key = k; | ||
return v; | ||
} | ||
|
||
override update(part: ChildPart, [k, v]: DirectiveParameters<this>) { | ||
if (k !== this.key) { | ||
// Clear the part before returning a value. The one-arg form of | ||
// setCommittedValue sets the value to a sentinel which forces a | ||
// commit the next render. | ||
setCommittedValue(part); | ||
this.key = k; | ||
} | ||
return v; | ||
} | ||
} | ||
|
||
/** | ||
* Associates a renderable value with a unique key. When the key changes, the | ||
* previous DOM is removed and disposed before rendering the next value, even | ||
* if the value - such as a template - is the same. | ||
* | ||
* This is useful for forcing re-renders of stateful components, or working | ||
* with code that expects new data to generate new HTML elements, such as some | ||
* animation techniques. | ||
*/ | ||
export const keyed = directive(Keyed); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/** | ||
* @license | ||
* Copyright 2021 Google LLC | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
|
||
import {keyed} from '../../directives/keyed.js'; | ||
import {html, render} from '../../lit-html.js'; | ||
import {stripExpressionMarkers} from '../test-utils/strip-markers.js'; | ||
import {assert} from '@esm-bundle/chai'; | ||
|
||
suite('keyed directive', () => { | ||
let container: HTMLDivElement; | ||
|
||
setup(() => { | ||
container = document.createElement('div'); | ||
}); | ||
|
||
test('re-renders when the key changes', () => { | ||
const go = (k: any) => | ||
render(keyed(k, html`<div .foo=${k}></div>`), container); | ||
|
||
// Initial render | ||
go(1); | ||
const div = container.firstElementChild; | ||
assert.equal(stripExpressionMarkers(container.innerHTML), '<div></div>'); | ||
assert.equal((div as any).foo, 1); | ||
|
||
// Rerendering with same key should reuse the DOM | ||
go(1); | ||
const div2 = container.firstElementChild; | ||
assert.equal(stripExpressionMarkers(container.innerHTML), '<div></div>'); | ||
assert.equal((div2 as any).foo, 1); | ||
assert.strictEqual(div, div2); | ||
|
||
// Rerendering with a different key should not reuse the DOM | ||
go(2); | ||
const div3 = container.firstElementChild; | ||
assert.equal(stripExpressionMarkers(container.innerHTML), '<div></div>'); | ||
assert.equal((div3 as any).foo, 2); | ||
assert.notStrictEqual(div, div3); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/** | ||
* @license | ||
* Copyright 2021 Google LLC | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
|
||
export * from 'lit-html/directives/keyed.js'; |