diff --git a/.changeset/hungry-dogs-agree.md b/.changeset/hungry-dogs-agree.md new file mode 100644 index 0000000000..b111b6e463 --- /dev/null +++ b/.changeset/hungry-dogs-agree.md @@ -0,0 +1,6 @@ +--- +'@backstage/core-app-api': patch +'@backstage/core-plugin-api': patch +--- + +Added `getSystemIcons()` function to the `AppContext` available through `useApp` that will pull a list of all the icons that have been registered in the App. diff --git a/docs/assets/getting-started/add-icons-links-example.png b/docs/assets/getting-started/add-icons-links-example.png new file mode 100644 index 0000000000..dfff84b79c Binary files /dev/null and b/docs/assets/getting-started/add-icons-links-example.png differ diff --git a/docs/getting-started/app-custom-theme.md b/docs/getting-started/app-custom-theme.md index 9ca82d01a1..25131f1c91 100644 --- a/docs/getting-started/app-custom-theme.md +++ b/docs/getting-started/app-custom-theme.md @@ -273,18 +273,22 @@ const LogoFull = () => { }; ``` -## Custom Icons +## Icons + +So far you've seen how to create your own theme and add your own logo, in the following sections you'll be shown how to override the existing icons and how to add more icons + +### Custom Icons You can also customize the Project's _default_ icons. You can change the following [icons](https://github.com/backstage/backstage/blob/master/packages/app-defaults/src/defaults/icons.tsx). -### Requirements +#### Requirements - Files in `.svg` format - React components created for the icons -### Create React Component +#### Create React Component In your front-end application, locate the `src` folder. We suggest creating the `assets/icons` directory and `CustomIcons.tsx` file. @@ -309,7 +313,7 @@ export const ExampleIcon = (props: SvgIconProps) => ( ); ``` -### Using the custom icon +#### Using the custom icon Supply your custom icon in `packages/app/src/App.tsx` @@ -338,6 +342,57 @@ const app = createApp({ [...] ``` +### Adding Icons + +You can add more icons, if the [default icons](https://github.com/backstage/backstage/blob/master/packages/app-defaults/src/defaults/icons.tsx) do not fit your needs, so that they can be used in other places like for Links in your entities. For this example we'll be using icons from[Material UI](https://v4.mui.com/components/material-icons/) and specifically the `AlarmIcon`. Here's how to do that: + +1. First you will want to open your `App.tsx` in `/packages/app/src` +2. Then you want to import your icon, add this to the rest of your imports: `import AlarmIcon from '@material-ui/icons/Alarm';` +3. Next you want to add the icon like this to your `createApp`: + + ```diff + const app = createApp({ + apis: ..., + plugins: ..., + + icons: { + + alert: AlarmIcon, + + }, + themes: ..., + components: ..., + }); + ``` + +4. Now we can reference `alert` for our icon in our entity links like this: + + ```yaml + apiVersion: backstage.io/v1alpha1 + kind: Component + metadata: + name: artist-lookup + description: Artist Lookup + links: + - url: https://example.com/alert + title: Alerts + icon: alert + ``` + + And this is the result: + + ![Example Link with Alert icon](../assets/getting-started/add-icons-links-example.png) + + Another way you can use these icons is from the `AppContext` like this: + + ```ts + import { useApp } from '@backstage/core-plugin-api'; + + const app = useApp(); + const alertIcon = app.getSystemIcon('alert'); + ``` + + You might want to use this method if you have an icon you want to use in several locations. + +Note: If the icon is not available as one of the default icons or one you've added then it will fall back to Material UI's `LanguageIcon` + ## Custom Homepage In addition to a custom theme, a custom logo, you can also customize the diff --git a/packages/core-app-api/api-report.md b/packages/core-app-api/api-report.md index beb0d11201..3cc1f4a8a8 100644 --- a/packages/core-app-api/api-report.md +++ b/packages/core-app-api/api-report.md @@ -157,6 +157,7 @@ export type AppConfigLoader = () => Promise; export type AppContext = { getPlugins(): BackstagePlugin[]; getSystemIcon(key: string): IconComponent | undefined; + getSystemIcons(): Record; getComponents(): AppComponents; }; diff --git a/packages/core-app-api/src/app/AppContext.test.tsx b/packages/core-app-api/src/app/AppContext.test.tsx index bc67ee3a9e..a27b7c6f35 100644 --- a/packages/core-app-api/src/app/AppContext.test.tsx +++ b/packages/core-app-api/src/app/AppContext.test.tsx @@ -36,6 +36,7 @@ describe('v1 consumer', () => { getPlugins: jest.fn(), getComponents: jest.fn(), getSystemIcon: jest.fn(), + getSystemIcons: jest.fn(), }; const renderedHook = renderHook(() => useMockAppV1(), { diff --git a/packages/core-app-api/src/app/AppManager.tsx b/packages/core-app-api/src/app/AppManager.tsx index 72c69f7da4..f36d37f796 100644 --- a/packages/core-app-api/src/app/AppManager.tsx +++ b/packages/core-app-api/src/app/AppManager.tsx @@ -153,6 +153,10 @@ class AppContextImpl implements AppContext { return this.app.getSystemIcon(key); } + getSystemIcons(): Record { + return this.app.getSystemIcons(); + } + getComponents(): AppComponents { return this.app.getComponents(); } @@ -194,6 +198,10 @@ export class AppManager implements BackstageApp { return this.icons[key]; } + getSystemIcons(): Record { + return this.icons; + } + getComponents(): AppComponents { return this.components; } diff --git a/packages/core-app-api/src/app/types.ts b/packages/core-app-api/src/app/types.ts index 979fb0496e..39bf9c0554 100644 --- a/packages/core-app-api/src/app/types.ts +++ b/packages/core-app-api/src/app/types.ts @@ -328,6 +328,11 @@ export type AppContext = { */ getSystemIcon(key: string): IconComponent | undefined; + /** + * Get a list of common and custom icons for this app. + */ + getSystemIcons(): Record; + /** * Get the components registered for various purposes in the app. */ diff --git a/packages/core-app-api/src/routing/RoutingProvider.test.tsx b/packages/core-app-api/src/routing/RoutingProvider.test.tsx index dec92072fc..c559c0fff0 100644 --- a/packages/core-app-api/src/routing/RoutingProvider.test.tsx +++ b/packages/core-app-api/src/routing/RoutingProvider.test.tsx @@ -124,6 +124,7 @@ const Extension5 = plugin.provide( const mockContext = { getComponents: () => ({ Progress: () => null } as any), getSystemIcon: jest.fn(), + getSystemIcons: jest.fn(), getPlugins: jest.fn(), }; diff --git a/packages/core-plugin-api/api-report.md b/packages/core-plugin-api/api-report.md index 49e0be3800..87fc344a02 100644 --- a/packages/core-plugin-api/api-report.md +++ b/packages/core-plugin-api/api-report.md @@ -149,6 +149,7 @@ export type AppComponents = { export type AppContext = { getPlugins(): BackstagePlugin_2[]; getSystemIcon(key: string): IconComponent_2 | undefined; + getSystemIcons(): Record; getComponents(): AppComponents; };