Skip to content

Commit 1ba3e3b

Browse files
committed
docs(search): move ai assistant at the top
1 parent d8a313b commit 1ba3e3b

File tree

4 files changed

+61
-37
lines changed

4 files changed

+61
-37
lines changed

docs/app/components/search/Search.vue

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
<script setup lang="ts">
2-
import type { UIMessage } from 'ai'
32
import type { ContentNavigationItem } from '@nuxt/content'
43
54
interface ContentSearchFile {
@@ -15,46 +14,18 @@ defineProps<{
1514
navigation?: ContentNavigationItem[]
1615
}>()
1716
18-
const chat = ref(false)
19-
const fullscreen = ref(false)
20-
const searchTerm = ref('')
21-
const messages = ref<UIMessage[]>([])
22-
2317
const { frameworks } = useFrameworks()
24-
const { links } = useSearch()
18+
const { links, fullscreen, chat, searchTerm, messages } = useSearch()
2519
2620
const groups = computed(() => [{
27-
id: 'ai',
28-
label: 'Assistant',
29-
ignoreFilter: true,
30-
items: [{
31-
label: 'Ask Nuxt AI',
32-
icon: 'i-lucide-bot',
33-
ui: {
34-
itemLeadingIcon: 'group-data-highlighted:not-group-data-disabled:text-primary'
35-
},
36-
onSelect: (e: any) => {
37-
e.preventDefault()
38-
39-
messages.value = searchTerm.value
40-
? [{
41-
id: '1',
42-
role: 'user',
43-
parts: [{ type: 'text', text: searchTerm.value }]
44-
}]
45-
: []
46-
47-
chat.value = true
48-
}
49-
}]
50-
}, {
5121
id: 'framework',
5222
label: 'Framework',
5323
items: frameworks.value
5424
}])
5525
5626
function onClose() {
5727
chat.value = false
28+
5829
fullscreen.value = false
5930
}
6031
</script>

docs/app/components/search/SearchChat.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,14 @@ const getCachedToolMessage = useMemoize((state: State, toolName: string, input:
9898
<template>
9999
<UChatPalette>
100100
<UChatMessages
101+
should-auto-scroll
101102
:messages="chat.messages"
102103
:status="chat.status"
103104
:user="{ side: 'left', variant: 'naked', icon: 'i-lucide-user' }"
104105
:assistant="{ icon: 'i-lucide-bot' }"
105106
>
106107
<template #content="{ message }">
107-
<template v-for="(part, index) in message.parts" :key="`${message.id}-${index}`">
108+
<template v-for="(part, index) in message.parts" :key="`${message.id}-${part.type}-${index}${'state' in part ? `-${part.state}` : ''}`">
108109
<MDCCached
109110
v-if="part.type === 'text'"
110111
:value="part.text"

docs/app/composables/useSearch.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,38 @@
1+
import type { UIMessage } from 'ai'
2+
13
export function useSearch() {
24
const route = useRoute()
35

6+
const chat = ref(false)
7+
const fullscreen = ref(false)
8+
const searchTerm = ref('')
9+
const messages = ref<UIMessage[]>([])
10+
411
const links = computed(() => [{
12+
label: 'Ask AI',
13+
description: 'Ask the AI assistant powered by our custom MCP server for help.',
14+
icon: 'i-lucide-bot',
15+
ui: {
16+
itemLeadingIcon: 'group-data-highlighted:not-group-data-disabled:text-primary'
17+
},
18+
onSelect: (e: any) => {
19+
e.preventDefault()
20+
21+
messages.value = searchTerm.value
22+
? [{
23+
id: '1',
24+
role: 'user',
25+
parts: [{ type: 'text', text: searchTerm.value }]
26+
}]
27+
: [{
28+
id: '1',
29+
role: 'assistant',
30+
parts: [{ type: 'text', text: 'Hello, how can I help you today?' }]
31+
}]
32+
33+
chat.value = true
34+
}
35+
}, {
536
label: 'Get Started',
637
description: 'Learn how to get started with Nuxt UI.',
738
icon: 'i-lucide-square-play',
@@ -64,6 +95,10 @@ export function useSearch() {
6495
}])
6596

6697
return {
67-
links
98+
links,
99+
chat,
100+
fullscreen,
101+
searchTerm,
102+
messages
68103
}
69104
}

playgrounds/nuxt/app/pages/chat.vue

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,33 @@ function onSubmit() {
4747
:spacing-offset="48"
4848
>
4949
<template #content="{ message }">
50-
<template v-for="(part, index) in message.parts" :key="`${message.id}-${index}`">
51-
<MDC v-if="part.type === 'text'" :value="part.text" :cache-key="`${message.id}-${index}`" class="*:first:mt-0 *:last:mb-0" />
52-
<p v-else-if="part.type === 'reasoning'" class="text-sm text-muted my-5">
50+
<template
51+
v-for="(part, index) in message.parts"
52+
:key="`${message.id}-${part.type}-${index}${'state' in part ? `-${part.state}` : ''}`"
53+
>
54+
<MDC
55+
v-if="part.type === 'text'"
56+
:value="part.text"
57+
:cache-key="`${message.id}-${index}`"
58+
class="*:first:mt-0 *:last:mb-0"
59+
/>
60+
<p
61+
v-else-if="part.type === 'reasoning'"
62+
class="text-sm text-muted my-5"
63+
>
5364
{{ part.state === 'done' ? 'Thoughts' : 'Thinking...' }}
5465
</p>
5566
</template>
5667
</template>
5768
</UChatMessages>
5869

59-
<UChatPrompt v-model="input" :error="chat.error" variant="subtle" class="sticky bottom-0" @submit="onSubmit">
70+
<UChatPrompt
71+
v-model="input"
72+
:error="chat.error"
73+
variant="subtle"
74+
class="sticky bottom-0"
75+
@submit="onSubmit"
76+
>
6077
<UChatPromptSubmit :status="chat.status" @stop="chat.stop" @reload="chat.regenerate" />
6178
</UChatPrompt>
6279
</div>

0 commit comments

Comments
 (0)