@zag-js/focus-visible
Installation
yarn add @zag-js/focus-visible
# or
npm i @zag-js/focus-visible
Contribution
Yes please! See the contributing guidelines for details.
Licence
This project is licensed under the terms of the MIT license.
Focus visible polyfill utility based on WICG
yarn add @zag-js/focus-visible
# or
npm i @zag-js/focus-visible
Yes please! See the contributing guidelines for details.
This project is licensed under the terms of the MIT license.
All notable changes to this project will be documented in this file.
See the Changesets for the latest changes.
Color Picker, Hover Card, Tooltip: Fix issue where placement could intermittently shift due to data-placement
being updated
File Upload:
api.setClipboardFiles(...)
was still called when file upload is disableddragging
when disabledapi.disabled
Tour: Fix issue where dialog tour step doesn't sync its z-index with the content
minView
and maxView
to provide better control of the datepicker views, making it easier to build
month and year only pickersparse
method to parse input value and return valid date, paired with format
option for better UXlocale
and timeZone
to the format
methodplaceholder
context property to customize input placeholder textmin
and max
dates are less than 1 year and
overlap 2 unique yearsFile Upload: Improve click detection for dropzone and add support for disableClick
prop on dropzone
General: Don't reset form-related components if reset event is cancelled
Hover Card, Tooltip: Fix issue where controlled open state could get into an inconsistent machine state during the
opening
or closing
state.
Tour: Remove zIndex
from elements in favor of userland control.
Steps: Fix issue where onStepComplete
is not implemented
Vue: Fix issue where svg viewBox
attribute handling between client and server
Pagination: Fix issue where page range could return incorrect end
value when pageSize
is greater than count
[NEW] Preact: Add support for Preact
TreeCollection: Add support for new methods
getPreviousSibling
: Get the previous sibling node of the given node.getNextSibling
: Get the next sibling node of the given node.remove
: Remove the given node from the collection.Tabs: Add support for navigate
context property to handle custom router navigations when trigger is rendered as
a link.
Here's a React example usage with the tabs machine.
const [state, send] = useMachine(
tabs.machine({
id: useId(),
value: "nils",
// use router.push to navigate to the selected tab
navigate(details) {
router.push(`#${details.value}`)
},
}),
)
onValueChange
callbackFile Upload: Fix issue where hidden input isn't synced with the accepted files.
QR Code: Fix issue where getDataUrl
doesn't render the full sized QR code.
File Upload
Add support for preventing drop on document when the file upload is used. Use the preventDropOnDocument
context
property. Set to true
by default to prevent drop on document.
Add api.setClipboardFiles
method to set the files from the clipboard data.
Menu, Popover
Fix issue where interaction outside detection doesn't work consistently when trigger is within a scrollable container.
Fix issue where positioning.hideWhenDetached
doesn't remove the visibility:hidden
attached to the positioner
when reference comes back into view.
Dialog, Popover: Fix issue where dialog or popover closes when the focused element is removed from the DOM.
Collapsible: Fix issue where re-rendering an open collapsible causes a replay of the opening animation
Focus Trap: Clean up requestAnimationFrame
properly to avoid memory leaks.
Orientation
typeCarousel [BREAKING]: Redesign carousel machine to improve touch handling and performance.
scroll-snap
feature, and added new features.index
prop to page
onIndexChange
to onPageChange
api.getViewportProps()
File Upload: Fix issue where accept
attribute is not applied to hidden input
Number Input: Fix issue where input event doesn't get dispatched when initially clicking the increment/decrement triggers
TreeView: Fix issue where react elements could not be passed to tree view. We've improved the entire machine store to better support complex objects like react and vue elements.
File Upload: Expose acceptedFiles
and rejectedFiles
to validate file method. This is useful for checking for
duplicate files.
DOM Query: Fix issue where signature pad getDataUrl(...)
doesn't render the correctly scaled image in Firefox
Date Picker: Remove unimplemented modal
prop in datepicker
Svelte: Fix prop normalization issue where viewBox
was incorrectly converted to viewbox
and renders svg
incorrectly
Svelte
$effect
time, rather than onMount
timeuseService
when context
changesPresence, Collapsible: Fix memory leak where machine might hold on to the element and it's styles after element is unmounted
Svelte: Fix issue where mergeProps
doesn't merge styles correctly
Angle Slider [NEW]: Add new angle slider component to allow for selecting an angle between 0 and 360 degrees.
Combobox: Add syncSelectedItems
api to allow rehydrating the select items after fetching from async items.
ColorPicker: Add support for invalid
and openAutoFocus
props.
ColorPicker
--color
to the swatch and swatch trigger partsAutoresize
rows
attribute changes and fonts are loaded.TagsInput: Fix issue where delete behavior is inconsistent between states.
TreeView: Add data-*
attributes to branch content
Clipboard: Fix issue where clipboard trigger doesn't have type=button
ToastGroupContext
type. The previously exported type was incorrectTreeView: Refactor treeview to use the new tree collection for better rendering and logic management
Combobox: Remove getSelectionValue
in favor of userland programmatic control
api.addValue(...)
doesn't work in tags inputreadOnly
is set to true
getSelectionValue
could gets called multiple times. Now, it only gets called when a
selection is madeTreeCollection
utility to traverse trees in the treeview and cascader componentsPopover: Fix race condition in iOS Safari where switching between multiple popovers causes both to close unexpectedly.
Presence: Fix issue where elements that use the presence machine doesn't exit unmounting state when closed with delay and the active tab is switched.
This is because the v8 engine doesn't trigger the animationend event when the tab is inactive even though the "present" state had changed before the tab is switched.
Slider: Add support for rendering a dragging indicator when a thumb is dragged by using
api.getDraggingIndicatorProps(...)
.
Editable: Add data-autoresize
to editable and preview parts when autoresize is enabled.
autoResize
is enabled, we removed the default all: unset
applied to the input in favor of
userland css. Please add this in your userland css.[data-scope="editable"][data-part="input"][data-autoresize] {
all: unset;
}
Time
type@internationalized/date
was not declared as peer dependency.TagsInput: Fix issue where tags input doesn't navigate tags after removing with the delete key
DatePicker: Fix issue in date range picker where clicking a preset trigger and blurring the input resets the value incorrectly.
grey
named colors and rebeccapurple
color resolution.@internationalized/date
to peer dependency to prevent mismatching type
errors.Dialog
Combobox
File Upload
acceptedFiles
is removed after an invalid file is uploadedDialog
Select, Combobox
multiple
and disabled
in api to allow for designing custom UIs.Tour [BREAKING]
All Packages
src
directory.Steps
data-incomplete
on it.api.value
to api.step
api.setValue
to api.setStep
DatePicker
FileUpload
api.getClearTriggerProps()
to render a clear trigger that clears the accepted files.Combobox
flip: false
default positioning option to ensure consistency with select.Select, Tabs
deselectable
prop to allow deselecting the current value by clicking on the item.FileUpload
directory: true
doesn't workSwitch, Checkbox, Radio Group
data-focus-visible
attribute to the selected radio button when it is interacted with the keyboard.Tooltip
DatePicker
min
and max
values throws an error.TreeView
Combobox
Timer
role"timer
to new area part.BEFORE:
<div>
<div {...api.getRootProps()}>
<div {...api.getItemProps({ type: "days" })}>{api.formattedTime.days}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "hours" })}>{api.formattedTime.hours}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "minutes" })}>{api.formattedTime.minutes}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "seconds" })}>{api.formattedTime.seconds}</div>
</div>
<div>
<button {...api.getActionTriggerProps({ action: "start" })}>START</button>
<button {...api.getActionTriggerProps({ action: "pause" })}>PAUSE</button>
<button {...api.getActionTriggerProps({ action: "resume" })}>RESUME</button>
<button {...api.getActionTriggerProps({ action: "reset" })}>RESET</button>
</div>
</div>
AFTER:
<div {...api.getRootProps()}>
<div {...api.getAreaProps()}>
<div {...api.getItemProps({ type: "days" })}>{api.formattedTime.days}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "hours" })}>{api.formattedTime.hours}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "minutes" })}>{api.formattedTime.minutes}</div>
<div {...api.getSeparatorProps()}>:</div>
<div {...api.getItemProps({ type: "seconds" })}>{api.formattedTime.seconds}</div>
</div>
<div {...api.getControlProps()}>
<button {...api.getActionTriggerProps({ action: "start" })}>START</button>
<button {...api.getActionTriggerProps({ action: "pause" })}>PAUSE</button>
<button {...api.getActionTriggerProps({ action: "resume" })}>RESUME</button>
<button {...api.getActionTriggerProps({ action: "reset" })}>RESET</button>
</div>
</div>
Popper
hideWhenDetached
positioning option. This can be used in the positioning
options for floating
components (select, popover, dialog, etc.)Highlight
@zag-js/highlight-word
package to help with highlighting text in a string.Date Utils
getWeekDays
had inconsistent behavior when both locale and startOfWeekProp
were setMenu
Floating Components
Popover
Avatar
Steps
aria-owns
FileUpload
accept
intellisenseToast
action
in toast options, giving you the ability to add a action.label
and action.onClick
. The
onClick
function will be called when the user clicks the action trigger.api.create({
title: "Uploaded successfully",
type: "success",
action: {
label: "Undo",
onClick: () => {
console.log("undo")
},
},
})
Floating Components
boundary
to only support function that returns an element.Select
File Upload
invalid
prop in file upload to explicitly mark upload operation as invalid. This could be paired
with the rejectedFiles
to show an error message.Popover
Svelte
peerDependencies
were configured incorrectlyDialog
Editable
edit
and onEditChange
Pagination
api.count
propertyEditable
onEdit
in favor of onEditChange
startsWithEditView
in favor of edit
propNumberInput
Collection
GridCollection
to manage grid base navigation and selectionCollection [BREAKING]
Collection
class to ListCollection
to better reflect its intentDatePicker
getPresetTrigger
Slider
onValueChangeEnd
gets called with incorrect valueTimer
DatePicker
index
in getLabelProps
TimePicker
TimePicker
typesToast
aria-labelledby
and aria-describedby
attributes on the toast root elementReact
useMachine
where HMR could lead to Maximum call stack exceeded
errorCombobox
aria-selected
and aria-disabled
when false
click
over pointerup
for consistent experience between screen readers and pointers.React
Steps
skippable
to linear
prop to better communicate its intentorientation
to horizontal
Tags Input
Select
closeOnSelect
could not be customized when multiple
is set to true
RadioGroup
data-readonly
attribute was misspeltTooltip
closeOnClick
to determine if the tooltip should close when trigger is clicked.All Machines
process.env
check in a functionCombobox
[NEW] Steps
Select, Combobox
TreeView
ColorPicker, Select, NumberInput
Combobox
multiple
is set to true
. The design intent is that when combobox is set
to multiple
, values should be rendered outside thedata-placement
on ContentProgress
viewBox
attribute on <svg>
Carousel
slidesPerView
and loop
Presence
0s
Select, Combobox
data-invalid
on Combobox and Select triggersMenu
All Machines
Ensure consistent application of form related properties like invalid
, required
, and readOnly
.
Export Service
from all machines for use in Lit based components.
Tooltip
closeOnScroll=false
doesn't work consistently in SafariAlert
api.goToNextPage()
, api.goToPrevPage()
,
api.goToFirstPage()
, api.goToLastPage()
DatePicker
FileUpload
Add support for api.clearRejectedFiles
to allow clearing the rejected files programmatically.
Improve DX of the accept
context property by providing autocompletions for common file type
Editable
activationMode=dblclick
clears the input value unexpectedly.SignaturePad
role=application
to signature pad control. This fixes the accessibility violation with aria-roledescription
Menu
Select
api.selectAll()
Tooltip
closeOnScroll
to control whether the tooltip should close when the trigger's overflow parent
scrolls.ColorPicker
format
to channel slider parts. Useful for building slider only color pickersapi.getChannelValueText
to get the formatted value text for specific channel sliderSlider
data-dragging
to the component parts when dragging the slider thumb. This allows you to style the slider
parts differently when the thumb is being dragged.readOnly
and disabled
context propertiesMenu
Presence
immediate
to synchronize the present change immediately instead of deferring to next tick. This
should be used when composing components like Tabs
.RadioGroup, Tabs
data-ssr
to item as a style hook to mimick the indicator styles while in ssr. This improves the visual
experience and prevents the indicator flashing on hydrationTimer [Breaking]
root
, segment
, control
, separator
root
, item
, itemValue
, itemLabel
, actionTrigger
, separator
,FileUpload
onFileAccept
gets called when deleting an item via the delete trigger. Now, only onFileChange
is
called when deleting or calling api.clearFiles
Combobox, Select
All Machines
Update all machines to use prop getters everywhere. This helps to improve render performance and reduce breaking changes in the future.
rootProps -> getRootProps()
labelProps -> getLabelProps()
console.log
Svelte
$state
usage in useMachine
hookreflect
utility to help design system maintainers manage api
reactivityPropTypes
type to improve type safety in spread propsSolid.js
readOnly: false
adds the readonly
attribute on editable elements,
making them uneditable.Popover
Fix issue where autoFocus
was not implemented. Now, it determines whether the popover should autofocus on open
true
, the first focusable element or the content is focusedfalse
, the content is focusedFix the issue where page scroll resets on opening popover
Select
textarea
as the input element in edit mode.General
mergeProps
utilitynativeEvent
currentTarget not been set sometimes.Avatar
naturalWidth|Height
instead of currentSrc
FileUpload
Progress
max
than 50
throws due to the fact the default value
is set to 50
. Now we
set the default value
to mid value between the min
and max
[NEW]: Added new Timer machine to create a timer (countdown or stopwatch) that can be paused, resumed, and reset.
[NEW]: Added new TimePicker machine to that allows selecting a time and day period.
Pagination
api.pageSize
to allow retrieving the current page sizeonPageSizeChange
to listen for page size changeEditable
api.valueText
that returns the current value or placeholder if emptyReact
Collection
Popover, Menu, Select
offset.crossAxis
Dialog, Popover:
persistElements
to prevent third-party elements from having pointer-events: none
applied to them
and closing when you interact with them.Dialog
role=alertdialog
is set.role=alertdialog
is set to prevent accidental selection of
destructive action.Slider
onValueChangeEnd
when using keyboard to interact with slider thumbTabs, Combobox, Select, Menu:
composite
prop to allow for composing these components within themselves.Combobox
triggerProps
to getTriggerProps()
to allow for more flexible compositionsPopover, Tooltip
closeOnEsc
to closeOnEscape
to be consistent with dialog machineTabs
activationMode=automatic
over focus triggering
selection. For keyboard, selection follows focus as usualStore, React
@zag-js/store
could lead to "proxy state is not iterable" errorsCollapsible
DatePicker
Splitter
onResize
was not calledTagsInput
Presence
api.unmount
to programmatically unmount the componentapi.skip
to skip initial animationThis release marks the journey to a more stable and consistent API across all components. We've made significant changes.
Collapsible
Toast
Select, Combobox
value
is unintentionally sorted when highlighting itemCheckbox, RadioGroup, Switch
readOnly
prop to prevent user interaction from changing the checkbox stateCombobox
open
and onOpenChange
openOnChange
property to automatically open the combobox when the value changes. Value can be a boolean or
a function that returns a boolean.const [state, send] = useMachine(
combobox.machine({
openOnChange: ({ inputValue }) => inputValue.length > 2,
}),
)
openOnKeypress
property to automatically open the combobox when the arrow keys (up and down) are pressed.persistFocus
to the item props to determine whether to clear the highlighted item on pointer leave.All machines
is<X>
to <x>
. For example,
isDisabled
-> disabled
, isFocused
-> focused
, isOpen
-> open
, etc.open()
, close()
methods to setOpen(true|false)
selectOnBlur
to prevent accidental selection of options. Prefer explicit selection by user via click or
enter key.Accordion
getItemState
propertiesisOpen
-> expanded
isDisabled
-> disabled
isFocused
-> focused
Avatar
api.isLoaded
to api.loaded
api.showFallback
since it's equivalent to !api.loaded
Carousel
isCurrent
to current
isNext
and isPrevious
to next
and previous
respectivelyisPrevious
to previous
Clipboard
api.isCopied
to api.copied
File Upload
api.open()
-> api.openFilePicker()
Menu
loop
to loopFocus
to better reflect its purposeTagsInput
allowTagEdit
to editable
onInputValueChange
to machine contextToast [BREAKING]:
<ToastContext.Provider value={api}>
- {Object.entries(api.getToastsByPlacement()).map(([placement, toasts]) => (
+ {api.getPlacements().map((placement) => (
<div key={placement} {...api.getGroupProps({ placement })}>
- {toasts.map((toast) => (
+ {api.getToastsByPlacement(placement).map((toast) => (
<Toast key={toast.id} actor={toast} />
))}
</div>
))}
{children}
</ToastContext.Provider>
Checkbox, Switch
data-active
doesn't get removed when pointer is release outside the elementToast
type
or duration
Signature Pad [NEW]
Svelte
useActor
hook to be consistent with other frameworksAvatar [Breaking]
onLoadingStatusChange
to onStatusChange
to match naming convention across machinesClipboard [Breaking]
onCopyStatusChange
to onStatusChange
to match naming convention across machinesToasts [Breaking]
overlap: true
in the toast.group
machine contextpauseOnInteraction
in favor of always pausing on hover. This is required for accessibility reasons (there
should always be a way to pause the widgets with time-based interactions)onOpen
, onClose
and onClosing
in favor of onStatusChange
which reports the lifecycle status of the
toast[data-scope="toast"][data-part="root"] {
translate: var(--x) var(--y);
scale: var(--scale);
z-index: var(--z-index);
height: var(--height);
opacity: var(--opacity);
will-change: translate, opacity, scale;
transition:
translate 400ms,
scale 400ms,
opacity 400ms;
}
[data-scope="toast"][data-state="closed"] {
transition:
translate 400ms,
scale 400ms,
opacity 200ms;
}
ghostBeforeProps
and ghostAfterProps
props to ensure the hover interaction works as expectedmergeProps
to prevent issues with children that read from context, and ensure props are always
up-to-date.RegExp
in delimiterstyle
to allow more flexible stylingMenu [Breaking]
getOptionItemIndicatorProps
to getItemIndicatorProps
getOptionItemTextProps
to getItemTextProps
data-part
to match new anatomyoption-item
-> item
option-item-indicator
-> item-indicator
option-item-text
-> item-text
File Upload [Breaking]
Remove files
form user defined context. File upload, just like <input type=file>
, is largely a readonly
operation that can't be set by the user.
Consider using the
onFileChange
event to handle file changes.
Rename api.files
to api.acceptedFiles
onFilesChange
to onFileChange
directory
propcapture
property that specifies which camera to use for capture of image or videovalue
and onValueChange
in favor of using explicit state to manage option items, and passing checked
and onCheckedChange
to the getOptionItemProps
callback.value
over id
in getItemProps
and getOptionItemProps
for consistency with other machine.onSelect
now provides value
not id
in its details.readOnly: true
is setDialog: Sync zIndex
of content with positioner and backdrop via --z-index
css variable. This helps with
stacking order when using multiple dialogs.
Dismissable: Improve interaction outside logic when layer rendering is deferred (via Portals or unmounted)
Utilities: Add support for formatDate
and formatList
functions that use the underlying Intl.*
implementations
interactive
to false
by defaultselectionBehavior
is set to clear
value
data-placement
to the select content to make it easier to stylescrollToIndexFn
to be used with virtualization librarieshighlightedIndex
in the onHighlightChange
callbackuseService
and useMachine
with other frameworksparse
functionaddOnPaste
to false
and pasting text prevents subsequent tags from being
addednull
crossAxis
positioning property doesn't work in some cases.name
attribute on the thumb elementdata-orientation
attribute to splitter panelonEscapeKeyDown
event handler💥 Breaking changes
api.tablistProps
to api.listProps
to match naming conventionDatePicker
FileUpload: Fix an issue where onFileReject
would not be called
Switch: Fix accessibility issue where aria-readonly
was incorrectly set on the wrong element.
onExitComplete
to listen for exit animation completion.Tour
component to guide users through a series of steps in an application.getBranchIndicator
function and other minor fixes.api.copy()
to copy text to clipboardAll components
Fix issue where scrolling into view could result in scrolling the body element.
Affected components: Select, Menu, Combobox
Select:
aria-activedecesendant
fieldDatePicker: Fix issue where date picker does not show correct number of weeks when startOfWeek
is set
[NEW] Clipboard: Add Clipboard machine for copying text to clipboard.
[NEW] Collapsible: Add Collapsible machine for interactive component which expands/collapses a panel.
Add support for open.controlled in the machine context as a way to fully control the machine's open state programmatically.
Affected components: Dialog, HoverCard, Popover, ColorPicker, DatePicker, Tooltip, Menu, HoverCard, and Combobox.
Combobox: Expose api.collection for better control over the collection of items in combobox.
api.inputProps
to api.getInputProps(...)
to support multiple inputs.getPresetTriggerProps
to support custom trigger for common date presets (e.g. Last 7 days, Last
30 days, etc.)--transition-duration
css variable.= Core: Fix issue where context mutation updates were missed due to the underlying proxy-compare
regression.
data-disabled
, data-invalid
, and data-readonly
to indicator propssetContext(...)
instead of withContext(...)
.PinInput: Fix an issue where paste in pin input would fill the input with all pasted characters instead of 1 per input
TreeView: Add new TreeView
component to render a tree view of items. This component is useful for rendering
nested data structures like a file system.
This component is still in beta and is subject to change.
TagsInput
component design by introducing a new item-preview
part. See the diff below for
more details.<div {...api.rootProps}>
{api.value.map((value, index) => (
- <span key={index}>
+ <span key={index} {...api.getItemProps({ index, value })}>
- <div {...api.getItemProps({ index, value })}>
+ <div {...api.getItemPreviewProps({ index, value })}>
<span>{value} </span>
<button {...api.getItemDeleteTriggerProps({ index, value })}>✕</button>
</div>
<input {...api.getItemInputProps({ index, value })} />
</span>
))}
<input placeholder="Add tag..." {...api.inputProps} />
</div>
ColorPicker: Fix issue where swatch indicator had incorrect data attributes
NumberInput:
onValueChange
Menu: Fix issue in non-portalled, nested menus where keyboard interactions within submenu bubble to parent menu
onFileAccept
and onFileReject
callbacks.ids
and aria labels using messages
context property.TOO_MANY_FILES_REJECTION
> TOO_MANY_FILES
TOO_LARGE
> FILE_TOO_LARGE
TOO_SMALL
> FILE_TOO_SMALL
messages
context property to translations
. This property was previously unusedColorPicker:
details.valueAsString
for
onValueChange
callbackonFormatChange
callback to listen for format changescloseOnSelect
prop to control whether the color picker should close when a swatch color is selectedToast: Add generic support to toast types to support framework-specific types.
Dialog: Fix issue where dialog positioner applied the hidden
attribute when closed leading to pre-mature exit of
css animations applied to the dialog content.
Only the backdrop and content should use the
hidden
attribute.
Combobox: Fix a case where item highlight was looping even though loop property was false
onValueChange
is not called when multiple
is set to true
aria-controls
was not added to triggerloop
property is not respected0
as the default index.open
context propertyNaN
. Now, it reverts back to the previous alpha valuecollection
is not returned in the api
use
directlyapi.isOpen
returned undefined
in some casesvertical
output
part to valueText
to match naming conventioninline
in datepicker and replace with closeOnSelect
for API consistency.data-placement
to trigger and content parts for position-aware styling.ColorPicker
hsl
12px
size for transparency gridRadioGroup: Fix issue where indicator stays visibile when the value is null
Combobox: Fix issue where combobox positioner is hidden
when combobox is not open
Toast: Redesign toast render apis to allow for framework control.
defaultOptions
can now be passed directly to the toast.group
machine context.render
function to the toast.group
machine context.api.render
in favor of userland control. This eliminates the bug in Solid.js for custom toasts.Carousel: Rename onSlideChange
to onIndexChange
Slider, RangeSlider: Merge the slider and range slider machines into one to prevent logic duplication.
value
and onValueChange
type has been updated to be number[]
api.getThumbProps(index)
to api.getThumbProps({ index })
Dialog: Rename dialog container to dialog positioner for better API consistency. This means api.containerProps
is now api.positionerProps
api.setFiles
and api.clearFiles
does not workDOMException
warning when third party iframes are present💥 Breaking changes
Combobox, Select, HoverCard: Rename api.setPositioning(...)
to api.reposition(...)
Carousel: Refactor components to ensure consistent naming convention
slideGroupProps
-> itemGroupProps
getSlideProps
-> getItemProps
nextSlideTrigger
-> nextTrigger
prevSlideTrigger
-> prevTrigger
ColorPicker:
api.getChannelValue
API to get the value of a specific color channelPagination: Rename component anatomy and parts
getPageTriggerProps
=> getTriggerProps
getNextPageTriggerProps
=> getNextTriggerProps
getPrevPageTriggerProps
=> getPrevTriggerProps
dir
is applied to all positioner elements💥 Breaking changes
FileUpload:
Item
: The element that represents a fileItemSizeText
: The element that represents the size of a fileItemName
: The element that represents the name of a fileItemDeleteTrigger
: The buttonelement used to delete a fileapi.getFileSize
method to get the size of a file in a human readable formatRatingGroup:
api.sizeArray
to api.items
max
to count
dir
attribute is applied consistently across all component parts.closeOnInteractOutside
being set to false
api.setPositioning(...)
to allow for repositioning the combobox contentoptionItemIndicator
and optionItemText
partapi.optionItemIndicatorProps(...)
, api.optionItemTextProps(...)
supportapi.getItemState
OptionItemState
and ItemState
typesapi.isOptionChecked
in favor of api.getOptionItemState
formatOptions
: validateCharacter
,
parse
, format
, minFractionDigits
, maxFractionDigits
modal: false
doesn't disable focus trapcloseOnEsc
to closeOnEscapeKeyDown
onEsc
to onEscapeKeyDown
closeOnOutsideClick
to closeOnInteractOutside
readonly
items could not be used in the collectiontabindex
attributeAccordionItemIndicator
, SelectIndicator
,
MenuIndicator
, PopoverIndicator
zIndex
as the content element💥 Breaking changes
Refactor component anatomy to use consistent naming convention across all machines.
Accordion
getTriggerProps
=> getItemTriggerProps
getContentProps
=> getItemContentProps
Radio
getRadioProps
=> getItemProps
getRadioControlProps
=> getItemControlProps
getRadioLabelProps
=> getItemTextProps
getRadioHiddenInputProps
=> getItemHiddenInputProps
getRatingState
=> getItemState
getRatingProps
=> getItemProps
TagsInput
getTagProps
=> getItemProps
getTagDeleteTriggerProps
=> getItemDeleteTriggerProps
getTagInputProps
=> getItemInputProps
Toggle Group
getToggleProps
=> getItemProps
ToggleGroup: Allow deselecting item when multiple
is false
.
onOpenChange
callback to listen for changes in the open state@zag-js/file-utils
package to help with file related operationsstartsWithEditView
is set to true
api.getTriggerState(...)
to get the current state of the tab trigger💥 Breaking changes
All machines: Unify all callbacks to follow a consistent naming convention
onOpen
and onClose
=> onOpenChange
onChange
=> onValueChange
onFocus
=> onFocusChange
onHighlight
=> onHighlightChange
onLoad
and onError
=> onLoadingStatusChange
onInputChange
=> onInputValueChange
Remove toggle machine in favor of userland implementation. For more advanced toggle functionality, use the
ToggleGroup
machine.
RadioGroup: Remove api.blur()
from radio group machine. Prefer to use document.activeElement.blur()
instead.
FileUpload
api.setValue
to api.setFiles
api.clearValue
to api.clearFiles
Tabs: Changed api.setIndicatorRect(id)
to api.setIndicatorRect(value)
for better userland control
CollectionItem
typeconnect
and machine
functionsPopper: Fix issue where passing the offset
positioning option to popper-related components causes undesired
placement in each render cycle.
RadioGroup: Fix issue where change event doesn't get dispatched when value changes programmatically.
control
and root
parts to select and combobox componentsCombobox, Select
Checkbox, Switch: Dispatch change event when checked state is set programmatically to get it working in Solid.js form libraries
onChange
returned a proxy arrayinline: true
is setcloseOnSelect
on menu item props isn't respected in machinePropTypes
from react package for consistencycloseOnSelect
readOnly
property from types💥 Breaking changes
Redesign select and combobox API to allow passing value as string
and collection
Prior to this change, Zag computes the label and value from the DOM element. While this worked, it makes it challenging
to manage complex objects that don't match the label
and value
convention.
// Create the collection
const collection = select.collection({
items: [],
itemToString(item) {
return item.label
},
itemToValue(item) {
return item.value
},
})
// Pass the collection to the select machine
const [state, send] = useMachine(
select.machine({
collection,
id: useId(),
}),
)
forwardRef
element show a LegacyRef
erroronKeyDown
eventCombobox, Select, Menu
Form Elements: Re-enable the input after removing disabled
attribute from the parent fieldset
thumbSize
in the machine context to avoid first-render flicker due to DOM
measurement.💥 Breaking changes
PublicApi
to Api
selectInputOnFocus
option in favor of userland controlvalue
as string
. The value
property must be an array of strings
string[]
onHighlight
to onFocusChange
onTagUpdate
, use onChange
insteadid
usage for better compositiongetRadioInputProps
to getRadioHiddenInputProps
tablist
part to list
to match naming conventioninputProps
to hiddenInputProps
hiddenInput
from machine anatomyoptionGroupLabel
part to ComboboxminSize
and maxSize
to minFileSize
and maxFileSize
respectivelyapi.openFilePicker
to api.open
💥 Breaking changes
nextTrigger
, prevTrigger
to nextSlideTrigger
and prevSlideTrigger
partsonPointerdownOutside
,
onFocusOutside
and onInteractOutside
) to better manage outside interactionisEqual
doesn't consider alpha channel.sameWidth
doesn't work consistently during
re-render.data-disabled
to all element partsdata-focus
to all element partsportalled
attribute to be true
by defaultdata-orientation
to all partssetPreviousValue
actionCore: Add support for transforming context before settings it in the machine's context. This is useful when some
values need to passed to ref
function
Toast: Add option to set toast default options like placement
, removeDelay
, duration
, etc
api.setChecked
does not work💥 Breaking changes
All machines:
data-state
attribute to allow styling the open/closed state or checked/unchecked statesWe replaced data-expanded
or data-checked
to data-state
attribute
data-expanded
maps to data-state="open"
or data-state="closed"
data-checked
maps to data-state="checked"
or data-state="unchecked"
data-indeterminate
maps to data-state="indeterminate"
data-open
maps to data-state="open"
onClick
to carousel indicatorvite
to tsup
document
instead of window
offset
is ignored from default gutterminSize
to 0
api
for controlling panel sizes wasn't implementedonClick
twice when parent element is clickedfocus-trap
package to ensure that trap works when the active element within the content is removedcreateAnatomy
to return an array of the anatomy instance's part namessetReturnFocus
used in focus-trap
throws a console errordefaultValue
is always overriden with an array with empty strings when mountedEnsure ids of underlying elements can customized based on
ids` context property.mergeProps
in zag core.mergeProps
functionsetPositioning
api method to allow empty argumentsfinalFocusEl
to allow for better return focus managementtype
property to the pagination's context to control properties used in trigger elementdefaultValue
does not get applied to input elementtoggleChecked
was not definedfocusedValue
was not synced with value
propertylocale
and value
changedgetRelativePointPercent
outputonOpenChange
to onOpen
and onClose
defaultChecked
property in favor of the checked
property that can now be controlled.// the checkbox will be checked initially
const [state, send] = useMachine(
checkbox.machine({
id: "1",
checked: true,
}),
)
// this will update the checkbox when the `checked` value changes
const [state, send] = useMachine(checkbox.machine({ id: "1" }), {
context: {
// when this value changes, the checkbox will be checked/unchecked
checked: true,
},
})
defaultOpen
property in favor of the open
property that can now be controlled.// this is will open the dialog initially
const [state, send] = useMachine(dialog.machine({ id: "1", open: true }))
// this will open the dialog when the `open` value changes
const [state, send] = useMachine(dialog.machine({ id: "1" }), {
context: {
// when this value changes, the dialog will open/close
open: true,
},
})
defaultOpen
property in favor of the open
property that can now be controlled.// this is will open the hoverCard initially
const [state, send] = useMachine(hoverCard.machine({ id: "1", open: true }))
// this will open the hoverCard when the `open` value changes
const [state, send] = useMachine(hoverCard.machine({ id: "1" }), {
context: {
// when this value changes, the hoverCard will open/close
open: true,
},
})
defaultOpen
property in favor of the open
property that can now be controlled.// this is will open the popover initially
const [state, send] = useMachine(popover.machine({ id: "1", open: true }))
// this will open the popover when the `open` value changes
const [state, send] = useMachine(popover.machine({ id: "1" }), {
context: {
// when this value changes, the popover will open/close
open: true,
},
})
defaultChecked
property in favor of the checked
property that can now be controlled.// the switch will be checked initially
const [state, send] = useMachine(
switch.machine({
id: "1",
checked: true,
}),
)
// this will update the switch when the `checked` value changes
const [state, send] = useMachine(switch.machine({ id: "1" }), {
context: {
// when this value changes, the switch will be checked/unchecked
checked: true,
},
})
defaultOpen
property in favor of the open
property that can now be controlled.// this is will open the tooltip initially
const [state, send] = useMachine(tooltip.machine({ id: "1", open: true }))
// this will open the tooltip when the `open` value changes
const [state, send] = useMachine(tooltip.machine({ id: "1" }), {
context: {
// when this value changes, the tooltip will open/close
open: true,
},
})