|
| 1 | +# UI component model |
| 2 | + |
| 3 | +Authors: Gordon Brander |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +Context: converge on a default UI component model for LLM-generated UI. |
| 8 | + |
| 9 | +## Goals |
| 10 | + |
| 11 | +Product goals: |
| 12 | + |
| 13 | +- Easy for LLMs to generate |
| 14 | +- Easy for humans to edit |
| 15 | +- Leverages familiar or established patterns for UI development |
| 16 | +- Conformable with existing web FE toolchains. |
| 17 | + |
| 18 | +Technical goals: |
| 19 | + |
| 20 | +- Components are encapsulated |
| 21 | + - A component may control its child tree, but not its siblings or parent |
| 22 | + - Components are black boxes, with inputs and outputs |
| 23 | +- Components have inputs, and output UI and events |
| 24 | + - Are pure-ish functions of state (we may allow cheats for local component state ala hooks) |
| 25 | +- Components have statically-typed inputs and outputs |
| 26 | + - E.g. via TypeScript |
| 27 | + - Allows the runtime to enforce data policies on component |
| 28 | +- Components have local state |
| 29 | + - State is encapsulated within component |
| 30 | + - Components may pass state down to child components as input |
| 31 | + - E.g. the React “[lifting state up](https://legacy.reactjs.org/docs/lifting-state-up.html)” pattern. |
| 32 | + - Local state may be persisted. If it isn’t, it is ephemeral, and lasts for the lifetime of the component. |
| 33 | +- Components are composable |
| 34 | + - Components can be combined together like lego to create larger components |
| 35 | + - Composition should involve plugging together component inputs, outputs, and events, and arranging UI tree. It shouldn’t be more complicated than that. |
| 36 | +- Components can have “holes”, allowing you to slot in an arbitrary component of the right shape. |
| 37 | + - Inversion of control for templates. |
| 38 | + - The shape of the hole is determined by the data input and output types |
| 39 | + - Example mechanisms: [slots](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots), [passing down closures that evaluate to components](https://swiftwithmajid.com/2019/11/06/the-power-of-closures-in-swiftui/), [overridable blocks](https://mustache.github.io/mustache.5.html#Blocks), etc. |
| 40 | +- Components have [high locality of behavior](https://github.com/gordonbrander/generative-ui-playbook?tab=readme-ov-file#llms-work-best-with-high-locality) |
| 41 | +- Components are islands |
| 42 | + - Components can be used free-standing, or within a larger component tree. |
| 43 | + - Note: in something like the Elm App Architecture Pattern, Models, Views, and Update functions are “zippered” together, meaning components are “some assembly required”. This would fall short of this goal without some additional means of making an individual component free-standing. |
| 44 | +- UI templates are pure |
| 45 | + - They take inputs, and output a UI tree and events |
| 46 | + - They produce a UI tree that is easy for the runtime to analyze and sanitize (probably a VDOM, probably not raw DOM). |
| 47 | +- Components can be rendered on the web platform |
| 48 | + |
| 49 | +Soft goals: |
| 50 | +- Static templates |
| 51 | + |
| 52 | +Non-goals: |
| 53 | + |
| 54 | +- Separation of concerns. At odds with high locality of behavior. |
| 55 | + |
| 56 | +Non-goals: |
| 57 | + |
| 58 | +- |
| 59 | + |
| 60 | +## Open questions |
| 61 | + |
| 62 | +## Prior art |
| 63 | + |
| 64 | +- [Svelt Runes](https://svelte.dev/blog/runes) |
| 65 | +- [Vue templates](https://vuejs.org/examples/#hello-world) |
| 66 | +- [Mustache](https://mustache.github.io/mustache.5.html) |
| 67 | +- [WICG Template Instantiation Proposal](https://github.com/WICG/webcomponents/blob/gh-pages/proposals/Template-Instantiation.md) |
| 68 | + - [Template Instantiation Proposal on CSS Tricks](https://css-tricks.com/apples-proposal-html-template-instantiation/) |
| 69 | +- [WICG DOM Parts Proposal](https://github.com/WICG/webcomponents/blob/gh-pages/proposals/DOM-Parts.md) |
0 commit comments