Skip to content

Audit ui.* VNode factories and harden interactive prop validation#78

Merged
RtlZeroMemory merged 2 commits into
mainfrom
vnode-factory-audit
Feb 18, 2026
Merged

Audit ui.* VNode factories and harden interactive prop validation#78
RtlZeroMemory merged 2 commits into
mainfrom
vnode-factory-audit

Conversation

@RtlZeroMemory

Copy link
Copy Markdown
Owner

Summary

  • audited and tightened ui.* factory behavior across packages/core/src/widgets/ui.ts
  • added key-forwarding support for ui.layers, ui.richText, ui.vstack, and ui.hstack
  • expanded child filtering to flatten nested children while removing null/false/undefined
  • added runtime interactive prop validation for select, slider, checkbox, and radioGroup, and strengthened button.id to non-empty
  • integrated new validators into leaf measurement/layout paths to return deterministic ZRUI_INVALID_PROPS fatals instead of downstream crashes
  • added three deterministic regression suites:
    • packages/core/src/widgets/__tests__/vnode.factory.test.ts
    • packages/core/src/widgets/__tests__/vnode.children-filter.test.ts
    • packages/core/src/widgets/__tests__/vnode.prop-validation.test.ts
  • updated widget docs with factory/validation guarantees and baseline lock metadata

Why

This closes type-safety and runtime-validation gaps in factory construction and interactive widget handling, and adds exhaustive coverage so regressions in factory shape, key forwarding, child normalization, and required-prop enforcement are caught immediately.

Validation

  • npm run lint
  • npm run build
  • npm run typecheck
  • node scripts/run-tests.mjs (# tests 2693, # pass 2693, # fail 0)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6f915fb88a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/core/src/layout/kinds/leaf.ts Outdated
Comment on lines +295 to +296
(propsRes.value.value.length > 0
? propsRes.value.value

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Align select measurement fallback with renderer

measureLeaf now uses the raw select.value when no option matches, but the renderer still falls back to the placeholder in that same state (renderToDrawlist/widgets/basic.ts sets label = placeholder when no match is found). When value is non-empty but stale/not present in options (common during async option reloads), measurement can become narrower than rendered text (e.g. value "x" vs rendered " Select… ▼"), which clips the control and destabilizes layout.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in ae17eb4.

I aligned measureLeaf select fallback with renderer behavior: when no option matches value, measurement now falls back to placeholder (default "Select…") instead of the raw stale value.

I also added a regression test in packages/core/src/widgets/__tests__/vnode.prop-validation.test.ts (select measurement uses placeholder width when value is stale) to lock this.

Validation rerun:

  • npm run lint
  • npm run build
  • npm run typecheck
  • node scripts/run-tests.mjs (pass: 2694, fail: 0)

@RtlZeroMemory
RtlZeroMemory merged commit e3d7094 into main Feb 18, 2026
15 of 16 checks passed
@RtlZeroMemory
RtlZeroMemory deleted the vnode-factory-audit branch February 19, 2026 17:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant