npm package: @jotnar/m-chip
Description: A reusable Vue 3 chip component with Tailwind CSS support
Author: Jotnar
Latest version: 0.1.2

# @jotnar/m-chip

A powerful and flexible Vue 3 chip component with Tailwind CSS 4 styling and Font Awesome support. Features comprehensive customization options including sizes, colors, variants, states, and accessibility features!

## ✨ Features

- 🎯 **5 Sizes**: xs, sm, md, lg, xl
- 🎨 **9 Colors**: primary, secondary, tertiary, accent, info, success, warning, error, neutral
- 🖌️ **5 Variants**: filled, outlined, light, ghost, elevated
- 🔄 **Special States**: skeleton, loading, disabled
- 👤 **Avatar Support**: Display profile images
- 🎭 **Multiple Shapes**: default, rounded, pill
- 🔗 **Interactive**: clickable, selectable, deletable
- ♿ **Accessible**: ARIA labels, focus management
- 🎪 **Slots**: Customizable icons and content
- 🔙 **Backward Compatible**: Legacy props still supported

## 📦 Installation

Install the package via npm:

```bash
npm i @jotnar/m-chip@latest
```

**Prerequisites:** Ensure your project has Vue 3 (version 3.4.0 or higher) and Tailwind CSS 4 set up, as this component relies on Tailwind CSS classes for styling and Vue 3 for functionality.

## 🧑‍💻 Quick Start

You can use the **m-chip** component in your Vue 3 application either by registering it globally or locally in specific components.

### 🌐 Global Registration

```javascript
import { createApp } from 'vue'
import MChip from '@jotnar/m-chip'
import App from './App.vue'

const app = createApp(App)
app.component('MChip', MChip)
app.mount('#app')
```

### 🏠 Local Registration

```vue
<script setup>
import MChip from '@jotnar/m-chip'
</script>

<template>
  <MChip label="Hello World!" />
</template>
```

## 📖 Examples

### Basic Usage

```vue
<template>
  <!-- Simple chip -->
  <MChip label="Default Chip" />

  <!-- Different sizes -->
  <MChip xs label="Extra Small" />
  <MChip sm label="Small" />
  <MChip md label="Medium" />
  <MChip lg label="Large" />
  <MChip xl label="Extra Large" />
</template>
```

### Variants & Colors

```vue
<template>
  <!-- Different variants -->
  <MChip variant="filled" color="primary" label="Filled" />
  <MChip variant="outlined" color="success" label="Outlined" />
  <MChip variant="light" color="warning" label="Light" />
  <MChip variant="ghost" color="error" label="Ghost" />
  <MChip variant="elevated" color="info" label="Elevated" />

  <!-- All colors -->
  <MChip color="neutral" label="Neutral" />
  <MChip color="accent" label="Accent" />
</template>
```

### Interactive Chips

```vue
<script setup>
import { ref } from 'vue'

const isSelected = ref(false)

const handleClick = () => {
  console.log('Chip clicked!')
}

const handleDelete = () => {
  console.log('Chip deleted!')
}
</script>

<template>
  <!-- Clickable -->
  <MChip clickable @click="handleClick" label="Click me!" />

  <!-- Selectable -->
  <MChip selectable v-model:selected="isSelected" label="Toggle me!" />

  <!-- Deletable -->
  <MChip deletable @delete="handleDelete" label="Delete me!" />

  <!-- Link -->
  <MChip href="https://example.com" target="_blank" label="Visit Link" />
</template>
```

### Special States

```vue
<template>
  <!-- Loading state -->
  <MChip loading label="Loading..." />

  <!-- Skeleton state -->
  <MChip skeleton />

  <!-- Disabled -->
  <MChip disabled label="Disabled" />

  <!-- With avatar -->
  <MChip avatar="/path/to/avatar.jpg" avatar-alt="User Avatar" label="John Doe" />
</template>
```

### With Icons

```vue
<template>
  <!-- Left icon -->
  <MChip licon="fa-solid fa-star" label="Favorite" />

  <!-- Right icon -->
  <MChip ricon="fa-solid fa-arrow-right" label="Next" />

  <!-- Icon only -->
  <MChip only-icon icon="fa-solid fa-heart" label="Like" />

  <!-- Custom icons with slots -->
  <MChip>
    <template #left-icon>
      <CustomIcon />
    </template>
    Custom Content
  </MChip>
</template>
```

### Shapes

```vue
<template>
  <!-- Default rounded corners -->
  <MChip label="Default" />

  <!-- More rounded -->
  <MChip rounded label="Rounded" />

  <!-- Pill shape -->
  <MChip pill label="Pill Shape" />
</template>
```

Register the **m-chip** component globally in your Vue app:

1. Import the component in your main JavaScript file (e.g., main.js):

```javascript
import { createApp } from 'vue'
import App from './App.vue'
import { MChip } from '@jotnar/m-chip'

const app = createApp(App)
app.component('m-chip', MChip)
app.mount('#app')
```

2. Import the styles in your main CSS file (e.g., main.css):

```css
@import '@jotnar/m-chip/style';
@import 'tailwindcss';
```

Once these steps are complete, you can use the <m-chip> component anywhere in your app.

### 📦 Local Registration

Import and use the component in specific components:

```html
<template>
  <m-chip color="primary" rounded label="Click Me" />
</template>

<script setup>
  import { MChip } from '@jotnar/m-chip'
</script>
```

## 🎛️ Props

The **m-chip** component offers a range of props to customize its appearance and behavior:

| Prop          | Type    | Default     | Description                                                             |
| ------------- | ------- | ----------- | ----------------------------------------------------------------------- |
| `label`       | String  | `'Chip'`    | The text displayed on the chip. Used as aria-label for icon-only chips. |
| `sm`          | Boolean | `false`     | Sets small size (height: 1.5rem, text: xs).                             |
| `md`          | Boolean | `false`     | Sets medium size (height: 1.75rem, text: sm). Default if sm/lg not set. |
| `lg`          | Boolean | `false`     | Sets large size (height: 2rem, text: base).                             |
| `color`       | String  | `'primary'` | Color variant: primary, secondary, tertiary, accent, info, etc.         |
| `outline`     | Boolean | `false`     | Outline style with transparent background and colored border.           |
| `text`        | Boolean | `false`     | Text-only style with no background.                                     |
| `elevated`    | Boolean | `false`     | Elevated style with shadow and hover scale effect.                      |
| `icon`        | String  | `null`      | Font Awesome icon for icon-only chips (e.g., fas fa-check).             |
| `licon`       | String  | `null`      | Font Awesome icon on the left side.                                     |
| `ricon`       | String  | `null`      | Font Awesome icon on the right side.                                    |
| `onlyIcon`    | Boolean | `false`     | Renders an icon-only chip (no text, uses icon prop).                    |
| `link`        | String  | `null`      | Converts chip to an <a> tag with the specified URL.                     |
| `autofocus`   | Boolean | `false`     | Automatically focuses the button on render.                             |
| `disabled`    | Boolean | `false`     | Disables the chip, applying opacity and grayscale.                      |
| `selectable`  | Boolean | `false`     | Makes the chip clickable to toggle selection state.                     |
| `selected`    | Boolean | `false`     | Indicates if the chip is selected (used with selectable).               |
| `dismissible` | Boolean | `false`     | Adds a dismiss button (close icon) to the chip.                         |

## ✨ Examples

```html
<template>
  <div class="flex gap-2 flex-wrap">
    <!-- Basic Chips -->
    <m-chip label="Primary" color="primary" />
    <m-chip label="Secondary" color="secondary" md />
    <m-chip label="Error" color="error" lg />

    <!-- Variants -->
    <m-chip label="Outline" color="info" outline rounded />
    <m-chip label="Text" color="success" text />
    <m-chip label="Elevated" color="primary" elevated />

    <!-- Icons -->
    <m-chip label="Filter" color="info" licon="fas fa-filter" rounded />
    <m-chip color="success" icon="fas fa-check" onlyIcon />

    <!-- Selectable -->
    <m-chip
      label="Selectable"
      color="accent"
      selectable
      :selected="selected"
      @update:selected="selected = $event"
    />

    <!-- Dismissible -->
    <m-chip label="Dismissible" color="warning" dismissible @dismiss="onDismiss" />

    <!-- Link -->
    <m-chip label="Link" color="tertiary" link="https://example.com"部分
```

```javascript
<script setup>
  import {ref} from 'vue'; const selected = ref(false); const onDismiss = () => console.log('Chip
  dismissed');
</script>
```

## 📋 API Reference

### Props

| Prop         | Type      | Default  | Description                  |
| ------------ | --------- | -------- | ---------------------------- |
| **label**    | `String`  | `'Chip'` | Text content of the chip     |
| **skeleton** | `Boolean` | `false`  | Shows skeleton loading state |

#### Sizes

| Prop   | Type      | Default | Description                                  |
| ------ | --------- | ------- | -------------------------------------------- |
| **xs** | `Boolean` | `false` | Extra small size                             |
| **sm** | `Boolean` | `false` | Small size                                   |
| **md** | `Boolean` | `false` | Medium size (default when no size specified) |
| **lg** | `Boolean` | `false` | Large size                                   |
| **xl** | `Boolean` | `false` | Extra large size                             |

#### Colors

| Prop      | Type     | Default     | Description                                                                                                      |
| --------- | -------- | ----------- | ---------------------------------------------------------------------------------------------------------------- |
| **color** | `String` | `'primary'` | `'primary' \| 'secondary' \| 'tertiary' \| 'accent' \| 'info' \| 'success' \| 'warning' \| 'error' \| 'neutral'` |

#### Variants

| Prop        | Type     | Default    | Description                                                  |
| ----------- | -------- | ---------- | ------------------------------------------------------------ |
| **variant** | `String` | `'filled'` | `'filled' \| 'outlined' \| 'light' \| 'ghost' \| 'elevated'` |

#### Shape & Style

| Prop        | Type      | Default | Description                     |
| ----------- | --------- | ------- | ------------------------------- |
| **rounded** | `Boolean` | `false` | More rounded corners            |
| **pill**    | `Boolean` | `false` | Completely rounded (pill shape) |

#### Icons

| Prop         | Type              | Default | Description                     |
| ------------ | ----------------- | ------- | ------------------------------- |
| **icon**     | `String \| Array` | `null`  | Main icon (FontAwesome classes) |
| **licon**    | `String \| Array` | `null`  | Left icon                       |
| **ricon**    | `String \| Array` | `null`  | Right icon                      |
| **onlyIcon** | `Boolean`         | `false` | Show only icon, hide label      |

#### Avatar

| Prop          | Type     | Default    | Description      |
| ------------- | -------- | ---------- | ---------------- |
| **avatar**    | `String` | `null`     | Avatar image URL |
| **avatarAlt** | `String` | `'Avatar'` | Avatar alt text  |

#### Interactive

| Prop           | Type              | Default          | Description                                |
| -------------- | ----------------- | ---------------- | ------------------------------------------ |
| **clickable**  | `Boolean`         | `false`          | Makes chip clickable                       |
| **selectable** | `Boolean`         | `false`          | Makes chip selectable (toggleable)         |
| **selected**   | `Boolean`         | `false`          | Selected state (use with v-model:selected) |
| **deletable**  | `Boolean`         | `false`          | Shows delete button                        |
| **deleteIcon** | `String \| Array` | `'fas fa-times'` | Custom delete icon                         |

#### Link

| Prop       | Type     | Default | Description           |
| ---------- | -------- | ------- | --------------------- |
| **href**   | `String` | `null`  | Makes chip a link     |
| **target** | `String` | `null`  | Link target attribute |

#### States

| Prop         | Type      | Default | Description                |
| ------------ | --------- | ------- | -------------------------- |
| **disabled** | `Boolean` | `false` | Disabled state             |
| **loading**  | `Boolean` | `false` | Loading state with spinner |

#### Legacy Props (Deprecated)

| Prop            | Type      | Default | Description                 |
| --------------- | --------- | ------- | --------------------------- |
| **outline**     | `Boolean` | `false` | ⚠️ Use `variant="outlined"` |
| **text**        | `Boolean` | `false` | ⚠️ Use `variant="ghost"`    |
| **elevated**    | `Boolean` | `false` | ⚠️ Use `variant="elevated"` |
| **dismissible** | `Boolean` | `false` | ⚠️ Use `deletable`          |
| **link**        | `String`  | `null`  | ⚠️ Use `href`               |

### Events

| Event               | Payload   | Description                                     |
| ------------------- | --------- | ----------------------------------------------- |
| **click**           | `Event`   | Fired when chip is clicked                      |
| **delete**          | `Event`   | Fired when delete button is clicked             |
| **dismiss**         | `Event`   | ⚠️ Legacy - use `@delete`                       |
| **update:selected** | `Boolean` | Fired when selection changes (v-model:selected) |

### Slots

| Slot            | Description                   |
| --------------- | ----------------------------- |
| **default**     | Main content (replaces label) |
| **icon**        | Custom icon content           |
| **left-icon**   | Custom left icon              |
| **right-icon**  | Custom right icon             |
| **delete-icon** | Custom delete button icon     |
| **skeleton**    | Custom skeleton content       |

## 🎨 Customization

### CSS Classes

The component uses Tailwind CSS classes. You can override styles by using CSS specificity or Tailwind's built-in customization features.

### Custom Colors

To add custom colors, extend your Tailwind config and add corresponding CSS classes.

## 🔄 Migration Guide

### From v1.x to v2.x

1. **Replace deprecated props:**

   ```vue
   <!-- Old -->
   <MChip outline />
   <MChip text />
   <MChip elevated />
   <MChip dismissible @dismiss="handler" />
   <MChip link="https://example.com" />

   <!-- New -->
   <MChip variant="outlined" />
   <MChip variant="ghost" />
   <MChip variant="elevated" />
   <MChip deletable @delete="handler" />
   <MChip href="https://example.com" />
   ```

2. **Take advantage of new features:**
   ```vue
   <!-- New in v2.x -->
   <MChip skeleton />
   <MChip loading />
   <MChip avatar="/avatar.jpg" />
   <MChip xs />
   <MChip xl />
   <MChip variant="light" />
   <MChip color="neutral" />
   <MChip pill />
   ```

## ℹ️ Notes

- **Custom Classes**:  
  If a custom `class` prop (e.g., `class="bg-blue-500 text-white"`), the `color` prop will be ignored, allowing your custom styles to take precedence.

- **Icon Support**:  
  Icons require **Font Awesome** to be set up in your project. Use the format `fa-solid fa-icon-name` (e.g., `fa-solid fa-code`).

- **Accessibility**:  
  For icon-only chips (`onlyIcon`), the `label` prop is used as the `aria-label` and `title` to ensure accessibility for screen readers.

## 🔨 Under Construction

The homepage for this project is currently under construction. In the meantime, you can find the source code and report issues on GitHub:

- [GitHub Repository](https://github.com/JotnarDev/m-chip)
- [Report Issues](https://github.com/JotnarDev/m-chip/issues)

## ⚖️ License

MIT

## 👤 Author

Jotnar