docs: resolve Vue-vs-React semantics placeholder (all 3 are idioms, not divergences) (#76)

The placeholder listed three candidates to evaluate as by-design divergences:
v-if/null comment host nodes, reactivity-driven re-render timing, and keyed
reconciliation order. Grounding each in the runtime code shows all three produce
byte-identical terminal output vs Ink — a commit always paints f(current host
tree), so *how* the tree was built never reaches the terminal. None is a
divergence, so the placeholder is removed and the three are recorded as concise
one-liners under "Framework idioms (noted, not behavioral divergences)":

- v-if=false / null|false|undefined children become an inert Comment vnode
  (TuiComment) — no yoga node, paints nothing, doesn't shift a sibling's yoga
  index, skipped for the positional <Transform> index (G52); output equals
  omitting the element.
- Commit timing is deliberately Ink-aligned (~32ms ceil(1000/maxFps) throttle,
  sync resize), so Vue's fine-grained re-render granularity stays unobservable.
- Keyed lists use Vue core's patchKeyedChildren, not React's fiber diff; output
  depends on the final tree, not the move order.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yunfei He
2026-05-31 00:28:31 +08:00
committed by GitHub
parent 369442d4b2
commit cc44098a84
+14 -6
View File
@@ -98,12 +98,6 @@ deliberate. Divergences fall into a few kinds:
Keeping a previous render's value, as Ink does for these two props, is the anomaly — and an
inconsistent one, since every other flex prop resets. Maintainer decision (2026-05-30): KEEP.
### Other Vue-vs-React semantics _(placeholder)_
- _(maintainer: candidates to document — `v-if`/`null` rendering as comment host nodes;
reactivity-driven re-render timing vs React's render cycle; keyed reconciliation order.
Add the ones that are genuinely by-design.)_
## Not applicable in Vue
### React concurrent mode
@@ -120,6 +114,20 @@ Surface conventions, listed so they aren't mistaken for gaps:
- kebab-case filenames; `.ts` over `.tsx` where there's no JSX.
- `shallowRef` by default for reactive state.
Reconciler/runtime mechanics that differ from React internally yet produce **byte-identical**
terminal output, because a commit always paints `f(current host tree)` — _how_ the tree was
built never reaches the terminal:
- **A `v-if=false` branch (or a `null`/`false`/`undefined` child) leaves a comment anchor
(`TuiComment`)** where Ink emits no node, but it is inert: no yoga node, paints nothing,
never shifts a sibling's yoga index, and is skipped for the positional `<Transform>` index
in all three squash paths (`G52`). Output equals omitting the element.
- **Commit timing is deliberately Ink-aligned** — leading+trailing throttle at
`ceil(1000/maxFps)` ≈ 32 ms (Ink's `renderThrottleMs`), synchronous resize — even though
re-renders are Vue's fine-grained reactivity, not a React subtree re-render.
- **Keyed lists use Vue core's `patchKeyedChildren`** (LIS), not React's fiber diff; output
depends on the final tree, not the move order.
---
## Maintainer additions