diff --git a/tools/ui-components/src/panel/index.ts b/tools/ui-components/src/panel/index.ts
new file mode 100644
index 00000000000..0a3fa400bdc
--- /dev/null
+++ b/tools/ui-components/src/panel/index.ts
@@ -0,0 +1,2 @@
+export { Panel } from './panel';
+export type { PanelProps } from './types';
diff --git a/tools/ui-components/src/panel/panel.stories.tsx b/tools/ui-components/src/panel/panel.stories.tsx
new file mode 100644
index 00000000000..22a9d90793c
--- /dev/null
+++ b/tools/ui-components/src/panel/panel.stories.tsx
@@ -0,0 +1,55 @@
+import React from 'react';
+import { Story } from '@storybook/react';
+import { Panel, PanelProps } from '.';
+
+const story = {
+ title: 'Example/Panel',
+ component: Panel,
+ parameters: {
+ controls: {
+ include: ['className', 'bsStyle']
+ }
+ },
+ argType: {
+ className: { control: { type: 'text' } },
+ bsStyle: { option: ['primary', 'danger', 'info', undefined] }
+ }
+};
+
+const Child = () => {
+ return (
+ <>
+
+ Here is panel Heading
+
+ Here is Panel body
+ >
+ );
+};
+
+const Template: Story = args => ;
+
+export const Default = Template.bind({});
+Default.args = {
+ children:
+};
+
+export const Primary = Template.bind({});
+Primary.args = {
+ children: ,
+ bsStyle: 'primary'
+};
+
+export const Info = Template.bind({});
+Info.args = {
+ children: ,
+ bsStyle: 'info'
+};
+
+export const Danger = Template.bind({});
+Danger.args = {
+ children: ,
+ bsStyle: 'danger'
+};
+
+export default story;
diff --git a/tools/ui-components/src/panel/panel.test.tsx b/tools/ui-components/src/panel/panel.test.tsx
new file mode 100644
index 00000000000..4e626c368d0
--- /dev/null
+++ b/tools/ui-components/src/panel/panel.test.tsx
@@ -0,0 +1,25 @@
+import React from 'react';
+import { render, screen } from '@testing-library/react';
+
+import { Panel } from '.';
+
+describe('', () => {
+ it('PanelTitle should render', () => {
+ render(Test Title);
+ const title = screen.getByText('Test Title');
+ expect(title).toBeInTheDocument();
+ });
+ it('PanelHead should inherit bsStyle', () => {
+ render(
+
+ Test
+ TestBody
+
+ );
+ expect(screen.getByRole('article')).toBeInTheDocument();
+ expect(screen.getByText('Test')).toHaveClass(
+ 'border-b-1 border-solid border-foreground-primary text-foreground-primary'
+ );
+ expect(screen.getByText('TestBody')).toBeInTheDocument();
+ });
+});
diff --git a/tools/ui-components/src/panel/panel.tsx b/tools/ui-components/src/panel/panel.tsx
new file mode 100644
index 00000000000..5c14fc37ed7
--- /dev/null
+++ b/tools/ui-components/src/panel/panel.tsx
@@ -0,0 +1,94 @@
+import React, { createContext, useContext } from 'react';
+
+import { PanelProps } from './types';
+
+type PanelContextProps = Pick;
+const PanelContext = createContext({});
+
+const styles = 'border-1 border-solid shadow-sm mb-6';
+const defaultBorder = 'border-background-tertiary';
+const primaryBorder = 'border-foreground-primary';
+const dangerBorder = 'border-foreground-danger';
+const infoBorder = 'border-foreground-info';
+const defaultHeadingStyle =
+ 'border-b-1 border-solid border-background-tertiary';
+const primaryHeadingStyle =
+ 'border-b-1 border-solid border-foreground-primary text-foreground-primary';
+const infoHeadingStyle = 'text-background-info bg-foreground-info';
+const dangerHeadingStyle = 'text-background-danger bg-foreground-danger';
+const headingPadding = 'px-2.5 py-3.5 ';
+
+let bsStyleClass = defaultBorder;
+let headingStyles = headingPadding + defaultHeadingStyle;
+
+const Body = ({
+ children,
+ props
+}: {
+ children?: React.ReactNode;
+ props?: React.ComponentProps<'div'>;
+}): JSX.Element => {
+ return (
+
+ {children}
+
+ );
+};
+
+export const Heading = ({
+ children,
+ props
+}: {
+ children?: React.ReactNode;
+ props?: React.ComponentProps<'div'>;
+}): JSX.Element => {
+ const { bsStyle } = useContext(PanelContext);
+ if (bsStyle === 'primary') headingStyles = primaryHeadingStyle;
+ else if (bsStyle === 'danger') headingStyles = dangerHeadingStyle;
+ else if (bsStyle === 'info') headingStyles = infoHeadingStyle;
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const Title = ({
+ children,
+ props
+}: {
+ children?: React.ReactNode;
+ props?: React.ComponentProps<'h3'>;
+}): JSX.Element => {
+ return (
+
+ {children}
+
+ );
+};
+
+export const Panel = ({
+ children,
+ className,
+ bsStyle,
+ ...restProps
+}: PanelProps): JSX.Element => {
+ if (bsStyle === 'primary') bsStyleClass = primaryBorder;
+ else if (bsStyle === 'danger') bsStyleClass = dangerBorder;
+ else if (bsStyle === 'info') bsStyleClass = infoBorder;
+
+ const panelClassed = [styles, bsStyleClass, className].join(' ');
+
+ return (
+
+
+ {children}
+
+
+ );
+};
+
+Panel.Body = Body;
+Panel.Heading = Heading;
+Panel.Title = Title;
diff --git a/tools/ui-components/src/panel/types.ts b/tools/ui-components/src/panel/types.ts
new file mode 100644
index 00000000000..ab25dc6ed62
--- /dev/null
+++ b/tools/ui-components/src/panel/types.ts
@@ -0,0 +1,5 @@
+import React from 'react';
+
+export interface PanelProps extends React.HTMLAttributes {
+ bsStyle?: 'primary' | 'info' | 'danger';
+}