Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
# Component specification

Displays short text or icons to represent status, categories, or counts. Badges help users quickly identify important information through visual indicators without cluttering the interface.

- **Component Name:** N8nBadge
- **Figma Component:** TBD
- **Current Implementation:** Custom component (no Element+ dependency)
- **Reka UI Component:** N/A (Reka UI does not provide a Badge primitive)
- **Nuxt UI Reference:** [Badge](https://ui.nuxt.com/docs/components/badge) (custom implementation, not based on Reka UI)

## Public API Definition

**Props**

- `theme?: BadgeTheme` - Visual style variant for the badge. Values: `'default' | 'success' | 'warning' | 'danger' | 'primary' | 'secondary' | 'tertiary'`. Default: `'default'`
- `default`: Subtle border badge with neutral styling
- `success`: Green indicator for positive states
- `warning`: Yellow/orange indicator for cautionary states
- `danger`: Red indicator for error/critical states
- `primary`: Filled badge with contrasting text (pill-shaped)
- `secondary`: Filled badge with tinted background
- `tertiary`: Minimal badge variant with reduced padding
- `size?: TextSize` - Size of the badge text. Values: `'xsmall' | 'small' | 'mini' | 'medium' | 'large' | 'xlarge'`. Default: `'small'`
- `bold?: boolean` - Whether to render text in bold weight. Default: `false`
- `showBorder?: boolean` - Whether to show the badge border. Default: `true`

**Slots**

- `default` - Badge content (text, icons, or mixed content). Wrapped in N8nText component for consistent typography.

### Template usage examples

**Simple text badge:**
```typescript
<script setup lang="ts">
import { N8nBadge } from '@n8n/design-system'
</script>

<template>
<N8nBadge theme="default">
Read Only
</N8nBadge>
</template>
```

**Status indicators:**
```typescript
<script setup lang="ts">
import { N8nBadge } from '@n8n/design-system'
import { computed } from 'vue'
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Nov 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The status-indicator example calls ref() but never imports it from Vue, so the provided code snippet will throw ref is not defined when used. Please import ref alongside computed so the example compiles.

Prompt for AI agents
Address the following comment on packages/frontend/@n8n/design-system/src/v2/components/Badge/component-badge.md at line 50:

<comment>The status-indicator example calls `ref()` but never imports it from Vue, so the provided code snippet will throw `ref is not defined` when used. Please import `ref` alongside `computed` so the example compiles.</comment>

<file context>
@@ -0,0 +1,220 @@
+```typescript
+&lt;script setup lang=&quot;ts&quot;&gt;
+import { N8nBadge } from &#39;@n8n/design-system&#39;
+import { computed } from &#39;vue&#39;
+
+const status = ref&lt;&#39;success&#39; | &#39;warning&#39; | &#39;danger&#39;&gt;(&#39;success&#39;)
</file context>
Suggested change
import { computed } from 'vue'
import { computed, ref } from 'vue'
Fix with Cubic


const status = ref<'success' | 'warning' | 'danger'>('success')

const statusTheme = computed(() => {
const themeMap = {
success: 'success',
warning: 'warning',
danger: 'danger',
}
return themeMap[status.value]
})
</script>

<template>
<N8nBadge :theme="statusTheme">
{{ status }}
</N8nBadge>
</template>
```

**Count badge (primary theme):**
```typescript
<script setup lang="ts">
import { N8nBadge } from '@n8n/design-system'

const filterCount = ref(5)
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Nov 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The count-badge example uses ref() for filterCount but never imports it from Vue, which makes the snippet uncompilable as written. Add the missing ref import so readers can paste the example without errors.

Prompt for AI agents
Address the following comment on packages/frontend/@n8n/design-system/src/v2/components/Badge/component-badge.md at line 76:

<comment>The count-badge example uses `ref()` for `filterCount` but never imports it from Vue, which makes the snippet uncompilable as written. Add the missing `ref` import so readers can paste the example without errors.</comment>

<file context>
@@ -0,0 +1,220 @@
+&lt;script setup lang=&quot;ts&quot;&gt;
+import { N8nBadge } from &#39;@n8n/design-system&#39;
+
+const filterCount = ref(5)
+&lt;/script&gt;
+
</file context>
Fix with Cubic

</script>

<template>
<N8nBadge theme="primary">
{{ filterCount }}
</N8nBadge>
</template>
```

**Tertiary minimal label:**
```typescript
<script setup lang="ts">
import { N8nBadge } from '@n8n/design-system'
</script>

<template>
<N8nBadge theme="tertiary" :bold="true">
Pending
</N8nBadge>
</template>
```

**Badge with icon and text:**
```typescript
<script setup lang="ts">
import { N8nBadge } from '@n8n/design-system'
import ProjectIcon from './ProjectIcon.vue'

const projectBadge = {
icon: 'project',
text: 'Team Project'
}
</script>

<template>
<N8nBadge
theme="tertiary"
:show-border="false"
>
<ProjectIcon :icon="projectBadge.icon" size="mini" />
<span>{{ projectBadge.text }}</span>
</N8nBadge>
</template>
```

**Multiple sizes:**
```typescript
<script setup lang="ts">
import { N8nBadge } from '@n8n/design-system'
</script>

<template>
<N8nBadge theme="primary" size="xsmall">XS</N8nBadge>
<N8nBadge theme="primary" size="small">Small</N8nBadge>
<N8nBadge theme="primary" size="medium">Medium</N8nBadge>
</template>
```

**With custom CSS classes:**
```typescript
<script setup lang="ts">
import { N8nBadge } from '@n8n/design-system'
</script>

<template>
<N8nBadge class="ml-3xs" theme="warning" :bold="true">
Action Required
</N8nBadge>
</template>
```

**Conditional rendering:**
```typescript
<script setup lang="ts">
import { N8nBadge } from '@n8n/design-system'

const isReadOnly = ref(true)
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Nov 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The conditional-rendering example references Vue’s ref() twice but never imports it, so copying the snippet results in a runtime ReferenceError. Import ref from 'vue' in this script block.

Prompt for AI agents
Address the following comment on packages/frontend/@n8n/design-system/src/v2/components/Badge/component-badge.md at line 153:

<comment>The conditional-rendering example references Vue’s `ref()` twice but never imports it, so copying the snippet results in a runtime ReferenceError. Import `ref` from &#39;vue&#39; in this script block.</comment>

<file context>
@@ -0,0 +1,220 @@
+&lt;script setup lang=&quot;ts&quot;&gt;
+import { N8nBadge } from &#39;@n8n/design-system&#39;
+
+const isReadOnly = ref(true)
+const needsSetup = ref(false)
+&lt;/script&gt;
</file context>
Fix with Cubic

const needsSetup = ref(false)
</script>

<template>
<N8nBadge v-if="isReadOnly" theme="tertiary" :bold="true">
Read Only
</N8nBadge>

<N8nBadge v-if="needsSetup" theme="warning">
Setup Required
</N8nBadge>
</template>
```

**With inline styles (advanced):**
```typescript
<script setup lang="ts">
import { N8nBadge } from '@n8n/design-system'
</script>

<template>
<N8nBadge
theme="warning"
style="height: 25px"
>
Custom Height
</N8nBadge>
</template>
```

**Dynamic theme binding:**
```typescript
<script setup lang="ts">
import { N8nBadge } from '@n8n/design-system'
import type { BadgeTheme } from '@n8n/design-system/types'

interface FileStatus {
status: 'completed' | 'pending' | 'failed'
}

const file = ref<FileStatus>({ status: 'completed' })

const getStatusTheme = (status: string): BadgeTheme => {
const themeMap: Record<string, BadgeTheme> = {
completed: 'success',
pending: 'warning',
failed: 'danger',
}
return themeMap[status] || 'default'
}

const statusLabel = (status: string) => {
const labelMap: Record<string, string> = {
completed: 'Completed',
pending: 'Pending',
failed: 'Failed',
}
return labelMap[status] || status
}
</script>

<template>
<N8nBadge :theme="getStatusTheme(file.status)">
{{ statusLabel(file.status) }}
</N8nBadge>
</template>
```