refactor(runtime)!: prefix host primitive tags with tui- (align to Ink, drop *Impl)
The renderer's intrinsic elements were named with bare words (box/text/static/
transform/virtual-text), which collide with the same-named public components: a
template `<box>` PascalCase-resolves to `<Box>` under vue-tsc (no isCustomElement
at the type layer), forcing the BoxImpl/TextImpl/StaticImpl workaround.
Prefix the 5 host elements to `tui-*` (mirroring Ink's `ink-box`/`ink-text`):
the prefix + hyphen keeps them in their own namespace, so the components keep
their real names (Box/Text/Static) with no self-recursion — the *Impl rename is
removed. root/text-leaf/comment stay unprefixed (not template tags, not elements).
Mechanics: renamed the TuiNode discriminant literals + factories first, then let
vue-tsc enumerate all 145 stale `node.type === "box"` comparisons (the type-
driven finder also kept `position: "static"` and the ansi-tokenizer's separate
`type: "text"` union untouched). Updated createElement cases, HOST_TAGS,
the .vue templates, transform.ts h(), and raw `h("box")` host-op tests.
Two non-type-checked contaminations the sed caused were caught by tests and fixed:
- patchProp's `key === "transform"` (the PROP name, not the node type) must stay
"transform" — the sed wrongly prefixed it, dropping the transform fn (identity).
- text-measure's `token.type === "text"` is an AnsiToken, not a TuiNode — reverted.
BREAKING CHANGE: the internal host element names are now tui-box/tui-text/
tui-virtual-text/tui-static/tui-transform. Public components (Box/Text/Static/
Spacer/Newline/Transform) and their props/types are unchanged; only raw host-op
callers (h("box") -> h("tui-box")) are affected.
vp run ready green: fmt, lint 0/0, vue-tsc, tests (runtime 350, integration 1161,
PTY 129).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -73,7 +73,7 @@ and fixed at the root:
|
||||
`fresh.length > 0` gate and `paintIsolated` painted the container's **padding** as stray
|
||||
blank lines — while `findStatics` in the same file already skipped `text-leaf`/`comment`.
|
||||
Fix: `paintStaticNode` skips inert anchors too (safe: `node-ops.ts` forbids non-empty bare
|
||||
text under `<static>`, so the only `text-leaf` there is an empty anchor).
|
||||
text under `<tui-static>`, so the only `text-leaf` there is an empty anchor).
|
||||
- **Text — `<slot/>` fragment anchors shifted the transform line-index, exposing an Ink-parity
|
||||
bug.** A `<slot/>` mounts as a Fragment whose boundary anchors are empty `text-leaf`s; the
|
||||
squash loops that give a nested `<Transform>` its positional line index counted every
|
||||
@@ -98,18 +98,23 @@ and fixed at the root:
|
||||
verbatim — so `:flex-grow="1"` reaches the renderer as `flex-grow` and is rejected. Use
|
||||
`:flexGrow="1"`, or `v-bind="someObject"` (object keys are preserved). `Box`/`Text`/`Static`
|
||||
bind a whole props/style object with `v-bind`; `Spacer` uses explicit camelCase.
|
||||
- **Name a component differently from any host tag it renders** (`BoxImpl`/`TextImpl`/
|
||||
`StaticImpl` via `defineOptions`). vue-tsc 3.3.4 self-recurses a `<box>` tag to a component
|
||||
named "Box" (it has no `isCustomElement` at the type layer). Public names (`Box`/`Text`/
|
||||
`Static`) come from `index.ts`.
|
||||
- **Host primitive tags are `tui-`-prefixed** (`tui-box`/`tui-text`/`tui-virtual-text`/
|
||||
`tui-static`/`tui-transform`), mirroring Ink's `ink-box`/`ink-text`. The prefix keeps the
|
||||
renderer's intrinsic elements in their own namespace, so a template `<tui-box>` never
|
||||
resolves to the public `<Box>` component — the components keep their real `name`
|
||||
(`Box`/`Text`/`Static`) with no vue-tsc self-recursion. (Earlier the tags were bare
|
||||
`box`/`text`/…, which collided with the same-named components and forced an `*Impl` internal
|
||||
rename to dodge it; the prefix removed that workaround. vue-tsc has no `isCustomElement` at
|
||||
the type layer, so a bare lowercase tag would PascalCase-resolve to the component — the
|
||||
hyphenated `tui-` name sidesteps that entirely.)
|
||||
- **Don't reintroduce parent-walking or `parent.type.name` matching for context** — use
|
||||
provide/inject (`.name` is also fragile under minification).
|
||||
- **Don't force child-vnode inspection into a template** (the double-materialization wart). If
|
||||
a new component needs it, make it a render function — where the whole ecosystem draws the line.
|
||||
- The host elements (`box`, `text`, `virtual-text`, `static`, `transform`) compile to raw
|
||||
element vnodes via the build's `isCustomElement` option and are an **internal** detail.
|
||||
Consumers use `<Box>` / `<Text>`, never `<box>`. SFC templates may reference the host tags
|
||||
directly; their loose typing under `vue-tsc` (no `strictTemplates`) is intentional.
|
||||
- The host elements (`tui-box`, `tui-text`, `tui-virtual-text`, `tui-static`, `tui-transform`)
|
||||
compile to raw element vnodes via the build's `isCustomElement` option and are an **internal**
|
||||
detail. Consumers use `<Box>` / `<Text>`, never `<tui-box>`. SFC templates may reference the
|
||||
host tags directly; their loose typing under `vue-tsc` (no `strictTemplates`) is intentional.
|
||||
- Components export typed props (`ExtractPublicPropTypes` over the runtime props object) and
|
||||
keep the `WithChildren` shim (`with-children.ts`): Vue's automatic JSX runtime routes
|
||||
children to a `children` prop that declared slots do NOT provide, so the shim is required for
|
||||
|
||||
Reference in New Issue
Block a user