# SourceBadge

> Where a record came from (a plugin, an integration, a feed) as a small icon-and-name chip, with an icon-only compact form, a brand-coloured icon and an optional external link.

Source: https://docs.nasaqui.com/components/source-badge

## Install

```bash
npx shadcn@latest add https://docs.nasaqui.com/r/source-badge.json
```

A chip that says where something came from: "GitHub", "Google Drive", "RSS". The icon can carry the
source's brand colour; the label stays in text colour.

## When to use

- Rows, search results and cards that mix records from several sources.
- Imported items, so people know which system owns them.

## When not to use

- A state ("Paid", "Failed"): use [`Badge`](https://docs.nasaqui.com/components/badge) or [`Status`](https://docs.nasaqui.com/components/status).
- A person: use [`Avatar`](https://docs.nasaqui.com/components/avatar).

## Import

```tsx
import { SourceBadge } from "@fadymondy/nasaq/web";
// inside this monorepo: "@nasaq/web"
```

## Quick start

```tsx
import { SourceBadge } from "@fadymondy/nasaq/web";
import { Database, Rss } from "lucide-react";

export function Sources() {
  return (
    <div className="flex gap-2">
      <SourceBadge label="Postgres" icon={Database} />
      <SourceBadge label="Blog feed" icon={Rss} color="var(--nq-accent-brand)" />
      <SourceBadge compact label="Postgres" icon={Database} />
    </div>
  );
}
```

## Anatomy

```
SourceBadge                     data-slot="source-badge"  (span, or a when href is set)
├─ icon                         data-slot="source-badge-icon", coloured by `color`
└─ label                        hidden when compact
```

## API

**SourceBadge**: every `span` prop except `children`, plus:

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `label` | `string` | required | The source's name, already localised. In compact mode it is the accessible name and tooltip. |
| `icon` | `LucideIcon \| ReactNode` | | A lucide icon, or any node (an `<svg>` mark, an `<img>`). |
| `color` | `string` | | Colour of the icon only. |
| `compact` | `boolean` | `false` | Icon only. |
| `size` | `"sm" \| "md"` | `"sm"` | |
| `href` | `string` | | Opens the source in a new tab. |

## Accessibility

- Compact badges are `role="img"` with the label as `aria-label` and `title`.
- With `href`, it is a real link with a focus ring and `rel="noopener noreferrer"`.
- The icon is decorative; the label carries the meaning, so colour is never the only cue.

## RTL & i18n

- Icon at the inline start; the chip mirrors with the layout. Pass a localised `label`.

## Styling & tokens

- `bg-secondary`, `border-border`, `rounded-control`, `text-caption` / `text-label`. Target `[data-slot="source-badge"]`.

## Do / Don't

- Do keep the label short: the product name, not "Imported from…".
- Don't colour the label; brand colours rarely have enough contrast as text.

## Related

- [`Badge`](https://docs.nasaqui.com/components/badge)
- [`Status`](https://docs.nasaqui.com/components/status)
- [`Avatar`](https://docs.nasaqui.com/components/avatar)

## Lab

https://docs.nasaqui.com/?path=/docs/components-data-display-source-badge--docs

## Code

### React

```tsx
import { SourceBadge } from "@fadymondy/nasaq/web";
import { Database, Rss } from "lucide-react";

export function Sources() {
  return (
    <div className="flex gap-2">
      <SourceBadge label="Postgres" icon={Database} />
      <SourceBadge label="Blog feed" icon={Rss} color="var(--nq-accent-brand)" />
      <SourceBadge compact label="Postgres" icon={Database} />
    </div>
  );
}
```

### shadcn

```tsx
import { SourceBadge } from "@/components/ui/source-badge";
import { Database, Rss } from "lucide-react";

export function Sources() {
  return (
    <div className="flex gap-2">
      <SourceBadge label="Postgres" icon={Database} />
      <SourceBadge label="Blog feed" icon={Rss} color="var(--nq-accent-brand)" />
      <SourceBadge compact label="Postgres" icon={Database} />
    </div>
  );
}
```

### Vue

```vue
<script setup lang="ts">
import { NqSourceBadge } from "@fadymondy/nasaq/vue";
import { Database, Rss } from "lucide-vue-next";
</script>

<template>
  <div class="flex gap-2">
    <NqSourceBadge label="Postgres" :icon="Database" />
    <NqSourceBadge label="Blog feed" :icon="Rss" color="var(--nq-accent-brand)" />
    <NqSourceBadge compact label="Postgres" :icon="Database" />
  </div>
</template>
```

### Blade

```blade
<div class="flex gap-2">
    <x-nq::source-badge label="Postgres" icon="database" />
    <x-nq::source-badge label="Blog feed" icon="rss" color="var(--nq-accent-brand)" />
    <x-nq::source-badge compact label="Postgres" icon="database" />
</div>
```

### HTML + Alpine

```html
<div class="flex gap-2">
    <span data-slot="source-badge"
            class="inline-flex shrink-0 items-center gap-1.5 rounded-control border border-border bg-secondary text-foreground h-6 px-2 text-caption [&_svg]:size-3.5">
            <span data-slot="source-badge-icon" class="inline-flex items-center [&_img]:size-3.5" >
            <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <ellipse cx="12" cy="5" rx="9" ry="3"/>
  <path d="M3 5V19A9 3 0 0 0 21 19V5"/>
  <path d="M3 12A9 3 0 0 0 21 12"/>
</svg>        </span>
        <span class="truncate">Postgres</span></span>
    <span data-slot="source-badge"
            class="inline-flex shrink-0 items-center gap-1.5 rounded-control border border-border bg-secondary text-foreground h-6 px-2 text-caption [&_svg]:size-3.5">
            <span data-slot="source-badge-icon" class="inline-flex items-center [&_img]:size-3.5"  style="color: var(--nq-accent-brand)" >
            <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <path d="M4 11a9 9 0 0 1 9 9"/>
  <path d="M4 4a16 16 0 0 1 16 16"/>
  <circle cx="5" cy="19" r="1"/>
</svg>        </span>
        <span class="truncate">Blog feed</span></span>
    <span data-slot="source-badge"
     role="img"      aria-label="Postgres" title="Postgres"     class="inline-flex shrink-0 items-center gap-1.5 rounded-control border border-border bg-secondary text-foreground h-6 text-caption [&_svg]:size-3.5 w-6 justify-center px-0">
            <span data-slot="source-badge-icon" class="inline-flex items-center [&_img]:size-3.5" >
            <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
  <ellipse cx="12" cy="5" rx="9" ry="3"/>
  <path d="M3 5V19A9 3 0 0 0 21 19V5"/>
  <path d="M3 12A9 3 0 0 0 21 12"/>
</svg>        </span>
        </span>
</div>
```
