O componente ChatMessages exibe uma lista de componentes ChatMessage usando o slot padrão ou a prop messages.
<template>
<NChatMessages>
<NChatMessage
v-for="(message, index) in messages"
:key="index"
v-bind="message"
/>
</NChatMessages>
</template>
shouldScrollToBottom).shouldAutoScroll).autoScroll).status).Use a prop messages para exibir uma lista de mensagens de chat.
<script setup lang="ts">
const messages = ref([
{
id: '6045235a-a435-46b8-989d-2df38ca2eb47',
role: 'user',
parts: [
{
type: 'text',
text: 'Hello, how are you?'
}
]
},
{
id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
role: 'assistant',
parts: [
{
type: 'text',
text: 'I am doing well, thank you for asking! How can I assist you today?'
}
]
},
{
id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
role: 'user',
parts: [
{
type: 'text',
text: 'What is the current weather in Tokyo?'
}
]
},
{
id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
role: 'assistant',
parts: [
{
type: 'text',
text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies."
}
]
}
])
</script>
<template>
<NChatMessages :messages="messages" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
const messages = ref([
{
id: '6045235a-a435-46b8-989d-2df38ca2eb47',
role: 'user',
parts: [
{
type: 'text',
text: 'Hello, how are you?'
}
]
},
{
id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
role: 'assistant',
parts: [
{
type: 'text',
text: 'I am doing well, thank you for asking! How can I assist you today?'
}
]
},
{
id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
role: 'user',
parts: [
{
type: 'text',
text: 'What is the current weather in Tokyo?'
}
]
},
{
id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
role: 'assistant',
parts: [
{
type: 'text',
text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies."
}
]
}
])
</script>
<template>
<NChatMessages :messages="messages" />
</template>
Use a prop status para exibir um indicador visual quando o assistente está processando.
<script setup lang="ts">
const messages = ref([
{
id: '6045235a-a435-46b8-989d-2df38ca2eb47',
role: 'user',
parts: [
{
type: 'text',
text: 'Hello, how are you?'
}
]
}
])
</script>
<template>
<NChatMessages status="submitted" :messages="messages" />
</template>
<script setup lang="ts">
import { ref } from 'vue'
const messages = ref([
{
id: '6045235a-a435-46b8-989d-2df38ca2eb47',
role: 'user',
parts: [
{
type: 'text',
text: 'Hello, how are you?'
}
]
}
])
</script>
<template>
<NChatMessages status="submitted" :messages="messages" />
</template>
useChat do AI SDK:submitted: The message has been sent to the API and we're awaiting the start of the response stream.streaming: The response is actively streaming in from the API, receiving chunks of data.ready: The full response has been received and processed; a new user message can be submitted.error: An error occurred during the API request, preventing successful completion.Use a prop user para alterar as props do ChatMessage para mensagens de user. O padrão é:
side: 'right'variant: 'soft'<script setup lang="ts">
const messages = ref([
{
id: '6045235a-a435-46b8-989d-2df38ca2eb47',
role: 'user',
parts: [
{
type: 'text',
text: 'Hello, how are you?'
}
]
},
{
id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
role: 'assistant',
parts: [
{
type: 'text',
text: 'I am doing well, thank you for asking! How can I assist you today?'
}
]
},
{
id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
role: 'user',
parts: [
{
type: 'text',
text: 'What is the current weather in Tokyo?'
}
]
},
{
id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
role: 'assistant',
parts: [
{
type: 'text',
text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies."
}
]
}
])
</script>
<template>
<NChatMessages
:user="{
side: 'left',
variant: 'solid',
avatar: {
src: 'https://github.com/benjamincanac.png',
loading: 'lazy'
}
}"
:messages="messages"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const messages = ref([
{
id: '6045235a-a435-46b8-989d-2df38ca2eb47',
role: 'user',
parts: [
{
type: 'text',
text: 'Hello, how are you?'
}
]
},
{
id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
role: 'assistant',
parts: [
{
type: 'text',
text: 'I am doing well, thank you for asking! How can I assist you today?'
}
]
},
{
id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
role: 'user',
parts: [
{
type: 'text',
text: 'What is the current weather in Tokyo?'
}
]
},
{
id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
role: 'assistant',
parts: [
{
type: 'text',
text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies."
}
]
}
])
</script>
<template>
<NChatMessages
:user="{
side: 'left',
variant: 'solid',
avatar: {
src: 'https://github.com/benjamincanac.png',
loading: 'lazy'
}
}"
:messages="messages"
/>
</template>
Use a prop assistant para alterar as props do ChatMessage para mensagens de assistant. O padrão é:
side: 'left'variant: 'naked'<script setup lang="ts">
const messages = ref([
{
id: '6045235a-a435-46b8-989d-2df38ca2eb47',
role: 'user',
parts: [
{
type: 'text',
text: 'Hello, how are you?'
}
]
},
{
id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
role: 'assistant',
parts: [
{
type: 'text',
text: 'I am doing well, thank you for asking! How can I assist you today?'
}
]
},
{
id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
role: 'user',
parts: [
{
type: 'text',
text: 'What is the current weather in Tokyo?'
}
]
},
{
id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
role: 'assistant',
parts: [
{
type: 'text',
text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies."
}
]
}
])
</script>
<template>
<NChatMessages
:assistant="{
side: 'left',
variant: 'outline',
avatar: {
icon: 'i-lucide-bot'
},
actions: [
{
label: 'Copy to clipboard',
icon: 'i-lucide-copy'
}
]
}"
:messages="messages"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const messages = ref([
{
id: '6045235a-a435-46b8-989d-2df38ca2eb47',
role: 'user',
parts: [
{
type: 'text',
text: 'Hello, how are you?'
}
]
},
{
id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
role: 'assistant',
parts: [
{
type: 'text',
text: 'I am doing well, thank you for asking! How can I assist you today?'
}
]
},
{
id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
role: 'user',
parts: [
{
type: 'text',
text: 'What is the current weather in Tokyo?'
}
]
},
{
id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
role: 'assistant',
parts: [
{
type: 'text',
text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies."
}
]
}
])
</script>
<template>
<NChatMessages
:assistant="{
side: 'left',
variant: 'outline',
avatar: {
icon: 'i-lucide-bot'
},
actions: [
{
label: 'Copy to clipboard',
icon: 'i-lucide-copy'
}
]
}"
:messages="messages"
/>
</template>
Use a prop auto-scroll para personalizar ou ocultar o botão de rolagem automática (com o valor false) exibido ao rolar para o topo do chat. O padrão é:
color: 'neutral'variant: 'outline'Você pode passar qualquer propriedade do componente Button para personalizá-lo.
<script setup lang="ts">
const messages = ref([
{
id: '6045235a-a435-46b8-989d-2df38ca2eb47',
role: 'user',
parts: [
{
type: 'text',
text: 'Hello, how are you?'
}
]
},
{
id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
role: 'assistant',
parts: [
{
type: 'text',
text: 'I am doing well, thank you for asking! How can I assist you today?'
}
]
},
{
id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
role: 'user',
parts: [
{
type: 'text',
text: 'What is the current weather in Tokyo?'
}
]
},
{
id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
role: 'assistant',
parts: [
{
type: 'text',
text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies. The forecast for the rest of the week shows a slight chance of rain on Thursday, with temperatures gradually rising to 28°C by the weekend. Humidity levels are moderate at around 65%, and wind speeds are light at 8 km/h from the southeast. Air quality is good with an index of 42. The UV index is high at 7, so it's recommended to wear sunscreen if you're planning to spend time outdoors. Sunrise was at 5:24 AM and sunset will be at 6:48 PM, giving Tokyo approximately 13 hours and 24 minutes of daylight today. The moon is currently in its waxing gibbous phase."
}
]
},
{
id: 'c3e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
role: 'user',
parts: [
{
type: 'text',
text: 'Can you recommend some popular tourist attractions in Kyoto?'
}
]
},
{
id: 'd4f5g8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
role: 'assistant',
parts: [
{
type: 'text',
text: 'Kyoto is known for its beautiful temples, traditional tea houses, and gardens. Some popular attractions include Kinkaku-ji (Golden Pavilion) with its stunning gold leaf exterior reflecting in the mirror pond, Fushimi Inari Shrine with its thousands of vermilion torii gates winding up the mountainside, Arashiyama Bamboo Grove where towering stalks create an otherworldly atmosphere, Kiyomizu-dera Temple perched on a hillside offering panoramic views of the city, and the historic Gion district where you might spot geisha hurrying to evening appointments through narrow stone-paved streets lined with traditional wooden machiya houses.'
}
]
}
])
</script>
<template>
<NChatMessages
:auto-scroll="{
color: 'neutral',
variant: 'outline'
}"
:should-scroll-to-bottom="false"
:messages="messages"
/>
</template>
<script setup lang="ts">
import { ref, h } from 'vue'
const messages = ref([
{
id: '6045235a-a435-46b8-989d-2df38ca2eb47',
role: 'user',
parts: [
{
type: 'text',
text: 'Hello, how are you?'
}
]
},
{
id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
role: 'assistant',
parts: [
{
type: 'text',
text: 'I am doing well, thank you for asking! How can I assist you today?'
}
]
},
{
id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
role: 'user',
parts: [
{
type: 'text',
text: 'What is the current weather in Tokyo?'
}
]
},
{
id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
role: 'assistant',
parts: [
{
type: 'text',
text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies. The forecast for the rest of the week shows a slight chance of rain on Thursday, with temperatures gradually rising to 28°C by the weekend. Humidity levels are moderate at around 65%, and wind speeds are light at 8 km/h from the southeast. Air quality is good with an index of 42. The UV index is high at 7, so it's recommended to wear sunscreen if you're planning to spend time outdoors. Sunrise was at 5:24 AM and sunset will be at 6:48 PM, giving Tokyo approximately 13 hours and 24 minutes of daylight today. The moon is currently in its waxing gibbous phase."
}
]
},
{
id: 'c3e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
role: 'user',
parts: [
{
type: 'text',
text: 'Can you recommend some popular tourist attractions in Kyoto?'
}
]
},
{
id: 'd4f5g8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
role: 'assistant',
parts: [
{
type: 'text',
text: 'Kyoto is known for its beautiful temples, traditional tea houses, and gardens. Some popular attractions include Kinkaku-ji (Golden Pavilion) with its stunning gold leaf exterior reflecting in the mirror pond, Fushimi Inari Shrine with its thousands of vermilion torii gates winding up the mountainside, Arashiyama Bamboo Grove where towering stalks create an otherworldly atmosphere, Kiyomizu-dera Temple perched on a hillside offering panoramic views of the city, and the historic Gion district where you might spot geisha hurrying to evening appointments through narrow stone-paved streets lined with traditional wooden machiya houses.'
}
]
}
])
</script>
<template>
<NChatMessages
:auto-scroll="{
color: 'neutral',
variant: 'outline'
}"
:should-scroll-to-bottom="false"
:messages="messages"
/>
</template>
Use a prop auto-scroll-icon para personalizar o Icon do botão de rolagem automática. O padrão é i-lucide-arrow-down.
<script setup lang="ts">
const messages = ref([
{
id: '6045235a-a435-46b8-989d-2df38ca2eb47',
role: 'user',
parts: [
{
type: 'text',
text: 'Hello, how are you?'
}
]
},
{
id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
role: 'assistant',
parts: [
{
type: 'text',
text: 'I am doing well, thank you for asking! How can I assist you today?'
}
]
},
{
id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
role: 'user',
parts: [
{
type: 'text',
text: 'What is the current weather in Tokyo?'
}
]
},
{
id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
role: 'assistant',
parts: [
{
type: 'text',
text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies. The forecast for the rest of the week shows a slight chance of rain on Thursday, with temperatures gradually rising to 28°C by the weekend. Humidity levels are moderate at around 65%, and wind speeds are light at 8 km/h from the southeast. Air quality is good with an index of 42. The UV index is high at 7, so it's recommended to wear sunscreen if you're planning to spend time outdoors. Sunrise was at 5:24 AM and sunset will be at 6:48 PM, giving Tokyo approximately 13 hours and 24 minutes of daylight today. The moon is currently in its waxing gibbous phase."
}
]
},
{
id: 'c3e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
role: 'user',
parts: [
{
type: 'text',
text: 'Can you recommend some popular tourist attractions in Kyoto?'
}
]
},
{
id: 'd4f5g8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
role: 'assistant',
parts: [
{
type: 'text',
text: 'Kyoto is known for its beautiful temples, traditional tea houses, and gardens. Some popular attractions include Kinkaku-ji (Golden Pavilion) with its stunning gold leaf exterior reflecting in the mirror pond, Fushimi Inari Shrine with its thousands of vermilion torii gates winding up the mountainside, Arashiyama Bamboo Grove where towering stalks create an otherworldly atmosphere, Kiyomizu-dera Temple perched on a hillside offering panoramic views of the city, and the historic Gion district where you might spot geisha hurrying to evening appointments through narrow stone-paved streets lined with traditional wooden machiya houses.'
}
]
}
])
</script>
<template>
<NChatMessages
auto-scroll-icon="i-lucide-chevron-down"
:should-scroll-to-bottom="false"
:messages="messages"
/>
</template>
<script setup lang="ts">
import { ref, h } from 'vue'
const messages = ref([
{
id: '6045235a-a435-46b8-989d-2df38ca2eb47',
role: 'user',
parts: [
{
type: 'text',
text: 'Hello, how are you?'
}
]
},
{
id: '7a92b3c1-d5f8-4e76-b8a9-3c1e5fb2e0d8',
role: 'assistant',
parts: [
{
type: 'text',
text: 'I am doing well, thank you for asking! How can I assist you today?'
}
]
},
{
id: '9c84d6a7-8b23-4f12-a1d5-e7f3b9c05e2a',
role: 'user',
parts: [
{
type: 'text',
text: 'What is the current weather in Tokyo?'
}
]
},
{
id: 'b2e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
role: 'assistant',
parts: [
{
type: 'text',
text: "Based on the latest data, Tokyo is currently experiencing sunny weather with temperatures around 24°C (75°F). It's a beautiful day with clear skies. The forecast for the rest of the week shows a slight chance of rain on Thursday, with temperatures gradually rising to 28°C by the weekend. Humidity levels are moderate at around 65%, and wind speeds are light at 8 km/h from the southeast. Air quality is good with an index of 42. The UV index is high at 7, so it's recommended to wear sunscreen if you're planning to spend time outdoors. Sunrise was at 5:24 AM and sunset will be at 6:48 PM, giving Tokyo approximately 13 hours and 24 minutes of daylight today. The moon is currently in its waxing gibbous phase."
}
]
},
{
id: 'c3e5f8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
role: 'user',
parts: [
{
type: 'text',
text: 'Can you recommend some popular tourist attractions in Kyoto?'
}
]
},
{
id: 'd4f5g8c3-a1d9-4e67-b3f2-c9d8e7a6b5f4',
role: 'assistant',
parts: [
{
type: 'text',
text: 'Kyoto is known for its beautiful temples, traditional tea houses, and gardens. Some popular attractions include Kinkaku-ji (Golden Pavilion) with its stunning gold leaf exterior reflecting in the mirror pond, Fushimi Inari Shrine with its thousands of vermilion torii gates winding up the mountainside, Arashiyama Bamboo Grove where towering stalks create an otherworldly atmosphere, Kiyomizu-dera Temple perched on a hillside offering panoramic views of the city, and the historic Gion district where you might spot geisha hurrying to evening appointments through narrow stone-paved streets lined with traditional wooden machiya houses.'
}
]
}
])
</script>
<template>
<NChatMessages
auto-scroll-icon="i-lucide-chevron-down"
:should-scroll-to-bottom="false"
:messages="messages"
/>
</template>
Use a prop should-auto-scroll para habilitar/desabilitar a rolagem automática contínua enquanto as mensagens são transmitidas. O padrão é false.
<template>
<NChatMessages :messages="messages" should-auto-scroll />
</template>
Use a prop should-scroll-to-bottom para habilitar/desabilitar a rolagem automática até o fim quando o componente é montado. O padrão é true.
<template>
<NChatMessages :messages="messages" :should-scroll-to-bottom="false" />
</template>
Use o slot #indicator para personalizar o indicador de carregamento com um efeito ChatShimmer.
| Prop | Default | Type |
|---|---|---|
messages | T | |
status | "submitted" | "streaming" | "ready" | "error" | |
shouldAutoScroll | false | boolean Whether to automatically scroll to the bottom when a message is streaming. |
shouldScrollToBottom | true | boolean Whether to scroll to the bottom on mounted. |
autoScroll | true | boolean | Omit<ButtonProps, LinkPropsKeys> Display an auto scroll button.
|
autoScrollIcon | appConfig.ui.icons.arrowDown | anyThe icon displayed in the auto scroll button. |
user | Pick<PropsBase<T>, "actions" | "ui" | "variant" | "icon" | "avatar" | "side">The | |
assistant | Pick<PropsBase<T>, "actions" | "ui" | "variant" | "icon" | "avatar" | "side">The | |
compact | false | boolean Render the messages in a compact style.
This is done automatically when used inside a |
spacingOffset | 0 | numberThe spacing offset for the last message in px. Can be useful when the prompt is sticky for example. |
ui | { root?: SlotClass; indicator?: SlotClass; viewport?: SlotClass; autoScroll?: SlotClass; } |
| Slot | Type |
|---|---|
default | { registerMessageRef: (id: string, element: ComponentPublicInstance | null) => void; } |
indicator | { ui: object; } |
viewport | { ui: object; } |
header | UIMessage<unknown, UIDataTypes, UITools> & { message: MessageBase<T>; } |
leading | UIMessage<unknown, UIDataTypes, UITools> & { avatar: (AvatarProps & { [key: string]: any; }) | undefined; ui: object; } & { message: MessageBase<T>; } |
files | Omit<UIMessage<unknown, UIDataTypes, UITools>, "parts"> & { parts: FileUIPart[]; } & { message: MessageBase<T>; } |
body | UIMessage<unknown, UIDataTypes, UITools> & { message: MessageBase<T>; } |
content | UIMessage<unknown, UIDataTypes, UITools> & { content?: string | undefined; } & { message: MessageBase<T>; } |
actions | UIMessage<unknown, UIDataTypes, UITools> & { actions: (Omit<ButtonProps, "onClick"> & { onClick?: ((e: MouseEvent, message: UIMessage<unknown, UIDataTypes, UITools>) => void) | undefined; })[] | undefined; } & { message: MessageBase<T>; } |
ChatMessage dentro do ChatMessages; eles são repassados automaticamente, permitindo personalizar mensagens individuais ao usar a prop messages.<script setup lang="ts">
import { isTextUIPart } from 'ai'
</script>
<template>
<NChatMessages :messages="messages" :status="status">
<template #content="{ message }">
<template
v-for="(part, index) in message.parts"
:key="`${message.id}-${part.type}-${index}`"
>
<p v-if="isTextUIPart(part)" class="whitespace-pre-wrap">
{{ part.text }}
</p>
</template>
</template>
</NChatMessages>
</template>
Ao acessar o componente por meio de um template ref, você pode usar o seguinte:
| Name | Type |
|---|---|
registerMessageRef(id: string, element: ComponentPublicInstance | null) | void |
export default defineAppConfig({
ui: {
chatMessages: {
slots: {
root: 'w-full flex flex-col gap-1 flex-1 px-2.5 [&>article]:last-of-type:min-h-(--last-message-height)',
indicator: 'h-6 flex items-center gap-1 py-3 *:size-2 *:rounded-full *:bg-elevated [&>*:nth-child(1)]:animate-[bounce_1s_infinite] [&>*:nth-child(2)]:animate-[bounce_1s_0.15s_infinite] [&>*:nth-child(3)]:animate-[bounce_1s_0.3s_infinite]',
viewport: 'absolute inset-x-0 top-[86%] data-[state=open]:animate-[fade-in_200ms_ease-out] data-[state=closed]:animate-[fade-out_200ms_ease-in]',
autoScroll: 'rounded-full absolute right-1/2 translate-x-1/2 bottom-0'
},
variants: {
compact: {
true: '',
false: ''
}
}
}
}
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nitro/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
chatMessages: {
slots: {
root: 'w-full flex flex-col gap-1 flex-1 px-2.5 [&>article]:last-of-type:min-h-(--last-message-height)',
indicator: 'h-6 flex items-center gap-1 py-3 *:size-2 *:rounded-full *:bg-elevated [&>*:nth-child(1)]:animate-[bounce_1s_infinite] [&>*:nth-child(2)]:animate-[bounce_1s_0.15s_infinite] [&>*:nth-child(3)]:animate-[bounce_1s_0.3s_infinite]',
viewport: 'absolute inset-x-0 top-[86%] data-[state=open]:animate-[fade-in_200ms_ease-out] data-[state=closed]:animate-[fade-out_200ms_ease-in]',
autoScroll: 'rounded-full absolute right-1/2 translate-x-1/2 bottom-0'
},
variants: {
compact: {
true: '',
false: ''
}
}
}
}
})
]
})