a2ui-project / a2ui-project/a2ui

[spec] children are unkeyed, making it impossible to move children correctly

Aperta
#1,745 5 commenti 0 reazioni 1 assegnatario Assegnata a @gspencergoog Vedi su GitHub
component: specification P1 type: feature/enhancement
Lingua principale
TypeScript
Stelle
16.4k
Fork
1.3k
Merge medio
2g 13h
PR unite (30g)
134

Descrizione

## Problem

Consider this example from https://a2ui.org/specification/v0.9.1-a2ui/#collection-scopes-relative-paths:

Data model:

```
{
"company": "Acme Corp",
"employees": [
{"name": "Alice", "role": "Engineer"},
{"name": "Bob", "role": "Designer"}
]
}
```

Component definition:

```
{
"id": "employee_list",
"component": "List",
"children": {
"path": "/employees",
"componentId": "employee_card_template"
}
},
{
"id": "employee_card_template",
"component": "Column",
"children": ["name_text", "company_text"]
},
{
"id": "name_text",
"component": "Text",
"text": { "path": "name" }
},
{
"id": "company_text",
"component": "Text",
"text": { "path": "/company" }
}
```

A list of employees is renderer using the "employee_card_template" template component. On the first render everything is correct. However, consider a data update that swaps Alice and Bob:

```
{
"company": "Acme Corp",
"employees": [
{"name": "Bob", "role": "Designer"}
{"name": "Alice", "role": "Engineer"},
]
}
```

Because `List` children are unkeyed by anything, the data for "Bob" will flow into the card that used to render "Alice" and vice versa. This may produce correct visual result in basic (e.g. read-only) cases. However, this breaks in the following situations:

* If a screen reader focus is focused on Bob, instead of the focus moving with the widget to its new location, the data underneath the screen reader focus will unexpectedly be replaced with Alice. There will also be no screen reader notification to the user about the order change.
* If the user made a selection (e.g. on the web), that selection will be lost.
* If employee cards are editable the editing state may get corrupted, or simply confuse the user.
* If employee card widgets are stateful, their state will not move to a new location in the list, but instead will receive data for a wrong employee, which could violate some business rules.

## Proposal

The data optionally supplies an identifier:

```
{
"company": "Acme Corp",
"employees": [
{"id": "123", "name": "Bob", "role": "Designer"}
{"id": "234", "name": "Alice", "role": "Engineer"},
]
}
```

The list provides the property name that should be used as the child key, and the runtime applies it to every child widget:

```
{
"id": "employee_list",
"component": "List",
"children": {
"path": "/employees",
"componentId": "employee_card_template",
"key": "id" // NEW!
}
}
```

Now that widgets are keyes, the respective UI framework can move the widgets around preserving their state.

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Look at the List component implementation and how it handles children. The spec change involves adding a 'key' property to the children mapping. Examine the runtime's widget creation and update logic to understand where keys need to be applied. Check existing tests for list rendering to see how to add tests for keyed children.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
typescript
Ambito
frontend
Tipo di issue
Funzionalità
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Attiva
Chiarezza
Specificata chiaramente
Idoneità per principianti
45/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.