From 7e743f4ad90d826f7464c6483f678be6574a894b Mon Sep 17 00:00:00 2001 From: Charles de Dreuille Date: Thu, 5 Feb 2026 13:49:59 +0000 Subject: [PATCH] Remove BUI docs Signed-off-by: Charles de Dreuille --- .changeset/toast-api-introduction.md | 38 +++ .storybook/main.ts | 1 + .../src/app/components/toast/components.tsx | 320 ------------------ docs-ui/src/app/components/toast/page.mdx | 136 -------- .../app/components/toast/props-definition.ts | 44 --- docs-ui/src/app/components/toast/snippets.ts | 287 ---------------- docs-ui/src/utils/data.ts | 5 - 7 files changed, 39 insertions(+), 792 deletions(-) create mode 100644 .changeset/toast-api-introduction.md delete mode 100644 docs-ui/src/app/components/toast/components.tsx delete mode 100644 docs-ui/src/app/components/toast/page.mdx delete mode 100644 docs-ui/src/app/components/toast/props-definition.ts delete mode 100644 docs-ui/src/app/components/toast/snippets.ts diff --git a/.changeset/toast-api-introduction.md b/.changeset/toast-api-introduction.md new file mode 100644 index 0000000000..24114797e6 --- /dev/null +++ b/.changeset/toast-api-introduction.md @@ -0,0 +1,38 @@ +--- +'@backstage/frontend-plugin-api': minor +'@backstage/plugin-app': minor +--- + +Introduced a new `ToastApi` for displaying rich toast notifications in the new frontend system. + +The new `ToastApi` provides enhanced notification capabilities compared to the existing `AlertApi`: + +- **Title and Description**: Toasts support both a title and an optional description +- **Custom Timeouts**: Each toast can specify its own timeout duration +- **Links**: Toasts can include action links +- **Icons**: Support for custom icons or disabling the default icon +- **Programmatic Dismiss**: Toasts can be dismissed programmatically using the key returned from `post()` + +**Usage:** + +```typescript +import { toastApiRef, useApi } from '@backstage/frontend-plugin-api'; + +const toastApi = useApi(toastApiRef); + +// Full-featured toast +toastApi.post({ + title: 'Entity saved', + description: 'Your changes have been saved successfully.', + status: 'success', + timeout: 5000, + links: [{ label: 'View entity', href: '/catalog/entity' }], +}); + +// Programmatic dismiss +const key = toastApi.post({ title: 'Uploading...', status: 'info' }); +// Later... +toastApi.close(key); +``` + +The `ToastDisplay` component subscribes to both `ToastApi` and `AlertApi`, providing a migration path where both systems work side by side until `AlertApi` is fully deprecated. diff --git a/.storybook/main.ts b/.storybook/main.ts index f891cd9692..a9cb4b243c 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -18,6 +18,7 @@ const allStories = isChromatic 'packages/ui', 'packages/core-components', 'packages/app', + 'plugins/app', 'plugins/org', 'plugins/search', 'plugins/search-react', diff --git a/docs-ui/src/app/components/toast/components.tsx b/docs-ui/src/app/components/toast/components.tsx deleted file mode 100644 index 5d032a7f17..0000000000 --- a/docs-ui/src/app/components/toast/components.tsx +++ /dev/null @@ -1,320 +0,0 @@ -'use client'; - -import { useState } from 'react'; -import { ToastContainer, toastQueue, Button, Flex } from '@backstage/ui'; -import type { ToastContent } from '@backstage/ui'; -import { MemoryRouter } from 'react-router-dom'; - -/** - * Single shared ToastContainer for all examples on this page. - * This prevents duplicate toasts when multiple examples share the same queue. - * Wrapped in MemoryRouter to support Link components inside toasts. - */ -export function SharedToastContainer() { - return ( - - - - ); -} - -const randomToasts: ToastContent[] = [ - // Info toasts - { title: 'New notification', status: 'info' }, - { - title: 'Update available', - description: 'A new version is ready to install.', - status: 'info', - }, - { - title: 'Tip', - description: 'You can use keyboard shortcuts to navigate faster.', - status: 'info', - links: [{ label: 'View shortcuts', href: '/shortcuts' }], - }, - // Success toasts - { title: 'Saved', status: 'success' }, - { - title: 'Files uploaded', - description: '3 files uploaded successfully.', - status: 'success', - }, - { - title: 'Deployment complete', - description: 'Your application has been deployed to production.', - status: 'success', - links: [ - { label: 'View logs', href: '/logs' }, - { label: 'Open app', href: '/app' }, - ], - }, - // Warning toasts - { title: 'Storage almost full', status: 'warning' }, - { - title: 'Session expiring', - description: 'Your session will expire in 5 minutes.', - status: 'warning', - }, - { - title: 'Rate limit warning', - description: 'You are approaching your API rate limit.', - status: 'warning', - links: [{ label: 'Upgrade plan', href: '/billing' }], - }, - // Danger toasts - { title: 'Connection lost', status: 'danger' }, - { - title: 'Error', - description: 'Something went wrong. Please try again.', - status: 'danger', - }, - { - title: 'Build failed', - description: 'The build process encountered an error.', - status: 'danger', - links: [{ label: 'View error details', href: '/errors' }], - }, -]; - -export function Default() { - return ( - - - - - ); -} - -export function StatusVariants() { - return ( - - - - - - - ); -} - -export function WithoutDescription() { - return ( - - - - - ); -} - -export function WithLinks() { - return ( - - - - - ); -} - -export function AutoDismiss() { - return ( - - - - - ); -} - -export function ProgrammaticControl() { - const [toastKey, setToastKey] = useState(null); - - return ( - - ); -} - -export function QueueManagement() { - return ( - - - - - - ); -} diff --git a/docs-ui/src/app/components/toast/page.mdx b/docs-ui/src/app/components/toast/page.mdx deleted file mode 100644 index ec8659a968..0000000000 --- a/docs-ui/src/app/components/toast/page.mdx +++ /dev/null @@ -1,136 +0,0 @@ -import { PropsTable } from '@/components/PropsTable'; -import { Snippet } from '@/components/Snippet'; -import { CodeBlock } from '@/components/CodeBlock'; -import { - toastContentPropDefs, - toastContainerPropDefs, -} from './props-definition'; -import { - toastUsageSnippet, - defaultSnippet, - statusVariantsSnippet, - withoutDescriptionSnippet, - withLinksSnippet, - autoDismissSnippet, - programmaticControlSnippet, - queueManagementSnippet, -} from './snippets'; -import { - SharedToastContainer, - Default, - StatusVariants, - WithoutDescription, - WithLinks, - AutoDismiss, - ProgrammaticControl, - QueueManagement, -} from './components'; -import { ChangelogComponent } from '@/components/ChangelogComponent'; -import { PageTitle } from '@/components/PageTitle'; -import { Theming } from '@/components/Theming'; -import { ToastDefinition } from '../../../utils/definitions'; - - - - - -} code={defaultSnippet} /> - -## Usage - -The Toast component uses a global queue system. Place the `ToastContainer` once in your app root, then trigger toasts from anywhere using the `queue` API. - - - -## API reference - -### ToastContent - -The content object passed to `queue.add()`: - - - -### ToastContainer - - - -## Examples - -### Status Variants - -The Toast component supports four status variants, each with its own color theme and icon. - -} - code={statusVariantsSnippet} -/> - -### Without Description - -Toasts can display a title only for simpler notifications. - -} - code={withoutDescriptionSnippet} -/> - -### With Links - -Toasts can include links to provide quick actions or navigation. - -} - code={withLinksSnippet} -/> - -### Auto Dismiss - -Toasts can automatically dismiss after a timeout. For accessibility, a minimum of 5 seconds is recommended. Timers automatically pause when users hover or focus on a toast. - -} - code={autoDismissSnippet} -/> - -### Programmatic Control - -You can programmatically dismiss toasts using the key returned from `queue.add()`. - -} - code={programmaticControlSnippet} -/> - -### Queue Management - -The toast queue supports multiple toasts with deep stacking. When multiple toasts are visible, they stack with the most recent toast fully visible and others slightly visible behind it with reduced opacity and scale. You can show multiple toasts at once or clear all toasts programmatically. - -} - code={queueManagementSnippet} -/> - - - - diff --git a/docs-ui/src/app/components/toast/props-definition.ts b/docs-ui/src/app/components/toast/props-definition.ts deleted file mode 100644 index 56945025c6..0000000000 --- a/docs-ui/src/app/components/toast/props-definition.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { - classNamePropDefs, - stylePropDefs, - type PropDef, -} from '@/utils/propDefs'; - -export const toastContentPropDefs: Record = { - title: { - type: 'enum', - values: ['React.ReactNode'], - responsive: false, - }, - description: { - type: 'enum', - values: ['React.ReactNode'], - responsive: false, - }, - status: { - type: 'enum', - values: ['info', 'success', 'warning', 'danger'], - responsive: false, - default: 'info', - }, - icon: { - type: 'enum', - values: ['boolean', 'React.ReactElement'], - responsive: false, - default: 'true', - }, - links: { - type: 'enum', - values: ['ToastLink[]'], - responsive: false, - }, -}; - -export const toastContainerPropDefs: Record = { - queue: { - type: 'enum', - values: ['ToastQueue'], - responsive: false, - }, - ...classNamePropDefs, -}; diff --git a/docs-ui/src/app/components/toast/snippets.ts b/docs-ui/src/app/components/toast/snippets.ts deleted file mode 100644 index 1c431966cf..0000000000 --- a/docs-ui/src/app/components/toast/snippets.ts +++ /dev/null @@ -1,287 +0,0 @@ -export const toastUsageSnippet = `import { ToastContainer, toastQueue } from '@backstage/ui'; - -// Place ToastContainer once in your app root -function App() { - return ( - <> - - - - ); -} - -// Trigger toasts from anywhere -toastQueue.add({ title: 'Success!', status: 'success' });`; - -export const defaultSnippet = `import { ToastContainer, toastQueue, Button } from '@backstage/ui'; - -export function Example() { - return ( - <> - - - - ); -}`; - -export const statusVariantsSnippet = `import { ToastContainer, toastQueue, Button, Flex } from '@backstage/ui'; - -export function Example() { - return ( - <> - - - - - - - - - ); -}`; - -export const withoutDescriptionSnippet = `import { ToastContainer, toastQueue, Button, Flex } from '@backstage/ui'; - -export function Example() { - return ( - <> - - - - - - - ); -}`; - -export const withLinksSnippet = `import { ToastContainer, toastQueue, Button, Flex } from '@backstage/ui'; - -export function Example() { - return ( - <> - - - - - - - ); -}`; - -export const autoDismissSnippet = `import { ToastContainer, toastQueue, Button, Flex } from '@backstage/ui'; - -export function Example() { - return ( - <> - - - - - - - ); -}`; - -export const programmaticControlSnippet = `import { useState } from 'react'; -import { ToastContainer, toastQueue, Button } from '@backstage/ui'; - -export function Example() { - const [toastKey, setToastKey] = useState(null); - - return ( - <> - - - - ); -}`; - -export const queueManagementSnippet = `import { ToastContainer, toastQueue, Button, Flex } from '@backstage/ui'; - -export function Example() { - return ( - <> - - - - - - - - ); -}`; diff --git a/docs-ui/src/utils/data.ts b/docs-ui/src/utils/data.ts index 9017262c6a..a1ef483785 100644 --- a/docs-ui/src/utils/data.ts +++ b/docs-ui/src/utils/data.ts @@ -121,11 +121,6 @@ export const components: Page[] = [ title: 'TextField', slug: 'text-field', }, - { - title: 'Toast', - slug: 'toast', - status: 'new', - }, { title: 'ToggleButton', slug: 'toggle-button',