Changelog

Version notes, breaking changes, and migration guidance for Giddaa UI.

This page summarizes user-facing changes for @giddaa-housing/ui.

The generated package changelog lives in packages/ui/CHANGELOG.md and is updated by Changesets during release PRs. Keep this docs page focused on what a consumer needs to know before upgrading: new capabilities, behavior changes, breaking changes, and migration steps.

Version 3.10.0

Release type: Minor

Breaking changes: None.

Highlights

  • Adds Kanban at @giddaa-housing/ui/kanban — drag-and-drop board primitives built on Pragmatic drag and drop. The board reports a move; your screen decides what it means and persists it. Includes locked columns and cards, an optional drag handle, localStorage-backed card order, a live region, and a post-move card flash.
  • Adds TabsListContainer and ScrollSpyListContainer, an optional bar around the list that owns the underline variant's baseline rule, plus ScrollSpyCount.
  • Makes SectionJumper hold its shape on long pages: the rail windows past maxDots, the menu is bounded and scrolls to the current section, and widths size to their content.
  • Fixes DialogContent spilling past its max height, SelectContent opening wider than a narrow trigger, the combobox's in-popup search box collapsing beside a long list, and InputGroup painting a min={0} number field at 0 as disabled.
  • Counts slides rather than the whole library in the MediaGalleryImages mobile carousel counter.

Migration Notes

  • totalMediaCount on MediaGalleryImages is deprecated and ignored. Move the library figure to MediaGalleryIndicator, where it labels the link into the full gallery.
  • Vertical line and underline tabs and scroll spies now draw their rail on the right, beside the active indicator, instead of the left. Nothing to change unless a screen depended on that edge.
  • Label ScrollSpyListContainer rather than the list inside it: the container takes over the nav landmark.
  • Kanban is pointer-only for dragging. Ship a keyboard-reachable way to make the same move — useKanbanFeedback announces and flashes those moves the way a drop does.

Version 3.9.1

Release type: Patch

Breaking changes: None.

Highlights

  • Aligns the Accordion trigger chevron with the first line of its label, so a question that wraps onto two lines no longer pushes the icon toward the vertical centre of the whole label.
  • Stops MediaPlayer controls from flashing on touch devices. Tapping the video now leaves the controls up for the usual idle delay instead of hiding them the moment the finger lifts.
  • Stops playback when MediaPlayerVideo or MediaPlayerAudio unmounts, exiting Picture-in-Picture when the element owns the PiP window, so navigating away from a player no longer leaves audio playing in the background.

Migration Notes

No migration is required.

Version 3.9.0

Release type: Minor

Breaking changes: None.

Highlights

  • Fixes responsive sizing for ComboboxChips and ComboboxChip when inherited from Combobox or SizeProvider.
  • Adds standalone, theme-aware orphan-green, orphan-blue, orphan-yellow, and orphan-purple color tokens.
  • Adds Base UI render support to Skeleton for rendering semantic elements such as span instead of the default div.
  • Replaces button press translation with scale feedback so absolutely centered buttons remain spatially stable.
  • Keeps fullscreen sheet controls visible as iOS Safari's browser chrome changes the visible viewport.
  • Mounts fullscreen photo-gallery carousels only while open so they initialize directly at the current index without visibly looping to it.

Migration Notes

No migration is required.

Version 3.8.0

Release type: Minor

Breaking changes: None.

Highlights

  • Adds LabelSupplement and FieldLabelSupplement for secondary inline label content such as selection guidance, while preserving withAsterisk and showOptionalText.
  • Makes required labels wrap naturally with baseline-aligned supplemental text and keeps the decorative asterisk out of the accessible label name.
  • Fixes responsive Combobox fields inherited from SizeProvider and keeps link-style buttons free of control height and horizontal padding at every breakpoint.
  • Stabilizes Popovers anchored to sticky or fixed content and prevents their positioners from increasing document height.
  • Prevents expanded Toast stacks from glitching when the pointer moves through the gap between notifications.

Migration Notes

No migration is required. Existing Label, FieldLabel, withAsterisk, and showOptionalText usage remains supported. For custom inline guidance, compose LabelSupplement from @giddaa-housing/ui/label or FieldLabelSupplement from @giddaa-housing/ui/field inside the corresponding label.

Version 3.7.0

Release type: Minor

Breaking changes: None.

Highlights

  • Adds Rating from @giddaa-housing/ui/rating, with accessible interactive, form-compatible, read-only, fractional, precision, and responsive-size modes.
  • Adds a read-only presentation to Match. Scores without an onClick now render as non-interactive content, while readOnly can select either mode explicitly.
  • Expands PhoneInput to accept national or international entry, normalize emitted values to E.164, detect the country of international numbers, and render optional trailing content with rightAddon.
  • Lets DialogContent and SheetContent disable nested surface stacking with nestingEffect="none", while preserving the existing stack effect by default.
  • Moves Sonar ring animation onto compositor-friendly transforms and opacity to prevent repaint stutter and flashing, particularly on iOS Safari.
  • Corrects sizing and alignment in InputGroupButton, Select, and Combobox, and improves MobileSidebar spacing and narrow-viewport sizing.

Migration Notes

No migration is required. A Match without an onClick now renders a span with role="img" instead of a button and hides its chevron by default. Pass readOnly={false} to retain an interactive button when its click behavior is provided through composition rather than onClick, or set showChevron explicitly when the affordance should differ from the interaction mode.

PhoneInput continues to emit an E.164 value through onChange; it now also accepts national numbers with their country's trunk prefix and international numbers beginning with +.

Version 3.6.0

Release type: Minor

Breaking changes: None.

Highlights

  • Adds SectionJumper from @giddaa-housing/ui/section-jumper, a compact responsive navigator for long pages. It can share an existing ScrollSpy, or SectionJumperProvider can discover configurable heading selectors in CMS article markup, generate missing IDs, and follow the nearest scrolling container without wrapping article sections.
  • Fixes Chromium autofill paint on Input, including password and input-group compositions, so saved values keep readable theme-aware text, caret, and background colors in light and dark themes.
  • Adds mobile-first responsive sizing across buttons, badges, match indicators, and form controls, including inherited breakpoint sizes through SizeProvider.
  • Adds fixed header and footer action slots to Select and Combobox while preserving valid listbox semantics and independently scrolling results.
  • Improves property-listing media composition and carousel controls, aligns mobile media-gallery surfaces, and corrects Dialog, Sheet, and video-dialog popup layout details.

Migration Notes

No migration is required. Existing ScrollSpy compositions remain supported. Import SectionJumper and SectionJumperProvider from @giddaa-housing/ui/section-jumper when adopting the new navigation pattern.

Version 3.5.0

Release type: Minor

Breaking changes: None. Two behaviour changes are worth reading before you upgrade: PropertyListingCardMedia with no images prop at all now renders an empty media well rather than the "Property Image" placeholder, and VideoPlayerDialogPlaylistIndicator is a button where it was a span. No export was removed or renamed, and no token or stylesheet path changed.

Highlights

  • Adds @giddaa-housing/ui/utils/* — the package's shared, component-free helpers, published under their own namespace so an import path says whether you reached for a component or a helper. utils/phone (validatePhoneNumber, parsePhoneNumber, formatPhoneNumber, getPhoneNumberCountry, getPhoneCountries), utils/format (formatDuration, formatDate, formatTimestamp, toDateTimeAttribute, getInitials), utils/cn, and the hooks utils/use-uncontrolled, utils/use-reduced-motion, utils/use-is-mobile, utils/use-intersection. None of the non-hook modules import React, so a schema file or a server action can use them.
  • validatePhoneNumber is written to be passed by reference to z.string().refine(...) or yup.string().test(...). Every phone helper takes unknown, so a refinement context, an array index, or a null from a database is a false or a "" rather than a crash. One rule runs through all of them: invalid in, empty out.
  • Adds @giddaa-housing/ui/image — an Image that is a plain <img> until you replace it, through render for one image or ImageProvider for a whole tree. A Next.js app names next/image once at the root and every listing photo, gallery slide, hero tile and playlist poster follows. PropertyListingCard, PhotoGallery, MediaGalleryHero and VideoPlayerDialog all read the provider.
  • Breaks PropertyListingCardMedia apart into a media well you fill yourself: PropertyListingCardCarousel, PropertyListingCardCarouselItem, PropertyListingCardCarouselIndicator, PropertyListingCardImage and PropertyListingCardImagePlaceholder. The image takes every <img> prop, so a slide can be lazy-loaded, and the indicator's offset is a default rather than a fixture. The images prop still builds the same backdrop and is deprecated.
  • VideoPlayerDialogPlaylistIndicator is now the way down to the playlist: a button carrying a chevron that scrolls the dialog's surface to the playlist section. It was under pointer-events-none, so the one element telling you a playlist existed was the one element you could not act on.
  • Fixes the Combobox popup landing short of its field when ComboboxInput is the trigger. The field now registers itself as the anchor, so the popup matches the width you can see. The same component used as the popup's search box is squared off and left out of the anchoring.
  • ComboboxTrigger, ComboboxInput and ComboboxChips trade their pill radius for a box once they are taller than one row, published as data-grown="true". A chips field also takes more side padding, so the first chip clears the curve.
  • DatePicker, DateRangePicker and TimePicker no longer pin their panels to the vertical axis, so a picker low in a dialog or a scroll container puts its panel beside the trigger rather than overflowing. All three now accept side, align, sideOffset, alignOffset and collisionAvoidance.
  • Reworks PriceTag's two-line layout: the price and its description sit flush left with the chevron on the price's row, and the corner radius is a box that scales with the size. A leading-* that tailwind-merge was stripping had been padding the tag from the inside.
  • Adds Share and Filter icons — Giddaa's own artwork rather than Lucide's, filled rather than stroked.
  • Promotes Image, utils/phone and PropertyListingCard to stable.

Migration Notes

PropertyListingCardMedia given no images prop at all now renders an empty media well instead of the "Property Image" placeholder, because an empty well is what composing your own backdrop needs. Render PropertyListingCardImagePlaceholder to ask for the placeholder explicitly. images={[]} and images={[...]} — the paths that come from data — are unchanged, as is the PropertyListingImage type. All of it is deprecated and goes in the next major.

PropertyListingCard's size variants set the icon size through [&_svg] rather than [&>svg], the chevron now being a level down. An icon you pass inside value or description is sized by the tag too, where it was left alone.

VideoPlayerDialogPlaylistIndicator renders a button rather than a span, so its props are now Omit<ComponentProps<"button">, "type">. Its accessible name gained the destination — "Video 2 of 5. Go to the playlist." A dialog that reveals its playlist another way opts out of the scroll by calling preventDefault in its own onClick.

ComboboxInput used as the trigger now renders through Base UI's own input group. Pressing anywhere in the field, its padding included, focuses the input, which comes with that part.

Combobox size variants now set a min-h-* beside each fixed h-*. If you were passing h-auto to let chips wrap, the control now keeps its floor rather than collapsing to its contents.

PriceTag's chevron moved inside the price's row, so a [&>svg] selector aimed at it no longer matches. The two text lines are flush left rather than centred.

Formatters moved out of the components that owned them into utils/format, and MediaPlayer, DatePicker, Message and EditorialCard now read from there. Output is unchanged; the modules are new.

Version 3.3.0 – 3.4.0

Release type: Minor. Written for one release and published across two, so these notes cover both; there is no separate 3.4.0 section.

Breaking changes: None, with one narrow exception: PriceTag's value is now the price rather than the button's HTML value attribute, which it no longer accepts. No export, token, or stylesheet path changes. Four fixes do change how existing markup renders, so check the migration notes if you use Button link variants, MediaGalleryHero, PropertyListingCardOptionsBar, or Badge variant="outline".

Highlights

  • Adds Sonar — a wrapper that pulses rings outward from a dot, badge or button to draw attention to it. The rings trace the child's own shape: Sonar reads its computed border-radius, so a circular dot pulses a circle and a rounded button pulses a rounded rectangle, with nothing to keep in sync by hand. Takes active, tone, size, waves, and radius.
  • Adds ScrollSpy — section navigation for pages that show everything at once. The parts mirror Tabs (ScrollSpy / ScrollSpyList / ScrollSpyTrigger / ScrollSpyContent, matched by value), but nothing is hidden: the triggers scroll to their section and the active one tracks the reader. scrollOffset sets the activation line and each section's scroll-margin-top together, for sticky headers. Instances are independent, so a spy on the page and one in an open Dialog or Sheet don't move each other.
  • ScrollSpyList takes scrollActiveIntoView to keep the active trigger visible when the strip itself scrolls. It moves only the list, never the page.
  • Adds useScrollSpy, so any descendant of a ScrollSpy can read the active section and scroll to one. Until now the only way to trigger a scroll was to render a ScrollSpyTrigger, which left the documented overflow pattern — extra sections behind a "More" dropdown — with no way to move the page from a menu item.
  • Fixes Badge variant="outline" losing its border. Outline is the one variant with no fill behind it, and border defaults to false, so the default <Badge variant="outline"> rendered as bare text.
  • Simplifies PriceTag to display only. It takes value and description, and each dropdown option takes currency, value and description — all printed exactly as given, with no sentence composed for you and no size threshold deciding a line isn't worth showing. Adds renderMenuOption for custom dropdown rows. The old amount, shortAmount, format, monthlyPayment and monthlyPaymentLabel props still work unchanged and go in the next major.
  • Adds variant to FooterLink: default (unchanged) and brand.
  • Fixes Button's link-brand and link-neutral variants, which kept the size variant's control box and rendered as tall, non-wrapping blocks.
  • AlertDescription takes the first row when the alert has no AlertTitle, instead of leaving an empty title row above it.
  • Tabs exports tabsIndicatorClassName, resolveTabsListVariant, and the TabsListVariant type, so recipes can reuse its look.
  • Adds the missing "use client" directive to toast and accordion, which render Base UI primitives and previously failed in a React Server Component tree.

Migration Notes

No import changes are required. ScrollSpy is available from @giddaa-housing/ui/scroll-spy and Sonar from @giddaa-housing/ui/sonar. Both ship stable.

Badge variant="outline" now keeps its border when border={false}, which is the default, so an outline badge that previously rendered as bare text now renders with one. Every other variant still honours border={false} — they each have a fill to hold the badge's shape without a border. If you were adding a border class by hand to work around this, it is now redundant, though it still wins over the default and needs no urgent change.

Sonar paints its rings with box-shadow spread, which lives outside the element's box, so an ancestor with overflow: hidden will clip them.

PriceTag needs no changes now — every old prop still works. When you migrate, amount becomes value, shortAmount + format become formatting you do before passing, monthlyPayment + monthlyPaymentLabel become a description string you write, and each option's code/amount become currency/value. New props win over the ones they replace, so you can move one field at a time. Two things differ once you do: a description renders at every size, where the monthly line was hidden below md, and it is printed verbatim rather than wrapped in "Low as … monthly". Separately, value is now the price rather than the button's HTML value attribute, and the non-dropdown pill now forwards id, aria-* and other props that it previously dropped.

Button link variants now render as text rather than as a control: no fixed height, no min-width, no horizontal padding, no pill radius, and labels wrap. Layout around a link will tighten up. If you added className overrides to work around the old rendering, they are probably now redundant, though they still win over the defaults and need no urgent change.

MediaGalleryHero no longer paints bg-surface-raised on its root or layout wrappers, so it sits transparently on whatever surface hosts it. Tiles keep their placeholder background. Add className="bg-surface-raised" if you relied on the opaque backdrop.

PropertyListingCardOptionsBar renders as a blurred scrim over the media instead of a flat black bar, falling back to a denser fill where backdrop-filter is unsupported.

Alert gains a group/alert class on its root, and the description and actions carry group-has-* row placement. This is internal styling, but it can affect tests that assert on exact class strings.

Version 3.2.0

Release type: Minor

Breaking changes: Two, both narrow. Icons rendered by the library no longer carry Lucide's lucide lucide-<name> classes, and CurrencySelectorOption["flag"] takes a ReactNode instead of a colour-stripe array, with CurrencyFlagStripe removed. Neither is expected to affect most consumers, but see the migration notes if you select on icon classes or build CurrencySelector options by hand.

Highlights

  • Drops the lucide-react runtime dependency. The 76 glyphs the library renders are inlined in a new @giddaa-housing/ui/icons entry point, keeping the Lucide props API and path data (ISC).
  • Adds composable VideoPlayerDialog primitives for accessible modal structure, responsive media placement, details, and playlists.
  • Adds ThemeSwitcher for selecting light, dark, or system appearance. Applying and persisting the theme stays with the application.
  • Adds toast.add for fully custom toast bodies, which keep the stacking, swipe-to-dismiss, and timeout behavior of the built-in variants.
  • CurrencySelector draws real SVG flags resolved from the currency code, so an option usually needs nothing but code and label.
  • Adds EditorialCardRating, and CTATag now takes an on-brand foreground inside a CTACard variant="brand".
  • Fixes MediaPlayerSeek progress drifting away from its thumb.

Migration Notes

Icons: import from @giddaa-housing/ui/icons rather than lucide-react. Props carry over unchanged. If any product code or test selects on .lucide or .lucide-<name>, switch to [data-icon="<name>"] — the old classes are gone.

Tokens: --color-whatsapp-button is renamed to --color-whatsapp-green, but the old name stays as a deprecated alias, so bg-whatsapp-button and any theme override keep resolving. Nothing is required now; prefer whatsapp-green in new code, as the alias is removed in the next major. Button and CTAButton with variant="whatsapp" are unaffected.

CurrencySelector: drop any flag: [{ color: … }] arrays, which the built-in flags replace. Options that only set code, label, or countryCode need no change. CurrencyFlag now takes a countryCode instead of a stripe list.

Also note that data-slot="media-player-seek-segment" no longer exists, and the toast body now sits in a nested element under Toast.Content. Neither is a public API change, but both can affect tests that assert on DOM structure.

Version 3.1.0

Release type: Minor

Breaking changes: None.

Highlights

  • Adds MaskInput and formatMaskValue for pattern and locale-aware numeric formatting, including named presets, currency display, ranges, affixes, and caret-safe editing.
  • Adds composable, responsive TopNavbar primitives and a standalone MobileSidebar export.
  • Adds a .light theme scope that can pin a light subtree inside a dark application, matching the existing .dark scope.
  • Aligns Footer primitives with the responsive layouts, mobile stacking, sitemap columns, newsletter controls, and legal ordering.

Migration Notes

No changes are required for existing imports. New components are available from @giddaa-housing/ui/mask-input, @giddaa-housing/ui/top-navbar, and @giddaa-housing/ui/mobile-sidebar.

Version 3.0.0

Release type: Major

Breaking changes: DashboardHeader's border prop is replaced by hideBorder, and DashboardHeaderGroup no longer accepts an orientation prop.

Highlights

  • Adds chat primitives: Message (bubbles with media, file, and voice attachments plus conversation markers), Chat (shell, following scroll body, and composer), and CallCard (voice-call overlay).
  • ChatInputAttach takes an items prop (with defaultChatInputAttachItems) so the attachment menu can add custom file kinds or non-file actions.
  • Reworks DashboardHeader composition for Figma-aligned list/detail layouts: the header now renders a bottom border by default, and adds DashboardHeaderNavigation and DashboardHeaderMain slots.
  • Adds a Figma-aligned back Button variant for header back-navigation, and ButtonGroup accepts an optional size override.
  • Fixes a Tailwind v4 bug where scale/translate/rotate transitions were named transform in transition-property lists, which silently prevented those animations from running (switch thumb, tabs indicator, accordion icon, button press-down, and more).
  • Tightens motion package-wide: shared motion tokens, direct-manipulation fixes for toast swipe and slider/media-player dragging, instant sidebar collapse, interruptible anchored popups and dialogs, edge-attached sheets, grouped toolbar tooltip timing, bounded time-picker scroll painting, standardized press feedback, and package-wide prefers-reduced-motion support.
  • Adds missing "use client" directives to hook-using components (Button, Card, Input, Textarea, Stepper, and others) so they can be imported directly into React Server Components without runtime errors.

Migration Notes

Replace <DashboardHeader border> with <DashboardHeader> (border is now the default) or add hideBorder to opt out.

Replace <DashboardHeaderGroup orientation="horizontal"> with <DashboardHeaderNavigation>, and wrap title/description/actions layouts that need the responsive row treatment in the new DashboardHeaderMain.

Version 2.1.0

Release type: Minor

Breaking changes: None.

Highlights

  • Adds public @giddaa-housing/ui/infinite-scroll slots for paginated lists, including loading, empty, error, end, content, and sentinel states.
  • Adds Combobox virtualization helpers for large option sets: ComboboxVirtualizedList and useComboboxVirtualizer.
  • Adds Card.removePadding and fixes Card slot padding so CardHeader, CardContent, and CardFooter read the root --card-padding variable.
  • Improves Table and DataTable behavior for long content by wrapping inside fixed-width columns instead of overflowing into neighboring cells.
  • Refines DatePicker and TimePicker popovers with centered alignment and subtle borders.
  • Fixes secondary pill Tabs so they do not render the underline baseline border.

Migration Notes

No required migration for existing imports. For media or edge-to-edge Card layouts, prefer removePadding over force-overriding the root with p-0!.

Use the new InfiniteScroll subpath for paginated lists:

import {
  InfiniteScroll,
  InfiniteScrollContent,
  InfiniteScrollSentinel,
} from "@giddaa-housing/ui/infinite-scroll";

Version 2.0.0

Release type: Major

Breaking changes: SheetContent no longer applies horizontal padding to content placed directly inside it. Nested Dialog and Sheet dismissal and stacking behavior has also changed.

Highlights

  • Adds public @giddaa-housing/ui/file-upload primitives for progress, preview, status, and cancellation flows.
  • Adds the size-aware @giddaa-housing/ui/input-otp component.
  • Adds SheetBody for inset, scrollable Sheet content and improves nested Dialog and Sheet overlays.
  • Moves Tabs sizing to TabsList, while retaining deprecated forwarding from Tabs for this release.

Migration Notes

Wrap Sheet body content in SheetBody instead of placing it directly in SheetContent:

<SheetContent>
  <SheetHeader>...</SheetHeader>
  <SheetBody>...</SheetBody>
  <SheetFooter>...</SheetFooter>
</SheetContent>

Move the Tabs size prop from Tabs to TabsList:

<Tabs>
  <TabsList size="lg">...</TabsList>
</Tabs>

If product tests depend on nested Dialog or Sheet outside-press dismissal, backdrop styling, parent scaling, or close-button visibility, update their expectations for the new topmost-overlay behavior.

Version 1.2.0

Release type: Minor

Breaking changes: None.

Highlights

  • Adds public subpath exports for @giddaa-housing/ui/list-item and @giddaa-housing/ui/purchase-option-card.
  • Expands chart primitives for metric, trend, tooltip, legend, and multi-series display patterns.
  • Refreshes chart and component docs with additional usage examples.

Migration Notes

No consumer migration is required for existing imports.

Version 1.1.0

Release type: Minor

Breaking changes: None.

Highlights

  • Adds public subpath exports for table and form primitives, including data table, filter, multi-step form, table card, and rich text editor.
  • Moves the package build pipeline to tsdown and updates the TypeScript toolchain.

Migration Notes

No consumer migration is required for existing imports.

Version 1.0.0

Release type: Major

Breaking changes: This is the first stable public contract. Consumers should use public package subpaths and stop relying on unpublished workspace or source paths.

Highlights

  • Establishes stable ESM component subpath exports, such as @giddaa-housing/ui/button, @giddaa-housing/ui/dialog, and @giddaa-housing/ui/property-listing-card.
  • Publishes the package CSS entrypoint at @giddaa-housing/ui/styles.css.
  • Publishes optional Giddaa brand theme CSS at @giddaa-housing/ui/css/giddaa.css.
  • Defines the public package contract for product-agnostic primitives, component styles, and design tokens.

Migration Notes

Import shared styles once at the application root:

import "@giddaa-housing/ui/styles.css";
import "@giddaa-housing/ui/css/giddaa.css";

Use public component subpaths:

import { Button } from "@giddaa-housing/ui/button";
import { Dialog, DialogContent, DialogTrigger } from "@giddaa-housing/ui/dialog";

Avoid unpublished source paths:

// Do not use this in consumer applications.
import { Button } from "@giddaa-housing/ui/src/button";

Version 0.1.0

Release type: Minor

Breaking changes: None recorded.

Highlights

  • Prepared the first prerelease/stable package publication for the Giddaa UI library and composed components.

How We Document Releases

Every released version should include:

  • Release type: patch, minor, or major.
  • Breaking changes: Use None when there are no breaking changes.
  • Highlights: User-facing additions, fixes, or behavior changes.
  • Migration notes: Required only when consumers need to change imports, props, CSS, tokens, package setup, or usage patterns.

Use this template when adding a new entry:

## Version x.y.z

**Release type:** Patch | Minor | Major

**Breaking changes:** None.

### Highlights

- ...

### Migration Notes

- ...

What Counts As Breaking

Treat a change as breaking when it can require consumer application changes, including:

  • Removing or renaming a public component export or subpath.
  • Renaming, removing, or changing the expected shape of public props.
  • Changing required CSS imports or public stylesheet paths.
  • Removing, renaming, or changing the meaning of public design tokens.
  • Changing default behavior or markup in a way that can break tests, accessibility expectations, or product flows.
  • Moving a previously published component back to experimental or unpublished status.

On this page