补丁变更
- 36fc155
Add
scrollItemIntoView()to preserve the position of visible sidebar items while honoring alignment for offscreen items.
最新的更新和功能。查看每个版本中的变更。
Add scrollItemIntoView() to preserve the position of visible sidebar items while honoring alignment for offscreen items.
Allow default Tooltip trigger children to control their line height, preventing inherited text from being clipped.
Position dialogs near the top of the viewport instead of vertically centering them.
Use the elevated surface color for even rows in the default Table variant.
fix(select): align the trigger surface with form controls
Select triggers now use bg-kumo-control, including their open and disabled
states, so they match Input, Combobox, and the rest of the form-control family.
Consumer background classes can still override the default without using
!important. The popup remains on the floating bg-kumo-base surface.
fix(select): anchor the popup below the trigger and expose placement props
Select.Positioner relied on Base UI's alignItemWithTrigger default (true),
which overlays the popup on the trigger so the selected option's text lands on
the trigger's value text, emulating a native <select>. Options always render at
text-base, so on xs/sm triggers the popup was much taller than its anchor,
and Base UI's compensating shift detached it from the trigger — on xs it
overhung by 12.5px above and 45.5px below and sat 8px to the left, covering
adjacent content.
The popup now prefers bottom placement and is offset from the trigger, with
Base UI's collision avoidance still flipping it automatically when the preferred
side lacks space. Placement is configurable:
| prop | default | notes |
|---|---|---|
side | "bottom" | preferred side; still flips automatically on collision |
sideOffset | 4 | gap between trigger and popup, matching Combobox/Autocomplete |
align | "start" | alignment along the trigger edge |
alignOffset | — | additional offset along the alignment axis |
alignItemWithTrigger | false | opt back in to the native <select> overlay |
The remaining Base UI Positioner controls are also forwarded unchanged:
anchor, arrowPadding, positionMethod, collisionAvoidance,
collisionBoundary, collisionPadding, sticky, and
disableAnchorTracking.
The popup also now tracks the trigger width via min-w-(--anchor-width) instead
of min-w-[calc(var(--anchor-width)+3px)], which existed to visually offset the
old item-alignment shift.
Allow non-heading Text variants to inherit line height from their surrounding context.
Make Combobox.Input sit flush with the top and sides of Combobox.Content and remove its bottom corner rounding.
Reduce the trailing inset for buttons inside large InputGroup addons.
Add the Text heading variant with a 16px semibold default and a 20px
size="lg" option. The variant defaults to a span, so callers choose heading
semantics explicitly with as. Deprecate the numbered heading1, heading2,
and heading3 variants.
Collapsible.DefaultTrigger now uses text-kumo-default (neutral) with font-medium instead of the blue text-kumo-link color.
deprecate MenuBar in favor of segmented Tabs
MenuBar component (and its exports) as @deprecated; it will be removed in a future releaseTabs with variant="segmented" (the default Tabs variant)MenuBar is unchanged for existing consumersMenuBar documentation page and demos from the docs siteFix Toast background clipping the ring outline at the corners — the inner background layer's radius (11px) was smaller than the root's rounded-xl (12px), painting over the ring at the corners. Matched them up.
Restore disabled and loading state handling for Toolbar.Button so disabled
controls expose the correct semantics and cannot be activated.
Normalize shadows and outlines on tip-style overlays (Popover, Tooltip, ClipboardText, Chart tooltip).
shadow-kumo-tip-shadow color override so shadows use Tailwind's default translucent black instead of an opaque light-gray in light mode.shadow-md; ClipboardText's "Copied" toast keeps shadow-lg to match the Toast component.outline-kumo-fill to outline-kumo-line, matching every other floating surface (Dropdown, Select, Combobox, Dialog, etc.).kumo-tip-shadow → kumo-arrow-edge and kumo-tip-stroke → kumo-arrow-stroke. The tokens draw the border on Popover/Tooltip arrow SVGs, not a box shadow. Both now resolve to kumo-line, so the arrow border aligns with the popup outline in both modes.Add scrollToItem(id, options?) to useSidebar() for imperatively scrolling
a nav item into the sidebar viewport. Tag items with the new itemId prop on
Sidebar.MenuButton or Sidebar.MenuItem.
Options:
align: "start" | "center" | "end" | "auto" (default "auto" — no-op if
the item is already visible; otherwise scroll the minimum distance).behavior: "auto" | "smooth" (default "auto" — instant, best for
cross-app landings so users don't watch the sidebar animate on entry).
prefers-reduced-motion forces "auto".Scrolls only the sidebar viewport (never the document) and works with
Sidebar.SlidingViews: items register with the provider via an internal
map, so scrollToItem walks up from the target to find its owning viewport
rather than querying the DOM.
Add icon support to filled Badge variants through the icon prop, add linked-badge hover styles, and use the base surface background for outline badges.
Allow users to select and copy LinkButton text while preserving Button text selection behavior.
Update Table rows to use borderless, alternating background styling.
Fix hydration mismatch in the Sidebar's useIsMobile hook on SSR frameworks like Next.js. The hook now uses useSyncExternalStore with a desktop getServerSnapshot, so the server-rendered HTML (desktop <aside>) hydrates cleanly on mobile viewports before switching to the mobile overlay.
Allow Select and Combobox triggers to compose directly with Toolbar.Button and Toolbar.Input through their render props, adding grouped styling and arrow-key focus management while preserving regular Select.* and Combobox.* APIs.
Deprecate Toolbar's configurable size prop and size metadata exports. They remain functional for compatibility; omitting size continues to use the base size.
Forward link-specific props in Tabs and Sidebar so link-rendered tabs can opt out of native button semantics, and Sidebar link buttons preserve attributes like aria-current.
Expose all positioner props on Combobox.Content (anchor, positionMethod, collisionAvoidance, collisionBoundary, collisionPadding, sticky, disableAnchorTracking).
Populate InputArea props in component registry so the docs API reference table renders correctly
Fix Sidebar peeking state during SlidingViews transitions.
Fix Tabs overflow controls when tabs are removed and the remaining tabs fit.
Update the default collapsible trigger and panel styling.
Collapsible.DefaultPanel now uses an inner content wrapper so the outer panel can animate height smoothly while clipping overflow during the transition. Consumers applying custom layout or spacing classes directly to DefaultPanel may need to move those styles to their content, or use Collapsible.Panel for a fully custom layout.
Fix initCatalog so it actually loads the validation schemas.
Previously it triggered a synchronous validation whose "schemas not loaded" error was swallowed, so await initCatalog(catalog) could resolve while hasComponent, componentNames, and the other synchronous catalog APIs still reported no components. It now awaits loadSchemas() directly.
A failed schema load is also no longer cached: retrying initCatalog (or loadSchemas) after a transient failure now re-attempts the import instead of returning the stale rejection.
Fix Shiki highlighter lifecycle in ShikiProvider and CodeHighlighted.
ShikiProvider no longer re-creates the highlighter when a parent rerender passes an equivalent inline languages array — initialization is keyed on the normalized language set. Highlighters are now disposed on unmount and when the engine or language set changes, instead of leaking. CodeHighlighted memoizes the highlighted HTML so unrelated rerenders (such as copy-button state changes) no longer re-highlight unchanged code, and initialization errors are logged once instead of on every render. Reinitializing after a failed initialization now clears the stale error state instead of showing it during the retry.
Reset the Tabs overflow control background so host button styles do not show through the scrim gradient.
Improves Banner contrast and CTA colors, adds compact sizing, and keeps components that consume the updated status tokens visually balanced.
Banner.Action CTA compound that builds on Button with banner-specific accent styling. It supports primary (filled), secondary (accent-hued outline on a transparent background), and ghost variants.size prop to Banner ("base" | "sm"); the compact "sm" size suits dialogs and other tight spaces and sets its Banner.Action children to the xs size.Improve chart loading states with a static, reduced-motion-aware TimeseriesChart skeleton (line and bar variants matching type) and a new loading prop for ChartLegend.SmallItem and ChartLegend.LargeItem.
Add a disabled prop to LinkButton. When disabled, it renders a real disabled <button> (dropping anchor-only attributes and event handlers) and supports title tooltips explaining why the action is unavailable.
Also removes stale Storybook references from the README and drops .stories.tsx generation from the component scaffolder, since Storybook is no longer set up in this repo.
LinkButton now wraps in a Kumo Tooltip when a title is provided, matching Button's behavior. Previously an enabled LinkButton only set a native title attribute; it now surfaces the same styled tooltip on hover and focus.
Add fullScreenOnMobile prop to Sidebar. When set, the mobile navigation
sheet expands to the full viewport instead of leaving a sliver of the page
visible, giving nav items comfortable touch targets. The backdrop is suppressed
and the divider border dropped, since neither has anything to separate. Defaults
to false.
Also adds Sidebar.Close, a ghost button that dismisses the mobile sheet. It is
intended for Sidebar.Header in full-screen mobile layouts where the backdrop is
hidden and there is no adjacent page content to tap.
Also fixes Breadcrumbs.Link shrinking alongside the current crumb. Flexbox
distributed truncation across every crumb, turning the trail into unreadable
stubs; ancestors now hold their width so only the current page truncates.
Add Sidebar.Loading, a nav loading skeleton so apps stop hand-rolling their own. It renders nav-item-shaped placeholder rows (icon + label) grouped like the real nav, composed from SkeletonLine and matching the Sidebar.MenuButton box model so there's no layout shift when the real nav swaps in. Collapse-aware (icon squares only when collapsed) and exposes role="status" with a configurable label.
Add useTableOfContentsActiveId hook for TableOfContents scroll tracking.
The TableOfContents component is presentational, so consumers had to wire up their own scroll-position tracking. This adds a shared hook: pass the section ids (in document order) and it returns the active section id plus a selectSection action for click handling.
const { activeId, selectSection } = useTableOfContentsActiveId({
ids: headings.map((h) => h.slug),
offset: HEADER_HEIGHT,
});
IntersectionObserver), offset by an optional fixed-header offset; supports custom scroll containers via root.location.hash deep links on load and hashchange automatically (opt out with trackHash: false).selectSection pins a clicked section until scrolling settles, so short sections stay highlighted after a jump. Works on browsers without scrollend support.activeId is null on the server).The docs site "On this page" table of contents now consumes this hook instead of its own bespoke observer.
Ship unminified dist output without sourcemaps or declaration maps
Consumers' bundlers minify (and tree-shake) the library code anyway, so
pre-minifying only obscured the shipped modules, and the declaration maps
pointed at source files that aren't published. The package shrinks from
~13.9 MB to ~6.5 MB unpacked, and the code in node_modules is now
readable. No API or behavior changes; final application bundle sizes are
effectively unchanged.
Use a string or numeric Button title as the fallback accessible label when the button has no text children.
Bump Prettier 3.6.2 → 3.9.5 and reformat (Prettier changed e.g. interface heritage-clause wrapping). No functional changes.
Prevent TimeseriesChart tooltips from following the cursor outside the chart after a browser context menu interaction.
ClipboardText: keep the check icon until the last copy click settles, and bump the anchored "Copied" toast (without stacking) when the button is pressed again while it's open.
Render Kumo Link actions inline in compact Banners while keeping CTA actions trailing.
Fix purple badge token fallback colors to use purple OKLCH values.
Add a lint rule that verifies custom components used with Flow.Node's render prop forward refs and spread received props.
Keep TimeseriesChart brush-to-zoom active after replacing ECharts options.
Remove the subtle shadow-xs drop shadow from InputGroup Root and from nested InputGroup.Button, so the component matches the flat appearance of the standalone Input and other form controls (previously non-ghost button variants still had the base Button's shadow-xs).
Bundle the library with vp pack (tsdown) instead of Vite lib mode; declarations are now bundled per entry and export types paths follow the import paths
Use muted chart colors for timeseries axes and horizontal gridlines.
One-time repo-wide format with the repo's own Prettier 3.6.2 (formatting was never enforced; drift accumulated). No functional changes.
Set default text-base and text-lg line heights to 1.5.
Remove inert Tailwind classes surfaced by class sorting: ring alongside ring-2 (overridden — later stylesheet rule wins) and bare outline in three places (no such utility in Tailwind v4; outline-1 already applies the default solid style). No visual changes.
Split Base UI across fine-grained chunks instead of one vendor-base-ui chunk
Components now pull in only the Base UI modules they actually use, improving consumer tree-shaking: a single-Button app bundle drops from ~173 KB to ~129 KB minified (~57 KB to ~44 KB gzipped) compared to 2.8.0.
Add clearer edge affordances when Tabs overflow horizontally.
Show Button title tooltips when the button is disabled or loading.
Fix command palette match highlight contrast in dark mode.
Normalize Tailwind class strings via Oxfmt class sorting (sortTailwindcss, canonical Tailwind order, duplicates removed). No functional changes.
Migrate the toolchain to Vite+ (vp): the library now builds with Vite 8 on Rolldown, tests run through vp test (Vitest), and linting/formatting run through vp lint (Oxlint) / vp fmt (Oxfmt, replacing Prettier). No API changes; published output is functionally identical, though entry files are now re-export facades whose source maps live in the shared chunks, and use-sync-external-store is now an explicit dependency instead of being bundled (bundling it left CJS require("react") calls that broke importing the package directly in Node).
Enable full type-checking in vp check / vp lint (typeAware + typeCheck) and fix the type issues it surfaced in files tsc --noEmit never covered. Only runtime-visible change: the CLI entrypoint explicitly voids its main() promise.
Rewrite Flow to use computed layout over relying on DOM layout.
Flow now measures node sizes, reconstructs the flow tree, and computes node positions and connector paths from that derived state instead of chaining DOM rect reads. This keeps connectors aligned through resize and scroll changes, supports nested flow structures more predictably, and makes anchor-based connector placement follow the anchor midpoint.
Add target prop to Sidebar.MenuSubButton for parity with Sidebar.MenuButton — forwarded to the link when href is set, so link sub-items can control where they open (e.g. same-tab cross-origin navigation).
Add auto-resize support to InputArea and Textarea.
Add vertical reference markers to TimeseriesChart.
Add horizontal threshold lines to TimeseriesChart.
Include chart components exported from multi-component barrel directories in the generated component registry, with complete props metadata for generic interfaces.
Keep the mobile Sidebar open when focus moves to portaled interactive content.
Disable Sidebar.MenuButton tooltips while the sidebar is expanded or peeking.
Add ChoroplethMap, a GeoJSON region choropleth chart component that joins data rows to features by name/nameProperty and shades regions with a continuous visualMap scale. Includes Kumo light/dark map colours, tooltip formatting, optional legend, hover/click callbacks, roam controls, docs, and demos.
Both BubbleMap and ChoroplethMap now apply a d3-geo projection (latitude-clamped Mercator by default; pass another d3-geo projection or null for raw plotting) and size by aspectRatio so the map fills its container without letterboxing. The container height now derives from the projected window's aspect ratio by default; pass an explicit height to opt back into a fixed pixel height.
Update BubbleMap viewport behavior to avoid resetting user pan and zoom while refreshing bubble data.
BubbleMap now defaults roam to false to avoid accidental pan and zoom interactions. Consumers that want drag-to-pan or scroll-to-zoom can pass roam={true}.
Add orientation="vertical" support to Flow for laying out nodes top-to-bottom. The align prop now controls cross-axis alignment in both orientations.
feat(chart): add BubbleMap chart component
New BubbleMap component renders proportional bubbles over a registered
geographic map using ECharts' scatter series. Includes value-based radius
scaling, a mapColors palette addition to ChartPalette, and supporting
types. Also extracts escapeHtml / defaultValueFormat tooltip helpers into a
shared tooltip-utils module reused by SankeyChart.
Keep primary and destructive button active/focus rings matched to their variant color.
Use the Button component for Toast close controls and match the hover tint to the toast variant.
Limit Dropdown content height to available viewport space to prevent overflow.
Replace the internal class merging implementation with cnfast.
fix(button): resolve Firefox rendering artifact when Turnstile is present
Replace translate-y-px with box-shadow: inset 0 1px 0 0 var(--kumo-button-emphasis-bg) on the primary/destructive button emphasis overlay span. The transform triggered a rendering bug in Firefox on pages with Turnstile's contain: strict CSS. The box-shadow achieves the same visual depth effect without the rendering issue.
Fix Dialog size prop to set a fixed width instead of only a minimum width. Previously, dialog content could stretch the dialog beyond its intended size.
Update Base UI to 1.6.0.
Add Toolbar for composing explicit toolbar controls into a shared grouped card.
feat(chart): add enableLegendSelection prop to TimeseriesChart
Opt-in (default false) hidden ECharts legend that lets consumers drive series
visibility imperatively via the legendSelect / legendUnSelect /
legendToggleSelect actions — useful for building a custom interactive legend
with ChartLegend. Series toggled off via the legend are also excluded from the
tooltip. Requires registering ECharts' LegendComponent
(echarts.use([LegendComponent])). When disabled, behaviour is unchanged.
Extend LegendItems to take pointer events & timeseries merges forwardref to support those events
Update the Button primary and destructive variants with token-derived gradient treatments.
Fix horizontal scroll in Sidebar.Content: always apply overflow-x: hidden on the scroll viewport, not just when collapsed. Base UI's ScrollArea.Viewport sets overflow: scroll as an inline style, which allowed ~14px of horizontal overflow when consumer content (e.g. search buttons with keyboard shortcuts) exceeded the sidebar width.
feat(radio): add generic value type support to Radio.Group and Radio.Item
Fix the green Badge variant missing its background color token.
Keep generated component registry descriptions to JSDoc summaries before markdown sections or code examples.
Allow unprefixed Dialog max-width classes to override the default viewport cap at desktop breakpoints.
Sidebar: mobile rewrite, smooth collapse transitions, and new props
New features:
mobileBreakpoint prop on Provider — configurable viewport width for mobile detectioncontentClassName prop on Sidebar root — pass-through class for the inner content containeropen prop now controls the mobile sidebar too, not just desktopFixes:
<nav> + backdrop for simpler, more predictable transitionshidden class from Sidebar.MenuSub so sub-menus participate in collapse animationsinertValue React-version helper — SidebarSlidingView now sets inert imperatively for React 18 compatibilityinert on closed SidebarCollapsibleContent while removing its data-open attributeStyling:
bg-kumo-tint → bg-(--sidebar-active-bg) CSS variable for active/hover/focus backgrounds0.5 → 0.4; chevron gains hover opacity transitionshrink-0 and animated padding on collapsegap transition and tabIndex={-1} on viewportmax-w-(--sidebar-width) to prevent overflow--sidebar-animation-duration CSS variable for slide transitionAdd React 18 and React 19 compatibility checks for Kumo tests.
Fix Chart (and SankeyChart) rendering in dark mode. The chart canvas
now stays transparent so the surrounding bg-kumo-* surface shows through
symmetrically in both modes, and ECharts' built-in "dark" theme is
applied when isDarkMode is true so the tooltip card, axes, splitLines,
and legend text are themed correctly.
fix(sidebar): add text truncation with ellipsis to Sidebar.MenuButton content
Previously, Sidebar.MenuButton used overflow-hidden which clipped long text without showing an ellipsis. Now uses truncate to match Sidebar.MenuSubButton's behavior.
Fix segmented Tabs scroll fade, scroll-into-view, and ring styling:
@property-animated custom properties, fixing proportional fade rendering across browsers.ring ring-kumo-hairline/70 from the inner list to the root container so the segmented variant ring wraps the entire component correctly.Fix Flow connector rendering in Firefox by emitting valid SVG path data without array commas and setting visible overflow on the SVG element attribute.
Restore React 18-compatible Sidebar inert attribute handling while keeping the full React compatibility CI suite.
Fix Combobox and Autocomplete rendering in React 18 by using the explicit context provider API.
Update Banner to use borderless tinted styling by default and add a secondary variant.
Re-export useFilter from Combobox and Autocomplete namespaces. Use it to write custom filter props that preserve Base UI's default case- and accent-insensitive matching via Intl.Collator.
Sidebar: comprehensive modernization
Breaking changes:
Sidebar.Input — build custom search triggers inlineSidebar.MenuAction — unused in practiceSidebar.GroupContent and group-level collapsible props (collapsible, defaultOpen, open, onOpenChange) from Sidebar.Group — use Sidebar.Collapsible at the item level insteadSidebarState type is now "expanded" | "collapsed" | "peeking" (was "expanded" | "collapsed")New features:
contained prop on Provider — absolute positioning for embedded/demo sidebarspeekable prop on Provider — hover/focus collapsed sidebar to temporarily expandanimationDuration prop on Provider — configurable animation timingSidebar.SlidingViews + Sidebar.SlidingView — animated horizontal transitions between navigation surfacesSidebarPanelIcon replacing Phosphor SidebarSimpleIconSidebar.Trigger with aria-expanded and dynamic aria-labelSidebar.Collapsible with keyboard auto-expand on focusToken/styling fixes:
border-kumo-hairline → border-kumo-line throughoutduration-250 → --sidebar-animation-duration CSS custom propertybg-kumo-base → bg-(--sidebar-bg) for theme overridabilityring-2/ring-kumo-brand → outline-none/text-kumo-strong/bg-kumo-tintisolate on sidebar root with low z-index (z-1, z-2) instead of z-20/z-50data-state/data-side/data-variant/data-collapsible attributesTimeseriesChart: React tooltip with Base UI positioning
Replaces ECharts' HTML-string tooltip with a React component positioned by Base UI's Tooltip primitive:
getComputedStyle hackstooltipFollowCursor prop: "both" (default, free-following) or "x" (axis-locked, Recharts-style)tooltipMode prop: "all" (default) or "single" (nearest series to cursor)tooltipMaxItems prop: caps rows in "all" mode with +N more footer (default 10)Intl.DateTimeFormat (locale-aware) instead of ISO stringBanner: replace dark: Tailwind variants with new kumo-banner-info and kumo-banner-warning semantic tokens so dark-mode opacity is baked into the design system. No visual change.
fix(styles): show pointer cursor on clickable Kumo elements by default
Adds a global cursor: pointer rule scoped to elements rendered by Kumo
components, identified by the new data-kumo-component and data-kumo-part
attributes. Interactive component roots and parts now opt into the rule by
setting these attributes, which gives the library a stable scoping primitive
that doesn't couple to Tailwind class names.
Components updated to set data-kumo-component / data-kumo-part:
Button, LinkButton, Link, Checkbox, Radio, Switch, Select (trigger, option),
DropdownMenu (item, link-item, checkbox-item, radio-item, submenu-trigger),
Combobox (trigger, item, clear, chip-remove), Autocomplete (item),
Dialog (trigger, close), Popover (trigger), Tabs (tab),
Collapsible (trigger, default-trigger), Breadcrumbs (link),
TableOfContents (item, group-link), Sidebar (menu-button, menu-sub-button,
trigger, rail), MenuBar (option), Toast (close), SensitiveInput
(toggle-visibility, copy, masked-container).
fix(sidebar): collapsed state styling, transitions, and sliding views
Add flex items-center to ComboboxBase.Icon in TriggerInput for consistency with TriggerValue and Select
Fix Select placeholder not showing when renderValue is provided and the value is empty.
Update semantic color tokens to better represent status icons and indicators:
Adjust toast visual styling for improved readability and emphasis: increase background tint intensity for success/warning/info variants, refine description text contrast, and update close-button icon contrast.
Fixed vertical alignment of checkbox and radio indicators with multi-line labels.
When label text wrapped to multiple lines, the indicators were vertically centered against the entire text block. They now align to the top, sitting next to the first line of text.
echarts is now an optional peer dependency. If you don't use Chart components (Chart, TimeseriesChart, SankeyChart), it will no longer be installed automatically. If you do use them, run npm install echarts (as documented).
Added Badge dot styling as a new variant for indicators that need a subtle visual cue.
Updated badge docs and demo examples to reflect the new badge variant and dot-style behavior.
Update Base UI to 1.5.0.
Fix InputGroup focus ring thickness and color: container mode uses 1.5px ring (wraps entire group including buttons), hybrid container zone and individual mode use 1px ring (thin to avoid colliding with adjacent buttons), and all modes use ring-kumo-focus/50 (50% opacity) to match the standalone Input component.
Fix error state red border on Combobox, Select, Autocomplete, and SensitiveInput to match Input behavior
Add inline label layout and fix auto-assigned node colors in tooltips
Fix Tooltip popup overflowing viewport when content is wider than available space. The popup now constrains its width to var(--available-width), a CSS variable provided by Base UI's Positioner that reflects the space between the trigger and the viewport edge.
Fix language alias normalization in ShikiProvider
normalizeLanguage() function that maps common language aliases (js, ts, sh, yml, py, md, gql) to their canonical SupportedLanguage namesShikiProvider when preloading grammars, so passing ['js', 'ts'] works the same as ['javascript', 'typescript']highlight() hook at runtime, so code fences using js or ts highlight correctly without warningsnormalizeLanguage from @cloudflare/kumo/code for consumers who need to normalize aliases themselvesmdx alias since MDX has a distinct grammar that would lose JSX highlighting if mapped to markdownfix(banner): remove variant selection background for legibility
Selected text inside Banner now uses the browser default selection color
instead of a same-hue variant-tinted background. The previous
selection:bg-kumo-{info,warning,danger} utilities produced low contrast
between the selection background and the variant text color (most notably
in light mode for the error and alert variants), making selected text
hard to read.
Add left and right props to SankeyChart for controlling series layout padding
Fix tooltip popup exit transitions by animating the Tailwind scale property alongside opacity.
Add passwordManagerIgnore to Input for suppressing password manager overlays on non-credential fields.
Add scroll fade to segmented tabs. When tabs overflow, gradient masks appear on the edges based on scroll position via scroll-driven animations (Chrome 115+, degrades gracefully). Scrollbar is hidden; the fade is the scroll affordance.
Add size="sm" variant to Tabs component (h-6.5 / 26px, matching Input sm)
Forward toastManager prop on <Toasty> so code outside the React tree (timers, query-cache listeners, module-load callbacks) can dispatch toasts via a manager created by createKumoToastManager(). Also surface createKumoToastManager on the top-level package export (previously only available via the deep @cloudflare/kumo/components/toast path).
Add transparent background to SankeyChart component
Expose optionUpdateBehavior prop on TimeseriesChart to control how ECharts applies option updates
Add hideLabel prop to Field so components can skip the native <label> while keeping description/error wiring. Use it in Select with Base UI's Select.Label to fix hover/focus coupling between the label text and trigger.
fix(input): render error and description props without requiring a label
fix(radio): prevent radio button distortion with long labels by adding shrink-0 to the default appearance radio indicator
Fix overflowing segmented Tabs drag-to-scroll interactions so mouse and touch drags reliably scroll while normal tab clicks still activate tabs.
Create Sankey Chart component
Fix CommandPalette List bottom ring being clipped by Footer background. Add scroll padding to prevent items from clipping behind rounded corners.
Deprecate to prop on Link in favor of href. The to prop is a routing-framework concept that doesn't belong on a presentational component. Use href for all link destinations and configure a LinkProvider wrapper to bridge to your router. to continues to work but emits a dev-mode deprecation warning.
Allow LayerCard.Primary and LayerCard.Secondary to accept all standard HTML div attributes, including data-testid for testing.
Set cursor-default on Tooltip triggers so disclosure buttons don't appear clickable. Overridable via className.
Export Combobox.Trigger, Combobox.Value, and Combobox.Icon — the raw Base UI primitives for building custom combobox triggers. Use these when you need full control over the trigger's visual treatment (e.g. a sidebar account switcher that renders as a plain button instead of an input-like control).
fix(CloudflareLogo): remove registered trademark symbol from full logo variant
Fix Google Translate DOM mutation crash in Button
Remove z-50 from mobile Sidebar Dialog backdrop and panel. The z-50 caused portaled floating elements (Popover, DropdownMenu, Select, Combobox) opened from inside the Sidebar to render behind the Dialog backdrop. Matches the pattern used by Kumo's own Dialog component, which relies on DOM order for stacking with no explicit z-index. Also adds data-sidebar-backdrop and data-sidebar-popup attributes as stable CSS hooks.
fix(combobox): forward all props from TriggerValue to ComboboxBase.Value, enabling placeholder support and styled placeholder text via data-[placeholder]:text-kumo-placeholder
fix(registry): correct Select component metadata for AI-generated code
The component registry metadata was incorrectly typing Select's value, defaultValue, and onValueChange props as string, causing AI agents to produce broken code when implementing Select with object values (e.g., rendering object.value in the trigger instead of the label).
Changes:
value type: string → T (generic, matches actual component interface)defaultValue type: string → TonValueChange type: (value: string) => void → (value: T) => voidrenderValue prop: (value: T) => ReactNode — required for object valuesitems prop: supports both Record<string, string> and Array<{ label, value }> formsisItemEqualToValue prop: required for object equality comparisonGracefully fall back to default variant instead of crashing when an invalid variant prop is passed at runtime. Previously 22 of 25 components would throw TypeError on unknown variant values; all 25 now use a shared resolveVariant() utility that returns the default config and logs a dev warning.
Forward all Base UI Panel props (including keepMounted and hiddenUntilFound) through Collapsible.DefaultPanel. Previously these were silently dropped because DefaultPanel used a standalone props interface instead of extending BasePanelProps.
Fix registry codegen to match demo examples when component export name differs from directory name (e.g. DropdownMenu vs dropdown). This restores missing examples for DropdownMenu and other affected components.
TooltipProvider props (delay, closeDelay, timeout) are now shown in the Tooltip component's API Reference on the docs site.
Rebalanced semantic text token usage to improve hierarchy and consistency across components, docs, and generated Figma output.
text-kumo-strong represents high-emphasis text and text-kumo-inactive is lighter/inactive in both light and dark modes.text-kumo-strong to text-kumo-subtle where content is supportive metadata, labels, or secondary text.BREAKING: Checkbox onCheckedChange now receives event details as second argument
The onCheckedChange callback signature now matches Base UI, providing access to the underlying event:
// Before
onCheckedChange={(checked) => console.log(checked)}
// After (event details available as optional second arg)
onCheckedChange={(checked, eventDetails) => {
console.log(checked);
console.log(eventDetails.event); // native event
}}
Removed deprecated props:
onChange - use onCheckedChange insteadonValueChange on individual checkboxes - use onCheckedChange insteadonClick - was redundant, use standard React event handling via spread propsMigration:
// Before (deprecated)
<Checkbox onChange={(e) => console.log(e.target.checked)} />
<Checkbox onValueChange={(checked) => setChecked(checked)} />
// After
<Checkbox onCheckedChange={(checked) => setChecked(checked)} />
Note: Checkbox.Group's onValueChange prop is unchanged - it still accepts (values: string[]) => void.
feat(Collapsible)!: refactor to compound component API
Breaking change: Collapsible now uses a compound component pattern matching other Kumo components like Popover and Dialog.
<Collapsible label="Show details" open={open} onOpenChange={setOpen}>
Content here
</Collapsible>
<Collapsible.Root open={open} onOpenChange={setOpen}>
<Collapsible.Trigger>Show details</Collapsible.Trigger>
<Collapsible.Panel>Content here</Collapsible.Panel>
</Collapsible.Root>
For the quickest migration, use the new DefaultTrigger and DefaultPanel components which preserve the previous styling:
<Collapsible.Root open={open} onOpenChange={setOpen}>
<Collapsible.DefaultTrigger>Show details</Collapsible.DefaultTrigger>
<Collapsible.DefaultPanel>Content here</Collapsible.DefaultPanel>
</Collapsible.Root>
| Component | Description |
|---|---|
Collapsible.Root | Manages open state |
Collapsible.Trigger | Composable trigger with render prop support |
Collapsible.Panel | Content container |
Collapsible.DefaultTrigger | Pre-styled trigger with caret icon (migration helper) |
Collapsible.DefaultPanel | Pre-styled panel with border-left accent (migration helper) |
feat(Text): decouple visual heading variants from semantic HTML elements
Breaking change: heading1, heading2, heading3 variants no longer auto-render <h1>, <h2>, <h3> tags. They now render as <span> by default. Use the as prop to set the appropriate semantic heading level for your document outline.
Before:
<Text variant="heading1">Title</Text> // rendered <h1>
After:
<Text variant="heading1" as="h1">
Title
</Text> // explicit semantic element
The as prop is now restricted to valid text elements: "h1" through "h6", "p", and "span".
BREAKING (v2): Text requires an explicit as prop when variant is a heading ("heading1", "heading2", "heading3").
The previous major bump (#393) decoupled heading variants from semantic HTML — heading variants render as <span> unless an as prop is provided. That made the library more flexible but introduced a silent accessibility footgun: forgetting as on a real section heading produced a <span>, excluding it from the document outline without any type-level feedback.
This change makes as required for heading variants via a discriminated union. Body and monospace variants are unchanged (as remains optional; defaults to <p> and <span> respectively).
Every <Text variant="heading1">, <Text variant="heading2">, <Text variant="heading3"> must now pass as. TypeScript will flag each call site:
// Before (compiled, silently produced a <span>)
<Text variant="heading1">Page Title</Text>
// After (required)
<Text variant="heading1" as="h1">Page Title</Text>
// Still allowed — decorative heading-styled text that is NOT a section heading:
<Text variant="heading1" as="span">Big bold card label</Text>
For each heading call site, decide whether it's a real section heading (use as="h1"/"h2"/etc.) or decorative (use as="span"). Codemod cannot make this choice mechanically — it is a semantic judgment per usage.
Body and monospace variants: no changes required.
feat(radio, checkbox, switch): add composable Legend sub-component for group components
Radio.Legend, Checkbox.Legend, and Switch.Legend sub-componentsclassName for full styling control (e.g. className="sr-only" to visually hide)legend string prop optional when using the sub-component insteadSwitch.Group no longer renders a visible border/padding/rounded container — now consistent with Radio.Group and Checkbox.Group. Use className to add a border if needed.Add InputGroup compound component for composing decorated inputs
Compound structure: InputGroup, InputGroup.Input, InputGroup.Addon, InputGroup.Suffix, InputGroup.Button.
label, description, error, required, and labelTooltip directly to InputGroupxs, sm, base, lg) propagate to all sub-components via context, including icon sizing in addonsInputGroup.Addon — positions icons, text, or buttons at align="start" (default) or align="end" of the inputInputGroup.Suffix — inline text suffix (e.g. .workers.dev)InputGroup.Button — ghost button for secondary actions with tooltip supportInputGroup.Label — use InputGroup.Addon insteadInputGroup.Description — use InputGroup.Suffix instead{
/* Reveal / hide password */
}
<InputGroup>
<InputGroup.Input
type={show ? "text" : "password"}
defaultValue="password"
aria-label="Password"
/>
<InputGroup.Addon align="end" className="pr-1">
<InputGroup.Button
size="sm"
aria-label={show ? "Hide password" : "Show password"}
onClick={() => setShow(!show)}
>
{show ? <EyeSlashIcon size={16} /> : <EyeIcon size={16} />}
</InputGroup.Button>
</InputGroup.Addon>
</InputGroup>;
{
/* Search input */
}
<InputGroup>
<InputGroup.Addon>
<MagnifyingGlassIcon className="text-kumo-subtle" />
</InputGroup.Addon>
<InputGroup.Input placeholder="Search..." />
</InputGroup>;
Adds Autocomplete component. A free-form text input with an optional filtered suggestion list. Unlike Combobox, the value is not constrained to the items list.
feat(radio): accept ReactNode for Radio.Item label and honor controlPosition on card appearance
Radio.Item's label prop now accepts ReactNode, allowing icons, badges, or other markup alongside text.Radio.Group's controlPosition prop now takes effect on appearance="card". Card appearance continues to default to "end" (radio on the right); pass controlPosition="start" to render the radio on the left of the label and description.Polish TableOfContents indicator and semantic HTML
ul/li HTML structurehref and active props to TableOfContents.Group for clickable labelsfeat(table): add onCheckedChange prop to Table.CheckCell and Table.CheckHead, aligning with the Checkbox component's signature.
The new prop exposes an optional second argument with event details, matching Base UI's idiom:
<Table.CheckCell
checked={selected.has(row.id)}
onCheckedChange={(checked, eventDetails) => {
toggle(row.id);
eventDetails?.event.stopPropagation();
}}
/>
The existing onValueChange prop still works but is now deprecated and flagged by the no-deprecated-props lint rule. It will be removed in a future major version. Migrate by renaming the prop — the single-argument callback shape is preserved.
This change is additive and does not require consumer code changes at this time.
Expand Text component's as prop to accept additional HTML text elements: label, dt, dd, li, figcaption, legend, pre, code, em, strong, small, abbr, and time. This unblocks downstream usage in Stratus where Text needs to render as definition list terms, labels, and code elements.
Remove invalid hover border utility from secondary button variants to keep hover styling consistent and avoid unintended class output.
Update chart color docs and demos, including sequential heatmap/CVD coverage and improved chart demo behavior.
Combobox.Item now renders a visible disabled state when the disabled prop is set. Previously the prop was forwarded to Base UI (so click/keyboard selection were correctly blocked) but the row looked identical to an enabled one. Adds data-[disabled]:* Tailwind classes for muted text, cursor-not-allowed, reduced opacity, and suppresses the highlight background on disabled rows during keyboard navigation. Also fixes className passthrough — user-supplied classes are now merged via cn() instead of being overridden.
Improve focus ring consistency and clipping behavior across inputs and related controls.
focus-within and remove duplicate input-level ring styles.Select trigger and option focus styles to use inset focus rings to prevent clipping in rounded/overflow contexts.InputGroup and InputGroup.Button focus ring color to ring-kumo-focus, including hybrid container-zone focus ring classes.react-day-picker) focus ring token to var(--color-kumo-brand).kumo-binding.css to use var(--color-kumo-focus) at 1px weight.Allow CommandPalette.Input to accept standard HTML input attributes (autoComplete, autoCorrect, autoCapitalize, spellCheck, data-*, etc.) by extending its props type with InputHTMLAttributes<HTMLInputElement>. Export new CommandPaletteInputProps type.
Fix InputGroup hover state incorrectly propagating to the first child button (e.g. in Pagination.Controls). Root now renders as <div> instead of <label> when it contains multiple labelable controls.
Fix Table body cells rendering at 16px. The Table root now sets text-base (14px) so <td> cells match Kumo's default body font-size instead of inheriting the browser default. Also replaces an arbitrary text-[14px] in Empty with text-base.
Improved focus and keyboard accessibility styles across Kumo components and docs navigation.
kumo-focus semantic token to the theme generator config and generated theme-kumo.css output.Button, Input, InputGroup, Select, Checkbox, Radio, Switch, Sidebar, Tabs, Menubar, and related controls) for more consistent and visible keyboard focus visibility.kumo-focus ring to keep pointer and keyboard focus visually consistent where browsers apply :focus-visible heuristics to typed-input controls.Select and Input styling/state combinations to align focus visuals with current semantic token usage.SidebarNav keyboard-focus affordances (links, section toggles, search trigger) and adjusted collapsible list overflow so focus rings remain visible.Select with kumo semantic tokens.Fix InputGroup container className to enforce mb-0, ensuring all container variants (not just the standalone <label> mode) reset inherited bottom margin.
Fix InputGroup label wrappers to enforce mb-0, preventing inherited label margins from shifting layout and click-target overlays.
chore: update @base-ui/react to v1.4.0
Bugfix release with improvements to Popover hover state, Checkbox/Switch readOnly mode, Select touch handling, Tabs activation direction, Toast timers, and various other fixes. No breaking changes.
feat(chart): rename formatter to dangerousHtmlFormatter for XSS awareness
BREAKING CHANGE: The formatter property in KumoChartOption['tooltip'] has been renamed to dangerousHtmlFormatter. This change makes the security implications of using HTML formatters more explicit to developers. The API remains identical—only the name has changed.
Migration: Replace formatter with dangerousHtmlFormatter in your chart tooltip configurations.
feat(tooltip, popover): deprecate asChild in favor of render prop
Unifies composition patterns across the library by adopting Base UI's render prop pattern. The asChild prop is now deprecated on:
TooltipPopover.TriggerPopover.CloseMigration:
- <Tooltip content="Save" asChild>
- <Button>Save</Button>
- </Tooltip>
+ <Tooltip content="Save" render={<Button>Save</Button>} />
- <Popover.Trigger asChild>
- <Button>Open</Button>
- </Popover.Trigger>
+ <Popover.Trigger render={<Button>Open</Button>} />
- <Popover.Close asChild>
- <Button>Close</Button>
- </Popover.Close>
+ <Popover.Close render={<Button>Close</Button>} />
The asChild prop remains functional for backward compatibility but will be removed in a future major version.
feat(popover): expose anchor prop on Popover.Content for virtual positioning
Forwards Base UI's anchor prop through Popover.Content to the underlying Positioner, enabling popover positioning against custom elements, refs, or virtual points (e.g., a DOMRect from getBoundingClientRect()). This is useful when the popover trigger and the desired anchor are in different component trees, or when anchoring to a coordinate rather than a DOM element.
Convert Table of Contents to exported Kumo component
feat(Select): add size prop (xs/sm/base/lg) matching Input and Combobox heights
feat(layer-card): support simple card usage and deprecate Surface
LayerCard to be used directly without LayerCard.Primary for simple single-layer card layoutsLayerCard.Secondary and LayerCard.Primary supported for the existing layered card patternSurface in favor of LayerCard while keeping the old API working as a compatibility wrapperLayerCard, including table examples that no longer need a nested LayerCard.Primaryfix(pagination): add ARIA attributes for screen reader accessibility
<nav> for proper landmark navigationaria-live="polite" and aria-atomic="true" to status text for page change announcementsnavigation to PaginationLabels for i18n customization of the nav aria-labelfix(chart): escape HTML in tooltip series name and values
Escapes HTML entities in TimeseriesChart tooltip series names and values before rendering.
fix(combobox): make TriggerInput caret button clickable for Playwright tests
fix(dropdown): pass children through when render prop is provided on DropdownMenu.Trigger
fix(Select): TypeScript inference with strictNullChecks and renderValue/placeholder interaction
TypeScript fix: Under strictNullChecks, using value={objectOrNull} would cause T to be inferred as never, making callbacks like onValueChange and renderValue unusable. This is now fixed.
Runtime fix: renderValue is now only called with non-null values. When value is null, the placeholder is shown instead. Previously, renderValue would receive null at runtime despite being typed as (value: T) => ReactNode.
// Recommended pattern
<Select
placeholder="Select..."
value={value}
onValueChange={setValue} // value is T | null (works with strictNullChecks)
renderValue={(v) => v.name} // v is T (non-null), no defensive coding needed
/>
Fix sidebar collapsible content snapping shut instead of animating smoothly when closing.
fix(table): align sticky column colors with compact header variant
fix(tokens): correct text-kumo-subtle dark mode value to provide visible contrast
Updated the token value for kumo-line and kumo-hairline in dark mode so they are more visible.
kumo-line usages with kumo-hairline across Kumo components and docs UI/content stylesring-kumo-line for shadowed surfaces (for example combobox, dialog, select, dropdown, toast, and related surface wrappers)fix(a11y): add accessible labels to icon-only controls
Add Enter key navigation to Pagination page number input and new pageSelector prop for dropdown mode
Pagination.Controls now navigates on Enter key press (previously only on blur)pageSelector prop on Pagination.Controls: set to "dropdown" to render a Select dropdown instead of a text input for page selectionAdd disabled option support, groups, group labels, and separators to Select
Select.Option now accepts disabled and className propsSelect.Group and Select.GroupLabel sub-components for organizing options under labeled headersSelect.Separator sub-component for visual dividers between groupsitems object-map prop now accepts SelectItemDescriptor values with disabled metadataExpose delay and closeDelay props on Tooltip component to control open and close timing. These props are forwarded to the underlying Base UI Trigger component.
Input and InputArea now automatically apply error styling when the error prop is truthy. You no longer need to set variant="error" separately - just pass an error message and the styling is applied automatically. The variant="error" prop is now deprecated but still works for backwards compatibility.
Adjust semantic tint usage for status/error ring styles across core form and feedback components.
Badge and Banner components to use *-tint tokens.kumo-danger to a darker token to improve a11y contrast.text-color-badge-red-subtle token in replacement of the danger token.Fix CodeBlock crash when an unsupported lang value is passed at runtime. The codeVariants() function now uses optional chaining with a nullish coalescing fallback to the default language, matching the defensive pattern already used by switchVariants() and badgeVariants().
fix(select): use ring-kumo-hairline token in Select popup (missed in PR #355)
Fix Select popup scrolling and height behavior; align popup/list structure with Base UI. Split popup into frame (Popup) and scroll container (List) to match Combobox pattern and fix touch scroll on long lists.
fix(loader): add ARIA attributes for screen reader accessibility
Added role="status" and aria-label="Loading" to the Loader SVG component to make it accessible to screen readers. This resolves a WCAG 2.1 SC 4.1.3 (Status Messages) violation where assistive technology users received no indication that content was loading.
Refine badge semantics/fill styling and banner tone updates
Badge variant model to prioritize semantic variants (primary, secondary, error, warning, success, info) with updated descriptions and primary as default.yellow with purple since yellow doesn't meet a11y contrast requirements, and keeping docs/demo examples in sync.default, alert, error) to stronger tinted backgrounds and borders.theme-kumo.css to match the new badge color system.Fix Switch label click not toggling when a custom id prop is provided
The id was not being forwarded to Base UI's Switch.Root, causing a mismatch between the label's htmlFor and the button's actual id.
Align semantic token documentation and docs presentation updates.
colors.mdx token documentation structure.kumo-ring with kumo-hairline for border/ring colors and all its instances in kumo components and docs.packages/kumo/ai/USAGE.md token reference categories and descriptions with the docs token guide.theme-kumo.css.kumo-fill-hover token value from neutral-700 to neutral-800Badge: add color-based variants and deprecate semantic variants
red, orange, yellow, green, teal, blue, neutral, invertedred-subtle, orange-subtle, etc.) with lighter backgrounds and darker textoutline and beta variants unchangedprimary (use inverted), secondary (use neutral), destructive (use red), success (use green)primary to neutralAdd action prop to Banner for rendering CTA buttons alongside structured title/description content without resorting to the children prop.
Refresh semantic surface color tokens and component surface usage.
kumo-canvas as the page-level surface token in theme output and docs usage.kumo-binding.css and generated theme variables for improved light/dark surface hierarchy.LayerCard, MenuBar, Tabs) to align with the refreshed canvas/elevated/recessed layering model.ai/USAGE.md to reflect page vs component background roles.Make timeseries' highlighted on hovering a data point
Add Shadow DOM support via KumoPortalProvider and container prop on all portal-based components
All overlay components (Dialog, DropdownMenu, Combobox, Select, Tooltip, Popover, CommandPalette, Toast) now support rendering inside Shadow DOM or custom containers.
New exports:
KumoPortalProvider - Context provider to set default portal container for all overlaysPortalContainer - Type for portal container (HTMLElement, ShadowRoot, or ref)Component updates:
All portal-based components now accept an optional container prop:
Dialog - container prop on Dialog componentDropdownMenu.Content - container propCombobox.Content - container propSelect - container propTooltip - container propPopover.Content - container propCommandPalette.Root and CommandPalette.Dialog - container propToasty (Toast provider) - container propUsage:
Set once at the app level:
<KumoPortalProvider container={shadowRoot}>
<App />
</KumoPortalProvider>
Or override per component:
<Dialog container={customContainer}>
<Dialog.Title>Modal inside shadow DOM</Dialog.Title>
</Dialog>
When no provider or prop is set, components default to document.body (existing behavior).
SkeletonLine: add blockHeight prop to set a container height and vertically center the skeleton line within it
Table: add sticky prop to Table.Head and Table.Cell for pinning columns to left/right edges, and sticky prop to Table.Header for sticky header rows. Uses isolate stacking context with z-0/z-1/z-2 layering.
Add toml as a supported language for syntax highlighting in the Code component
Add title prop to Button — wraps the button in a Tooltip when provided.
Checkbox.Group & Radio.Group: remove fieldset border box and simplify styling
rounded-lg border border-kumo-line p-4 wrapper from both group fieldsetstext-lg to text-base with inline-flex layoutfont-medium from Checkbox.Item and Radio.Item labelsFix missing disabled styling on Combobox triggers. TriggerValue and TriggerMultipleWithInput now apply opacity-50 and cursor-not-allowed when disabled, matching the behaviour of the Select component.
Update dialog backdrop overlay to use bg-kumo-recessed token
Remove ai/schemas.ts from version control (now fully generated at build time)
Fix LayerCard.Primary stacking order when sandwiched between LayerCard.Secondary elements
Fix SensitiveInput focus ring and global CSS pollution
SkeletonLine: move .skeleton-line styles into @layer base so Tailwind utility classes (e.g. className="h-6") can override the default height
Tabs indicator now uses translate-x for its transition animation, replacing the CSS left transition with a GPU-accelerated transform.
fix flow component not reflecting padding prop
Surface: replace as prop with Base UI render prop for polymorphism
The as prop used a hand-rolled generic forwardRef pattern (with as any casts) that conflicted with how the rest of the library handles polymorphism via Base UI's useRender hook.
Surface now accepts a render prop, consistent with Link and other components. The old as prop is kept as a deprecated alias and continues to work unchanged — no migration required.
// Still works (deprecated)
<Surface as="section">...</Surface>
// Preferred going forward
<Surface render={<section />}>...</Surface>
Switch: polish squircle styling
ring-inset on thumb to prevent border protruding beyond the trackring to outline with outline-offset-2 to avoid clashing with the track's own ring borderfix(Tabs): update segmented tab spacing and track styling
Tabs list styling colour to bg-kumo-recessed and added ring to make the Tabs background more visibleupdate toast styling to use a subtle ring and background that reflect each state.
update status text token values for info and danger to improve a11y contrast ratio on banners.
Add truncate prop to Text component. When true, applies truncate min-w-0 classes to clip overflowing text with an ellipsis.
Make Chart components keyboard focusable with tabindex. Timeseries adds ariaDescription prop
Generate component-registry files at build time, remove from git
Eliminates contributor friction by generating component-registry.json, component-registry.md, and schemas.ts during the build process instead of tracking them in git. Contributors will no longer see stale diffs or need to manually regenerate these files.
feat(code): add HCL (HashiCorp Configuration Language) as a supported syntax highlighting language
fix(flow): connector lines no longer misalign when the page scrolls or a sidebar shifts the layout
getBoundingClientRect values were stored in React state per node and later subtracted against a freshly-read container rect at connector-draw time. Any layout shift (sidebar open/close, page scroll, inner container scroll) between those two reads produced stale coordinates, causing connector lines to jump out of place or disappear entirely.
Fix: add scroll and resize listeners (capture phase) at the FlowNode, FlowParallelNode, and FlowNodeList levels so all rects are remeasured after any layout shift. Connector computation in FlowNodeList and FlowParallelNode is also moved from the render phase into useLayoutEffect so the container rect and node rects are always read in the same synchronous pass.
Add missing HCL language import to server-side Shiki bundle
The HCL language was added to SupportedLanguage type and the client-side provider in a previous commit, but the server.tsx BUNDLED_LANGS object was missed. This caused typecheck failures when building.
Sidebar: polish animations, fix separator reflow bug, improve header spacing
Fix connector alignment and spacing between adjacent parallel nodes in Flow diagrams
Add success and info toast variants with semantic token styling. Migrate error/warning variants from raw CSS to semantic tokens for consistent theming.
Add radio card appearance via appearance="card" prop on Radio.Group and Radio.Item. Cards display a bordered, selectable container with title and description. Also adds description prop to Radio.Item for helper text. Supports vertical and horizontal orientations, error state, and disabled state.
Expose Chart optionUpdateBehavior to control how ECharts applies option updates; notMerge now defaults to false.
Add neutral variant to Switch component and improve accessibility
variant="neutral" option: monochrome switch with squircle shape, matching the design from stratuserror variant (not useful for toggle switches)removed outline-none to bring back focus states on all buttons
Fix flaky vitest "Closing rpc while fetch was pending" error in deep-imports test
Fix InputArea label click not focusing textarea. Use FieldBase.Control with render callback to properly associate the label with the textarea element.
Fix TypeScript return types for ShikiProvider and CodeHighlighted components.
Changed return type from ReactNode to React.JSX.Element to resolve JSX compatibility errors. This fixes issues when consuming these components in projects with stricter TypeScript configurations (e.g., skipLibCheck: false), where ReactNode was incorrectly inferred as a valid JSX element return type.
Fix table header font size to ensure consistent rendering across dashboards with different default font sizes
Add dedicated kumo-placeholder text color token and use it for Input, InputArea, SensitiveInput, and CommandPalette placeholder text. The new token provides better visual distinction between placeholder and active text in both light and dark modes.
Replace the package-level ESLint pass with Oxlint JS plugin coverage for the remaining jsx-a11y rules, and pin the library build to es2022 with a post-build browser-compat test that blocks newer runtime APIs from shipping in dist.
fix(Select): prevent chevron overflow with long multi-select values
Added min-w-0 truncate to the value element and shrink-0 to the chevron icon so that long option names truncate gracefully instead of pushing the chevron outside the select bounds.
add xAxisTickFormat, yAxisTickFormat, and tooltipValueFormat props to TimeseriesChart; deprecate yAxisTickLabelFormat
If you were using yAxisTickLabelFormat to customize tooltip output, switch to tooltipValueFormat.
Before:
<TimeseriesChart yAxisTickLabelFormat={(v) => `${v} req/s`} />
After:
<TimeseriesChart tooltipValueFormat={(v) => `${v} req/s`} />
Fix combobox caret icon visibility by using fill-kumo-subtle instead of fill-kumo-ring
reorganize greyscale tokens and update color preferences
updated button styles for outline and secondary
Fix Jest module resolution failures and reduce Shiki bundle size
Jest Fix:
chunkFileNames config to prevent double-dash filenames (e.g., combobox--ec3iibR.js) that Jest cannot resolvedist/chunks/ subdirectory for cleaner structureBundle Size Reduction:
shiki/coreSupported Languages:
javascript, typescript, jsx, tsx, json, jsonc, html, css, python, yaml, markdown, graphql, sql, bash, shell, diff
Breaking Change:
BundledLanguage type is now deprecated, use SupportedLanguage insteadFix npm publish failure by removing cross-package dependency from prepublish hook
Select: Improved label API to match Input component pattern
hideLabel is now deprecated. When label is provided, the label is visible by default (previously hidden by default).
<Select label="Country" /> (no changes needed if you were using hideLabel={false})<Select aria-label="Select a country" /> instead of <Select label="Country" hideLabel={true} />items format (e.g., items={{ a: "Option A" }}). Previously, placeholders only worked with array format items.Backward compatibility: hideLabel={true} still works but shows a deprecation warning in development. Existing code using hideLabel={false} requires no changes.
Migration guide:
// Before (label hidden by default)
<Select label="Country" /> // label was sr-only
<Select label="Country" hideLabel={false} /> // label was visible
// After (label visible by default, matching Input)
<Select label="Country" /> // label is now visible
<Select aria-label="Country" /> // use aria-label for hidden labels
Add optional id prop to Flow.Node for stable node identification and connector test IDs
Avoid adding multiple toasts with the same ID. Use a subtle bump animation when a toast with an existing ID is added.
Fix theme token flicker by generating stable light/dark fallback variables with safer scope and layer precedence.
fix: add defensive styles to prevent global CSS pollution
When Kumo components are used in applications with aggressive global styles (e.g., Stratus's cfBaseStyles layer), certain elements get polluted:
label { margin-bottom: 1rem } adds unwanted margins to all labelsbutton { background: gray } affects unstyled button wrappers (e.g., tooltip triggers)a { color: var(--text-color-primary) } can override link colors if the consuming app defines --text-color-primary differentlyAdd defensive Tailwind utility classes directly to components. These:
cn() (tailwind-merge) so consumer styles via className still override themm-0)labelVariants() now includes m-0FieldBase.Label gets m-0m-0m-0m-0!asChild): bg-transparent border-none shadow-none p-0 m-0 h-auto min-h-0 leading-[0] inline-flex items-centerbg-transparent border-none shadow-none p-0 m-0text-primary to text-kumo-link to avoid collision with consuming apps that define --text-color-primary differently<Button variant="ghost" size="xs" shape="square"> with asChild, leveraging composition instead of relying on defensive resetsAdded "Custom Trigger" section to Tooltip docs demonstrating that className can fully override defensive styles when not using asChild.
fix(dropdown): use Base UI CheckboxItemIndicator for proper accessibility
Replace custom Checkbox component with Base UI's CheckboxItemIndicator in DropdownMenuCheckboxItem. The previous implementation nested an interactive Checkbox inside the menuitemcheckbox role, causing duplicate accessibility labels. CheckboxItemIndicator is automatically aria-hidden and only renders when checked, following the standard Base UI pattern.
Fix Field error message line height by adding leading-snug for consistent text spacing
Improve info banner dark mode contrast for WCAG AA compliance. Changes kumo-info from blue-700 (L=48.8%) to blue-400 (L=70.7%), achieving 7.97:1 contrast ratio against the banner background.
Fix Combobox.TriggerValue icon misalignment caused by inherited line-height
The caret icon span was inheriting line-height from the parent button's text-base class, causing the span's height to exceed the icon's height (e.g., 21.5px vs 16px). The icon sits at the top of the span by default, so when the span is centered via top-1/2 -translate-y-1/2, the icon appears offset.
Added flex items-center to the icon wrapper to ensure proper vertical centering regardless of inherited styles. This matches the pattern used in TriggerInput.
fix(Pagination): use aria-label instead of label for PageSize select
The Select component now shows visible labels by default. Since Pagination.PageSize
already displays "Per page:" text next to the select, the internal Select should use
aria-label for accessibility without showing a duplicate visible label.
chore(toast): replace inline XIcon with Phosphor icon
Prevent password managers autofilling Pagination input field
fix(tabs): improve focus ring and hover styling
ring-kumo-ring token instead of browser default bluefix(Tabs): pass TabItem render prop through to Base UI for custom tab rendering (e.g., link-based tabs)
Add Shiki-powered CodeHighlighted component for syntax highlighting
@cloudflare/kumo/code - keeps Shiki out of main bundle@cloudflare/kumo/code/server for SSR/static highlightinggithub-light and vesper defaults, supports any Shiki theme--kumo-code-highlight-bg variable for highlight colorCode and CodeBlock components (will be removed in v2)feat(combobox): add size prop with xs, sm, base, lg variants matching Input component
feat(flow): make nested lists work inside parallel nodes
Add role prop to Dialog component supporting both "dialog" (default) and "alertdialog" ARIA roles
New Feature:
Dialog.Root now accepts a role prop to specify the dialog's ARIA semanticsrole="alertdialog" is used, the dialog uses Base UI's AlertDialog primitives for proper accessibilityWhen to use role="alertdialog":
Example:
// Standard dialog (default)
<Dialog.Root>
<Dialog.Trigger render={(p) => <Button {...p}>Edit</Button>} />
<Dialog>...</Dialog>
</Dialog.Root>
// Alert dialog for destructive actions
<Dialog.Root role="alertdialog">
<Dialog.Trigger render={(p) => <Button variant="destructive" {...p}>Delete</Button>} />
<Dialog>...</Dialog>
</Dialog.Root>
Add TimeseriesChart component with ECharts integration, supporting legends, gradient fills, custom axis formatting, loading skeleton state, and configurable color palettes.
feat(select): auto-render options from items prop when children omitted
The Select component now automatically renders Select.Option elements from the items prop when children are not explicitly provided.
Add missing success background and tint semantic color tokens (bg-kumo-success, bg-kumo-success-tint) for parity with info, warning, and danger. Fix text-kumo-success dark mode contrast by using green-400 instead of green-500. Add new success Badge variant for positive state indicators.
fix(breadcrumbs): improve mobile breadcrumb readability
breadcrumbs now render a compact mobile trail for deeper hierarchies by collapsing early levels to ... and keeping the trailing path visible. labels in breadcrumb links and the current page now truncate correctly to prevent stacking or overlap on narrow viewports.
fix(badge): prevent crash when unknown variant is passed
Add defensive fallback to primary variant when an unrecognized variant string is provided to Badge component. This prevents "Cannot read properties of undefined (reading 'classes')" errors when consumers use a variant that doesn't exist in their installed version.
fix(code): Fix CodeHighlighted dark mode, layout, and SSR issues
<pre> background transparent so container's bg-kumo-base handles theming and border-radius is respectedw-full to container for proper full-width display"use client" directive from @cloudflare/kumo/code/server entry point so server utilities work in RSC/SSR contextsfix(CommandPalette): add explicit text-base class to Item component for consistent 14px font size
Fix Select to render description and error when hideLabel is true
Previously, the description and error props were silently ignored when
hideLabel was true (the default). Now, helper text and error messages
display correctly even when the label is visually hidden.
Fix TypeScript errors when consumers type-check their projects with kumo installed.
Previously, TypeScript would attempt to type-check raw .tsx and .ts source files
shipped in the package (block sources in dist/src/blocks/, ai/schemas.ts, and
scripts/theme-generator/*.ts), causing build failures in downstream projects.
This change:
dist/blocks-source/ directoryai/schemas.ts and scripts/theme-generator/*.ts to JavaScript.js files with proper .d.ts typesfix(inputs): expand small control hit areas
Fix pagination component to properly wrap numbers in tabular-nums class for consistent number alignment. Both the page range and total count now use tabular numerals.
Simplify Select placeholder implementation by using Base UI's native placeholder prop on SelectBase.Value instead of manually injecting placeholder items into the items array. This provides a cleaner, more intuitive API that aligns with standard HTML select behavior while maintaining backward compatibility with the null-value placeholder pattern.
fix(breadcrumbs): enhance mobile breadcrumb display for better readability
Add variant="compact" prop to Table.Header for a more condensed header style
Fix Combobox group label styling to use semantic token and correct padding
Standardize z-index usage with isolation containment
isolation: isolate to components with internal stacking (Tabs, MenuBar, InputGroup, Flow/Parallel)z-0/z-1/z-2 instead of arbitrary values like z-10/z-20z-10 from CommandPalette Listz-1 (matching Base UI's documented pattern)isolate instead of z-50This prevents z-index values from leaking outside component boundaries.
feat(dropdown): add LinkItem for navigation links and fix icon rendering
New Features:
DropdownMenu.LinkItem for navigation links (semantic <a> element with proper menu item behavior)@base-ui/react from 1.0.0 to 1.2.0csp-provider and drawer from Base UI 1.2.0Bug Fixes:
icon prop not rendering on DropdownMenu.Item when no href is providedDeprecations:
href prop on DropdownMenu.Item is deprecated. Use DropdownMenu.LinkItem instead.Migration:
// Before (deprecated)
<DropdownMenu.Item href="https://example.com">Link</DropdownMenu.Item>
// After (recommended)
<DropdownMenu.LinkItem href="https://example.com" target="_blank">
Link
</DropdownMenu.LinkItem>
DropdownMenu.LinkItem gives you full control over link attributes (target, rel, etc.) without the component making assumptions about your intent.
Add positionMethod prop to Popover.Content to control CSS positioning strategy. Use "fixed" when the popover needs to escape stacking contexts (e.g., inside sticky headers). Defaults to "absolute".
Improve Flow diagram components with disabled node support and better connector rendering:
disabled prop to FlowNode for greying out connectorsalign prop to FlowParallelNode for start/end alignmentRefactor Banner component with softer styling and i18n-friendly props
title and description props for structured content with i18n supporttext-kumo-default for readability, with colored icons for variant indicationiconClasses to variant config for per-variant icon coloringforwardRef and sets displayName per conventionschildren and text props in favor of title/descriptionchildren prop still works for backwards compatibilityFix Checkbox ring color to use ring-kumo-contrast when checked or indeterminate
Fix Combobox dropdown scrolling regression and improve scroll behavior.
Bug fix: The overflow-hidden class was accidentally re-introduced during a semantic color token migration, which overrode overflow-y-auto and caused dropdown content to be clipped instead of scrollable.
Improvement: Restructured Combobox.Content to use flexbox layout so that when using Combobox.Input inside the dropdown (searchable popup pattern), the input stays fixed at the top while only the list scrolls. Previously, the entire popup content would scroll together.
Scrollbar fix: Moved horizontal padding from the popup container to individual child components, so the scrollbar renders flush with the popup edge instead of being inset (which was clipping the checkmark indicators).
feat(flow): add FlowDiagram components for building directed flow diagrams
New components for visualizing workflows and data flows:
FlowDiagram - Root container with pan/scroll support for large diagramsFlowNode - Individual node with automatic connector pointsFlowNode.Anchor - Custom attachment points for connectors within nodesFlowParallelNode - Container for parallel branches with junction connectorsAdds motion as a new dependency for smooth panning interactions.
Deprecate DateRangePicker in favor of DatePicker with mode="range"
@deprecated JSDoc comments to DateRangePicker component and its exportsPrevented ClipboardText from overflowing with long text values.
chore(kumo): add test scripts to root package.json
Add DatePicker component built on react-day-picker v9
New Component: DatePicker
single, multiple, and rangetimeZone propUsage:
// Single date
<DatePicker mode="single" selected={date} onSelect={setDate} />
// Multiple dates
<DatePicker mode="multiple" selected={dates} onSelect={setDates} max={5} />
// Date range
<DatePicker mode="range" selected={range} onSelect={setRange} numberOfMonths={2} />
Composing with Popover:
<Popover>
<Popover.Trigger asChild>
<Button variant="outline" icon={CalendarDotsIcon}>
Pick a date
</Button>
</Popover.Trigger>
<Popover.Content className="p-3">
<DatePicker mode="single" selected={date} onSelect={setDate} />
</Popover.Content>
</Popover>
Note: Consider using DatePicker with mode="range" instead of DateRangePicker for new projects - it offers more flexibility and a smaller bundle size.
Internal changes:
react-day-picker v9 as a dependencyjsx-a11y/no-autofocus rule (intentional prop forwarding)feat(clipboard-text): add slide animation with tooltip on copy
Updated the MenuBar so its child buttons align with the container’s outer corners.
Fix kumo add to consolidate imports from @cloudflare/kumo into a single statement using inline type syntax.
Previously, running kumo add DeleteResource would produce non-conformant code with duplicate imports:
import { Dialog, DialogRoot } from "@cloudflare/kumo";
import { Input } from "@cloudflare/kumo";
import { Button } from "@cloudflare/kumo";
Now it produces a single consolidated import:
import {
Dialog,
DialogRoot,
Input,
Button,
type DialogProps,
} from "@cloudflare/kumo";
This satisfies ESLint's import/no-duplicates rule with prefer-inline: true.
Fix z-index stacking issues with nested portaled components (e.g., Select inside Dialog)
.z-modal { z-index: 9999 } - DOM order now handles stacking naturallyfix(dropdown): improve external link detection to handle http:// and protocol-relative urls
updated the external link check to use a regex that matches https://, http://, and protocol-relative URLs (//). previously only https:// links opened in a new tab.
Changed ClipboardIcon to CopyIcon in ClipboardText component
Fix AI command USAGE.md path resolution to work correctly from bundled dist output
fix(cli): include block source files in build for kumo add command
The kumo add command was failing because block source files (.tsx) were not being copied to dist/ during the build process. This adds copying of block source files from src/blocks/ to dist/src/blocks/ so the CLI can install them into user projects.
fix(Table): Add indeterminate prop and fix checkbox click handling
indeterminate prop to Table.CheckHead and Table.CheckCell components to support indeterminate checkbox state (shows minus icon when some but not all rows are selected)TableSelectedRowDemo and TableFullDemo) with proper React state management for interactive row selectionfix: delete-resource shouldn't nest buttons within each other
support overwriting text in pagination component
fix(cli): resolve broken doc/docs/ls commands by fixing registry path from catalog/ to ai/
fix(dialog): wrap sub-components to isolate @base-ui/react type references from downstream consumers
fix(label): render as <label> element with htmlFor support instead of <span>
feat(input): add Textarea alias for InputArea
feat(toast): add ToastProvider alias for Toasty
feat(button): require aria-label on icon-only buttons (shape="square" | "circle") via discriminated union
fix(docs): add Tailwind 4 @source directive to usage example, add confirmation dialog recipe, update Select basic example, document icon-only button aria-label pattern
add 'Delete Resource' block
The first stable release of Kumo, Cloudflare's component library.
Blocks (PageHeader, ResourceListPage) are no longer exported from @cloudflare/kumo. They must now be installed via the CLI:
npx @cloudflare/kumo init # Initialize kumo.json
npx @cloudflare/kumo add PageHeader
Blocks are copied to your project for full customization with imports automatically transformed to @cloudflare/kumo.
HTMLInputElement → HTMLButtonElementInputHTMLAttributes (explicit props only)onChange/onValueChange → onCheckedChange (deprecated handlers still work)The text prop is deprecated in favor of children:
// Before (deprecated)
<Banner text="Your message" />
// After (preferred)
<Banner>Your message</Banner>
render prop for framework routingSub, SubTrigger, SubContent) and radio items (RadioGroup, RadioItem)kumo/no-deprecated-props detects @deprecated JSDoc tagsIf you were using blocks (note: they were never officially exported):
# 1. Initialize configuration
npx @cloudflare/kumo init
# 2. Install blocks
npx @cloudflare/kumo add PageHeader
npx @cloudflare/kumo add ResourceListPage
# 3. Update imports to the local path shown after installation
// Before
<Checkbox onChange={(e) => setValue(e.target.checked)} />;
const ref = useRef<HTMLInputElement>(null);
// After
<Checkbox onCheckedChange={(checked) => setValue(checked)} />;
const ref = useRef<HTMLButtonElement>(null);
// Before (still works, but deprecated)
<Banner text="Your message" />
// After
<Banner>Your message</Banner>
feat(banner): add children prop, deprecate text prop
Banner now supports children for content, which is the preferred API. The text prop is deprecated but still works for backwards compatibility.
// Preferred (new)
<Banner>Your message</Banner>
<Banner icon={<Icon />}>Your message</Banner>
// Deprecated (still works)
<Banner text="Your message" />
The text prop will be removed in a future major version.
feat(cli): blocks are now distributed via CLI instead of npm exports
New CLI commands for block management:
kumo init - Initialize kumo.json configuration filekumo blocks - List all available blocks for CLI installationkumo add <block-name> - Install a block to your project with transformed importsBlocks are copied to your project for full customization, with relative imports automatically converted to @cloudflare/kumo.
Add lint rule to detect usage of deprecated props on Kumo components.
kumo/no-deprecated-props lint rule automatically detects deprecated props from @deprecated JSDoc tagsdeprecated field for props with @deprecated annotations@deprecated badge for deprecated props in API reference tablesTo deprecate a prop, add a JSDoc comment:
interface MyComponentProps {
/** @deprecated Use `newProp` instead */
oldProp?: string;
}
The lint rule will flag usage and show a helpful message:
The `oldProp` prop on <MyComponent> is deprecated. Use `newProp` instead.
Add nested menu (submenu) and RadioGroup/RadioItem support to DropdownMenu
DropdownMenu.Sub, DropdownMenu.SubTrigger, and DropdownMenu.SubContent for nested submenusDropdownMenu.RadioGroup, DropdownMenu.RadioItem, and DropdownMenu.RadioItemIndicator for single-selection menusSubTrigger styling to match Item componentfix(checkbox): make label clickable, add new onCheckedChange API
onCheckedChange callback (preferred over deprecated onChange/onValueChange)HTMLButtonElement (aligns with Base UI implementation)Add Link component with Base UI composition API
Link component for consistent inline text linksrender prop for composition with framework-specific links (e.g., React Router)useRender hook for proper ref/event merginginline (default), current, and plainLink.ExternalIcon subcomponent for external link indicatorsLinkProvider for framework-agnostic routingfeat: theme generator, color token consolidation, component catalog
run component-registry when starting docs site
Fix color contrast issue in Dropdown danger variant by using subtle bg-kumo-danger/5 background instead of bg-kumo-danger-tint, improving readability while maintaining the visual "danger" cue
Add render prop for Tabs component
Fix Combobox dropdown not scrolling when it has many items. The overflow-hidden class was overriding overflow-y-auto, causing content to be clipped instead of scrollable.
fix: improve primary button hover/focus contrast by using bg-hover-selected instead of bg-primary/70
Adds disabled prop for table cell checkboxes
fix(tabs): adjust segmented indicator border radius for proper visual nesting
Ship component registry with @cloudflare/kumo module
feat(popover): Add new Popover component
Adds a new Popover component based on Base UI's popover primitive. The Popover provides an accessible popup anchored to a trigger element, with support for:
Popover, Popover.Trigger, Popover.Content, Popover.Title, Popover.Description, Popover.Closeside (top, bottom, left, right), align (start, center, end), sideOffsetopenOnHover behavioropen and onOpenChange propsMigrate documentation site from React Router (kumo-docs) to Astro (kumo-docs-astro) as the primary docs platform, consolidate CI/CD pipelines, and add version display features.
Bump node to v24.12.0
Add Figma plugin for UI kit generation
packages/figma/ (@cloudflare/figma-plugin)feat(kumo): add command-palette component
semantic color changes and more consolidation for non-text colors
feat(tooltip): Update tooltip to use bg-kumo-base with proper light/dark mode support
Changes the tooltip background from a fixed dark color to a surface-aware background that adapts to light and dark modes. Implements Base UI's 3-path arrow SVG approach for pixel-perfect border alignment across color modes.
fix(kumo): updated version in package.json (unintentionally downgraded)
feat(PageHeader): add optional title and description props
title?: string and description?: string props to PageHeader blockWithout this feature, pages using only PageHeader would lack a semantic page title (h1), requiring developers to manually add titles elsewhere. This creates:
With this feature, PageHeader provides a standardized way to include accessible page titles that:
Breadcrumbs serve navigation purposes and cannot replace semantic page titles. Both should coexist:
Add table component
kumo-docslighter red in light mode
Add Label component with standardized label features for form fields
label prop now accepts ReactNode (not just strings)required={false} shows "(optional)" textlabelTooltip prop for info icon with hover tooltipAdd Radio component for single-selection from a set of options
Radio.Group and Radio.Item compound components built on Base UI primitivescontrolPosition prop for label placement ("start" or "end")Add Storybook preview deployments and MR reporter system
storybook.staging.kumo-ui.com on merge to mainAdd variant prop to Tabs component with 'segmented' (default) and 'underline' options
Fix label not appearing in Combobox unless a description or error given.
fix bug where delete user external links were being treated as internal navigation and appending urls to domain
Fix Base UI nativeButton warning in Switch component by adding nativeButton prop to BaseSwitch.Root
Update deployment configs to enable preview urls
added a next / previous form of pagination
Modernize Active Sessions page with updated Kumo design patterns
Add bg-kumo-base as default background for Surface component
Fix Combobox button styles
Migrate to @base-ui/react V1
Breaking Change: Updated from @base-ui-components/react to the new @base-ui/react V1 package.
@base-ui-components/react → @base-ui/react^1.0.0-rc.0 > ^1.0.0This is a major version bump because the underlying Base UI package has changed. While the Kumo API remains the same, you'll need to:
pnpm install
After merging this PR, run:
# Install the new @base-ui/react package
pnpm install
# Regenerate primitive files with new package references
pnpm --filter @cloudflare/kumo build:primitives
# Rebuild the package
pnpm --filter @cloudflare/kumo build
# Run tests to verify everything works
pnpm --filter @cloudflare/kumo test:run
@base-ui-components/react/* to @base-ui/react/*generate-primitives.ts script to reference new packagevite.config.ts manualChunks to match new package nameAdd built-in Field integration to form components with automatic layout
New Features:
label, description, and error props for built-in Field wrapper support:has() selectorsAccessibility:
Breaking Changes:
Migration:
// Before: Explicit Field wrapper
<Field label="Email" description="...">
<Input placeholder="[email protected]" />
</Field>
// After: Built-in Field API (recommended)
<Input
label="Email"
description="..."
placeholder="[email protected]"
/>
change error color for text component to match field input error colors
secondary-destructive button variant
fix: update changeset validation logic
Complete semantic color tokens migrated from Stratus app
[data-theme] and [data-mode] attributesAdd data-theme and data-mode attributes to your root element:
// React example
<html data-theme="kumo" data-mode={isDark ? "dark" : "light"}>
// Static HTML
<html data-theme="kumo" data-mode="light">
data-theme: Set to "kumo" (default theme) or other theme variants like "fedramp"data-mode: Set to "light" or "dark" to control color schemeIf no data-mode is set, the system defaults to light mode.
tab and text style fixes; storybook theme select always visible
inputs with built-in fields
Bundle Base UI primitives with granular exports and fix critical compatibility issues
Added granular exports for all 37 Base UI primitives alongside the existing barrel export. This enables better tree-shaking and smaller bundle sizes when using individual primitives.
// Barrel export (imports all primitives)
import { Slider, Popover, Tooltip } from "@cloudflare/kumo/primitives";
// Granular exports (tree-shakeable, recommended)
import { Slider } from "@cloudflare/kumo/primitives/slider";
import { Popover } from "@cloudflare/kumo/primitives/popover";
Available primitives: accordion, alert-dialog, autocomplete, avatar, button, checkbox, checkbox-group, collapsible, combobox, context-menu, dialog, direction-provider, field, fieldset, form, input, menu, menubar, meter, navigation-menu, number-field, popover, preview-card, progress, radio, radio-group, scroll-area, select, separator, slider, switch, tabs, toast, toggle, toggle-group, toolbar, tooltip.
Fixed critical compatibility issues with Jest and React Server Components by improving the build configuration.
preserveModules: true, which preserved the pnpm directory structure (node_modules/.pnpm/) in dist. This caused Jest to fail parsing ESM imports because Jest's transformIgnorePatterns blocks nested node_modules by default.rollup-plugin-preserve-directives plugin only works with preserveModules: true. When bundling with preserveModules: false, all "use client" directives were stripped, breaking components in Next.js App Router (RSC).preserveModules: false to eliminate nested node_modules/.pnpm/ pathsoutput.banner to inject the directive into all output chunks (since the plugin doesn't work without preserveModules)manualChunks to split large vendor dependencies for better caching:
vendor-base-ui (598 KB, 152 KB gzipped) - Base UI componentsvendor-styling (74 KB, 13 KB gzipped) - clsx + tailwind-mergevendor-floating-ui (33 KB, 10 KB gzipped) - Floating UI positioningvendor-utils (24 KB, 7 KB gzipped) - tabbable, reselect, etc.kumo cli
semantic text colors - consolidation
Removed label prop from input components. Prefer using Field to compose a label with an input.
consolidate blue text to match banner blue text across: badge, expandable, text components
consolidate on the green text tokens
Update kumo package to use literal depdency versions for better yarn linking/portal support.
improve input group label to be semantic and use htmlFor
Combobox Type Fixes
any type and eslint-disable commentsComboboxBase.Root.Props<Value, Multiple> from base-ui's namespacefix remaining lint errors and increase lint warn -> error
Update reamde documentation
Consolidate AGENTS.md and CLAUDE.md LLM instructions
fix resource-list href lint errors
Improve expandable component semantics
Update Storybook imports from @storybook/react to @storybook/react-vite for Storybook 10 compatibility. Also removes generatedAt timestamp from component registry to prevent merge conflicts during rebases.
improve sensitive input component - semantics, button nesting, labelling, screen reader experience
Fix: Resolve type check errors across components/blocks/layouts Fix: Export Kumo Breadcrumb as Breadcrumbs + Documentation Improvements Fix: MenuBar -Bypass the React 19 type checking issue with IconContext.Provider
improve semantics and labelling for date picker component
docs updates and semantic colors for banner
ship dark-mode color scheme styles from kumo lib instead of setting it at the app
Adds Storybook 10 integration to the Kumo component library for interactive component development, testing, and documentation. Includes stories for 29 components, automated plop generator updates, and documentation.
enforce button background transparency for tabs
Combobox - Adjust multiple select height with standard Kumo component height
Checkbox indeterminate state
Improve development workflow with 10x faster rebuilds and comprehensive documentation
Add development mode with optimized builds, skip minification and enable incremental TypeScript compilation. Update all READMEs and contributing docs with clear guidance on Storybook (recommended) vs watch build workflows. Add story file documentation to scaffolding sections and two-terminal setup instructions for testing components in docs.
Enhance CICD to publish beta releases
Fix: Resolve type check erros across components/blocks/layouts Fix: Export Kumo Breadcrumb as Breadcrumbs + Documentation Improvements Fix: MenuBar -Bypass the React 19 type checking issue with IconContext.Provider