ReviewOS

stacks/stx

Preserve native DOM properties and types in generated component libraries

#2129
Closed chris opened this 6 days ago ·
6 days ago

Generated component libraries overwrite native HTMLElement properties when a source component declares a prop with the same name. The real framework sample declares style?: string and onclick?: string: its elements replace the native style object and event handler accessor with prop storage accessors. The declarations repeat those string fields on classes extending HTMLElement and fail a strict TypeScript consumer check.

Two standalone regressions reproduce the problem. Chrome reports that element.style is not a CSSStyleDeclaration, and assigning a native click handler does not behave like a normal HTMLElement. A real TypeScript consumer, with skipLibCheck: false, rejects both the generated classes and ordinary native style/click usage. This is separate from the prop alias correction in #2128.

Related release qualification: stacksjs/stacks#3029. Suppressing declaration checks or changing valid source aliases is not a fix.

Acceptance:

  • Preserve native DOM property descriptors on generated elements.
  • Keep declared attributes available to the component render scope and reactive bindings, including after native attribute/property changes.
  • Preserve native property types in emitted element declarations while retaining custom prop fields and the source Props interface.
  • Cover native style mutation, click handler assignment and real clicks, attribute reactivity and a strict TypeScript consumer without DOM stubs.
  • Pass the component library suite, types, lint, full source and normal patch release gates.
  • Qualify original published packages and the rebuilt real framework sample before downstream acceptance.
6 days ago

The compiler now retains native DOM descriptors and element types while reading declared attribute values in the component render scope. Three real Chrome/TypeScript regressions pass: native style mutation and click handling with reactive attributes, a strict consumer of the emitted declarations, and a clear rejection when attribute: false would replace a native API. Types and lint also pass.

The retained library tests exposed a separate DOM implementation defect: its generic HTMLElement inherited a readonly options getter. That is fixed at its owning source in stacksjs/very-happy-dom#1625. The next gate is normal adoption of its published patch, followed by the full STX suite and the real Stacks sample package. No retained tests have been removed or relaxed.

6 days ago

The source correction is on main, including normal adoption of very-happy-dom@0.4.1 and removal of the obsolete options preload polyfill. The retained hydration and property-upgrade cases pass alongside the Chrome and strict TypeScript regressions.

Local gates passed on CI's Bun 1.4.2: 17,317 source tests, 1,809 component coverage tests and 45 integration tests, with zero failures. Types, lint, formatting and release preflight also pass. The normal patch release and rebuilt framework sample remain pending CI and publication qualification.

5 days ago

Verified fixed and published. Source fix: 23e412b. Native style/onclick descriptors and DOM types are preserved, while declared attribute values remain reactive in component rendering. Publication audit completed against fresh registry installations of STX and components 0.2.736, plus the original @stacksjs/hello-world-stx@0.75.334 sample package. Downloaded all three original npm archives, verified SHA1 and SHA512 against registry metadata, and compared every archived file to the installed copy (1,363 / 572 / 37 files respectively); no installed-package edits or workspace links.

Rebuilt the real 13-component Stacks resources/components snapshot with the published STX builder and the framework's existing library options, into an isolated scratch directory. Both that rebuild and the original sample package pass Chrome checks for supplied/default prop aliases, reactive labels, public manifest/type names, native style mutation, native click assignment and real clicks, reactive IDs and highlight on/off branches. Both expose importable public classes and pass a real DOM TypeScript consumer with strict: true and skipLibCheck: false.

Results on Bun 1.4.2: 12 published-package/sample qualification tests passed, 0 failed; 38 maintained source regressions passed, 0 failed. Maintained tests include packages/stx/test/web-components/component-library-alias-browser.test.ts, component-library-native-properties.test.ts and component-library.test.ts, plus the dialog/ref regressions. The exact 0.2.736 release source gate (lint, formatting, release preflight, full source suite) and npm publication passed: https://github.com/stacksjs/stx/actions/runs/40662611298/job/122729098568 and https://github.com/stacksjs/stx/actions/runs/40662611298/job/122735480150 . Latest main CI is also green: https://github.com/stacksjs/stx/actions/runs/40673334028 .

Local audit scripts, qualification.log and archive-receipts.json are retained at /tmp/stx-2126-2129-audit.tZWOJh . No Craft or Stacks source changes were made. This closes the STX compiler issue, not the separate Stacks publisher acceptance issue stacksjs/stacks#3029.

Sign in to comment on this issue.