diff --git a/plugins/woocommerce-blocks/packages/components/panel/index.tsx b/plugins/woocommerce-blocks/packages/components/panel/index.tsx
index 3d71466cc1f..7c4e70a51e1 100644
--- a/plugins/woocommerce-blocks/packages/components/panel/index.tsx
+++ b/plugins/woocommerce-blocks/packages/components/panel/index.tsx
@@ -11,12 +11,12 @@ import type { ReactNode, ReactElement } from 'react';
*/
import './style.scss';
-interface PanelProps {
- children?: ReactNode;
- className?: string;
+export interface PanelProps {
+ children: ReactNode;
+ className?: string | undefined;
initialOpen?: boolean;
hasBorder?: boolean;
- title?: ReactNode;
+ title: ReactNode;
titleTag?: keyof JSX.IntrinsicElements;
}
diff --git a/plugins/woocommerce-blocks/packages/components/panel/stories/index.stories.tsx b/plugins/woocommerce-blocks/packages/components/panel/stories/index.stories.tsx
new file mode 100644
index 00000000000..c4bded716bc
--- /dev/null
+++ b/plugins/woocommerce-blocks/packages/components/panel/stories/index.stories.tsx
@@ -0,0 +1,104 @@
+/**
+ * External dependencies
+ */
+import type { StoryFn, Meta } from '@storybook/react';
+import { useArgs } from '@storybook/preview-api';
+
+/**
+ * Internal dependencies
+ */
+import Panel, { type PanelProps } from '..';
+
+export default {
+ title: 'External Components/Panel',
+ component: Panel,
+ argTypes: {
+ children: {
+ control: 'null',
+ description: "The content element to display in the panel's body",
+ table: {
+ type: {
+ summary: 'ReactNode',
+ },
+ },
+ },
+ className: {
+ description: 'Additional CSS classes to be added to the panel.',
+ control: 'text',
+ table: {
+ type: {
+ summary: 'string',
+ },
+ },
+ },
+ initialOpen: {
+ description: 'Whether the panel body should be visible by default.',
+ table: {
+ type: {
+ summary: 'boolean',
+ },
+ },
+ },
+ title: {
+ control: 'null',
+ description: "The React element to display as the panel's title",
+ table: {
+ type: {
+ summary: 'ReactNode',
+ },
+ },
+ },
+ titleTag: {
+ control: 'text',
+ description:
+ 'The HTML tag used to display the title element. Defaults to `div`.',
+ table: {
+ type: {
+ summary: 'string',
+ },
+ },
+ },
+ },
+} as Meta< PanelProps >;
+
+const Template: StoryFn< PanelProps > = ( args ) => {
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ let [ { titleTag }, _ ] = useArgs();
+
+ titleTag = ( titleTag || 'div' ).replace( /\n/g, '' );
+ if (
+ document.createElement( titleTag.toUpperCase() ).toString() ===
+ '[object HTMLUnknownElement]'
+ ) {
+ titleTag = 'div';
+ }
+ return (
+