From 29ec4b03e6e414508170b272a0a22601d65f5181 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Tue, 14 Nov 2023 15:40:30 -0800 Subject: [PATCH 1/7] RFC: List rendering reform --- text/0000-list-rendering-reform.md | 258 +++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 text/0000-list-rendering-reform.md diff --git a/text/0000-list-rendering-reform.md b/text/0000-list-rendering-reform.md new file mode 100644 index 00000000..580a32fe --- /dev/null +++ b/text/0000-list-rendering-reform.md @@ -0,0 +1,258 @@ +--- +title: List rendering reform +status: DRAFTED +created_at: 2023-11-14 +updated_at: 2023-11-14 +pr: (leave this empty until the PR is created) +--- + +# List rendering reform + +## Summary + +This RFC proposes a new template directive, `lwc:each`, which resolves issues and provides enhancements compared to the existing `for:each` and `iterator:*` directives. + +## Basic example + +```html + +``` + +## Motivation + +This proposal supersedes the existing [`for:each`](https://lwc.dev/guide/html_templates#for%3Aeach) and [`iterator:*`](https://lwc.dev/guide/html_templates#iterator) directives and resolves several issues with them: + +- We have two directives for lists instead of one, with different features available on each. The new directive unifies them. +- The existing directives do not use the `lwc:` prefix, unlike every other modern LWC directive. Using `lwc:` makes it clear which attributes are LWC-specific, and would allow for improvements in the future such as [shorthands](https://github.com/salesforce/lwc/issues/3303) (out of scope for this RFC). +- The key should be defined on the list root element, not on each element inside the list. The current behavior requires tediously repeating the `key` for each element inside the list, and also leads to [inconsistent behavior](https://github.com/salesforce/lwc/issues/3860) for text/comment nodes. +- There is no way to easily render based on even vs odd list items. + +### Prior art + +- [Vue `v-for`](https://vuejs.org/guide/essentials/list.html) +- [Svelte `{#each}`](https://svelte.dev/docs/logic-blocks#each) +- [Angular `*ngFor`](https://angular.io/api/common/NgForOf#local-variables) +- [Solid ``](https://docs.solidjs.com/references/api-reference/control-flow/For) +- [Lit `repeat`](https://lit.dev/docs/templates/lists/#the-repeat-directive) + +## Detailed design + +The design of `lwc:each` is almost identical to that of `for:each`. There are only a few modifications. + +First, all directives are prefixed with `lwc:`: + +- `for:each` → `lwc:each` +- `for:item` → `lwc:item` +- `key` → `lwc:key` +- `for:index` → `lwc:index` + +Second, the `lwc:key` must be declared on the iterator root, not on each item within the loop: + +```html + +``` + +Third, four new convenience directives are added: + +- `lwc:first` - boolean that is `true` if the item is first in the list +- `lwc:last` - boolean that is `true` if the item is last in the list +- `lwc:even` - boolean that is `true` if the item index is even +- `lwc:odd` - boolean that is `true` if the item index is odd + +Each directive will be detailed separately. + +### `lwc:each` + +This functions nearly identically to `for:each`. (That's kind of the point – it should not be difficult for component authors to migrate.) Like `for:each`, it is supported in both the `