diff --git a/public/app/core/components/AppChrome/Breadcrumbs.tsx b/public/app/core/components/AppChrome/Breadcrumbs.tsx
deleted file mode 100644
index 7f64568c98f..00000000000
--- a/public/app/core/components/AppChrome/Breadcrumbs.tsx
+++ /dev/null
@@ -1,90 +0,0 @@
-import { css } from '@emotion/css';
-import React from 'react';
-
-import { GrafanaTheme2, NavModelItem } from '@grafana/data';
-import { useStyles2, Icon, IconName, LinkButton } from '@grafana/ui';
-
-export interface Props {
- breadcrumbs: Breadcrumb[];
-}
-
-export interface Breadcrumb {
- text?: string;
- icon?: IconName;
- href?: string;
-}
-
-export function Breadcrumbs({ breadcrumbs }: Props) {
- const styles = useStyles2(getStyles);
-
- return (
-
- {breadcrumbs.map((breadcrumb, index) => (
- -
- {breadcrumb.href && breadcrumb.text && (
-
- {breadcrumb.text}
-
- )}
- {breadcrumb.href && breadcrumb.icon && (
-
- )}
- {!breadcrumb.href && {breadcrumb.text}}
- {index + 1 < breadcrumbs.length && (
-
-
-
- )}
-
- ))}
-
- );
-}
-
-export function buildBreadcrumbs(sectionNav: NavModelItem, pageNav?: NavModelItem) {
- const crumbs: Breadcrumb[] = [{ icon: 'home-alt', href: '/' }];
-
- function addCrumbs(node: NavModelItem) {
- if (node.parentItem) {
- addCrumbs(node.parentItem);
- }
-
- crumbs.push({ text: node.text, href: node.url });
- }
-
- addCrumbs(sectionNav);
-
- if (pageNav) {
- addCrumbs(pageNav);
- }
-
- return crumbs;
-}
-
-const getStyles = (theme: GrafanaTheme2) => {
- return {
- breadcrumbs: css({
- display: 'flex',
- alignItems: 'center',
- flexWrap: 'nowrap',
- fontWeight: theme.typography.fontWeightMedium,
- }),
- breadcrumb: css({
- display: 'flex',
- alignItems: 'center',
- }),
- separator: css({
- color: theme.colors.text.secondary,
- }),
- breadcrumbLink: css({
- alignItems: 'center',
- color: theme.colors.text.primary,
- display: 'flex',
- padding: theme.spacing(0, 0.5),
- whiteSpace: 'nowrap',
- '&:hover': {
- textDecoration: 'underline',
- },
- }),
- };
-};
diff --git a/public/app/core/components/AppChrome/NavToolbar.tsx b/public/app/core/components/AppChrome/NavToolbar.tsx
index 424a62fe92d..260e4229e07 100644
--- a/public/app/core/components/AppChrome/NavToolbar.tsx
+++ b/public/app/core/components/AppChrome/NavToolbar.tsx
@@ -4,7 +4,9 @@ import React from 'react';
import { GrafanaTheme2, NavModelItem } from '@grafana/data';
import { Icon, IconButton, ToolbarButton, useStyles2 } from '@grafana/ui';
-import { Breadcrumbs, buildBreadcrumbs } from './Breadcrumbs';
+import { Breadcrumbs } from '../Breadcrumbs/Breadcrumbs';
+import { buildBreadcrumbs } from '../Breadcrumbs/utils';
+
import { NavToolbarSeparator } from './NavToolbarSeparator';
import { TOP_BAR_LEVEL_HEIGHT } from './types';
diff --git a/public/app/core/components/Breadcrumbs/BreadcrumbItem.tsx b/public/app/core/components/Breadcrumbs/BreadcrumbItem.tsx
new file mode 100644
index 00000000000..7b41f9cccbe
--- /dev/null
+++ b/public/app/core/components/Breadcrumbs/BreadcrumbItem.tsx
@@ -0,0 +1,69 @@
+import { css, cx } from '@emotion/css';
+import React from 'react';
+
+import { GrafanaTheme2 } from '@grafana/data';
+import { Icon, LinkButton, useStyles2 } from '@grafana/ui';
+
+import { Breadcrumb } from './types';
+
+type Props = Breadcrumb & {
+ isCurrent: boolean;
+};
+
+export function BreadcrumbItem(props: Props) {
+ const styles = useStyles2(getStyles);
+ return (
+
+ {props.isCurrent ? (
+
+ {props.text}
+
+ ) : (
+ <>
+ {'icon' in props ? (
+
+ ) : (
+
+ {props.text}
+
+ )}
+
+
+
+ >
+ )}
+
+ );
+}
+
+const getStyles = (theme: GrafanaTheme2) => {
+ return {
+ breadcrumb: css({
+ alignItems: 'center',
+ display: 'flex',
+ padding: theme.spacing(0, 0.5),
+ whiteSpace: 'nowrap',
+ }),
+ breadcrumbLink: css({
+ '&:hover': {
+ textDecoration: 'underline',
+ },
+ }),
+ breadcrumbWrapper: css({
+ alignItems: 'center',
+ color: theme.colors.text.primary,
+ display: 'flex',
+ fontWeight: theme.typography.fontWeightMedium,
+ }),
+ separator: css({
+ color: theme.colors.text.secondary,
+ }),
+ };
+};
diff --git a/public/app/core/components/Breadcrumbs/Breadcrumbs.tsx b/public/app/core/components/Breadcrumbs/Breadcrumbs.tsx
new file mode 100644
index 00000000000..c08a1d67d27
--- /dev/null
+++ b/public/app/core/components/Breadcrumbs/Breadcrumbs.tsx
@@ -0,0 +1,36 @@
+import { css } from '@emotion/css';
+import React from 'react';
+
+import { GrafanaTheme2 } from '@grafana/data';
+import { useStyles2 } from '@grafana/ui';
+
+import { BreadcrumbItem } from './BreadcrumbItem';
+import { Breadcrumb } from './types';
+
+export interface Props {
+ breadcrumbs: Breadcrumb[];
+}
+
+export function Breadcrumbs({ breadcrumbs }: Props) {
+ const styles = useStyles2(getStyles);
+
+ return (
+
+ );
+}
+
+const getStyles = (theme: GrafanaTheme2) => {
+ return {
+ breadcrumbs: css({
+ display: 'flex',
+ alignItems: 'center',
+ flexWrap: 'nowrap',
+ }),
+ };
+};
diff --git a/public/app/core/components/Breadcrumbs/types.ts b/public/app/core/components/Breadcrumbs/types.ts
new file mode 100644
index 00000000000..271d16b4dc4
--- /dev/null
+++ b/public/app/core/components/Breadcrumbs/types.ts
@@ -0,0 +1,12 @@
+import { IconName } from '@grafana/ui';
+
+interface TextBreadcrumb {
+ text: string;
+ href: string;
+}
+
+interface IconBreadcrumb extends TextBreadcrumb {
+ icon: IconName;
+}
+
+export type Breadcrumb = TextBreadcrumb | IconBreadcrumb;
diff --git a/public/app/core/components/Breadcrumbs/utils.ts b/public/app/core/components/Breadcrumbs/utils.ts
new file mode 100644
index 00000000000..6bea1e7bf06
--- /dev/null
+++ b/public/app/core/components/Breadcrumbs/utils.ts
@@ -0,0 +1,23 @@
+import { NavModelItem } from '@grafana/data';
+
+import { Breadcrumb } from './types';
+
+export function buildBreadcrumbs(sectionNav: NavModelItem, pageNav?: NavModelItem) {
+ const crumbs: Breadcrumb[] = [{ icon: 'home-alt', href: '/', text: 'Home' }];
+
+ function addCrumbs(node: NavModelItem) {
+ if (node.parentItem) {
+ addCrumbs(node.parentItem);
+ }
+
+ crumbs.push({ text: node.text, href: node.url ?? '' });
+ }
+
+ addCrumbs(sectionNav);
+
+ if (pageNav) {
+ addCrumbs(pageNav);
+ }
+
+ return crumbs;
+}