diff --git a/apps/design-system/src/components/Tabs.stories.tsx b/apps/design-system/src/components/Tabs.stories.tsx
new file mode 100644
index 000000000..2683c1ec8
--- /dev/null
+++ b/apps/design-system/src/components/Tabs.stories.tsx
@@ -0,0 +1,29 @@
+import React from 'react';
+import { Meta } from '@storybook/react';
+import { Tabs, TabsContent, TabsList, TabsTrigger } from '@asyncapi/studio-ui'
+
+const meta: Meta = {
+ component: Tabs,
+ parameters: {
+ layout: 'centered',
+ backgrounds: {
+ default: 'dark'
+ }
+ }
+}
+
+export default meta
+
+
+export const Default = {
+ render: () => (
+
+ Visual Editor
+ Code Editor
+ Examples
+
+ Visual Editor Layout
+ Code Editor Layout
+ Examples Layout
+ )
+}
diff --git a/apps/design-system/src/styles/tailwind.output.css b/apps/design-system/src/styles/tailwind.output.css
index 0a66c7bef..ca8ba5104 100644
--- a/apps/design-system/src/styles/tailwind.output.css
+++ b/apps/design-system/src/styles/tailwind.output.css
@@ -563,6 +563,10 @@ video {
margin-bottom: 0.75rem;
}
+.mb-1 {
+ margin-bottom: 0.25rem;
+}
+
.flex {
display: flex;
}
@@ -579,6 +583,10 @@ video {
width: 100%;
}
+.w-\[360px\] {
+ width: 360px;
+}
+
.grow {
flex-grow: 1;
}
@@ -603,6 +611,14 @@ video {
border-radius: 0.25rem;
}
+.rounded-xl {
+ border-radius: 0.75rem;
+}
+
+.border {
+ border-width: 1px;
+}
+
.bg-gray-100 {
--tw-bg-opacity: 1;
background-color: rgb(241 245 249 / var(--tw-bg-opacity));
diff --git a/packages/ui/components/Separator.tsx b/packages/ui/components/Separator.tsx
new file mode 100644
index 000000000..d0d3218ec
--- /dev/null
+++ b/packages/ui/components/Separator.tsx
@@ -0,0 +1,29 @@
+"use client"
+
+import * as React from "react"
+import * as SeparatorPrimitive from "@radix-ui/react-separator"
+
+import { cn } from "@asyncapi/studio-utils"
+
+const Separator = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(
+ (
+ { className, orientation = "horizontal", decorative = true, ...props },
+ ref
+ ) => (
+
+ )
+)
+Separator.displayName = SeparatorPrimitive.Root.displayName
+
+export { Separator }
diff --git a/packages/ui/components/Tabs.tsx b/packages/ui/components/Tabs.tsx
new file mode 100644
index 000000000..d080f1e49
--- /dev/null
+++ b/packages/ui/components/Tabs.tsx
@@ -0,0 +1,58 @@
+"use client"
+
+import * as React from "react"
+import * as TabsPrimitive from "@radix-ui/react-tabs"
+import { cn } from "@asyncapi/studio-utils"
+import { Separator } from './Separator'
+
+const Tabs = TabsPrimitive.Root
+
+const TabsList = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+
+))
+TabsList.displayName = TabsPrimitive.List.displayName
+
+const TabsTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+TabsTrigger.displayName = TabsPrimitive.Trigger.displayName
+
+const TabsContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+TabsContent.displayName = TabsPrimitive.Content.displayName
+
+export { Tabs, TabsList, TabsTrigger, TabsContent }
diff --git a/packages/ui/components/index.tsx b/packages/ui/components/index.tsx
index d7aecb761..f15628aff 100644
--- a/packages/ui/components/index.tsx
+++ b/packages/ui/components/index.tsx
@@ -19,4 +19,5 @@ export * from './AppCard'
export * from './VisualEditor/Example'
export * from './VisualEditor/CodeEditor'
export * from './VisualEditor'
+export * from './Tabs'
export { default as Tooltip } from './Tooltip'
diff --git a/packages/ui/package.json b/packages/ui/package.json
index 1ce790ecb..c3aeff26e 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -25,7 +25,9 @@
"@radix-ui/react-dropdown-menu": "^2.0.5",
"@radix-ui/react-form": "^0.0.3",
"@radix-ui/react-select": "^1.2.2",
+ "@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-switch": "^1.0.3",
+ "@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-toolbar": "^1.0.4",
"@radix-ui/react-tooltip": "^1.0.6",
"classnames": "^2.3.2",
@@ -35,12 +37,12 @@
"react-icons": "^5.2.1"
},
"devDependencies": {
+ "@asyncapi/studio-utils": "workspace:*",
"@types/lodash": "^4.17.0",
"@types/react": "^18.2.5",
"eslint-config-custom": "workspace:*",
"postcss": "^8.4.31",
"tailwind-config": "workspace:*",
- "@asyncapi/studio-utils": "workspace:*",
"tsconfig": "workspace:*",
"tsup": "^8.0.2",
"typescript": "^4.9.4"
diff --git a/packages/utils/package.json b/packages/utils/package.json
index 0563c6eb3..560d88407 100644
--- a/packages/utils/package.json
+++ b/packages/utils/package.json
@@ -6,7 +6,8 @@
"types": "dist/index.d.ts",
"private": true,
"scripts": {
- "build": "tsup"
+ "build": "tsup",
+ "dev": "tsup --watch"
},
"keywords": [],
"author": "",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 2a91162dc..40b21f724 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -654,9 +654,15 @@ importers:
'@radix-ui/react-select':
specifier: ^1.2.2
version: 1.2.2(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-separator':
+ specifier: ^1.0.3
+ version: 1.0.3(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0)
'@radix-ui/react-switch':
specifier: ^1.0.3
version: 1.0.3(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-tabs':
+ specifier: ^1.0.4
+ version: 1.0.4(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0)
'@radix-ui/react-toolbar':
specifier: ^1.0.4
version: 1.0.4(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0)
@@ -6086,6 +6092,33 @@ packages:
react-dom: 18.2.0(react@18.2.0)
dev: false
+ /@radix-ui/react-tabs@1.0.4(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-egZfYY/+wRNCflXNHx+dePvnz9FbmssDTJBtgRfDY7e8SE5oIo3Py2eCB1ckAbh1Q7cQ/6yJZThJ++sgbxibog==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.24.5
+ '@radix-ui/primitive': 1.0.1
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.18)(react@18.2.0)
+ '@radix-ui/react-direction': 1.0.1(@types/react@18.2.18)(react@18.2.0)
+ '@radix-ui/react-id': 1.0.1(@types/react@18.2.18)(react@18.2.0)
+ '@radix-ui/react-presence': 1.0.1(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-roving-focus': 1.0.4(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.18)(react@18.2.0)
+ '@types/react': 18.2.18
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
/@radix-ui/react-toggle-group@1.0.4(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-Uaj/M/cMyiyT9Bx6fOZO0SAG4Cls0GptBWiBmBxofmDbNVnYYoyRWj/2M/6VCi/7qcXFWnHhRUfdfZFvvkuu8A==}
peerDependencies: