Add aria-labels to the theme select, color scheme toggle group,
and the individual light/dark toggle buttons.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
Change changelog badge labels from spaced title case (e.g.
"Button Link") to PascalCase (e.g. "ButtonLink") so they match
the actual component names and are searchable. Hook slugs
starting with `use-` display as camelCase (e.g. "useTable").
Signed-off-by: Johan Persson <johanopersson@gmail.com>
Add `badge`, `slider`, and `use-table` to the Component type so
the changelog sync script recognizes them. Add `useTable` special
case mapping in the sync script, and include `use-table` in the
Table docs page changelog.
Also fix CHANGELOG.md to use `Slider` instead of `RangeSlider`
as the affected component name.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* feat(ui): export TableBodySkeleton as public API
Export the TableBodySkeleton component so it can be used independently
of the built-in Table component. Relax the column type constraint from
ColumnConfig<T> to { id: string } for compatibility with custom column
types.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* fix(ui): use direct index instead of parsing skeleton item ID
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* Update .changeset/export-table-body-skeleton.md
Co-authored-by: Johan Persson <johanopersson@gmail.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* docs(ui): add TableBodySkeleton to table primitives documentation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
---------
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Johan Persson <johanopersson@gmail.com>
* feat(ui): widen activeTabId type to accept null
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* feat(ui): add automatic active tab detection to HeaderNav
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* feat(ui): update Header stories to demonstrate auto-detection and explicit activeTabId
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* refactor(ui): remove manual useActiveTabId from PluginHeaderAndHeader recipe
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* docs(ui): update Header docs for activeTabId auto-detection
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* chore(ui): add API report and changeset for activeTabId auto-detection
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* fix(ui): resolve relative hrefs in HeaderNav tabs
Add resolveHref to HeaderNavItemDefinition so tab links with relative
hrefs are resolved against the router context before rendering.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* chore(ui): add breaking change changeset for HeaderNav resolveHref
Signed-off-by: Johan Persson <johanopersson@gmail.com>
---------
Signed-off-by: Johan Persson <johanopersson@gmail.com>
Adds a new `Badge` component to the Backstage UI library. Badge shares the same visual appearance as `Tag` (size tokens, colors, border radius, icon slot) but renders as a plain non-interactive `<span>` with no React Aria plumbing.
Key characteristics:
- Plain DOM element — accessible text content exposed to screen readers without any role override
- Background consumer — participates in the bg context system and steps up neutral background levels (`neutral-2` → `neutral-3` → `neutral-4`) when placed inside colored containers
- Supports `icon`, `size` (`small` | `medium`, defaults to `small`), `children`, and `className` props
- Fully themeable via `BadgeDefinition`
Also includes Storybook stories and full docs-ui documentation (props table, examples, theming section, changelog).
Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
Made-with: Cursor
Add `CompletePaginationOptions` type extending `PaginationOptions`
with a `type` field supporting `'page'` (default) and `'none'`.
When using `mode: 'complete'` with `type: 'none'`, `useTable` skips
data slicing and produces `pagination: { type: 'none' }` in
`tableProps` directly.
Also sync `pageSize` state when `paginationOptions.pageSize` changes
dynamically, fixing cases where the initial value became stale.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* feat(ui): add showPaginationLabel to type definitions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* feat(ui): wire showPaginationLabel through useTable and Table
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* feat(ui): conditionally render pagination label based on showPaginationLabel
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* chore(ui): add changeset and update API reports for showPaginationLabel
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* Update .changeset/show-pagination-label.md
Co-authored-by: Johan Persson <johanopersson@gmail.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* docs(ui): document showPaginationLabel prop in docs-ui
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* fix(ui): wrap component names in backticks in changeset
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* fix(ui): move pagination display options to inner useMemo dependency array
Move showPageSizeOptions, getLabel, and showPaginationLabel from the
outer useMemo dependency array to the inner pagination useMemo
dependency array so that changes to these options correctly trigger
a new pagination object reference.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
* chore(ui): remove backticks from changeset
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* Revert "chore(ui): remove backticks from changeset"
This reverts commit 9b7f8bb6e83c28587219b7734676b1c062661a8a.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
---------
Signed-off-by: Jonathan Roebuck <jroebuck@spotify.com>
Signed-off-by: Johan Persson <johanopersson@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Johan Persson <johanopersson@gmail.com>
Replace the RA Tabs/TabList/Tab rendering in the Header component
with a nav-based approach that supports grouped dropdown items via
BUI Menu. Active state is consumer-controlled via a new activeTabId
prop. The indicator system follows the TabsIndicators CSS custom
property pattern for animated active/hover/focus states.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
Generated changelog entries for @backstage/ui v0.12.0 (30 entries)
and v0.13.0 (48 entries) using the sync-changelog script.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
Add all exported sub-components to the Component type union so
changelog entries referencing them are resolved correctly. Update
ChangelogComponent to accept an array of components, showing scoped
badges when filtering by multiple components. Update 13 component
pages to include their sub-components in the changelog section.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
Move the cell wrapper requirement documentation from the package
README to the docs-ui table component page where it belongs.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
* feat(ui): centralize routing in BUIProvider
BUIProvider now auto-detects React Router context and provides
client-side navigation for all BUI components. Retired
InternalLinkProvider and added BUIRouterProvider as a public
export for integration use.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* feat(plugin-app): move BUIProvider inside app router
Moved BUIProvider from wrapping AppRouter to being a child inside
it, so it detects the React Router context and provides client-side
routing for all BUI components.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* feat(core-app-api): add BUIRouterProvider to legacy app router
Added BUIRouterProvider inside the legacy AppRouter to provide
React Aria routing for all BUI components.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* docs(ui): update BUIProvider documentation for routing
Updated installation docs to cover BUIProvider's routing role
and the requirement to render it inside a React Router context.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* refactor(ui): move BUIProvider from analytics to provider directory
BUIProvider now handles both analytics and routing, so it no longer
belongs in the analytics directory.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* fix(ui): add BUIProvider to storybook stories with MemoryRouter
Added BUIProvider inside MemoryRouter in all stories that use
routing, so client-side navigation works in Storybook.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* fix(plugin-app): move BUIProvider inside RouterComponent
Moved BUIProvider to wrap all content inside RouterComponent
so that extraElements (like dialogs) also get BUI context.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* refactor: replace BUIRouterProvider with BUIProvider in legacy app
Use BUIProvider directly inside the legacy AppRouter instead of a
separate BUIRouterProvider export. Removes BUIRouterProvider from
the public API of @backstage/ui.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
* refactor(ui): inline routing logic into BUIProvider
Removed the routing/ directory and inlined the RouterProvider
setup directly into BUIProvider since it's the only consumer.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
---------
Signed-off-by: Johan Persson <johanopersson@gmail.com>
Add SearchAutocomplete and SearchAutocompleteItem components for
building accessible search-with-results patterns. Built on React
Aria's Autocomplete with virtual focus for keyboard navigation
and a non-modal popover for results.
Features:
- Controlled input via inputValue/onInputChange
- Configurable popover width and placement
- Rich content support per result item
- Item selection via onAction
- defaultOpen prop for visual testing
- Close on interact outside and input clear
Includes Storybook stories, docs-ui documentation, changeset,
and API report.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
Adds standalone `ListBox` and `ListBoxItem` components to `@backstage/ui`,
built on top of React Aria's ListBox primitives. Items support icons,
descriptions, and single or multiple selection modes.
Includes Storybook stories and docs-ui documentation page.
Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
Made-with: Cursor
* Deprecate HeaderPage in favor of Header in @backstage/ui
Rename the HeaderPage component to Header, keeping HeaderPage as a
deprecated alias for backwards compatibility. Also deprecate
HeaderPageProps, HeaderPageOwnProps, HeaderPageBreadcrumb, and
HeaderPageDefinition with new Header* equivalents. Update all internal
usages, stories, and docs-ui documentation to use the new names.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
* Rename HeaderPage files and directories to Header
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
* Add changeset for mui-to-bui Header rename
Document the plugin release impact of switching the MUI to BUI theme converter page to the renamed Header component.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
---------
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Fix pre-existing variant default from 'body' to 'body-medium' to match
actual CSS selectors. Add missing 'info' color to docs-ui props definition.
Signed-off-by: Johan Persson <johanopersson@gmail.com>
Renamed the Header component to PluginHeader for clarity, along with
all associated exports (HeaderProps, HeaderDefinition) and CSS class
names. Updated docs-ui documentation to match.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>