ChatReasoning

CollapsibleGitLab
Exiba um processo de raciocínio ou pensamento da IA de forma recolhível.

Uso

O componente ChatReasoning renderiza um bloco recolhível que exibe o conteúdo de raciocínio ou pensamento da IA. Ele abre automaticamente durante o streaming e fecha automaticamente depois.

O conteúdo do corpo usa o composable useScrollShadow para aplicar sombras de esmaecimento quando há transbordamento.

Texto

Use a prop text para definir o conteúdo do raciocínio. O texto é exibido dentro do corpo recolhível.

<template>
  <NChatReasoning text="The user is asking about Vue components..." />
</template>

Streaming

Use a prop streaming para indicar um raciocínio ativo. O componente abre automaticamente quando o streaming começa e fecha automaticamente quando ele termina.

The user is asking about Vue components...
<template>
  <NChatReasoning streaming text="The user is asking about Vue components..." />
</template>
Use o utilitário isPartStreaming de @nitro/ui/utils/ai para determinar se um part está sendo transmitido no momento.

Shimmer

Durante o streaming, o rótulo do gatilho usa o componente ChatShimmer. Use a prop shimmer para personalizar sua duration e seu spread.

The user is asking about Vue components...
<template>
  <NChatReasoning
    streaming
    text="The user is asking about Vue components..."
    :shimmer="{
      duration: 2,
      spread: 2
    }"
  />
</template>

Ícone

Use a prop icon para exibir um componente Icon ao lado do gatilho.

<template>
  <NChatReasoning icon="i-lucide-brain" text="The user is asking about Vue components..." />
</template>

Chevron

Use a prop chevron para alterar a posição do ícone de chevron.

Quando chevron é definido como leading com um icon, o ícone troca de lugar com o chevron no hover e quando aberto.
<template>
  <NChatReasoning
    chevron="leading"
    icon="i-lucide-brain"
    text="The user is asking about Vue components..."
  />
</template>

Ícone de chevron

Use a prop chevron-icon para personalizar o Icon de chevron. O padrão é i-lucide-chevron-down.

<template>
  <NChatReasoning
    chevron-icon="i-lucide-arrow-down"
    text="The user is asking about Vue components..."
  />
</template>
Você pode personalizar esse ícone globalmente no seu app.config.ts na chave ui.icons.chevronDown.
Você pode personalizar esse ícone globalmente no seu vite.config.ts na chave ui.icons.chevronDown.

Exemplos

Confira a página de visão geral do Chat para instruções de instalação, configuração do servidor e exemplos de uso.

API

Props

Prop Default Type
text string

The reasoning text content to display.

streamingfalseboolean

Whether the reasoning content is currently streaming.

duration number

The duration in seconds that the AI spent reasoning. If not provided, it will be calculated automatically based on streaming time.

iconany

The icon displayed next to the trigger.

chevron'trailing' "leading" | "trailing"

The position of the chevron icon.

chevronIconappConfig.ui.icons.chevronDownany

The icon displayed as the chevron.

autoCloseDelay500 number

The delay in milliseconds before auto-closing when streaming ends. Set to 0 to disable auto-close.

shimmer Partial<Omit<ChatShimmerProps, "text">>

Customize the ChatShimmer component when streaming.

disabledboolean

When true, prevents the user from interacting with the collapsible.

openundefinedboolean

The controlled open state of the collapsible. Can be binded with v-model.

defaultOpenboolean

The open state of the collapsible when it is initially rendered.
Use when you do not need to control its open state.

unmountOnHidefalseboolean

When true, the element will be unmounted on closed state.

ui { root?: SlotClass; trigger?: SlotClass; leading?: SlotClass; leadingIcon?: SlotClass; chevronIcon?: SlotClass; label?: SlotClass; trailingIcon?: SlotClass; content?: SlotClass; body?: SlotClass; }

Slots

Slot Type
default{ open: boolean; }

Emits

Event Type
update:open[value: boolean]

Tema

app.config.ts
export default defineAppConfig({
  ui: {
    chatReasoning: {
      slots: {
        root: '',
        trigger: [
          'group flex w-full items-center gap-1.5 text-muted text-sm disabled:cursor-default disabled:hover:text-muted hover:text-default rounded-sm outline-primary/25 focus-visible:outline-3 min-w-0',
          'transition-colors'
        ],
        leading: 'relative size-4 shrink-0',
        leadingIcon: 'size-4 shrink-0',
        chevronIcon: 'size-4 shrink-0 group-data-[state=open]:rotate-180 transition-transform duration-200',
        label: 'truncate',
        trailingIcon: 'size-4 shrink-0 group-data-[state=open]:rotate-180 transition-transform duration-200',
        content: 'data-[state=open]:animate-[collapsible-down_200ms_ease-out] data-[state=closed]:animate-[collapsible-up_200ms_ease-out] data-[state=closed]:overflow-hidden rounded-sm outline-primary/25 has-focus-visible:outline-3',
        body: 'max-h-[200px] pt-2 overflow-y-auto text-sm text-dimmed whitespace-pre-wrap focus:outline-none'
      },
      variants: {
        chevron: {
          leading: {
            leadingIcon: 'group-hover:opacity-0'
          },
          trailing: ''
        },
        alone: {
          false: {
            leadingIcon: [
              'absolute inset-0 group-data-[state=open]:opacity-0',
              'transition-opacity duration-200'
            ],
            chevronIcon: [
              'absolute inset-0 opacity-0 group-hover:opacity-100 group-data-[state=open]:opacity-100',
              'transition-[rotate,opacity] duration-200'
            ]
          }
        }
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nitro/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        chatReasoning: {
          slots: {
            root: '',
            trigger: [
              'group flex w-full items-center gap-1.5 text-muted text-sm disabled:cursor-default disabled:hover:text-muted hover:text-default rounded-sm outline-primary/25 focus-visible:outline-3 min-w-0',
              'transition-colors'
            ],
            leading: 'relative size-4 shrink-0',
            leadingIcon: 'size-4 shrink-0',
            chevronIcon: 'size-4 shrink-0 group-data-[state=open]:rotate-180 transition-transform duration-200',
            label: 'truncate',
            trailingIcon: 'size-4 shrink-0 group-data-[state=open]:rotate-180 transition-transform duration-200',
            content: 'data-[state=open]:animate-[collapsible-down_200ms_ease-out] data-[state=closed]:animate-[collapsible-up_200ms_ease-out] data-[state=closed]:overflow-hidden rounded-sm outline-primary/25 has-focus-visible:outline-3',
            body: 'max-h-[200px] pt-2 overflow-y-auto text-sm text-dimmed whitespace-pre-wrap focus:outline-none'
          },
          variants: {
            chevron: {
              leading: {
                leadingIcon: 'group-hover:opacity-0'
              },
              trailing: ''
            },
            alone: {
              false: {
                leadingIcon: [
                  'absolute inset-0 group-data-[state=open]:opacity-0',
                  'transition-opacity duration-200'
                ],
                chevronIcon: [
                  'absolute inset-0 opacity-0 group-hover:opacity-100 group-data-[state=open]:opacity-100',
                  'transition-[rotate,opacity] duration-200'
                ]
              }
            }
          }
        }
      }
    })
  ]
})

Changelog

No recent changes