packages/lit-dev-content/site/blog/2022-01-05-lit-2.1-release.md
Happy New Year from the Lit team! This week we're excited to share a few updates with our fantastic community in the form of the Lit 2.1 release and some Lit Labs updates.
Lit 2.1 consists of:
@queryAssignedElements decorator, related to the existing
@queryAssignedNodes decorator.Plus we have some Lit Labs updates to make your season bright:
@lit-labs/observers package provides reactive controllers for
working with web platform observers like MutationObserver and
ResizeObserver.@lit-labs/task package.@lit-labs/ssr package.For more details, read on.
Lit brings a handful of new convenience directives that make working with conditionals and looping a bit more declarative. Mostly wrappers around plain JavaScript expressions, we've found that many users appreciate the way these helpers reduce clutter in their templates.
Like all of the directives included with Lit, these new directives are pay-as-you-go: they're shipped as separate modules, so you only bundle the directives that you choose to import.
when(cond, t, f) is like a ternary where the else clause is optional. It
renders the first template if the condition is true, and the second if present
and the condition is false.
render() {
return html`
${when(this.user, () => html`User: ${this.user.username}`, () => html`Sign In...`)}
`;
}
map(iter, fn) is like Array.map, but also works on iterators. It's similar
to repeat() without the key function, but much smaller in code size.
render() {
return html`
<ul>
${map(this.items, (i) => html`<li>${i}</li>`)}
</ul>
`;
}
join(iter, t) interleaves items in an iterable with a joiner value or
function. Useful for adding separators between items, like Array.join() but
instead of returning a string returns an iterable of renderable values.
render() {
return html`
${join(this.items, html`<span class="separator">|</span>`)}
`;
}
range(start, end, step) is useful for iterating a specific number of times in
a template.
render() {
return html`
${map(range(8), () => html`<div class="cell"></div>`)}
`;
}
choose(v, cases, defaultCase) chooses one template to render among a set of
cases. It's like an inline switch statement.
render() {
return html`
${choose(this.section, [
['home', () => html`<h1>Home</h1>`],
['about', () => html`<h1>About</h1>`]
],
() => html`<h1>Error</h1>`)}
`;
}
@queryAssignedElements() returns the slotted or assigned elements for a given
slot. It's similar to the existing @queryAssignedNodes() but uses the
slot.assignedElements() method rather than slot.assignedNodes().
@queryAssignedNodes() has been updated to take an options object as an
alternative to the positional argument API.
@queryAssignedElements({ slot: 'icon' })
private _icon!: Array<HTMLElement>;
In Lit Labs we've introduced a new package called @lit-labs/observers which
contains reactive controllers that let you easily use the web platform observer
APIs: MutationObserver, IntersectionObserver, ResizeObserver, and
PerformanceObserver. The controllers automatically drive the host element's
update lifecycle when they observe changes.
import { ResizeController } from '@lit-labs/observers/resize_controller.js';
class MyResizableElement extends LitElement {
_resizeController = new ResizeController(this, {});
render() {
return html`Current size is ${this.offsetWidth} x ${this.offsetHeight}`;
}
}
We've landed some changes to @lit-labs/task that allow for manually run tasks
and automatic tasks with no dependencies. Tasks with no dependencies will run
once when the host is connected, and all tasks can be run manually with the new
run() method.
We've also landed some bug fixes to @lit-labs/ssr, reduced its NPM
dependencies footprint, and refactored the importModule function into a new
ImportModule class as some groundwork for upcoming changes.
We hope your 2022 is off to a good start. If you've tried the new releases, we'd love to hear from you. For questions and discussions, please join us on Discord or on GitHub Discussions. As always you can check out our documentation and code playground at lit.dev and report issues on our GitHub issue tracker.