Changelog

Updates & Releases

What changed in each version of xiod-ui: new components and props, fixes, and anything to do when you upgrade.

v1.1.5Latest
Oct 21, 2026Released
8Releases
Sep 13, 2026First release

Addedยท 32

  • CopyToClipboard: showTooltip and showToast turn the tooltip and the "Copied!" toast on or off. onCopy and onError report the result, timeout sets how long the copied state lasts, side places the tooltip and toast, and disabled turns copying off. buttonProps and textProps reach the button and the text, and children replaces the text shown without changing what is copied.
  • useHasAnchoredToastProvider() from xiod-ui/toast tells whether an AnchoredToastProvider is mounted above a component.
  • LabelsProvider from xiod-ui/labels-provider replaces the built-in English text (button names, announcements, validation messages, placeholders) for everything inside it, so the library can be translated. Every component with built-in text also takes a labels prop that overrides it for one instance.
  • Grid: columns and rows take a value per breakpoint, such as columns={{ base: 1, md: 3 }}, and GridItem's colSpan and rowSpan do too. New justifyContent spreads the columns themselves.
  • Slider: thumbClassName, trackClassName, indicatorClassName, getAriaLabel and getAriaValueText. A single-thumb slider passes its aria-label to the thumb.
  • ListBox: disabled, deselectable and onHighlightChange; null clears a controlled value. Multiple lists select a range with Shift (click or arrows) and everything with Ctrl or โŒ˜ + A. ListBoxItem takes textValue for typeahead and indicator to replace the check on selected items.
  • ThemeProvider: forcedTheme locks a page to light or dark, and disableTransitionOnChange={false} keeps transitions running while the theme changes. A mode or palette saved in another tab or a same-origin iframe is picked up at once. useTheme() returns forcedTheme.
  • DashboardGrid: onTileDragStart, onTileDragEnd, onTileResizeStart and onTileResizeEnd.
  • Draggable: position/onPositionChange, size/onSizeChange, minimized/defaultMinimized/onMinimizedChange, maximized/defaultMaximized/onMaximizedChange, closeOnEscape and resizeHandleProps.
  • Sortable: disabled (on the list or one SortableItem), getItemLabel and SortableItem's textValue for what screen readers announce, onSortStart, onSortEnd and renderOverlay. Items scroll their container while dragged near its edge.
  • RulerPicker: step, format, disabled and name.
  • Gauge: min and format. CircularProgress: min, format and showValue; children render over the ring.
  • DotMatrix: decorative hides it from screen readers.
  • Resizable: the handle has a name, "Resize panels" by default.
  • Timeline is a list: the active item has aria-current="step", and each item's status is read out.
  • Carousel: index/defaultIndex/onIndexChange, opts.duration and opts.draggable, a play/pause control while autoplay runs, and "N of M" slide names. api.on("reInit") fires after a resize.
  • Calendar: locale, month/defaultMonth/onMonthChange and showFooter.
  • DatePicker: locale, open/defaultOpen/onOpenChange, side, align, sideOffset, name, endName, required and controlId. disabled={true} disables the whole picker.
  • OptionPicker: value (with null for none), placeholder, open/defaultOpen/onOpenChange, side, align, sideOffset, name, and disabled on an option.
  • ColorPicker: format/defaultFormat/onFormatChange and formats. showLightnessSlider names what showAlphaSlider always did.
  • InputSensitive: showCopy, revealed/defaultRevealed/onRevealedChange and revealWhileTyping.
  • InputPhone: required.
  • InputOtpInput: inputClassName styles the input inside the box.
  • FileUpload: minSizeMB, validate and preventDuplicates.
  • WheelPicker: disabled, readOnly, name and fade. PageUp and PageDown move by a page.
  • WaveformScrubber: onMicrophoneError on the live waveform.
  • MorphicToaster: closeButton and limit. Escape closes a focused toast.
  • ToastProvider: classNames for the viewport and each toast's parts, and a per-toast icon.
  • Drawer: backdrop and backdropClassName.
  • Sidebar: onOpenChange, keyboardShortcut (or false to turn โŒ˜/Ctrl + B off) and cookieName. Active menu buttons have aria-current="page".
  • PaginationLink: disabled.
  • AgentSteps: compound steps can be a list (list).

Changedยท 13

  • Updated the xiod-icons dependency to 1.1.3.
  • CopyToClipboard: the tooltip follows your app's TooltipProvider delay instead of always opening after 200 ms. onCopy and onError now report the copy, replacing the wrapper's native onCopy and onError events. disableTooltip is deprecated; use showTooltip={false}.
  • useCopyToClipboard: onCopy receives the copied value, and copyToClipboard keeps the same identity across renders.
  • Built on Base UI 1.9. Disabled AccordionTrigger and CollapsibleTrigger buttons are now natively disabled.
  • InputPhone: the country button is announced as "+1 United States, change country" instead of "Select country, current United States (+1)", so its name starts with the text it shows.
  • DashboardGrid: a tile dropped or resized onto others pushes them out of the way, as preventCollision={false} always promised, and never lands on a static tile. onLayoutChange fires once per change, and not for a click that moved nothing. The remove button is named "Remove tile".
  • RulerPicker no longer calls onChange when it mounts. Its default name is "Ruler picker".
  • Sortable: items are named by getItemLabel, then textValue, then their id.
  • ListBox: selected items show a check, and only the highlighted item gets the accent background. data-selected and data-disabled are present or absent instead of "true"/"false".
  • Bubble follows the align of the Message it sits in unless you set it.
  • MessageAvatar lines up with the last bubble above a footer of any height.
  • MorphicToast keeps your title's capitalisation.
  • BreadcrumbPage is announced as the current page, not a disabled link.

Fixedยท 34

  • CopyToClipboard: copying is confirmed without any setup. Without an AnchoredToastProvider, the tooltip shows copiedText and screen readers announce it.
  • Tooltip-style anchored toasts show their description. CopyToClipboard's toast was empty before.
  • CopyToClipboard lays out correctly in right-to-left pages, and the full value shows on hover when the field cuts it off.
  • useCopyToClipboard calls onError for an empty value instead of failing silently.
  • AccordionTrigger and CollapsibleTrigger look disabled when they are.
  • Dark mode: muted text, such as descriptions, labels and hints, now meets WCAG AA contrast on cards, popovers and muted surfaces.
  • TabsList, and the shortcuts in Menu, ContextMenu and Command, now meet WCAG AA contrast. A shortcut on the highlighted item takes the item's text color instead of staying grey on the highlight.
  • Calendar: "today" can no longer shift to a different date while the calendar stays mounted.
  • Right-to-left pages: Calendar, Carousel, Drawer, Sidebar, Timeline, Slider, Resizable, Sortable, RulerPicker, DashboardGrid, Draggable, ColorPicker, InputPhone, InputSensitive, FileUpload, Message and Bubble lay out, drag and respond to arrow keys the right way round, and directional chevrons mirror.
  • A ref passed to DashboardGrid, Draggable, Sortable, WheelPicker, WaveformScrubber, Orb, KineticClick or a ResizableHandle no longer stops dragging, measuring or hit-testing from working.
  • Slider: the segmented slider shows keyboard focus, and vertical sliders get their track and thumb sizes.
  • ListBox: a ListBoxGroup is named by its ListBoxLabel.
  • Grid: GridItem's colStart and colEnd count from the start edge in right-to-left pages too.
  • ThemeProvider: a storageKey or palette name containing </script> can't break out of the inline script.
  • DashboardGrid: tiles, the drop placeholder and the grid lines line up, also with containerPadding. Tiles wider than the columns shrink when the breakpoint changes, and statics are never overlapped after compacting.
  • Draggable: the panel stays on screen when the window shrinks, maximising follows the window, and it no longer points aria-labelledby at a missing title.
  • Gauge and CircularProgress have an accessible name and value text. A max of 0 or less no longer produces NaN, and the indeterminate spinner slows down under reduced motion.
  • DotMatrix pauses while offscreen and has a name by default.
  • WheelPicker calls onValueChange when uncontrolled, forgets wheels that unmount, and lets the page scroll past it at either end.
  • WaveformScrubber: arrow keys move the position when uncontrolled.
  • Carousel: the slide stays in place after a resize, a custom onClick on the arrows no longer replaces scrolling, inputs inside slides can be focused, and plugins are cleaned up.
  • Calendar: { dayOfWeek: 0 } matches Sundays, picking a range end in a later month keeps that month in view, and the month and year views respect minDate and maxDate.
  • DatePicker: a controlled null clears the date, typed dates respect minDate, maxDate and disabled, impossible dates like 2026-02-31 are rejected, and the inputs can be labelled.
  • OptionPicker: the selected option is exposed to screen readers, the opening easing applies, and every option is shown, not just the first five.
  • ColorPicker: typing HSL values gives the colour typed, the opacity slider works right to left, and hex accepts #abc and #rrggbbaa. Colour strings keep their alpha.
  • InputPhone: countries that share a dial code, such as Canada and the US, stay selected; a Label or Field names the input; and the country search no longer zooms the page on iOS.
  • InputPayment and InputPhone fields keep a name from a Label or Field.
  • InputSensitive: a Label reaches the input while the value is masked.
  • FileUpload: your onChange on FileUploadInput no longer stops files being added, quick successive drops keep every file, sizes of 1 TB and up format correctly, and a file dropped on a disabled zone no longer opens in the browser.
  • MorphicToast: a toast shown again right after dismissing one with the same id stays visible.
  • Toast: toasts at the top of the screen leave upwards.
  • Sidebar: no error in browsers without the Cookie Store API, โŒ˜/Ctrl + B is left alone inside text fields, and the tooltip opens away from a right-hand sidebar.
  • PaginationInput: your onBlur or onKeyDown no longer stops Enter from going to the page.
  • AgentSteps: the executing, planning and completed icons render as icons. Large labels are no longer cut off, and long ones end in an ellipsis.

Deprecatedยท 5

  • ColorPicker's showAlphaSlider: use showLightnessSlider.
  • DotMatrix's ariaLabel: use aria-label.
  • Carousel's opts.speed, which never had an effect: use opts.duration.
  • OTPField, OTPFieldGroup, OTPFieldInput and OTPFieldSeparator: use the InputOtp names.
  • Grid's justify="between": use justifyContent="between".

Addedยท 1

  • Every component prop now has a description, in your editor's hover and in the Agent Skill references.

Fixedยท 3

  • DashboardGrid: a tile's own isDraggable and isResizable now apply. Before, only the grid's settings did.
  • DotMatrix: autoplay={false} now stops every preset animation, not only some of them.
  • InputSensitive: onCopy is typed as the callback it is, called after the copy button copies the value.

Removedยท 1

  • Props that did nothing and only showed up in autocomplete: Carousel's activeIndex (read it from useCarousel()), ColorPicker's showOpacitySlider, and the isDragging, isResizing, isStatic, isMinimized, isHoveredTarget and isKeyboardActive flags on SortableItem, DashboardTile and Draggable.

Changedยท 1

  • SortableItemHandle's id is now the element's HTML id, as on every other part. It was ignored before.

Fixedยท 3

  • No light flash on load in dark mode, with nothing to add to your layout. ThemeProvider now applies the saved theme and palette before the first paint, on server-rendered pages as well as client-only apps. Before, a server-rendered page painted in light mode until React hydrated, and apps needed their own <head> script plus suppressHydrationWarning on <html>. Remove both when you upgrade. The provider leaves <html> alone until React has hydrated, so there is no hydration warning to suppress, then moves the theme there when the browser is idle. With a Content Security Policy that requires a nonce for inline scripts, pass it with the new nonce prop.
  • useTheme() settles on the saved theme before the browser paints, so a switcher no longer shows the wrong mode for a frame after load.
  • Orb picks the right colours before hydration.

Changedยท 2

  • color-scheme: dark is set by the stylesheet with the dark tokens, so scrollbars and native form controls are dark from the first paint.
  • The dark: variant also matches <html> itself, so @variant dark works inside :root { โ€ฆ }. Override dark tokens that way rather than with a plain .dark { โ€ฆ } rule, which only applies once React has hydrated:

The components XiodUI builds itself, rather than on a Base UI primitive, now match Base UI's keyboard, screen reader, touch and reduced-motion behaviour.

Addedยท 8

  • Swappable icons. Replace any built-in icon with your own โ€” from any icon library, an inline <svg>, or an emoji. Pass an icon prop to change one instance (icon, or named props such as prevIcon / nextIcon), or wrap your app in IconProvider from xiod-ui/icon-provider to change it everywhere. Existing code is unaffected. See Icons.
  • render on 31 more components, so you can swap the rendered element or merge a component into one of your own anywhere in the library: AgentSteps, Alert, AlertDialog, Breadcrumb, ButtonGroup, Calendar, Carousel, ColorPicker, Command, ContextMenu, DatePicker, Dialog, DotMatrix, Empty, FileUpload, Frame, Group, InputGroup, Kbd, KineticClick, Marker, Menu, Message, NavigationMenu, Pagination, Resizable, RulerPicker, Sidebar, Skeleton, Table, Waveform and WheelPicker.
  • An agent skill, so coding assistants know the library's real API instead of guessing at it. Install it with npx skills add ImKKingshuk/XiodUI.
  • PreviewCardCreateHandle, to open a PreviewCard from a trigger outside it, as Dialog, Popover, Tooltip and the other popups already allow.
  • Form support: name on ListBox and InputPhone (InputPhone submits the E.164 number), and defaultValue on ListBox. FileUpload's input now carries dropped files too, so a plain form submit sends them.
  • onFilesRejected on FileUpload, for files over maxFiles.
  • DraggableHandle, to move a Draggable panel from a part you choose.
  • onError on useCopyToClipboard.

Changedยท 4

  • Breaking. 38 compatibility aliases were removed. Each part now has exactly one name. If you used any of the names on the left, rename them:
    RemovedUse instead
    DropdownMenu, DropdownMenu* (16 exports)Menu, Menu*
    HoverCard, HoverCardArrow, HoverCardContent, HoverCardTriggerPreviewCard, PreviewCardArrow, PreviewCardPopup, PreviewCardTrigger
    DialogContent, AlertDialogContentDialogPopup, AlertDialogPopup
    DialogOverlay, AlertDialogOverlayDialogBackdrop, AlertDialogBackdrop
    PopoverContent, SelectContent, TooltipContentPopoverPopup, SelectPopup, TooltipPopup
    MenubarContent, MenubarSubContentMenubarPopup, MenubarSubPopup
    ContextMenuContent, ContextMenuSubContentContextMenuPopup, ContextMenuSubPopup
    AccordionContent, CardContent, CollapsibleContentAccordionPanel, CardPanel, CollapsiblePanel
    TabsContent, TabsTriggerTabsPanel, TabsTab
    RadioGroup, RadioGroupItemRadio, RadioItem

    The import path and the props are unchanged โ€” only the name moves.

  • MorphicToast's animation and colour tokens (--morphic-duration, --morphic-spring-easing, --morphic-state-*) moved into xiod-ui/styles, so you can now override them from your own stylesheet.
  • ListBox is a single tab stop: arrow keys, Home/End and typing a letter move between options, as in a native list box.
  • copyToClipboard from useCopyToClipboard now resolves to whether the copy succeeded.

Fixedยท 14

  • An icon in an Autocomplete or Command item no longer sits flush against its label.
  • Loader, Gauge, CircularProgress, DotMatrix and the InputPayment card logos no longer shrink to icon size inside a Button, Empty, InputGroup or Sidebar.
  • AgentSteps, DotMatrix and MorphicToast no longer add a copy of their styles to the page for every instance, and each DotMatrix keeps its own speed, gradient and glow.
  • Keyboard:
    • Calendar supports Home/End, PageUp/PageDown (Shift for a year) and no longer takes focus when it re-renders.
    • The ColorPicker arcs, DashboardGrid tiles, Draggable panels and Sortable items can be moved and resized from the keyboard. Escape cancels a Sortable move.
    • RulerPicker supports every slider key.
    • InputPhone's country list works with the arrow keys and Enter.
    • Carousel's arrow keys no longer fire from text fields or sliders inside a slide.
    • Drawer menu items and the MorphicToast action show keyboard focus.
  • Screen readers:
    • Moves in DashboardGrid and Sortable are announced, and so are FileUpload changes (including rejected files), AgentSteps progress and MorphicToast messages. MorphicToast now announces its first toast and no longer reads each toast twice.
    • Step statuses and upload errors are spoken, not only shown.
  • Pointer and touch:
    • Right and middle clicks no longer start drags, and an interrupted touch drag snaps back instead of sticking.
    • A Resizable drag cut short (by the browser or by unmounting) no longer leaves the resize cursor on the page, and handles work with touch.
    • A cancelled touch on WheelPicker no longer selects a value.
    • FileUpload's drop zone no longer flickers as the pointer crosses its content.
    • Backspace over a (, ) or - in InputPhone deletes the digit before it instead of doing nothing, and the caret stays in place.
  • Reduced motion: Waveform, WheelPicker, RulerPicker, Carousel autoplay, AgentSteps, KineticClick, MorphicToast and CopyToClipboard all respect it.
  • Focus: removing a FileUpload file or clearing InputPhone keeps focus where you are.
  • InputSensitive's text no longer runs under its copy and reveal buttons, the reveal button works while the value is masked, and copying works on plain http pages.
  • MorphicToast stays open while it has focus or the tab is in the background, and its shape renders with any toast id.
  • CopyToClipboard works on plain http pages and shows "Copied!" only after a copy succeeds.
  • KineticClick is sharp on high-density screens and bursts from the element when triggered from the keyboard.
  • Waveform draws only while something changes, instead of every frame.
  • SidebarMenuButton variant="outline" draws its border again, and a SidebarMenuButton or SidebarMenuAction that opens a Menu keeps its open styles while the menu is open.

Fixedยท 2

  • ColorPicker: the sliders no longer open toward a cramped edge when there is room on the other side.
  • ColorPicker: the arcs no longer jump to the other side while the picker closes.

Fixedยท 2

  • ColorPicker's sliders and MorphicToast's pill no longer shrink to icon size.
  • DashboardGrid no longer pushes tiles that span several columns off-screen.

Changedยท 1

  • Updated the xiod-icons dependency.

Initial public release.

Addedยท 3

  • 89 accessible components built on Base UI and Tailwind CSS 4.
  • 19 colour palettes โ€” 9 core (clay, sepia, sage, lagoon, cobalt, iris, roast, crimson, sorbet) and 10 expressive (riso, afterglow, cathode, ion, cel, taffy, mochi, toxin, cinder, blacklight).
  • Per-component subpath exports (xiod-ui/button), a design-token stylesheet at xiod-ui/styles, and ThemeProvider / useTheme at xiod-ui/theme-provider.
January 2026

Project kickoff

Work began on XiodUI's design system and first components.

These notes also ship in the package as CHANGELOG.md.