Skip to content

Commit 9ebe32d

Browse files
authored
fix: demo examples and dark mode issue for grok demo (#83)
* feat: introduce ChatGPT, Claude, and Grok demo examples and update introduction docs page * chore(docs): add new usage and troubleshooting guides while removing the setup guide * chore(docs): update components documentation pages * fix: demo examples and dark mode issue for grok demo
1 parent 4b993f4 commit 9ebe32d

File tree

6 files changed

+316
-420
lines changed

6 files changed

+316
-420
lines changed

packages/elements/src/reasoning/Reasoning.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ watch(() => props.isStreaming, (streaming) => {
5353
// Auto-open when streaming starts
5454
isOpen.value = true
5555
56-
if (startTime.value === null) {
56+
if (startTime.value === null && props.duration === undefined) {
5757
startTime.value = Date.now()
5858
}
5959
}
@@ -62,7 +62,7 @@ watch(() => props.isStreaming, (streaming) => {
6262
updateDuration(calculatedDuration)
6363
startTime.value = null
6464
}
65-
})
65+
}, { immediate: true })
6666
6767
// Auto-close logic
6868
watch([() => props.isStreaming, isOpen, () => props.defaultOpen, hasAutoClosed], (_, __, onCleanup) => {

packages/examples/src/demo-chatgpt.vue

Lines changed: 96 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
<!-- eslint-disable no-console -->
21
<script setup lang="ts">
32
import type { PromptInputMessage } from '@repo/elements/prompt-input'
43
import type { ToolUIPart } from 'ai'
@@ -95,7 +94,7 @@ const mockMessages: MessageType[] = [
9594
versions: [
9695
{
9796
id: nanoid(),
98-
content: 'Can you explain how to use React hooks effectively?',
97+
content: 'Can you explain how to use Vue reactivity effectively?',
9998
},
10099
],
101100
},
@@ -104,40 +103,40 @@ const mockMessages: MessageType[] = [
104103
from: 'assistant',
105104
sources: [
106105
{
107-
href: 'https://react.dev/reference/react',
108-
title: 'React Documentation',
106+
href: 'https://vuejs.org/api/reactivity-core.html',
107+
title: 'Vue Reactivity Core',
109108
},
110109
{
111-
href: 'https://react.dev/reference/react-dom',
112-
title: 'React DOM Documentation',
110+
href: 'https://vuejs.org/guide/extras/composition-api-faq.html',
111+
title: 'Composition API FAQ',
113112
},
114113
],
115114
tools: [
116115
{
117116
name: 'mcp',
118-
description: 'Searching React documentation',
119-
status: 'input-available',
117+
description: 'Searching Vue documentation',
118+
status: 'input-available' as ToolUIPart['state'],
120119
parameters: {
121-
query: 'React hooks best practices',
122-
source: 'react.dev',
120+
query: 'Vue reactivity best practices',
121+
source: 'vuejs.org',
123122
},
124123
result: `{
125-
"query": "React hooks best practices",
124+
"query": "Vue reactivity best practices",
126125
"results": [
127126
{
128-
"title": "Rules of Hooks",
129-
"url": "https://react.dev/warnings/invalid-hook-call-warning",
130-
"snippet": "Hooks must be called at the top level of your React function components or custom hooks. Don't call hooks inside loops, conditions, or nested functions."
127+
"title": "Reactivity Core",
128+
"url": "https://vuejs.org/api/reactivity-core.html",
129+
"snippet": "Reactivity Core is a set of core APIs for creating reactive data in Vue. It provides the basic building blocks for creating reactive data in Vue."
131130
},
132-
{
133-
"title": "useState Hook",
134-
"url": "https://react.dev/reference/react/useState",
135-
"snippet": "useState is a React Hook that lets you add state to your function components. It returns an array with two values: the current state and a function to update it."
131+
{
132+
"title": "Computed Properties",
133+
"url": "https://vuejs.org/guide/essentials/computed.html",
134+
"snippet": "Computed properties are cached based on their dependencies and only re-evaluate when necessary."
136135
},
137136
{
138-
"title": "useEffect Hook",
139-
"url": "https://react.dev/reference/react/useEffect",
140-
"snippet": "useEffect lets you synchronize a component with external systems. It runs after render and can be used to perform side effects like data fetching."
137+
"title": "Watchers",
138+
"url": "https://vuejs.org/guide/essentials/watchers.html",
139+
"snippet": "Watch is used to perform side effects in response to reactive state changes."
141140
}
142141
]
143142
}`,
@@ -147,42 +146,45 @@ const mockMessages: MessageType[] = [
147146
versions: [
148147
{
149148
id: nanoid(),
150-
content: `# React Hooks Best Practices
151-
152-
React hooks are a powerful feature that let you use state and other React features without writing classes. Here are some tips for using them effectively:
153-
154-
## Rules of Hooks
155-
156-
1. **Only call hooks at the top level** of your component or custom hooks
157-
2. **Don't call hooks inside loops, conditions, or nested functions**
158-
159-
## Common Hooks
160-
161-
- **useState**: For local component state
162-
- **useEffect**: For side effects like data fetching
163-
- **useContext**: For consuming context
164-
- **useReducer**: For complex state logic
165-
- **useCallback**: For memoizing functions
166-
- **useMemo**: For memoizing values
167-
168-
## Example of useState and useEffect
169-
170-
\`\`\`jsx
171-
function ProfilePage({ userId }) {
172-
const [user, setUser] = useState(null);
173-
174-
useEffect(() => {
175-
// This runs after render and when userId changes
176-
fetchUser(userId).then(userData => {
177-
setUser(userData);
178-
});
179-
}, [userId]);
180-
181-
return user ? <Profile user={user} /> : <Loading />;
182-
}
149+
content: `# Vue Reactivity Best Practices
150+
151+
Vue reactivity is a powerful feature that let you use state and other Vue features without writing classes. Here are some tips for using them effectively:
152+
153+
## Rules of Reactivity
154+
155+
1. **Only call reactivity at the top level** of your component or custom hooks
156+
2. **Don't call reactivity inside loops, conditions, or nested functions**
157+
158+
## Core Reactivity APIs
159+
160+
- **ref()** – for primitive reactive values
161+
- **reactive()** – for objects
162+
- **computed()** – memoized derived values
163+
- **watch()** – respond to state changes
164+
- **watchEffect()** – run effects automatically
165+
166+
## Example of ref() and watchEffect()
167+
168+
\`\`\`vue
169+
<script setup>
170+
import { ref, watchEffect } from "vue";
171+
172+
const userId = ref(1);
173+
const user = ref(null);
174+
175+
watchEffect(async () => {
176+
user.value = await fetchUser(userId.value);
177+
});
178+
<\/script>
179+
180+
<template>
181+
<Profile v-if="user" :user="user" />
182+
<Loading v-else />
183+
</template>
183184
\`\`\`
184185
185-
Would you like me to explain any specific hook in more detail?`,
186+
Want deeper explanation of computed() and handling expensive logic?
187+
`,
186188
},
187189
],
188190
},
@@ -193,85 +195,85 @@ Would you like me to explain any specific hook in more detail?`,
193195
{
194196
id: nanoid(),
195197
content:
196-
'Yes, could you explain useCallback and useMemo in more detail? When should I use one over the other?',
198+
'Yes, could you explain computed and function memoization in more detail? When should I use one over the other?',
197199
},
198200
{
199201
id: nanoid(),
200202
content:
201-
'I\'m particularly interested in understanding the performance implications of useCallback and useMemo. Could you break down when each is most appropriate?',
203+
'I\'m particularly interested in understanding the performance implications of computed and memoized functions in Vue. Could you break down when each is most appropriate?',
202204
},
203205
{
204206
id: nanoid(),
205207
content:
206-
'Thanks for the overview! Could you dive deeper into the specific use cases where useCallback and useMemo make the biggest difference in React applications?',
208+
'Thanks for the overview! Could you dive deeper into the specific use cases where computed and memoized functions make the biggest difference in Vue applications?',
207209
},
208210
],
209211
},
210212
{
211213
key: nanoid(),
212214
from: 'assistant',
213215
reasoning: {
214-
content: `The user is asking for a detailed explanation of useCallback and useMemo. I should provide a clear and concise explanation of each hook's purpose and how they differ.
215-
216-
The useCallback hook is used to memoize functions to prevent unnecessary re-renders of child components that receive functions as props.
216+
content: `The user is asking for a detailed explanation of how Vue handles memoized values and reactive updates. I should provide a clear and concise explanation of each concept's purpose and how they differ.
217+
218+
The computed() function is used to create cached, derived values that only update when their reactive dependencies change.
217219
218-
The useMemo hook is used to memoize values to avoid expensive recalculations on every render.
220+
Regular functions inside setup() rely on Vue’s reactivity system and only run when the state they depend on changes.
219221
220-
Both hooks help with performance optimization, but they serve different purposes.`,
222+
Both features help with performance optimization, but they serve different purposes.`,
221223
duration: 10,
222224
},
223225
versions: [
224226
{
225227
id: nanoid(),
226-
content: `## useCallback vs useMemo
228+
content: `## computed vs watch
227229
228-
Both hooks help with *performance optimization*, but they serve different purposes:
230+
Both features help with _performance optimization_, but they serve different purposes:
229231
230-
### useCallback
232+
### computed
231233
232-
\`useCallback\` memoizes **functions** to prevent unnecessary re-renders of child components that receive functions as props.
234+
\`computed\` memoizes **derived values** and only updates when their reactive dependencies change.
233235
234-
\`\`\`jsx
235-
// Without useCallback - a new function is created on every render
236-
const handleClick = () => {
237-
console.log(count);
238-
};
236+
\`\`\`ts
237+
// A simple reactive state
238+
const count = ref(0);
239239
240-
// With useCallback - the function is only recreated when dependencies change
241-
const handleClick = useCallback(() => {
242-
console.log(count);
243-
}, [count]);
240+
// Using computed - value is cached until 'count' changes
241+
const doubled = computed(() => count.value * 2);
244242
\`\`\`
245243
246-
### useMemo
244+
### watch
247245
248-
\`useMemo\` memoizes **values** to avoid expensive recalculations on every render.
246+
\`watch\` is used to run **side effects** in response to reactive state changes.
249247
250-
\`\`\`jsx
251-
// Without useMemo - expensive calculation runs on every render
252-
const sortedList = expensiveSort(items);
253-
254-
// With useMemo - calculation only runs when items change
255-
const sortedList = useMemo(() => expensiveSort(items), [items]);
248+
\`\`\`ts
249+
// Watching a value - function runs only when 'count' changes
250+
watch(count, (newValue) => {
251+
console.log("Count changed:", newValue);
252+
});
256253
\`\`\`
257254
258255
### When to use which?
259256
260-
- Use **useCallback** when:
261-
- Passing callbacks to optimized child components that rely on reference equality
262-
- Working with event handlers that you pass to child components
257+
- Use **computed** when:
258+
- You need a cached, derived value
259+
- You want something to behave like state but depend on other state
260+
- You want to avoid recalculating expensive logic on every update
263261
264-
- Use **useMemo** when:
265-
- You have computationally expensive calculations
266-
- You want to avoid recreating objects that are used as dependencies for other hooks
262+
- Use **watch** when:
263+
- You need to run side effects (API calls, logging, syncing data)
264+
- You want to respond to changes without returning a value
267265
268266
### Performance Note
269267
270-
Don't overuse these hooks! They come with their own overhead. Only use them when you have identified a genuine performance issue.
268+
Don't overuse \`watch\` for things that should be computed values. \`computed\` is more efficient and should be preferred for derived state.
269+
270+
### ~~Common Mistakes~~
271271
272-
### ~~Deprecated Methods~~
272+
Avoid these ~~anti-patterns~~ when using Vue reactivity:
273+
- ~~Doing heavy computation directly inside templates~~ — move logic to \`computed\`
274+
- Overusing \`watch\` for transformations that should be computed
275+
- Mutating reactive objects in ways Vue can't track (e.g., replacing arrays incorrectly)`,
273276
274-
Note that ~~class-based lifecycle methods~~ like \`componentDidMount\` are now replaced by the \`useEffect\` hook in modern React development.`,
275277
},
276278
],
277279
},
@@ -474,7 +476,6 @@ function handleSubmit(message: PromptInputMessage) {
474476
}
475477
476478
function handleFileAction(action: string) {
477-
console.log('hello')
478479
toast.success('File action', {
479480
description: action,
480481
})
@@ -485,7 +486,7 @@ function handleSuggestionClick(suggestion: string) {
485486
addUserMessage(suggestion)
486487
}
487488
488-
let initTimer: any
489+
let initTimer: NodeJS.Timeout
489490
490491
onMounted(() => {
491492
// Reset state on mount to ensure fresh component

0 commit comments

Comments
 (0)