PraxisJS

@praxisjs/jsx

Changelog for @praxisjs/jsx — JSX runtime and HTML/SVG attribute types.

@praxisjs/jsx

0.7.1

Internal: component prop inference no longer depends on _rawProps.

JSX component prop inference now uses a type-only symbol marker from @praxisjs/core/internal, preserving StatelessComponent<T> and @Prop() inference without exposing _rawProps on component instances.

0.7.0

Reactive<T> now accepts null/undefined.

Reactive<T> is now T | null | undefined | (() => T | null | undefined) — both as a static value and as what the reactive function returns. This lets any JSX attribute be conditionally omitted or cleared (href={maybeUrl}, checked={() => flag() || null}) without a type-cast; the runtime already removes the attribute when a prop resolves to null/undefined.

0.6.1

Audited every attribute in dom-types.ts for Reactive<T> coverage and closed every gap. The runtime has always accepted a zero-argument function for any JSX attribute (re-evaluated reactively in an effect — see applyProp in @praxisjs/runtime), but the types only reflected that for a subset of attributes. Passing a function for the rest was a type error even though it worked at runtime.

  • AriaAttributes — all 30 previously-static aria-* attributes (aria-activedescendant, aria-autocomplete, aria-colcount, aria-colindex, aria-colindextext, aria-colspan, aria-controls, aria-describedby, aria-description, aria-details, aria-errormessage, aria-flowto, aria-keyshortcuts, aria-labelledby, aria-level, aria-orientation, aria-owns, aria-placeholder, aria-posinset, aria-roledescription, aria-rowcount, aria-rowindex, aria-rowindextext, aria-rowspan, aria-setsize, aria-sort, aria-valuemax, aria-valuemin, aria-valuenow, aria-valuetext) plus role, now Reactive<T> — matching aria-selected, aria-checked, etc.
  • HTMLAttributes globalsslot, accessKey, translate, popover, part, and the micro-data attributes (itemID, itemProp, itemRef, itemScope, itemType) are now Reactive<T>.
  • Per-element attributes — every remaining static attribute across BaseHTMLAttributes, LinkHTMLAttributes, MetaHTMLAttributes, ScriptHTMLAttributes, StyleHTMLAttributes, OlHTMLAttributes, LiHTMLAttributes, MenuHTMLAttributes, AnchorHTMLAttributes, ImgHTMLAttributes, IframeHTMLAttributes, EmbedHTMLAttributes, ObjectHTMLAttributes, SourceHTMLAttributes, TrackHTMLAttributes, MediaHTMLAttributes/VideoHTMLAttributes, MapHTMLAttributes, AreaHTMLAttributes, FormHTMLAttributes, FieldsetHTMLAttributes, InputHTMLAttributes, ButtonHTMLAttributes, LabelHTMLAttributes, SelectHTMLAttributes, OptgroupHTMLAttributes, OptionHTMLAttributes, OutputHTMLAttributes, TextareaHTMLAttributes, MeterHTMLAttributes, ProgressHTMLAttributes, DetailsHTMLAttributes, SlotHTMLAttributes, TableHTMLAttributes, ColHTMLAttributes, ColgroupHTMLAttributes, TdHTMLAttributes, ThHTMLAttributes, DelHTMLAttributes, and InsHTMLAttributes is now Reactive<T>. This also fixes several same-attribute inconsistencies that existed between interfaces, e.g. href/target (reactive on <a>/<area> but not <base>/<link>/<form>), value (reactive everywhere except <li>), max (reactive on <input>/<meter> but not <progress>), src (reactive on <img>/<iframe>/media but not <script>/<track>/<input>), width/height (reactive almost everywhere but not <table>/<col>/<td>), and dateTime (reactive on <time> but not <del>/<ins>).
  • Left intentionally static (matching browser/spec semantics, not a gap): key, ref, children (JSX internals), xmlns/xmlns:xlink (namespace declarations), autoFocus/autoPlay/defaultValue/defaultChecked (one-shot, browser only consults these at insertion time), is (custom-element name, immutable post-construction), and nonce (CSP nonce, blanked out by the browser after first read).

0.6.0

Expanded DOM event types and new HTML/SVG attributes.

AriaAttributes:

  • "aria-expanded" — was missing entirely; used in accordions, disclosures, and dropdowns
  • "aria-autocomplete" — combobox and searchbox hint values: "none" | "inline" | "list" | "both"
  • "aria-errormessage" — references the element providing the validation error message

DOMAttributes<T> — new handlers matching the runtime's expanded EVENT_MAP:

  • Pointer: onPointerDown, onPointerUp, onPointerMove, onPointerEnter, onPointerLeave, onPointerOver, onPointerOut, onPointerCancel, onGotPointerCapture, onLostPointerCapture — typed as PointerEvent
  • Mouse: onMouseOver, onMouseOut (bubbling variants of enter/leave)
  • Drag: onDrag, onDragEnter, onDragLeave
  • Clipboard: onCopy, onCut, onPaste — typed as ClipboardEvent
  • Composition: onCompositionStart, onCompositionUpdate, onCompositionEnd — typed as CompositionEvent
  • Form: onBeforeInput (InputEvent), onSelect, onInvalid
  • Resource: onLoad, onError
  • Scroll: onScrollEnd

HTMLAttributes<T> — new global attributes:

  • autoFocusautofocus is a global HTML5 attribute, not restricted to form controls
  • inert: Reactive<boolean> — blocks all user interaction and assistive technology
  • popover: boolean | "auto" | "manual" — Popover API; true emits the empty attribute (defaults to "auto")
  • accessKey, nonce, part
  • data-* — any data- prefixed attribute is now accepted on all JSX elements with a reactive value; no cast needed

MediaHTMLAttributes<T> — all 21 standard media events (onPlay, onPause, onTimeUpdate, onProgress, etc.) are now typed and wired.

DetailsHTMLAttributes / DialogHTMLAttributes: onBeforeToggle added.

InputHTMLAttributes: popovertarget and popovertargetaction added (consistent with ButtonHTMLAttributes).

SVGAttributes<T> — new presentation attributes:

  • pointerEvents — typed with all valid SVG pointer-events keyword values
  • vectorEffect, shapeRendering, textRendering, imageRendering, colorInterpolation, paintOrder, cursor

LiteralUnion<T> is now exported from @praxisjs/jsx for use in application code.

0.5.4

Bug fix: fragments preserve primitive children.

Fragments now keep primitive children such as strings and 0 instead of dropping them before runtime mounting. Nested fragment arrays are still flattened, and null, undefined, and false continue to render nothing.

0.5.2

  • ComponentRef<C> type added — resolves to (instance: InstanceType<C> | null) => void. Use it to type a field that holds a component instance obtained via ref.
  • ref prop now accepted on all component JSX tags — the runtime strips it before forwarding props to the component and calls the callback after onMount (and with null after unmount).

0.4.6

  • children prop now accepted on all component JSX usages — LibraryManagedAttributes includes children?: Children so components using @Slot or receiving any JSX children no longer produce a TypeScript error at the call site.
  • innerHTML added to HTMLAttributes<div innerHTML={html} /> now type-checks correctly.

0.4.0

Major HTML/SVG type system overhaul — all attribute interfaces rewritten in a React-style layered architecture.

  • LiteralUnion<T> applied to string-literal unions (ButtonType, HTMLInputTypeAttribute, FormMethod, etc.) — string variables are assignable without a cast while IDE autocomplete still suggests canonical values
  • CSSProperties for object-style style props with camelCase CSS property autocomplete and --custom-property support
  • AriaAttributes — full WAI-ARIA 1.2 attribute set
  • DOMAttributes<T> — all event handlers with currentTarget narrowed to the host element type
  • HTMLAttributes<T> — generic base with element-specific ref: (el: T) => void
  • 40+ per-element attribute interfaces (ButtonHTMLAttributes, InputHTMLAttributes, AnchorHTMLAttributes, VideoHTMLAttributes, DialogHTMLAttributes, …)
  • SVGAttributes<T> for all SVG elements
  • ~120 intrinsic element entries covering metadata, sectioning, grouping, text-level, embedded, form, interactive, tabular, and scripting categories
  • Removed the [key: string]: HTMLAttributes catch-all index signature — typos like <dvi> are now compile-time errors

InstancePropsOf now strips all framework internals via the _${string} template-literal pattern and lifecycle method names, inferring only @Prop() and @State() fields as JSX props without any explicit declaration.

0.3.1

Fix JSX prop typing for StatelessComponent. LibraryManagedAttributes now uses InstancePropsOf directly instead of intersecting with raw constructor props, preventing the erroneous T | (T & (() => T)) type expansion. InstancePropsOf uses _rawProps to infer props from @Prop() fields accurately.

0.3.0

Component props now accept reactive getters in JSX. Any prop can be passed as a plain value (static) or as an arrow function (reactive):

<Counter value={this.count} />        // static — read once
<Counter value={() => this.count} />  // reactive — updates on change

PropsOf<T> and InstancePropsOf<C> now map each key to Reactive<P[K]> (P[K] | (() => P[K])). Reactive<T> is exported from @praxisjs/jsx.

0.2.0

Refactored to delegate rendering to @praxisjs/runtime. Migrated to the TC39 decorator context API. Introduced StatefulComponent and StatelessComponent as base classes, replacing the deprecated BaseComponent pattern.

0.1.0

Initial beta release.

On this page