Lzh on GitHub

Chip

表示数值或状态的指示器。

用法

用 Chip 包裹任何组件,以显示一个指示器。

<template>
  <UChip>
    <UButton icon="i-lucide-mail" color="neutral" variant="subtle" />
  </UChip>
</template>

颜色 (Color)

使用 color prop 来改变 Chip 的颜色。

<template>
  <UChip color="neutral">
    <UButton icon="i-lucide-mail" color="neutral" variant="subtle" />
  </UChip>
</template>

尺寸 (Size)

使用 size prop 来改变 Chip 的尺寸。

<template>
  <UChip size="3xl">
    <UButton icon="i-lucide-mail" color="neutral" variant="subtle" />
  </UChip>
</template>

文本 (Text)

使用 text prop 来设置 Chip 的文本。

5
<template>
  <UChip :text="5" size="3xl">
    <UButton icon="i-lucide-mail" color="neutral" variant="subtle" />
  </UChip>
</template>

位置 (Position)

使用 position prop 来改变 Chip 的位置。

<template>
  <UChip position="bottom-left">
    <UButton icon="i-lucide-mail" color="neutral" variant="subtle" />
  </UChip>
</template>

内嵌 (Inset)

使用 inset prop 来将 Chip 显示在组件内部。这在处理圆角组件时非常有用。

<template>
  <UChip inset>
    <UAvatar src="https://github.com/benjamincanac.png" />
  </UChip>
</template>

独立 (Standalone)

standalone prop 与 inset prop 一起使用,以行内显示 Chip。

<template>
  <UChip standalone inset />
</template>
例如,在 CommandPalette, InputMenu, SelectSelectMenu 组件中就是这样使用的。

示例

控制可见性

你可以使用 show prop 来控制 Chip 的可见性。

<script setup lang="ts">
const statuses = ['online', 'away', 'busy', 'offline']
const status = ref(statuses[0])

const color = computed(() => status.value ? { online: 'success', away: 'warning', busy: 'error', offline: 'neutral' }[status.value] as any : 'online')

const show = computed(() => status.value !== 'offline')

// Note: This is for demonstration purposes only. Don't do this at home.
onMounted(() => {
  setInterval(() => {
    if (status.value) {
      status.value = statuses[(statuses.indexOf(status.value) + 1) % statuses.length]
    }
  }, 1000)
})
</script>

<template>
  <UChip :color="color" :show="show" inset>
    <UAvatar src="https://github.com/benjamincanac.png" />
  </UChip>
</template>
在此示例中,Chip 根据不同的状态拥有不同的颜色,并在状态不是 offline 时显示。

API

Props

Prop Default Type
as

'div'

any

The element or component this component should render as.

text

string | number

Display some text inside the chip.

color

'primary'

"error" | "primary" | "secondary" | "success" | "info" | "warning" | "neutral"

size

'md'

"2xl" | "md" | "3xs" | "2xs" | "xs" | "sm" | "lg" | "xl" | "3xl"

position

'top-right'

"top-right" | "bottom-right" | "top-left" | "bottom-left"

The position of the chip.

inset

false

boolean

When true, keep the chip inside the component for rounded elements.

standalone

false

boolean

When true, render the chip relatively to the parent.

show

boolean

ui

{ root?: ClassNameValue; base?: ClassNameValue; }

Slots

Slot Type
default

{}

content

{}

Theme

app.config.ts
export default defineAppConfig({
  ui: {
    chip: {
      slots: {
        root: 'relative inline-flex items-center justify-center shrink-0',
        base: 'rounded-full ring ring-bg flex items-center justify-center text-inverted font-medium whitespace-nowrap'
      },
      variants: {
        color: {
          primary: 'bg-primary',
          secondary: 'bg-secondary',
          success: 'bg-success',
          info: 'bg-info',
          warning: 'bg-warning',
          error: 'bg-error',
          neutral: 'bg-inverted'
        },
        size: {
          '3xs': 'h-[4px] min-w-[4px] text-[4px]',
          '2xs': 'h-[5px] min-w-[5px] text-[5px]',
          xs: 'h-[6px] min-w-[6px] text-[6px]',
          sm: 'h-[7px] min-w-[7px] text-[7px]',
          md: 'h-[8px] min-w-[8px] text-[8px]',
          lg: 'h-[9px] min-w-[9px] text-[9px]',
          xl: 'h-[10px] min-w-[10px] text-[10px]',
          '2xl': 'h-[11px] min-w-[11px] text-[11px]',
          '3xl': 'h-[12px] min-w-[12px] text-[12px]'
        },
        position: {
          'top-right': 'top-0 right-0',
          'bottom-right': 'bottom-0 right-0',
          'top-left': 'top-0 left-0',
          'bottom-left': 'bottom-0 left-0'
        },
        inset: {
          false: ''
        },
        standalone: {
          false: 'absolute'
        }
      },
      compoundVariants: [
        {
          position: 'top-right',
          inset: false,
          class: '-translate-y-1/2 translate-x-1/2 transform'
        },
        {
          position: 'bottom-right',
          inset: false,
          class: 'translate-y-1/2 translate-x-1/2 transform'
        },
        {
          position: 'top-left',
          inset: false,
          class: '-translate-y-1/2 -translate-x-1/2 transform'
        },
        {
          position: 'bottom-left',
          inset: false,
          class: 'translate-y-1/2 -translate-x-1/2 transform'
        }
      ],
      defaultVariants: {
        size: 'md',
        color: 'primary',
        position: 'top-right'
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        chip: {
          slots: {
            root: 'relative inline-flex items-center justify-center shrink-0',
            base: 'rounded-full ring ring-bg flex items-center justify-center text-inverted font-medium whitespace-nowrap'
          },
          variants: {
            color: {
              primary: 'bg-primary',
              secondary: 'bg-secondary',
              success: 'bg-success',
              info: 'bg-info',
              warning: 'bg-warning',
              error: 'bg-error',
              neutral: 'bg-inverted'
            },
            size: {
              '3xs': 'h-[4px] min-w-[4px] text-[4px]',
              '2xs': 'h-[5px] min-w-[5px] text-[5px]',
              xs: 'h-[6px] min-w-[6px] text-[6px]',
              sm: 'h-[7px] min-w-[7px] text-[7px]',
              md: 'h-[8px] min-w-[8px] text-[8px]',
              lg: 'h-[9px] min-w-[9px] text-[9px]',
              xl: 'h-[10px] min-w-[10px] text-[10px]',
              '2xl': 'h-[11px] min-w-[11px] text-[11px]',
              '3xl': 'h-[12px] min-w-[12px] text-[12px]'
            },
            position: {
              'top-right': 'top-0 right-0',
              'bottom-right': 'bottom-0 right-0',
              'top-left': 'top-0 left-0',
              'bottom-left': 'bottom-0 left-0'
            },
            inset: {
              false: ''
            },
            standalone: {
              false: 'absolute'
            }
          },
          compoundVariants: [
            {
              position: 'top-right',
              inset: false,
              class: '-translate-y-1/2 translate-x-1/2 transform'
            },
            {
              position: 'bottom-right',
              inset: false,
              class: 'translate-y-1/2 translate-x-1/2 transform'
            },
            {
              position: 'top-left',
              inset: false,
              class: '-translate-y-1/2 -translate-x-1/2 transform'
            },
            {
              position: 'bottom-left',
              inset: false,
              class: 'translate-y-1/2 -translate-x-1/2 transform'
            }
          ],
          defaultVariants: {
            size: 'md',
            color: 'primary',
            position: 'top-right'
          }
        }
      }
    })
  ]
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import uiPro from '@nuxt/ui-pro/vite'

export default defineConfig({
  plugins: [
    vue(),
    uiPro({
      ui: {
        chip: {
          slots: {
            root: 'relative inline-flex items-center justify-center shrink-0',
            base: 'rounded-full ring ring-bg flex items-center justify-center text-inverted font-medium whitespace-nowrap'
          },
          variants: {
            color: {
              primary: 'bg-primary',
              secondary: 'bg-secondary',
              success: 'bg-success',
              info: 'bg-info',
              warning: 'bg-warning',
              error: 'bg-error',
              neutral: 'bg-inverted'
            },
            size: {
              '3xs': 'h-[4px] min-w-[4px] text-[4px]',
              '2xs': 'h-[5px] min-w-[5px] text-[5px]',
              xs: 'h-[6px] min-w-[6px] text-[6px]',
              sm: 'h-[7px] min-w-[7px] text-[7px]',
              md: 'h-[8px] min-w-[8px] text-[8px]',
              lg: 'h-[9px] min-w-[9px] text-[9px]',
              xl: 'h-[10px] min-w-[10px] text-[10px]',
              '2xl': 'h-[11px] min-w-[11px] text-[11px]',
              '3xl': 'h-[12px] min-w-[12px] text-[12px]'
            },
            position: {
              'top-right': 'top-0 right-0',
              'bottom-right': 'bottom-0 right-0',
              'top-left': 'top-0 left-0',
              'bottom-left': 'bottom-0 left-0'
            },
            inset: {
              false: ''
            },
            standalone: {
              false: 'absolute'
            }
          },
          compoundVariants: [
            {
              position: 'top-right',
              inset: false,
              class: '-translate-y-1/2 translate-x-1/2 transform'
            },
            {
              position: 'bottom-right',
              inset: false,
              class: 'translate-y-1/2 translate-x-1/2 transform'
            },
            {
              position: 'top-left',
              inset: false,
              class: '-translate-y-1/2 -translate-x-1/2 transform'
            },
            {
              position: 'bottom-left',
              inset: false,
              class: 'translate-y-1/2 -translate-x-1/2 transform'
            }
          ],
          defaultVariants: {
            size: 'md',
            color: 'primary',
            position: 'top-right'
          }
        }
      }
    })
  ]
})