Skip to content

@b9g/jsx-web-types — typed JSX intrinsic elements (#60)#362

Open
brainkim wants to merge 1 commit into
mainfrom
jsx-web-types-update
Open

@b9g/jsx-web-types — typed JSX intrinsic elements (#60)#362
brainkim wants to merge 1 commit into
mainfrom
jsx-web-types-update

Conversation

@brainkim

@brainkim brainkim commented Jun 13, 2026

Copy link
Copy Markdown
Member

Introduces @b9g/jsx-web-types and wires it into Crank's JSX.IntrinsicElements (#60). Spec-driven, framework-agnostic types for HTML, SVG, and MathML intrinsic elements.

What it is

  • A generated .d.ts package: element → attributes/properties, ARIA, microdata/RDFa, global attributes, and a DOM event map. Each attribute carries its MDN description.
  • The standard types use native platform names (class, onclick). A separate camelCase variant (@b9g/jsx-web-types/camel-case) re-keys them for React/Inferno (className, htmlFor, …), with names sourced from React's own possibleStandardNames.js.
  • Crank's JSX.IntrinsicElements extends WebIntrinsicElements<…>, supplying its own intrinsic attributes (key/ref/prop:/attr:), children attribute, and object-style/class value overrides via the TPropOverrides parameter — so Crank's conventions live in the parameters, not the base types.

Everything is sourced — no hand-coded platform data

Generation is a reproducible function of authoritative sources:

Source What it provides How accessed
BCD (@mdn/browser-compat-data) element names, per-element attributes, global_attributes, deprecated/experimental status, mdn_url imported JSON
MDN pages human descriptions + code examples (the hover text) scraped with cheerio, cached in data/mdn-cache.json (offline-capable; network only on a cache miss)
aria-data ARIA attributes and their value enums imported JSON
TypeScript lib.dom.d.ts tag → DOM interface maps, DOM property types, the *EventMap interfaces parsed with ts-morph
W3C RDFa Core spec RDFa attributes scripts/parse-rdfa-w3c.tsdata/rdfa-attributes.json
MDN Microdata guide microdata attributes scripts/parse-microdata-mdn.tsdata/microdata-attributes.json
React possibleStandardNames.js the camelCase prop-name map (pinned to a release) scripts/parse-camel-case-names.tssrc/camel-case.generated.d.ts
(hand-written) only structural constants — the namespace names and the fixed XMLAttributes W3C set inline in the generator

Every .d.ts and data/*.json is regenerable from these and stamped do-not-edit; there is no hand-frozen platform data.

One known wrinkle: BCD omits fill and systemLanguage from svg.global_attributes despite their families being present. The generator promotes exactly those two (cross-referenced against BCD's per-element data); reported upstream as mdn/browser-compat-data#29912, and the workaround deletes itself once that lands.

Descriptions surface in editors (LSP)

Each attribute's MDN JSDoc reaches hover/completion. The prop types are composed so TypeScript preserves per-attribute doc comments (homomorphic mapped types; multi-namespace tags resolved by precedence rather than unioned), verified end-to-end through Crank JSX with the TypeScript language service — <div class>, <a href>, <label for>, etc. all show their descriptions.

Children

Void elements aren't specially typed: every element accepts children (the runtime ignores stray ones), so there's no void set or TIsVoid plumbing to maintain.

Tests

bun run test typechecks both src/ and the type-level test suite in tests/. Root tsc --noEmit is clean.

🤖 Generated with Claude Code

@brainkim brainkim mentioned this pull request Jun 14, 2026
7 tasks
@brainkim brainkim changed the title WIP: @b9g/jsx-web-types — typed JSX intrinsic elements (#60) @b9g/jsx-web-types — typed JSX intrinsic elements (#60) Jun 23, 2026
@brainkim brainkim marked this pull request as ready for review June 23, 2026 19:12
// node_modules layout. require.resolve can land in a package store that omits
// the bundled lib files (e.g. Bun's .bun store), so we also walk up from this
// script looking for node_modules/typescript/lib, which handles hoisting.
function resolveDomLib(): string {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@claude Please use acrocase: https://acrocase.org

@brainkim brainkim force-pushed the jsx-web-types-update branch 2 times, most recently from 7fdbc62 to 8e825dd Compare July 14, 2026 04:54
Adds the @b9g/jsx-web-types workspace package and wires it into Crank's
JSX.IntrinsicElements, giving first-class typing for HTML, SVG, and MathML
intrinsic elements and their attributes.

Element and global-attribute data is generated from BCD and MDN rather than
hand-maintained, with a corrections layer covering the SVG presentation and
MathML global-attribute gaps upstream still has. Unknown intrinsic tags now
error, not just unknown attributes.
@brainkim brainkim force-pushed the jsx-web-types-update branch from 8e825dd to aef0618 Compare July 14, 2026 06:53
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