diff --git a/src/components/Badge/Badge.stories.mdx b/src/components/Badge/Badge.stories.mdx
new file mode 100644
index 0000000..0722f32
--- /dev/null
+++ b/src/components/Badge/Badge.stories.mdx
@@ -0,0 +1,132 @@
+import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs';
+
+import Badge from './Badge.vue';
+import Icon from '../Icon/Icon.vue';
+import IconList from '../Shared/IconList.js';
+export const icons = [null, ...Object.keys(IconList.solid)];
+
+export const defaultArgs = {
+ placement: {
+ control: {
+ type: 'select',
+ options: ['right', 'bottom', 'left'],
+ },
+ defaultValue: 'right',
+ },
+ bgColor: {
+ control: {
+ type: 'color',
+ },
+ defaultValue: '#2dd4bf',
+ },
+ size: {
+ control: {
+ type: 'select',
+ options: ['small', 'medium', 'large'],
+ },
+ defaultValue: 'medium',
+ },
+ square: {
+ control: {
+ type: 'boolean',
+ },
+ defaultValue: false,
+ },
+ overlap: {
+ control: {
+ type: 'boolean',
+ },
+ defaultValue: false,
+ },
+ hover: {
+ control: {
+ type: 'boolean',
+ },
+ defaultValue: false,
+ },
+ icon: {
+ control: {
+ type: 'select',
+ options: icons,
+ },
+ defaultValue: icons[0],
+ },
+ color: {
+ control: {
+ type: 'color',
+ },
+ defaultValue: '#000',
+ },
+ content: {
+ control: {
+ type: 'text',
+ },
+ defaultValue: '',
+ },
+ onClick: {
+ action: 'click',
+ },
+};
+
+
+
+export const Default = (args) => ({
+ components: { Badge, Icon },
+ setup() {
+ return { args };
+ },
+ template: `
+
+
+
+ `,
+});
+
+# Badges
+
+
+
+
diff --git a/src/components/Badge/Badge.vue b/src/components/Badge/Badge.vue
new file mode 100644
index 0000000..65c53ca
--- /dev/null
+++ b/src/components/Badge/Badge.vue
@@ -0,0 +1,71 @@
+
+
+
+
+ {{ props.content }}
+
+
+
+
+
diff --git a/src/components/Badge/badge.css b/src/components/Badge/badge.css
new file mode 100644
index 0000000..50e4026
--- /dev/null
+++ b/src/components/Badge/badge.css
@@ -0,0 +1,53 @@
+@tailwind components;
+
+.wrapper {
+ @apply font-sans relative max-w-max p-2;
+}
+
+.badge {
+ @apply h-3 w-3 absolute z-50 rounded-full;
+}
+
+.badge--right {
+ @apply top-0 right-0;
+}
+
+.badge--left {
+ @apply top-0 left-0;
+}
+
+.badge--bottom {
+ @apply right-0 bottom-0;
+}
+
+.badge--overlap {
+ @apply top-1 right-1;
+}
+
+.badge--square {
+ @apply rounded-none;
+}
+
+.badge--hover {
+ @apply opacity-0 group-hover:opacity-100 transition-opacity duration-300;
+}
+
+.badge__content {
+ @apply grid place-items-center leading-none text-xs text-white font-bold h-3.5 w-3.5;
+}
+
+.badge--small {
+ @apply h-2 w-2;
+}
+
+.badge__content--small {
+ font-size: 8px;
+}
+
+.badge--large {
+ @apply h-4 w-4;
+}
+
+.badge__content--large {
+ font-size: 1rem;
+}
diff --git a/src/components/Badge/badge.spec.ts b/src/components/Badge/badge.spec.ts
new file mode 100644
index 0000000..a5e1b0c
--- /dev/null
+++ b/src/components/Badge/badge.spec.ts
@@ -0,0 +1,22 @@
+import { describe, it, expect } from 'vitest';
+
+import { mount } from '@vue/test-utils';
+import Badge from './Badge.vue';
+
+describe('Badge', () => {
+ it('renders properly', () => {
+ const wrapper = mount(Badge, {
+ props: {
+ placement: 'right',
+ size: 'small',
+ content: '1',
+ },
+ });
+ console.log();
+
+ expect(wrapper.element.classList.contains('badge'));
+ expect(wrapper.element.classList.contains('badge--right'));
+ expect(wrapper.element.classList.contains('badge--small'));
+ expect(wrapper.element.innerHTML.includes('1'));
+ });
+});