diff --git a/.changeset/five-cows-cheer.md b/.changeset/five-cows-cheer.md
new file mode 100644
index 00000000000..d4461a474e6
--- /dev/null
+++ b/.changeset/five-cows-cheer.md
@@ -0,0 +1,5 @@
+---
+"@razorpay/blade": minor
+---
+
+feat(blade): breadcrumb web implementation
diff --git a/packages/blade/src/components/Breadcrumb/Breadcrumb.native.tsx b/packages/blade/src/components/Breadcrumb/Breadcrumb.native.tsx
new file mode 100644
index 00000000000..cd0aba1d8ce
--- /dev/null
+++ b/packages/blade/src/components/Breadcrumb/Breadcrumb.native.tsx
@@ -0,0 +1,13 @@
+import type { BreadcrumbProps } from './types';
+import { throwBladeError } from '~utils/logger';
+
+const Breadcrumb = (_: BreadcrumbProps): React.ReactElement => {
+ throwBladeError({
+ message: 'Breadcrumb is not yet implemented for native',
+ moduleName: 'Breadcrumb',
+ });
+
+ return <>>;
+};
+
+export { Breadcrumb };
diff --git a/packages/blade/src/components/Breadcrumb/Breadcrumb.stories.tsx b/packages/blade/src/components/Breadcrumb/Breadcrumb.stories.tsx
new file mode 100644
index 00000000000..6fabac8d455
--- /dev/null
+++ b/packages/blade/src/components/Breadcrumb/Breadcrumb.stories.tsx
@@ -0,0 +1,330 @@
+/* eslint-disable @typescript-eslint/no-unnecessary-type-assertion */
+/* eslint-disable jsx-a11y/label-has-associated-control */
+/* eslint-disable @typescript-eslint/explicit-function-return-type */
+import { Title } from '@storybook/addon-docs';
+import type { StoryFn, Meta } from '@storybook/react';
+import React from 'react';
+import type { LinkProps } from 'react-router-dom';
+import { useLocation, Link as RouterLink, matchPath, Route } from 'react-router-dom';
+import StoryRouter from 'storybook-react-router';
+import type { BreadcrumbItemProps, BreadcrumbProps } from './types';
+import { Breadcrumb } from './Breadcrumb';
+import { BreadcrumbItem } from './BreadcrumbItem';
+import StoryPageWrapper from '~utils/storybook/StoryPageWrapper';
+import { Sandbox } from '~utils/storybook/Sandbox';
+import { Box } from '~components/Box';
+import { HomeIcon } from '~components/Icons';
+import { Code, Text } from '~components/Typography';
+import { Card, CardBody, CardHeader, CardHeaderLeading } from '~components/Card';
+import { Link } from '~components/Link';
+import { getStyledPropsArgTypes } from '~components/Box/BaseBox/storybookArgTypes';
+
+const Page = (): React.ReactElement => {
+ return (
+
+ Usage
+
+ {`
+ import { Box, Breadcrumb, BreadcrumbItem, HomeIcon } from '@razorpay/blade/components';
+
+ function App(): React.ReactElement {
+ return (
+
+
+
+ Dashboard
+
+ Settlements
+
+
+
+ );
+ }
+
+ export default App;
+ `}
+
+
+ );
+};
+
+export default {
+ title: 'Components/Breadcrumb',
+ component: Breadcrumb,
+ tags: ['autodocs'],
+ argTypes: {
+ ...getStyledPropsArgTypes(),
+ },
+ args: {
+ size: 'medium',
+ color: 'primary',
+ showLastSeparator: false,
+ },
+ // eslint-disable-next-line babel/new-cap
+ decorators: [StoryRouter(undefined, { initialEntries: ['/home'] })] as unknown,
+ parameters: {
+ docs: {
+ page: Page,
+ },
+ },
+} as Meta;
+
+const BasicToastTemplate: StoryFn = (props) => {
+ return (
+
+
+
+ Dashboard
+
+ Settlements
+
+
+
+ );
+};
+
+BasicToastTemplate.storyName = 'Basic';
+export const Basic = BasicToastTemplate.bind({});
+
+const BreadcrumbSizes: StoryFn = () => {
+ return (
+
+
+
+ Dashboard
+
+ Settlements
+
+
+
+
+ Dashboard
+
+ Settlements
+
+
+
+
+ Dashboard
+
+ Settlements
+
+
+
+ );
+};
+
+BreadcrumbSizes.storyName = 'Sizes';
+export const Sizes = BreadcrumbSizes.bind({});
+
+const BreadcrumbColors: StoryFn = () => {
+ return (
+
+
+
+
+ Dashboard
+
+ Settlements
+
+
+
+
+
+
+ Dashboard
+
+ Settlements
+
+
+
+
+
+
+ Dashboard
+
+ Settlements
+
+
+
+
+ );
+};
+
+BreadcrumbColors.storyName = 'Colors';
+export const Colors = BreadcrumbColors.bind({});
+
+const BreadcrumbWrapMultilineTemplate: StoryFn = () => {
+ return (
+
+
+
+
+ Item 1
+ Item 2
+ Item 3
+ Item 4
+ Item 5
+ Item 6
+ Item 7
+
+
+
+ );
+};
+
+BreadcrumbWrapMultilineTemplate.storyName = 'BreadcrumbWrapMultiline';
+export const BreadcrumbWrapMultiline = BreadcrumbWrapMultilineTemplate.bind({});
+
+const urls = {
+ home: '/home',
+ products: '/products',
+ payments: '/payments',
+ intPayments: '/international-payments',
+ acceptIntPayments: '/accepts-international-payments',
+};
+
+type BreadcrumbLinkProps = Omit &
+ BreadcrumbItemProps & { navigate: () => void };
+
+const BreadcrumbLink = ({ onClick, ...props }: BreadcrumbLinkProps): React.ReactElement => {
+ const location = useLocation();
+
+ const isCurrentPage =
+ matchPath(location.pathname, {
+ path: props.href,
+ exact: true,
+ }) !== null;
+
+ return (
+ {
+ onClick?.(e as never);
+ e.preventDefault();
+ props.navigate();
+ }}
+ {...props}
+ />
+ );
+};
+
+const BreadcrumbNavLink = (
+ props: Omit & LinkProps,
+): React.ReactElement => {
+ return ;
+};
+
+const Page1 = (): React.ReactElement => {
+ return (
+
+
+
+ );
+};
+
+const Page2 = (): React.ReactElement => {
+ return (
+
+
+ Products
+
+ );
+};
+
+const Page3 = (): React.ReactElement => {
+ return (
+
+
+ Products
+ Payments
+
+ );
+};
+
+const Page4 = (): React.ReactElement => {
+ return (
+
+
+ Products
+ Payments
+ International Payments
+
+ );
+};
+
+const Page5 = (): React.ReactElement => {
+ return (
+
+
+ Products
+ Payments
+ International Payments
+
+ Accept International Payments
+
+
+ );
+};
+
+const CommonPage = (): React.ReactElement => {
+ const location = useLocation();
+ return (
+
+
+
+
+
+
+
+ You can use Breadcrumbs
with{' '}
+ react-router
to create a breadcrumb trail for your app.
+
+
+ Open this{' '}
+ Stackblitz link to
+ see the source code.
+
+
+
+ Trigger URL Change:
+
+ Home
+ Products
+ Payments
+ International Payments
+
+ Accept International Payments
+
+
+
+
+ );
+};
+
+const RouterExample = (): React.ReactElement => {
+ return (
+
+
+
+
+
+
+
+
+ );
+};
+
+const ReactRouterUsageTemplate: StoryFn = () => {
+ return ;
+};
+
+ReactRouterUsageTemplate.storyName = 'ReactRouterUsage';
+export const ReactRouterUsage = ReactRouterUsageTemplate.bind({});
diff --git a/packages/blade/src/components/Breadcrumb/Breadcrumb.web.tsx b/packages/blade/src/components/Breadcrumb/Breadcrumb.web.tsx
new file mode 100644
index 00000000000..4e3fd89c65f
--- /dev/null
+++ b/packages/blade/src/components/Breadcrumb/Breadcrumb.web.tsx
@@ -0,0 +1,88 @@
+/* eslint-disable react-native-a11y/has-valid-accessibility-role */
+import React from 'react';
+import type { BreadcrumbProps } from './types';
+import { BreadcrumbContext } from './BreadcrumbContext';
+import BaseBox from '~components/Box/BaseBox';
+import { Text } from '~components/Typography';
+import { makeAccessible } from '~utils/makeAccessible';
+import { getStyledProps } from '~components/Box/styledProps';
+import { metaAttribute, MetaConstants } from '~utils/metaAttribute';
+
+const Separator = ({
+ size,
+ color,
+}: Pick): React.ReactElement => {
+ return (
+
+ /
+
+ );
+};
+
+const listStyleNone = { listStyle: 'none' };
+
+const Breadcrumb = ({
+ size = 'medium',
+ color = 'primary',
+ showLastSeparator = false,
+ accessibilityLabel = 'Breadcrumb',
+ children,
+ ...styledProps
+}: BreadcrumbProps): React.ReactElement => {
+ const contextValue = React.useMemo(() => ({ size, color }), [size, color]);
+
+ return (
+
+
+
+ {React.Children.map(children, (child, index) => {
+ const ariaCurrent = (child as React.ReactElement)?.props?.isCurrentPage
+ ? 'page'
+ : undefined;
+
+ return (
+
+ {child}
+
+ {index !== React.Children.count(children) - 1 && }
+ {index === React.Children.count(children) - 1 && showLastSeparator && (
+
+ )}
+
+
+ );
+ })}
+
+
+
+ );
+};
+
+export { Breadcrumb };
diff --git a/packages/blade/src/components/Breadcrumb/BreadcrumbContext.tsx b/packages/blade/src/components/Breadcrumb/BreadcrumbContext.tsx
new file mode 100644
index 00000000000..ade158efe70
--- /dev/null
+++ b/packages/blade/src/components/Breadcrumb/BreadcrumbContext.tsx
@@ -0,0 +1,10 @@
+import React from 'react';
+import type { BreadcrumbProps } from './types';
+
+type BreadcrumbContextValue = Pick;
+const BreadcrumbContext = React.createContext({
+ size: 'medium',
+ color: 'primary',
+});
+
+export { BreadcrumbContext };
diff --git a/packages/blade/src/components/Breadcrumb/BreadcrumbItem.native.tsx b/packages/blade/src/components/Breadcrumb/BreadcrumbItem.native.tsx
new file mode 100644
index 00000000000..14ea0fae26f
--- /dev/null
+++ b/packages/blade/src/components/Breadcrumb/BreadcrumbItem.native.tsx
@@ -0,0 +1,13 @@
+import type { BreadcrumbItemProps } from './types';
+import { throwBladeError } from '~utils/logger';
+
+const BreadcrumbItem = (_: BreadcrumbItemProps): React.ReactElement => {
+ throwBladeError({
+ message: 'BreadcrumbItem is not yet implemented for native',
+ moduleName: 'BreadcrumbItem',
+ });
+
+ return <>>;
+};
+
+export { BreadcrumbItem };
diff --git a/packages/blade/src/components/Breadcrumb/BreadcrumbItem.web.tsx b/packages/blade/src/components/Breadcrumb/BreadcrumbItem.web.tsx
new file mode 100644
index 00000000000..5df63cbf85b
--- /dev/null
+++ b/packages/blade/src/components/Breadcrumb/BreadcrumbItem.web.tsx
@@ -0,0 +1,55 @@
+import React from 'react';
+import type { BreadcrumbItemProps } from './types';
+import { BreadcrumbContext } from './BreadcrumbContext';
+import { BaseLink } from '~components/Link/BaseLink';
+import { Text } from '~components/Typography';
+import BaseBox from '~components/Box/BaseBox';
+import { opacity } from '~tokens/global';
+
+const BreadcrumbItem = ({
+ children,
+ href,
+ icon: Icon,
+ isCurrentPage,
+ onClick,
+ accessibilityLabel,
+}: BreadcrumbItemProps): React.ReactElement => {
+ const { color, size } = React.useContext(BreadcrumbContext);
+
+ if (isCurrentPage) {
+ const isWhite = color === 'white';
+ return (
+
+ {Icon && (
+
+ )}
+
+ {children}
+
+
+ );
+ }
+
+ return (
+
+ {children ?? ''}
+
+ );
+};
+
+export { BreadcrumbItem };
diff --git a/packages/blade/src/components/Breadcrumb/_KitchenSink.Breadcrumb.stories.tsx b/packages/blade/src/components/Breadcrumb/_KitchenSink.Breadcrumb.stories.tsx
new file mode 100644
index 00000000000..9d4a4bbddc5
--- /dev/null
+++ b/packages/blade/src/components/Breadcrumb/_KitchenSink.Breadcrumb.stories.tsx
@@ -0,0 +1,31 @@
+import { composeStories } from '@storybook/react';
+import * as BreadcrumbStories from './Breadcrumb.stories';
+import { Box } from '~components/Box';
+import { Heading } from '~components/Typography';
+
+const allStories = Object.values(composeStories(BreadcrumbStories));
+
+export const Breadcrumb = (): JSX.Element => {
+ return (
+
+ {allStories.map((Story) => {
+ return (
+ <>
+ {Story.storyName}
+
+ >
+ );
+ })}
+
+ );
+};
+
+export default {
+ title: 'Components/KitchenSink/Breadcrumb',
+ component: Breadcrumb,
+ parameters: {
+ // enable Chromatic's snapshotting only for kitchensink
+ chromatic: { disableSnapshot: false },
+ options: { showPanel: false },
+ },
+};
diff --git a/packages/blade/src/components/Breadcrumb/__tests__/Breadcrumb.ssr.test.tsx b/packages/blade/src/components/Breadcrumb/__tests__/Breadcrumb.ssr.test.tsx
new file mode 100644
index 00000000000..5712f9871c7
--- /dev/null
+++ b/packages/blade/src/components/Breadcrumb/__tests__/Breadcrumb.ssr.test.tsx
@@ -0,0 +1,20 @@
+import { Breadcrumb, BreadcrumbItem } from '../';
+import { HomeIcon } from '~components/Icons';
+import renderWithSSR from '~utils/testing/renderWithSSR.web';
+
+describe('', () => {
+ it('should render breadcrumb', () => {
+ const { container } = renderWithSSR(
+
+
+ Home
+
+ About
+
+ Contact
+
+ ,
+ );
+ expect(container).toMatchSnapshot();
+ });
+});
diff --git a/packages/blade/src/components/Breadcrumb/__tests__/Breadcrumb.web.test.tsx b/packages/blade/src/components/Breadcrumb/__tests__/Breadcrumb.web.test.tsx
new file mode 100644
index 00000000000..6c1e270c08e
--- /dev/null
+++ b/packages/blade/src/components/Breadcrumb/__tests__/Breadcrumb.web.test.tsx
@@ -0,0 +1,71 @@
+import userEvent from '@testing-library/user-event';
+import { Breadcrumb, BreadcrumbItem } from '../';
+import renderWithTheme from '~utils/testing/renderWithTheme.web';
+import assertAccessible from '~utils/testing/assertAccessible.web';
+
+describe('', () => {
+ it('should render', () => {
+ const { container } = renderWithTheme(
+
+ Home
+ About
+ Contact
+ ,
+ );
+
+ expect(container).toMatchSnapshot();
+ });
+
+ test('current item should have aria-current', () => {
+ const { container, getByText } = renderWithTheme(
+
+ Home
+ About
+
+ Contact
+
+ ,
+ );
+
+ expect(container).toMatchSnapshot();
+ expect(getByText('Contact').closest('li')).toHaveAttribute('aria-current', 'page');
+ });
+
+ test('should work with showLastSeparator', () => {
+ const { container } = renderWithTheme(
+
+ Home
+ About
+ Contact
+ ,
+ );
+
+ expect(container).toMatchSnapshot();
+ });
+
+ test('should work with onClick', async () => {
+ const onClick = jest.fn();
+ const { getByText } = renderWithTheme(
+
+
+ Home
+
+ ,
+ );
+ const link = getByText('Home');
+ await userEvent.click(link);
+ expect(onClick).toHaveBeenCalledTimes(1);
+ });
+
+ it('should pass a11y render', async () => {
+ const { container } = renderWithTheme(
+
+ Home
+ About
+ Contact
+ ,
+ );
+
+ await assertAccessible(container);
+ });
+});
diff --git a/packages/blade/src/components/Breadcrumb/__tests__/__snapshots__/Breadcrumb.ssr.test.tsx.snap b/packages/blade/src/components/Breadcrumb/__tests__/__snapshots__/Breadcrumb.ssr.test.tsx.snap
new file mode 100644
index 00000000000..b9896bdeaa2
--- /dev/null
+++ b/packages/blade/src/components/Breadcrumb/__tests__/__snapshots__/Breadcrumb.ssr.test.tsx.snap
@@ -0,0 +1,293 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` should render breadcrumb 1`] = `""`;
+
+exports[` should render breadcrumb 2`] = `
+.c0.c0.c0.c0.c0 {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-wrap: wrap;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ padding: 0px;
+ margin: 0px;
+ gap: 4px;
+}
+
+.c1.c1.c1.c1.c1 {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ gap: 4px;
+}
+
+.c3.c3.c3.c3.c3 {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: row;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ opacity: 1;
+}
+
+.c4.c4.c4.c4.c4 {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ padding-right: 4px;
+}
+
+.c5.c5.c5.c5.c5 {
+ color: hsla(227,71%,51%,1);
+ font-family: "Inter",-apple-system,BlinkMacSystemFont,San Francisco,Segoe UI,Roboto,Helvetica Neue,sans-serif;
+ font-size: 1rem;
+ font-weight: 500;
+ font-style: normal;
+ -webkit-text-decoration-line: none;
+ text-decoration-line: none;
+ line-height: 1.5rem;
+ -webkit-letter-spacing: 0px;
+ -moz-letter-spacing: 0px;
+ -ms-letter-spacing: 0px;
+ letter-spacing: 0px;
+ text-align: center;
+ margin: 0;
+ padding: 0;
+}
+
+.c6.c6.c6.c6.c6 {
+ color: hsla(211,22%,56%,1);
+ font-family: "Inter",-apple-system,BlinkMacSystemFont,San Francisco,Segoe UI,Roboto,Helvetica Neue,sans-serif;
+ font-size: 1rem;
+ font-weight: 500;
+ font-style: normal;
+ -webkit-text-decoration-line: none;
+ text-decoration-line: none;
+ line-height: 1.5rem;
+ -webkit-letter-spacing: 0px;
+ -moz-letter-spacing: 0px;
+ -ms-letter-spacing: 0px;
+ letter-spacing: 0px;
+ margin: 0;
+ padding: 0;
+}
+
+.c7.c7.c7.c7.c7 {
+ color: hsla(212,39%,16%,1);
+ font-family: "Inter",-apple-system,BlinkMacSystemFont,San Francisco,Segoe UI,Roboto,Helvetica Neue,sans-serif;
+ font-size: 1rem;
+ font-weight: 500;
+ font-style: normal;
+ -webkit-text-decoration-line: none;
+ text-decoration-line: none;
+ line-height: 1.5rem;
+ -webkit-letter-spacing: 0px;
+ -moz-letter-spacing: 0px;
+ -ms-letter-spacing: 0px;
+ letter-spacing: 0px;
+ margin: 0;
+ padding: 0;
+}
+
+.c2.c2.c2.c2.c2 {
+ padding: 0;
+ background-color: transparent;
+ outline: none;
+ -webkit-text-decoration: none;
+ text-decoration: none;
+ border: none;
+ cursor: pointer;
+ display: inline-block;
+ border-radius: 2px;
+ -webkit-transition-property: box-shadow;
+ transition-property: box-shadow;
+ -webkit-transition-timing-function: cubic-bezier(0.3,0,0.2,1);
+ transition-timing-function: cubic-bezier(0.3,0,0.2,1);
+ -webkit-transition-duration: 70ms;
+ transition-duration: 70ms;
+}
+
+.c2.c2.c2.c2.c2 .content-container {
+ width: -webkit-max-content;
+ width: -moz-max-content;
+ width: max-content;
+ border-radius: 2px;
+}
+
+.c2.c2.c2.c2.c2:focus-visible .content-container {
+ box-shadow: 0px 0px 0px 4px hsla(227,100%,59%,0.09);
+}
+
+.c2.c2.c2.c2.c2 * {
+ -webkit-transition-property: color,fill;
+ transition-property: color,fill;
+ -webkit-transition-timing-function: cubic-bezier(0.3,0,0.2,1);
+ transition-timing-function: cubic-bezier(0.3,0,0.2,1);
+ -webkit-transition-duration: 70ms;
+ transition-duration: 70ms;
+}
+
+
+`;
diff --git a/packages/blade/src/components/Breadcrumb/__tests__/__snapshots__/Breadcrumb.web.test.tsx.snap b/packages/blade/src/components/Breadcrumb/__tests__/__snapshots__/Breadcrumb.web.test.tsx.snap
new file mode 100644
index 00000000000..982404e49b6
--- /dev/null
+++ b/packages/blade/src/components/Breadcrumb/__tests__/__snapshots__/Breadcrumb.web.test.tsx.snap
@@ -0,0 +1,731 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` current item should have aria-current 1`] = `
+.c0.c0.c0.c0.c0 {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-wrap: wrap;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ padding: 0px;
+ margin: 0px;
+ gap: 4px;
+}
+
+.c1.c1.c1.c1.c1 {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ gap: 4px;
+}
+
+.c3.c3.c3.c3.c3 {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: row;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ opacity: 1;
+}
+
+.c4.c4.c4.c4.c4 {
+ color: hsla(227,71%,51%,1);
+ font-family: "Inter",-apple-system,BlinkMacSystemFont,San Francisco,Segoe UI,Roboto,Helvetica Neue,sans-serif;
+ font-size: 0.875rem;
+ font-weight: 500;
+ font-style: normal;
+ -webkit-text-decoration-line: none;
+ text-decoration-line: none;
+ line-height: 1.25rem;
+ -webkit-letter-spacing: 0px;
+ -moz-letter-spacing: 0px;
+ -ms-letter-spacing: 0px;
+ letter-spacing: 0px;
+ text-align: center;
+ margin: 0;
+ padding: 0;
+}
+
+.c5.c5.c5.c5.c5 {
+ color: hsla(211,22%,56%,1);
+ font-family: "Inter",-apple-system,BlinkMacSystemFont,San Francisco,Segoe UI,Roboto,Helvetica Neue,sans-serif;
+ font-size: 0.875rem;
+ font-weight: 500;
+ font-style: normal;
+ -webkit-text-decoration-line: none;
+ text-decoration-line: none;
+ line-height: 1.25rem;
+ -webkit-letter-spacing: 0px;
+ -moz-letter-spacing: 0px;
+ -ms-letter-spacing: 0px;
+ letter-spacing: 0px;
+ margin: 0;
+ padding: 0;
+}
+
+.c6.c6.c6.c6.c6 {
+ color: hsla(212,39%,16%,1);
+ font-family: "Inter",-apple-system,BlinkMacSystemFont,San Francisco,Segoe UI,Roboto,Helvetica Neue,sans-serif;
+ font-size: 0.875rem;
+ font-weight: 500;
+ font-style: normal;
+ -webkit-text-decoration-line: none;
+ text-decoration-line: none;
+ line-height: 1.25rem;
+ -webkit-letter-spacing: 0px;
+ -moz-letter-spacing: 0px;
+ -ms-letter-spacing: 0px;
+ letter-spacing: 0px;
+ margin: 0;
+ padding: 0;
+}
+
+.c2.c2.c2.c2.c2 {
+ padding: 0;
+ background-color: transparent;
+ outline: none;
+ -webkit-text-decoration: none;
+ text-decoration: none;
+ border: none;
+ cursor: pointer;
+ display: inline-block;
+ border-radius: 2px;
+ -webkit-transition-property: box-shadow;
+ transition-property: box-shadow;
+ -webkit-transition-timing-function: cubic-bezier(0.3,0,0.2,1);
+ transition-timing-function: cubic-bezier(0.3,0,0.2,1);
+ -webkit-transition-duration: 70ms;
+ transition-duration: 70ms;
+}
+
+.c2.c2.c2.c2.c2 .content-container {
+ width: -webkit-max-content;
+ width: -moz-max-content;
+ width: max-content;
+ border-radius: 2px;
+}
+
+.c2.c2.c2.c2.c2:focus-visible .content-container {
+ box-shadow: 0px 0px 0px 4px hsla(227,100%,59%,0.09);
+}
+
+.c2.c2.c2.c2.c2 * {
+ -webkit-transition-property: color,fill;
+ transition-property: color,fill;
+ -webkit-transition-timing-function: cubic-bezier(0.3,0,0.2,1);
+ transition-timing-function: cubic-bezier(0.3,0,0.2,1);
+ -webkit-transition-duration: 70ms;
+ transition-duration: 70ms;
+}
+
+
+`;
+
+exports[` should render 1`] = `
+.c0.c0.c0.c0.c0 {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-wrap: wrap;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ padding: 0px;
+ margin: 0px;
+ gap: 4px;
+}
+
+.c1.c1.c1.c1.c1 {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ gap: 4px;
+}
+
+.c3.c3.c3.c3.c3 {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: row;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ opacity: 1;
+}
+
+.c4.c4.c4.c4.c4 {
+ color: hsla(227,71%,51%,1);
+ font-family: "Inter",-apple-system,BlinkMacSystemFont,San Francisco,Segoe UI,Roboto,Helvetica Neue,sans-serif;
+ font-size: 0.875rem;
+ font-weight: 500;
+ font-style: normal;
+ -webkit-text-decoration-line: none;
+ text-decoration-line: none;
+ line-height: 1.25rem;
+ -webkit-letter-spacing: 0px;
+ -moz-letter-spacing: 0px;
+ -ms-letter-spacing: 0px;
+ letter-spacing: 0px;
+ text-align: center;
+ margin: 0;
+ padding: 0;
+}
+
+.c5.c5.c5.c5.c5 {
+ color: hsla(211,22%,56%,1);
+ font-family: "Inter",-apple-system,BlinkMacSystemFont,San Francisco,Segoe UI,Roboto,Helvetica Neue,sans-serif;
+ font-size: 0.875rem;
+ font-weight: 500;
+ font-style: normal;
+ -webkit-text-decoration-line: none;
+ text-decoration-line: none;
+ line-height: 1.25rem;
+ -webkit-letter-spacing: 0px;
+ -moz-letter-spacing: 0px;
+ -ms-letter-spacing: 0px;
+ letter-spacing: 0px;
+ margin: 0;
+ padding: 0;
+}
+
+.c2.c2.c2.c2.c2 {
+ padding: 0;
+ background-color: transparent;
+ outline: none;
+ -webkit-text-decoration: none;
+ text-decoration: none;
+ border: none;
+ cursor: pointer;
+ display: inline-block;
+ border-radius: 2px;
+ -webkit-transition-property: box-shadow;
+ transition-property: box-shadow;
+ -webkit-transition-timing-function: cubic-bezier(0.3,0,0.2,1);
+ transition-timing-function: cubic-bezier(0.3,0,0.2,1);
+ -webkit-transition-duration: 70ms;
+ transition-duration: 70ms;
+}
+
+.c2.c2.c2.c2.c2 .content-container {
+ width: -webkit-max-content;
+ width: -moz-max-content;
+ width: max-content;
+ border-radius: 2px;
+}
+
+.c2.c2.c2.c2.c2:focus-visible .content-container {
+ box-shadow: 0px 0px 0px 4px hsla(227,100%,59%,0.09);
+}
+
+.c2.c2.c2.c2.c2 * {
+ -webkit-transition-property: color,fill;
+ transition-property: color,fill;
+ -webkit-transition-timing-function: cubic-bezier(0.3,0,0.2,1);
+ transition-timing-function: cubic-bezier(0.3,0,0.2,1);
+ -webkit-transition-duration: 70ms;
+ transition-duration: 70ms;
+}
+
+
+`;
+
+exports[` should work with showLastSeparator 1`] = `
+.c0.c0.c0.c0.c0 {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-wrap: wrap;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ padding: 0px;
+ margin: 0px;
+ gap: 4px;
+}
+
+.c1.c1.c1.c1.c1 {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ gap: 4px;
+}
+
+.c3.c3.c3.c3.c3 {
+ display: -webkit-box;
+ display: -webkit-flex;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-flex-direction: row;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-align-items: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ opacity: 1;
+}
+
+.c4.c4.c4.c4.c4 {
+ color: hsla(227,71%,51%,1);
+ font-family: "Inter",-apple-system,BlinkMacSystemFont,San Francisco,Segoe UI,Roboto,Helvetica Neue,sans-serif;
+ font-size: 0.875rem;
+ font-weight: 500;
+ font-style: normal;
+ -webkit-text-decoration-line: none;
+ text-decoration-line: none;
+ line-height: 1.25rem;
+ -webkit-letter-spacing: 0px;
+ -moz-letter-spacing: 0px;
+ -ms-letter-spacing: 0px;
+ letter-spacing: 0px;
+ text-align: center;
+ margin: 0;
+ padding: 0;
+}
+
+.c5.c5.c5.c5.c5 {
+ color: hsla(211,22%,56%,1);
+ font-family: "Inter",-apple-system,BlinkMacSystemFont,San Francisco,Segoe UI,Roboto,Helvetica Neue,sans-serif;
+ font-size: 0.875rem;
+ font-weight: 500;
+ font-style: normal;
+ -webkit-text-decoration-line: none;
+ text-decoration-line: none;
+ line-height: 1.25rem;
+ -webkit-letter-spacing: 0px;
+ -moz-letter-spacing: 0px;
+ -ms-letter-spacing: 0px;
+ letter-spacing: 0px;
+ margin: 0;
+ padding: 0;
+}
+
+.c2.c2.c2.c2.c2 {
+ padding: 0;
+ background-color: transparent;
+ outline: none;
+ -webkit-text-decoration: none;
+ text-decoration: none;
+ border: none;
+ cursor: pointer;
+ display: inline-block;
+ border-radius: 2px;
+ -webkit-transition-property: box-shadow;
+ transition-property: box-shadow;
+ -webkit-transition-timing-function: cubic-bezier(0.3,0,0.2,1);
+ transition-timing-function: cubic-bezier(0.3,0,0.2,1);
+ -webkit-transition-duration: 70ms;
+ transition-duration: 70ms;
+}
+
+.c2.c2.c2.c2.c2 .content-container {
+ width: -webkit-max-content;
+ width: -moz-max-content;
+ width: max-content;
+ border-radius: 2px;
+}
+
+.c2.c2.c2.c2.c2:focus-visible .content-container {
+ box-shadow: 0px 0px 0px 4px hsla(227,100%,59%,0.09);
+}
+
+.c2.c2.c2.c2.c2 * {
+ -webkit-transition-property: color,fill;
+ transition-property: color,fill;
+ -webkit-transition-timing-function: cubic-bezier(0.3,0,0.2,1);
+ transition-timing-function: cubic-bezier(0.3,0,0.2,1);
+ -webkit-transition-duration: 70ms;
+ transition-duration: 70ms;
+}
+
+
+`;
diff --git a/packages/blade/src/components/Breadcrumb/index.ts b/packages/blade/src/components/Breadcrumb/index.ts
new file mode 100644
index 00000000000..c8f5f169de6
--- /dev/null
+++ b/packages/blade/src/components/Breadcrumb/index.ts
@@ -0,0 +1,3 @@
+export * from './Breadcrumb';
+export * from './BreadcrumbItem';
+export * from './types';
diff --git a/packages/blade/src/components/Breadcrumb/types.ts b/packages/blade/src/components/Breadcrumb/types.ts
new file mode 100644
index 00000000000..7bcb57a9f0f
--- /dev/null
+++ b/packages/blade/src/components/Breadcrumb/types.ts
@@ -0,0 +1,65 @@
+import type { StyledPropsBlade } from '~components/Box/styledProps';
+import type { IconComponent } from '~components/Icons';
+import type { LinkProps } from '~components/Link';
+import type { StringChildrenType } from '~utils/types';
+
+type BreadcrumbProps = StyledPropsBlade & {
+ /**
+ * Size of the Breadcrumb
+ *
+ * @default medium
+ */
+ size?: 'small' | 'medium' | 'large';
+ /**
+ * Color of the Breadcrumb
+ *
+ * @default neutral
+ */
+ color?: 'neutral' | 'primary' | 'white';
+ /**
+ * Content of the Breadcrumb, accepts BreadcrumbItem
+ */
+ children: React.ReactNode;
+ /**
+ * Whether to show the last separator
+ */
+ showLastSeparator?: boolean;
+ /**
+ * aria-label for breadcrumb
+ */
+ accessibilityLabel?: string;
+};
+
+type BreadcrumbItemProps = {
+ /**
+ * Href of the BreadcrumbItem
+ */
+ href: string;
+ /**
+ * Function to be called on click of the BreadcrumbItem,
+ *
+ * This can be used to integrate with routing libraries like `react-router-dom`
+ */
+ onClick?: LinkProps['onClick'];
+ /**
+ * Whether the BreadcrumbItem is the current page,
+ * Sets the aria-current attribute to `page`
+ *
+ * @default false
+ */
+ isCurrentPage?: boolean;
+ /**
+ * Content of the BreadcrumbItem
+ */
+ children?: StringChildrenType;
+ /**
+ * Icon to be shown before the BreadcrumbItem
+ */
+ icon?: IconComponent;
+ /**
+ * Accessibility label for the BreadcrumbItem, can be used in icon only variant
+ */
+ accessibilityLabel?: string;
+};
+
+export type { BreadcrumbProps, BreadcrumbItemProps };
diff --git a/packages/blade/src/components/Link/BaseLink/BaseLink.tsx b/packages/blade/src/components/Link/BaseLink/BaseLink.tsx
index 9c67be12828..b9a0a6547eb 100644
--- a/packages/blade/src/components/Link/BaseLink/BaseLink.tsx
+++ b/packages/blade/src/components/Link/BaseLink/BaseLink.tsx
@@ -78,6 +78,7 @@ type BaseLinkCommonProps = {
* The title of the link which is displayed as a tooltip. This is a web only prop and has no effect on react-native.
*/
htmlTitle?: string;
+ opacity?: number;
} & TestID &
StyledPropsBlade &
Omit;
@@ -269,6 +270,7 @@ const _BaseLink: React.ForwardRefRenderFunction
target,
rel,
color = 'primary',
+ opacity,
accessibilityProps,
// @ts-expect-error avoiding exposing to public
className,
@@ -394,6 +396,7 @@ const _BaseLink: React.ForwardRefRenderFunction
flexDirection="row"
className="content-container"
alignItems="center"
+ opacity={opacity}
>
{Icon && iconPosition == 'left' ? (
diff --git a/packages/blade/src/components/index.ts b/packages/blade/src/components/index.ts
index 6add468277f..a84600bf861 100644
--- a/packages/blade/src/components/index.ts
+++ b/packages/blade/src/components/index.ts
@@ -5,6 +5,7 @@ export * from './Amount';
export * from './Badge';
export * from './BladeProvider';
export * from './BottomSheet';
+export * from './Breadcrumb';
export * from './Box';
export * from './Button';
export * from './Button/IconButton';
diff --git a/packages/blade/src/utils/metaAttribute/metaConstants.ts b/packages/blade/src/utils/metaAttribute/metaConstants.ts
index a923bc74cca..e12f2ba7625 100644
--- a/packages/blade/src/utils/metaAttribute/metaConstants.ts
+++ b/packages/blade/src/utils/metaAttribute/metaConstants.ts
@@ -13,6 +13,8 @@ export const MetaConstants = {
BaseBox: 'base-box',
BaseText: 'base-text',
Button: 'button',
+ Breadcrumb: 'breadcrumb',
+ BreadcrumbItem: 'breadcrumb-item',
Carousel: 'carousel',
Checkbox: 'checkbox',
CheckboxGroup: 'checkbox-group',