diff --git a/playground/app.vue b/playground/app.vue
index e1a1590f..ee281ff7 100644
--- a/playground/app.vue
+++ b/playground/app.vue
@@ -28,6 +28,7 @@ const components = [
'navigation-menu',
'popover',
'radio-group',
+ 'separator',
'skeleton',
'slideover',
'switch',
diff --git a/playground/pages/separator.vue b/playground/pages/separator.vue
new file mode 100644
index 00000000..fa9bd44e
--- /dev/null
+++ b/playground/pages/separator.vue
@@ -0,0 +1,38 @@
+
+
+
+
+ Nuxt UI
+
+
An open-source UI component library.
+
+
+
+
+
+
+ Blog
+
+
+
+
+
+ Docs
+
+
+
+
+
+
+
+ Source
+
+
+
+
+
+
diff --git a/src/runtime/components/Separator.vue b/src/runtime/components/Separator.vue
new file mode 100644
index 00000000..20e1cde7
--- /dev/null
+++ b/src/runtime/components/Separator.vue
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ label }}
+
+
+
+
+
+
+
+
+
diff --git a/src/runtime/types/index.d.ts b/src/runtime/types/index.d.ts
index 20f4357f..48e93655 100644
--- a/src/runtime/types/index.d.ts
+++ b/src/runtime/types/index.d.ts
@@ -18,6 +18,8 @@ export * from '../components/Link.vue'
export * from '../components/Modal.vue'
export * from '../components/NavigationMenu.vue'
export * from '../components/Popover.vue'
+export * from '../components/RadioGroup.vue'
+export * from '../components/Separator.vue'
export * from '../components/Skeleton.vue'
export * from '../components/Slideover.vue'
export * from '../components/Switch.vue'
diff --git a/src/theme/index.ts b/src/theme/index.ts
index e948d6f7..3f9fba7a 100644
--- a/src/theme/index.ts
+++ b/src/theme/index.ts
@@ -17,6 +17,7 @@ export { default as modal } from './modal'
export { default as navigationMenu } from './navigation-menu'
export { default as popover } from './popover'
export { default as radioGroup } from './radio-group'
+export { default as separator } from './separator'
export { default as skeleton } from './skeleton'
export { default as slideover } from './slideover'
export { default as switch } from './switch'
diff --git a/src/theme/separator.ts b/src/theme/separator.ts
new file mode 100644
index 00000000..c40f8637
--- /dev/null
+++ b/src/theme/separator.ts
@@ -0,0 +1,103 @@
+export default (config: { colors: string[] }) => ({
+ slots: {
+ root: 'flex items-center align-center text-center',
+ border: '',
+ container: 'font-medium text-gray-700 dark:text-gray-200 flex',
+ icon: 'shrink-0 size-5',
+ avatar: 'shrink-0',
+ label: 'text-sm'
+ },
+ variants: {
+ color: {
+ ...Object.fromEntries(config.colors.map((color: string) => [color, { border: `border-${color}-500 dark:border-${color}-400` }])),
+ white: { border: 'border-white dark:border-gray-900' },
+ gray: { border: 'border-gray-200 dark:border-gray-800' },
+ black: { border: 'border-gray-900 dark:border-white' }
+ },
+ orientation: {
+ horizontal: {
+ root: 'w-full flex-row',
+ border: 'w-full',
+ container: 'mx-3 whitespace-nowrap'
+ },
+ vertical: {
+ root: 'h-full flex-col',
+ border: 'h-full',
+ container: 'my-2'
+ }
+ },
+ size: {
+ '2xs': '',
+ xs: '',
+ sm: '',
+ md: '',
+ lg: '',
+ xl: ''
+ },
+ type: {
+ solid: {
+ border: 'border-solid'
+ },
+ dashed: {
+ border: 'border-dashed'
+ },
+ dotted: {
+ border: 'border-dotted'
+ }
+ }
+ },
+ compoundVariants: [{
+ orientation: 'horizontal',
+ size: '2xs',
+ class: { border: 'border-t' }
+ }, {
+ orientation: 'horizontal',
+ size: 'xs',
+ class: { border: 'border-t-[2px]' }
+ }, {
+ orientation: 'horizontal',
+ size: 'sm',
+ class: { border: 'border-t-[3px]' }
+ }, {
+ orientation: 'horizontal',
+ size: 'md',
+ class: { border: 'border-t-[4px]' }
+ }, {
+ orientation: 'horizontal',
+ size: 'lg',
+ class: { border: 'border-t-[5px]' }
+ }, {
+ orientation: 'horizontal',
+ size: 'xl',
+ class: { border: 'border-t-[6px]' }
+ }, {
+ orientation: 'vertical',
+ size: '2xs',
+ class: { border: 'border-s' }
+ }, {
+ orientation: 'vertical',
+ size: 'xs',
+ class: { border: 'border-s-[2px]' }
+ }, {
+ orientation: 'vertical',
+ size: 'sm',
+ class: { border: 'border-s-[3px]' }
+ }, {
+ orientation: 'vertical',
+ size: 'md',
+ class: { border: 'border-s-[4px]' }
+ }, {
+ orientation: 'vertical',
+ size: 'lg',
+ class: { border: 'border-s-[5px]' }
+ }, {
+ orientation: 'vertical',
+ size: 'xl',
+ class: { border: 'border-s-[6px]' }
+ }],
+ defaultVariants: {
+ color: 'gray',
+ size: '2xs',
+ type: 'solid'
+ }
+})
diff --git a/test/components/Separator.spec.ts b/test/components/Separator.spec.ts
new file mode 100644
index 00000000..aabba809
--- /dev/null
+++ b/test/components/Separator.spec.ts
@@ -0,0 +1,33 @@
+import { describe, it, expect } from 'vitest'
+import Separator, { type SeparatorProps } from '../../src/runtime/components/Separator.vue'
+import ComponentRender from '../component-render'
+
+describe('Separator', () => {
+ it.each([
+ ['basic case', {}],
+ ['with as', { props: { as: 'span' } }],
+ ['with class', { props: { class: 'flex-row-reverse' } }],
+ ['with size 2xs', { props: { size: '2xs' as const } }],
+ ['with size xs', { props: { size: 'xs' as const } }],
+ ['with size sm', { props: { size: 'sm' as const } }],
+ ['with size md', { props: { size: 'md' as const } }],
+ ['with size lg', { props: { size: 'lg' as const } }],
+ ['with size xl', { props: { size: 'xl' as const } }],
+ ['with label', { props: { label: '+1' } }],
+ ['with icon', { props: { icon: 'i-heroicons-photo' } }],
+ ['with avatar', { props: { avatar: { src: 'https://avatars.githubusercontent.com/u/739984?v=4' } } }],
+ ['with orientation horizontal', { props: { orientation: 'horizontal' as const } }],
+ ['with orientation vertical', { props: { orientation: 'vertical' as const } }],
+ ['with type dashed', { props: { type: 'dashed' as const } }],
+ ['with type dotted', { props: { type: 'dotted' as const } }],
+ ['with color green', { props: { color: 'green' as const } }],
+ ['with color white', { props: { color: 'white' as const } }],
+ ['with color gray', { props: { color: 'gray' as const } }],
+ ['with color black', { props: { color: 'black' as const } }],
+ ['with decorative', { props: { decorative: true } }],
+ ['with ui', { props: { ui: { label: 'text-lg' } } }]
+ ])('renders %s correctly', async (nameOrHtml: string, options: { props?: SeparatorProps, slots?: any }) => {
+ const html = await ComponentRender(nameOrHtml, options, Separator)
+ expect(html).toMatchSnapshot()
+ })
+})
diff --git a/test/components/__snapshots__/Separator.spec.ts.snap b/test/components/__snapshots__/Separator.spec.ts.snap
new file mode 100644
index 00000000..cad2ce8c
--- /dev/null
+++ b/test/components/__snapshots__/Separator.spec.ts.snap
@@ -0,0 +1,155 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`Separator > renders basic case correctly 1`] = `
+"
"
+`;
+
+exports[`Separator > renders with as correctly 1`] = `""`;
+
+exports[`Separator > renders with avatar correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with class correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with color black correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with color gray correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with color green correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with color white correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with decorative correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with icon correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with label correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with orientation horizontal correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with orientation vertical correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with size 2xs correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with size lg correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with size md correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with size sm correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with size xl correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with size xs correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with type dashed correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with type dotted correctly 1`] = `
+""
+`;
+
+exports[`Separator > renders with ui correctly 1`] = `
+""
+`;