Minor Changes
-
#3252
6d57458Thanks
@github-actions! - Separate the props you pass touseMachinefrom the
props the machine sees after defaults are applied.- Fixed issue where omitting a required prop type-checked and then failed at runtime with
[zag-js] missing required props. Affectsasync-list,carousel,dnd,gridlist,listbox,pin-input,
select,splitter,toastandtoc, whose required props were reported as optional. - Fixed issue where a prop listed as having a default lost
nullfrom its public type, so props that acceptnull
rejected it.
Machine schemas now declare the public props type plus a
defaultPropKeyunion naming the props the machine fills in:export interface DialogSchema { props: DialogProps defaultPropKey: PropsWithDefault }
Schemas that do not declare
defaultPropKeykeep the previous behaviour, so custom machines continue to work
unchanged. - Fixed issue where omitting a required prop type-checked and then failed at runtime with
Patch Changes
-
#3252
06ddeb3Thanks
@github-actions! - - Fixed issue whereinitialFocusElrejectednull,
despite it being handled at runtime. Ondialoganddrawerit was listed as a prop with a default, which stripped
null | undefinedfrom its public type.- Fixed issue where
Portal'scontainerrejected theRefObject<T | null>that React 19'suseRef<T>(null)
returns.
- Fixed issue where
-
#3304
2859ef6Thanks
@segunadebayo! - Fix portalled content failing to render, throwing
Cannot read properties of undefined (reading '__H'). This affected every component that portals, including dialog,
popover, menu, select and tooltip.Portalimported hooks frompreact/compat. Bundlers commonly give compat its own copy of the hooks registry, so
those hooks ran with no current component. Hooks now come frompreact/hooks.useSyncExternalStorehad the same
exposure and is implemented directly onpreact/hooksinstead of re-exported, with no change in behaviour. -
#3304
2859ef6Thanks
@segunadebayo! - AddwatchEffect(deps, setup)to effect implementations, so an
effect can re-run when the props or context it depends on change, without re-entering the state that owns it. It
mirrorstrackinwatch, which runs an action rather than an effect.effects: { trapFocus({ prop, watchEffect }) { return watchEffect([() => prop("trapFocus")], () => { if (!prop("trapFocus")) return return trapFocus(/* ... */) }) }, }
Only the declared effect restarts, sibling effects and entry actions are untouched, and anything outside the call runs
once. Deps must return a primitive, the same constrainttrackhas, so usecontext.hash()for anything else. Unlike
Vue's similarly named API, they are explicit rather than auto-tracked. -
Updated dependencies [
6d57458,
734b5e8,
e8b99d2,
2859ef6,
2859ef6]:- @zag-js/core@2.0.0-next.2
- @zag-js/types@2.0.0-next.2
- @zag-js/utils@2.0.0-next.2
- @zag-js/store@2.0.0-next.2