-
Notifications
You must be signed in to change notification settings - Fork 51.5k
docs: Add component specification and usage examples for N8nBadge #22049
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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' | ||
|
|
||
| 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) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The count-badge example uses Prompt for AI agents |
||
| </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) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The conditional-rendering example references Vue’s Prompt for AI agents |
||
| 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> | ||
| ``` | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
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 throwref is not definedwhen used. Please importrefalongsidecomputedso the example compiles.Prompt for AI agents