mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-21 15:31:46 +01:00
Compare commits
19 Commits
docs/ai-se
...
fix/3394
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c326180f15 | ||
|
|
6887e33aae | ||
|
|
d75093a160 | ||
|
|
47ed1e0f74 | ||
|
|
d6a3a65b8e | ||
|
|
a81d0e55c7 | ||
|
|
5b172b0fb3 | ||
|
|
fbf7475e0d | ||
|
|
0f90645c84 | ||
|
|
33193d782d | ||
|
|
d1f2b50033 | ||
|
|
bd75d2d184 | ||
|
|
28e869e8aa | ||
|
|
cabad480f9 | ||
|
|
d86956e1d5 | ||
|
|
23e4f0ec4d | ||
|
|
91d06d4d51 | ||
|
|
f1128c2450 | ||
|
|
c00f6e8cdf |
@@ -12,6 +12,7 @@ const { data: files } = useLazyAsyncData('search', () => queryCollectionSearchSe
|
|||||||
})
|
})
|
||||||
|
|
||||||
const links = useLinks()
|
const links = useLinks()
|
||||||
|
const searchLinks = useSearchLinks()
|
||||||
const color = computed(() => colorMode.value === 'dark' ? (colors as any)[appConfig.ui.colors.neutral][900] : 'white')
|
const color = computed(() => colorMode.value === 'dark' ? (colors as any)[appConfig.ui.colors.neutral][900] : 'white')
|
||||||
const radius = computed(() => `:root { --ui-radius: ${appConfig.theme.radius}rem; }`)
|
const radius = computed(() => `:root { --ui-radius: ${appConfig.theme.radius}rem; }`)
|
||||||
const blackAsPrimary = computed(() => appConfig.theme.blackAsPrimary ? `:root { --ui-primary: black; } .dark { --ui-primary: white; }` : ':root {}')
|
const blackAsPrimary = computed(() => appConfig.theme.blackAsPrimary ? `:root { --ui-primary: black; } .dark { --ui-primary: white; }` : ':root {}')
|
||||||
@@ -41,6 +42,7 @@ useServerSeoMeta({
|
|||||||
|
|
||||||
useFaviconFromTheme()
|
useFaviconFromTheme()
|
||||||
|
|
||||||
|
const { frameworks, modules } = useSharedData()
|
||||||
const { mappedNavigation, filteredNavigation } = useContentNavigation(navigation)
|
const { mappedNavigation, filteredNavigation } = useContentNavigation(navigation)
|
||||||
|
|
||||||
provide('navigation', mappedNavigation)
|
provide('navigation', mappedNavigation)
|
||||||
@@ -63,7 +65,23 @@ provide('navigation', mappedNavigation)
|
|||||||
<template v-if="!route.path.startsWith('/examples')">
|
<template v-if="!route.path.startsWith('/examples')">
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|
||||||
<Search :files="files" :navigation="filteredNavigation" />
|
<ClientOnly>
|
||||||
|
<LazyUContentSearch
|
||||||
|
:links="searchLinks"
|
||||||
|
:files="files"
|
||||||
|
:groups="[{
|
||||||
|
id: 'framework',
|
||||||
|
label: 'Framework',
|
||||||
|
items: frameworks
|
||||||
|
}, {
|
||||||
|
id: 'module',
|
||||||
|
label: 'Module',
|
||||||
|
items: modules
|
||||||
|
}]"
|
||||||
|
:navigation="filteredNavigation"
|
||||||
|
:fuse="{ resultLimit: 100 }"
|
||||||
|
/>
|
||||||
|
</ClientOnly>
|
||||||
</template>
|
</template>
|
||||||
</UApp>
|
</UApp>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,199 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import type { DefineComponent } from 'vue'
|
|
||||||
import type { ContentNavigationItem } from '@nuxt/content'
|
|
||||||
import { useChat } from '@ai-sdk/vue'
|
|
||||||
import ProseStreamPre from './prose/PreStream.vue'
|
|
||||||
|
|
||||||
const components = {
|
|
||||||
pre: ProseStreamPre as unknown as DefineComponent
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ContentSearchFile {
|
|
||||||
id: string
|
|
||||||
title: string
|
|
||||||
titles: string[]
|
|
||||||
level: number
|
|
||||||
content: string
|
|
||||||
}
|
|
||||||
|
|
||||||
defineProps<{
|
|
||||||
files?: ContentSearchFile[]
|
|
||||||
navigation?: ContentNavigationItem[]
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const { frameworks, modules } = useSharedData()
|
|
||||||
const { messages, input, handleSubmit, status, error, reload, setMessages } = useChat({
|
|
||||||
maxSteps: 2
|
|
||||||
})
|
|
||||||
|
|
||||||
const ai = ref(false)
|
|
||||||
const searchTerm = ref('')
|
|
||||||
|
|
||||||
const links = computed(() => [{
|
|
||||||
label: 'Ask AI',
|
|
||||||
icon: 'i-lucide-bot',
|
|
||||||
onSelect: (e: any) => {
|
|
||||||
e.preventDefault()
|
|
||||||
|
|
||||||
ai.value = true
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
label: 'Docs',
|
|
||||||
icon: 'i-lucide-square-play',
|
|
||||||
to: '/getting-started'
|
|
||||||
}, {
|
|
||||||
label: 'Components',
|
|
||||||
icon: 'i-lucide-square-code',
|
|
||||||
to: '/components'
|
|
||||||
}, {
|
|
||||||
icon: 'i-lucide-sparkles',
|
|
||||||
label: 'Pro > Features',
|
|
||||||
description: 'A collection of premium Vue components.',
|
|
||||||
to: '/pro'
|
|
||||||
}, {
|
|
||||||
icon: 'i-lucide-credit-card',
|
|
||||||
label: 'Pro > Pricing',
|
|
||||||
description: 'Free in development, buy when ready to launch.',
|
|
||||||
to: '/pro/pricing'
|
|
||||||
}, {
|
|
||||||
icon: 'i-lucide-panels-top-left',
|
|
||||||
label: 'Pro > Templates',
|
|
||||||
description: 'Official templates made with Nuxt UI Pro.',
|
|
||||||
to: '/pro/templates'
|
|
||||||
}, {
|
|
||||||
icon: 'i-lucide-circle-check',
|
|
||||||
label: 'Pro > Activate',
|
|
||||||
description: 'Enable Nuxt UI Pro in your production projects.',
|
|
||||||
to: '/pro/activate'
|
|
||||||
}, {
|
|
||||||
label: 'Figma',
|
|
||||||
icon: 'i-simple-icons-figma',
|
|
||||||
to: '/figma'
|
|
||||||
}, {
|
|
||||||
icon: 'i-lucide-presentation',
|
|
||||||
label: 'Community > Showcase',
|
|
||||||
description: 'Check out some of the amazing projects built with Nuxt UI.',
|
|
||||||
to: '/showcase'
|
|
||||||
}, {
|
|
||||||
label: 'Community > Contribution',
|
|
||||||
description: 'A comprehensive guide on contributing to Nuxt UI, including project structure, development workflow, and best practices.',
|
|
||||||
icon: 'i-lucide-git-pull-request-arrow',
|
|
||||||
to: '/getting-started/contribution'
|
|
||||||
}, {
|
|
||||||
label: 'Community > Roadmap',
|
|
||||||
description: 'Track our development progress in real-time.',
|
|
||||||
icon: 'i-lucide-map',
|
|
||||||
to: '/roadmap'
|
|
||||||
}, {
|
|
||||||
label: 'Community > Devtools',
|
|
||||||
description: 'Integrate Nuxt UI with Nuxt Devtools with Compodium.',
|
|
||||||
icon: 'i-lucide-code',
|
|
||||||
to: 'https://github.com/romhml/compodium',
|
|
||||||
target: '_blank'
|
|
||||||
}, {
|
|
||||||
label: 'Community > Team',
|
|
||||||
description: 'Meet the team behind Nuxt UI.',
|
|
||||||
icon: 'i-lucide-users',
|
|
||||||
to: '/team'
|
|
||||||
}, {
|
|
||||||
label: 'Releases',
|
|
||||||
icon: 'i-lucide-rocket',
|
|
||||||
to: 'https://github.com/nuxt/ui/releases',
|
|
||||||
target: '_blank'
|
|
||||||
}])
|
|
||||||
|
|
||||||
const groups = computed(() => [{
|
|
||||||
id: 'ai',
|
|
||||||
label: 'AI',
|
|
||||||
ignoreFilter: true,
|
|
||||||
items: [{
|
|
||||||
label: searchTerm.value ? `Ask Nuxt AI for “${searchTerm.value}”` : 'Ask Nuxt AI',
|
|
||||||
icon: 'i-lucide-bot',
|
|
||||||
onSelect: (e: any) => {
|
|
||||||
e.preventDefault()
|
|
||||||
|
|
||||||
ai.value = true
|
|
||||||
|
|
||||||
if (searchTerm.value) {
|
|
||||||
setMessages([{
|
|
||||||
id: '1',
|
|
||||||
role: 'user',
|
|
||||||
content: searchTerm.value
|
|
||||||
}])
|
|
||||||
|
|
||||||
reload()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
}, {
|
|
||||||
id: 'framework',
|
|
||||||
label: 'Framework',
|
|
||||||
items: frameworks.value
|
|
||||||
}, {
|
|
||||||
id: 'module',
|
|
||||||
label: 'Module',
|
|
||||||
items: modules.value
|
|
||||||
}])
|
|
||||||
|
|
||||||
function onClose(e: Event) {
|
|
||||||
console.log('onClose')
|
|
||||||
e.preventDefault()
|
|
||||||
|
|
||||||
ai.value = false
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<LazyUContentSearch
|
|
||||||
v-model:search-term="searchTerm"
|
|
||||||
:links="links"
|
|
||||||
:files="files"
|
|
||||||
:groups="groups"
|
|
||||||
:navigation="navigation"
|
|
||||||
:fuse="{ resultLimit: 100 }"
|
|
||||||
>
|
|
||||||
<template v-if="ai" #content>
|
|
||||||
<UChatPalette>
|
|
||||||
<UChatMessages
|
|
||||||
:messages="messages"
|
|
||||||
:status="status"
|
|
||||||
:user="{ side: 'left', variant: 'naked', icon: 'i-lucide-user' }"
|
|
||||||
:assistant="{ icon: 'i-lucide-bot' }"
|
|
||||||
>
|
|
||||||
<template #content="{ message }">
|
|
||||||
<MDCCached
|
|
||||||
v-if="message.toolInvocations?.[0]?.state === 'result'"
|
|
||||||
:value="message.toolInvocations?.[0]?.result"
|
|
||||||
:cache-key="message.id"
|
|
||||||
unwrap="p"
|
|
||||||
:components="components"
|
|
||||||
:parser-options="{ highlight: false }"
|
|
||||||
/>
|
|
||||||
<MDCCached
|
|
||||||
v-else-if="message.content.length > 0"
|
|
||||||
:value="message.content"
|
|
||||||
:cache-key="message.id"
|
|
||||||
unwrap="p"
|
|
||||||
:components="components"
|
|
||||||
:parser-options="{ highlight: false }"
|
|
||||||
/>
|
|
||||||
<span v-else class="italic font-light">
|
|
||||||
Searching documentation...
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</UChatMessages>
|
|
||||||
|
|
||||||
<template #prompt>
|
|
||||||
<UChatPrompt
|
|
||||||
v-model="input"
|
|
||||||
icon="i-lucide-search"
|
|
||||||
variant="naked"
|
|
||||||
:error="error"
|
|
||||||
@submit="handleSubmit"
|
|
||||||
@close="onClose"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</UChatPalette>
|
|
||||||
</template>
|
|
||||||
</LazyUContentSearch>
|
|
||||||
</template>
|
|
||||||
@@ -25,6 +25,7 @@ function getEmojiFlag(locale: string): string {
|
|||||||
kk: 'kz', // Kazakh -> Kazakhstan
|
kk: 'kz', // Kazakh -> Kazakhstan
|
||||||
km: 'kh', // Khmer -> Cambodia
|
km: 'kh', // Khmer -> Cambodia
|
||||||
ko: 'kr', // Korean -> South Korea
|
ko: 'kr', // Korean -> South Korea
|
||||||
|
ms: 'my', // Malay -> Malaysia
|
||||||
nb: 'no', // Norwegian Bokmål -> Norway
|
nb: 'no', // Norwegian Bokmål -> Norway
|
||||||
sl: 'si', // Slovenian -> Slovenia
|
sl: 'si', // Slovenian -> Slovenia
|
||||||
sv: 'se', // Swedish -> Sweden
|
sv: 'se', // Swedish -> Sweden
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { ShikiCachedRenderer } from 'shiki-stream/vue'
|
|
||||||
|
|
||||||
const colorMode = useColorMode()
|
|
||||||
const highlighter = await useHighlighter()
|
|
||||||
const props = defineProps<{
|
|
||||||
code: string
|
|
||||||
language: string
|
|
||||||
class?: string
|
|
||||||
meta?: string
|
|
||||||
}>()
|
|
||||||
const trimmedCode = computed(() => {
|
|
||||||
return props.code.trim().replace(/`+$/, '')
|
|
||||||
})
|
|
||||||
const lang = computed(() => {
|
|
||||||
switch (props.language) {
|
|
||||||
case 'vue':
|
|
||||||
return 'vue'
|
|
||||||
case 'javascript':
|
|
||||||
return 'js'
|
|
||||||
case 'typescript':
|
|
||||||
return 'ts'
|
|
||||||
case 'css':
|
|
||||||
return 'css'
|
|
||||||
default:
|
|
||||||
return props.language
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const key = computed(() => {
|
|
||||||
return `${lang.value}-${colorMode.value}`
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<ProsePre v-bind="props">
|
|
||||||
<ShikiCachedRenderer
|
|
||||||
:key="key"
|
|
||||||
:highlighter="highlighter"
|
|
||||||
:code="trimmedCode"
|
|
||||||
:lang="lang"
|
|
||||||
:theme="colorMode.value === 'dark' ? 'material-theme-palenight' : 'material-theme-lighter'"
|
|
||||||
/>
|
|
||||||
</ProsePre>
|
|
||||||
</template>
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
import { createHighlighter, type HighlighterGeneric } from 'shiki'
|
|
||||||
import { createJavaScriptRegexEngine } from 'shiki/engine-javascript.mjs'
|
|
||||||
|
|
||||||
let highlighter: HighlighterGeneric<any, any> | null = null
|
|
||||||
|
|
||||||
let promise: Promise<HighlighterGeneric<any, any>> | null = null
|
|
||||||
|
|
||||||
export const useHighlighter = async () => {
|
|
||||||
if (!promise) {
|
|
||||||
promise = createHighlighter({
|
|
||||||
langs: ['vue', 'js', 'ts', 'css', 'html', 'json', 'yaml', 'markdown', 'bash'],
|
|
||||||
themes: ['material-theme-palenight', 'material-theme-lighter'],
|
|
||||||
engine: createJavaScriptRegexEngine()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (!highlighter) {
|
|
||||||
highlighter = await promise
|
|
||||||
}
|
|
||||||
|
|
||||||
return highlighter
|
|
||||||
}
|
|
||||||
66
docs/app/composables/useSearchLinks.ts
Normal file
66
docs/app/composables/useSearchLinks.ts
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
export function useSearchLinks() {
|
||||||
|
return [{
|
||||||
|
label: 'Docs',
|
||||||
|
icon: 'i-lucide-square-play',
|
||||||
|
to: '/getting-started'
|
||||||
|
}, {
|
||||||
|
label: 'Components',
|
||||||
|
icon: 'i-lucide-square-code',
|
||||||
|
to: '/components'
|
||||||
|
}, {
|
||||||
|
icon: 'i-lucide-sparkles',
|
||||||
|
label: 'Pro > Features',
|
||||||
|
description: 'A collection of premium Vue components.',
|
||||||
|
to: '/pro'
|
||||||
|
}, {
|
||||||
|
icon: 'i-lucide-credit-card',
|
||||||
|
label: 'Pro > Pricing',
|
||||||
|
description: 'Free in development, buy when ready to launch.',
|
||||||
|
to: '/pro/pricing'
|
||||||
|
}, {
|
||||||
|
icon: 'i-lucide-panels-top-left',
|
||||||
|
label: 'Pro > Templates',
|
||||||
|
description: 'Official templates made with Nuxt UI Pro.',
|
||||||
|
to: '/pro/templates'
|
||||||
|
}, {
|
||||||
|
icon: 'i-lucide-circle-check',
|
||||||
|
label: 'Pro > Activate',
|
||||||
|
description: 'Enable Nuxt UI Pro in your production projects.',
|
||||||
|
to: '/pro/activate'
|
||||||
|
}, {
|
||||||
|
label: 'Figma',
|
||||||
|
icon: 'i-simple-icons-figma',
|
||||||
|
to: '/figma'
|
||||||
|
}, {
|
||||||
|
icon: 'i-lucide-presentation',
|
||||||
|
label: 'Community > Showcase',
|
||||||
|
description: 'Check out some of the amazing projects built with Nuxt UI.',
|
||||||
|
to: '/showcase'
|
||||||
|
}, {
|
||||||
|
label: 'Community > Contribution',
|
||||||
|
description: 'A comprehensive guide on contributing to Nuxt UI, including project structure, development workflow, and best practices.',
|
||||||
|
icon: 'i-lucide-git-pull-request-arrow',
|
||||||
|
to: '/getting-started/contribution'
|
||||||
|
}, {
|
||||||
|
label: 'Community > Roadmap',
|
||||||
|
description: 'Track our development progress in real-time.',
|
||||||
|
icon: 'i-lucide-map',
|
||||||
|
to: '/roadmap'
|
||||||
|
}, {
|
||||||
|
label: 'Community > Devtools',
|
||||||
|
description: 'Integrate Nuxt UI with Nuxt Devtools with Compodium.',
|
||||||
|
icon: 'i-lucide-code',
|
||||||
|
to: 'https://github.com/romhml/compodium',
|
||||||
|
target: '_blank'
|
||||||
|
}, {
|
||||||
|
label: 'Community > Team',
|
||||||
|
description: 'Meet the team behind Nuxt UI.',
|
||||||
|
icon: 'i-lucide-users',
|
||||||
|
to: '/team'
|
||||||
|
}, {
|
||||||
|
label: 'Releases',
|
||||||
|
icon: 'i-lucide-rocket',
|
||||||
|
to: 'https://github.com/nuxt/ui/releases',
|
||||||
|
target: '_blank'
|
||||||
|
}]
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@ const { data: files } = useLazyAsyncData('search', () => queryCollectionSearchSe
|
|||||||
})
|
})
|
||||||
|
|
||||||
const links = useLinks()
|
const links = useLinks()
|
||||||
|
const searchLinks = useSearchLinks()
|
||||||
const color = computed(() => colorMode.value === 'dark' ? (colors as any)[appConfig.ui.colors.neutral][900] : 'white')
|
const color = computed(() => colorMode.value === 'dark' ? (colors as any)[appConfig.ui.colors.neutral][900] : 'white')
|
||||||
const radius = computed(() => `:root { --ui-radius: ${appConfig.theme.radius}rem; }`)
|
const radius = computed(() => `:root { --ui-radius: ${appConfig.theme.radius}rem; }`)
|
||||||
const blackAsPrimary = computed(() => appConfig.theme.blackAsPrimary ? `:root { --ui-primary: black; } .dark { --ui-primary: white; }` : ':root {}')
|
const blackAsPrimary = computed(() => appConfig.theme.blackAsPrimary ? `:root { --ui-primary: black; } .dark { --ui-primary: white; }` : ':root {}')
|
||||||
@@ -48,6 +49,7 @@ useServerSeoMeta({
|
|||||||
|
|
||||||
useFaviconFromTheme()
|
useFaviconFromTheme()
|
||||||
|
|
||||||
|
const { frameworks, modules } = useSharedData()
|
||||||
const { mappedNavigation, filteredNavigation } = useContentNavigation(navigation)
|
const { mappedNavigation, filteredNavigation } = useContentNavigation(navigation)
|
||||||
|
|
||||||
provide('navigation', mappedNavigation)
|
provide('navigation', mappedNavigation)
|
||||||
@@ -65,6 +67,22 @@ provide('navigation', mappedNavigation)
|
|||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|
||||||
<Search :files="files" :navigation="filteredNavigation" />
|
<ClientOnly>
|
||||||
|
<LazyUContentSearch
|
||||||
|
:links="searchLinks"
|
||||||
|
:files="files"
|
||||||
|
:groups="[{
|
||||||
|
id: 'framework',
|
||||||
|
label: 'Framework',
|
||||||
|
items: frameworks
|
||||||
|
}, {
|
||||||
|
id: 'module',
|
||||||
|
label: 'Module',
|
||||||
|
items: modules
|
||||||
|
}]"
|
||||||
|
:navigation="filteredNavigation"
|
||||||
|
:fuse="{ resultLimit: 100 }"
|
||||||
|
/>
|
||||||
|
</ClientOnly>
|
||||||
</UApp>
|
</UApp>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -5,20 +5,20 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ai-sdk/vue": "^1.2.12",
|
"@ai-sdk/vue": "^1.2.12",
|
||||||
"@iconify-json/logos": "^1.2.4",
|
"@iconify-json/logos": "^1.2.4",
|
||||||
"@iconify-json/lucide": "^1.2.43",
|
"@iconify-json/lucide": "^1.2.44",
|
||||||
"@iconify-json/simple-icons": "^1.2.34",
|
"@iconify-json/simple-icons": "^1.2.34",
|
||||||
"@iconify-json/vscode-icons": "^1.2.21",
|
"@iconify-json/vscode-icons": "^1.2.21",
|
||||||
"@nuxt/content": "^3.5.1",
|
"@nuxt/content": "^3.5.1",
|
||||||
"@nuxt/image": "^1.10.0",
|
"@nuxt/image": "^1.10.0",
|
||||||
"@nuxt/ui": "latest",
|
"@nuxt/ui": "latest",
|
||||||
"@nuxt/ui-pro": "^3.1.2",
|
"@nuxt/ui-pro": "https://pkg.pr.new/@nuxt/ui-pro@9038c43",
|
||||||
"@nuxthub/core": "^0.8.27",
|
"@nuxthub/core": "^0.8.27",
|
||||||
"@nuxtjs/plausible": "^1.2.0",
|
"@nuxtjs/plausible": "^1.2.0",
|
||||||
"@octokit/rest": "^21.1.1",
|
"@octokit/rest": "^21.1.1",
|
||||||
"@rollup/plugin-yaml": "^4.1.2",
|
"@rollup/plugin-yaml": "^4.1.2",
|
||||||
"@vueuse/integrations": "^13.2.0",
|
"@vueuse/integrations": "^13.2.0",
|
||||||
"@vueuse/nuxt": "^13.2.0",
|
"@vueuse/nuxt": "^13.2.0",
|
||||||
"ai": "^4.3.15",
|
"ai": "^4.3.16",
|
||||||
"capture-website": "^4.2.0",
|
"capture-website": "^4.2.0",
|
||||||
"joi": "^17.13.3",
|
"joi": "^17.13.3",
|
||||||
"motion-v": "^1.0.2",
|
"motion-v": "^1.0.2",
|
||||||
@@ -27,7 +27,6 @@
|
|||||||
"nuxt-llms": "^0.1.2",
|
"nuxt-llms": "^0.1.2",
|
||||||
"nuxt-og-image": "^5.1.3",
|
"nuxt-og-image": "^5.1.3",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"shiki-stream": "^0.1.2",
|
|
||||||
"shiki-transformer-color-highlight": "^1.0.0",
|
"shiki-transformer-color-highlight": "^1.0.0",
|
||||||
"sortablejs": "^1.15.6",
|
"sortablejs": "^1.15.6",
|
||||||
"superstruct": "^2.0.2",
|
"superstruct": "^2.0.2",
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { streamText, tool } from 'ai'
|
import { streamText } from 'ai'
|
||||||
import { createWorkersAI } from 'workers-ai-provider'
|
import { createWorkersAI } from 'workers-ai-provider'
|
||||||
import { z } from 'zod'
|
|
||||||
|
|
||||||
export default defineEventHandler(async (event) => {
|
export default defineEventHandler(async (event) => {
|
||||||
const { messages } = await readBody(event)
|
const { messages } = await readBody(event)
|
||||||
@@ -13,30 +12,11 @@ export default defineEventHandler(async (event) => {
|
|||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
const workersAI = createWorkersAI({ binding: hubAI(), gateway })
|
const workersAI = createWorkersAI({ binding: hubAI(), gateway })
|
||||||
const autorag = hubAutoRAG('ui3')
|
|
||||||
|
|
||||||
return streamText({
|
return streamText({
|
||||||
model: workersAI('@cf/meta/llama-3.3-70b-instruct-fp8-fast'),
|
model: workersAI('@cf/meta/llama-3.2-3b-instruct'),
|
||||||
messages,
|
maxTokens: 10000,
|
||||||
system: `You are a helpful assistant for Nuxt UI. Check your knowledge base before answering any questions.
|
system: 'You are a helpful assistant that can answer questions and help.',
|
||||||
Only respond to questions using information from tool calls.
|
messages
|
||||||
if no relevant information is found in the tool calls, respond, "Sorry, I don't know."
|
|
||||||
Format your markdown response using the following rules:
|
|
||||||
- Use the vue lang for code blocks syntax highlighting.
|
|
||||||
- Don't use markdown headings.
|
|
||||||
`,
|
|
||||||
tools: {
|
|
||||||
searchDocumentation: tool({
|
|
||||||
description: `search the documentation for information to answer questions.`,
|
|
||||||
parameters: z.object({
|
|
||||||
question: z.string().describe('the users question')
|
|
||||||
}),
|
|
||||||
execute: async ({ question }) => {
|
|
||||||
return (await autorag.aiSearch({
|
|
||||||
query: question
|
|
||||||
})).response
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}).toDataStreamResponse()
|
}).toDataStreamResponse()
|
||||||
})
|
})
|
||||||
|
|||||||
16
package.json
16
package.json
@@ -116,15 +116,15 @@
|
|||||||
"@internationalized/date": "^3.8.0",
|
"@internationalized/date": "^3.8.0",
|
||||||
"@internationalized/number": "^3.6.1",
|
"@internationalized/number": "^3.6.1",
|
||||||
"@nuxt/fonts": "^0.11.4",
|
"@nuxt/fonts": "^0.11.4",
|
||||||
"@nuxt/icon": "^1.12.0",
|
"@nuxt/icon": "^1.13.0",
|
||||||
"@nuxt/kit": "^3.17.3",
|
"@nuxt/kit": "^3.17.3",
|
||||||
"@nuxt/schema": "^3.17.3",
|
"@nuxt/schema": "^3.17.3",
|
||||||
"@nuxtjs/color-mode": "^3.5.2",
|
"@nuxtjs/color-mode": "^3.5.2",
|
||||||
"@standard-schema/spec": "^1.0.0",
|
"@standard-schema/spec": "^1.0.0",
|
||||||
"@tailwindcss/postcss": "^4.1.6",
|
"@tailwindcss/postcss": "^4.1.7",
|
||||||
"@tailwindcss/vite": "^4.1.6",
|
"@tailwindcss/vite": "^4.1.7",
|
||||||
"@tanstack/vue-table": "^8.21.3",
|
"@tanstack/vue-table": "^8.21.3",
|
||||||
"@unhead/vue": "^2.0.8",
|
"@unhead/vue": "^2.0.9",
|
||||||
"@vueuse/core": "^13.2.0",
|
"@vueuse/core": "^13.2.0",
|
||||||
"@vueuse/integrations": "^13.2.0",
|
"@vueuse/integrations": "^13.2.0",
|
||||||
"colortranslator": "^4.1.0",
|
"colortranslator": "^4.1.0",
|
||||||
@@ -147,7 +147,7 @@
|
|||||||
"reka-ui": "^2.2.1",
|
"reka-ui": "^2.2.1",
|
||||||
"scule": "^1.3.0",
|
"scule": "^1.3.0",
|
||||||
"tailwind-variants": "^1.0.0",
|
"tailwind-variants": "^1.0.0",
|
||||||
"tailwindcss": "^4.1.6",
|
"tailwindcss": "^4.1.7",
|
||||||
"tinyglobby": "^0.2.13",
|
"tinyglobby": "^0.2.13",
|
||||||
"unplugin": "^2.3.4",
|
"unplugin": "^2.3.4",
|
||||||
"unplugin-auto-import": "^19.2.0",
|
"unplugin-auto-import": "^19.2.0",
|
||||||
@@ -156,13 +156,13 @@
|
|||||||
"vue-component-type-helpers": "^2.2.10"
|
"vue-component-type-helpers": "^2.2.10"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxt/eslint-config": "^1.3.1",
|
"@nuxt/eslint-config": "^1.4.0",
|
||||||
"@nuxt/module-builder": "^1.0.1",
|
"@nuxt/module-builder": "^1.0.1",
|
||||||
"@nuxt/test-utils": "^3.18.0",
|
"@nuxt/test-utils": "^3.19.0",
|
||||||
"@release-it/conventional-changelog": "^10.0.1",
|
"@release-it/conventional-changelog": "^10.0.1",
|
||||||
"@vue/test-utils": "^2.4.6",
|
"@vue/test-utils": "^2.4.6",
|
||||||
"embla-carousel": "^8.6.0",
|
"embla-carousel": "^8.6.0",
|
||||||
"eslint": "^9.26.0",
|
"eslint": "^9.27.0",
|
||||||
"happy-dom": "^17.4.7",
|
"happy-dom": "^17.4.7",
|
||||||
"nuxt": "^3.17.3",
|
"nuxt": "^3.17.3",
|
||||||
"release-it": "^19.0.2",
|
"release-it": "^19.0.2",
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
"typecheck": "nuxt typecheck"
|
"typecheck": "nuxt typecheck"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iconify-json/lucide": "^1.2.43",
|
"@iconify-json/lucide": "^1.2.44",
|
||||||
"@iconify-json/simple-icons": "^1.2.34",
|
"@iconify-json/simple-icons": "^1.2.34",
|
||||||
"@nuxt/ui": "latest",
|
"@nuxt/ui": "latest",
|
||||||
"@nuxthub/core": "^0.8.27",
|
"@nuxthub/core": "^0.8.27",
|
||||||
|
|||||||
1072
pnpm-lock.yaml
generated
1072
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@ import icons from './theme/icons'
|
|||||||
|
|
||||||
import { pick } from './runtime/utils'
|
import { pick } from './runtime/utils'
|
||||||
|
|
||||||
export const getDefaultUiConfig = (colors?: string[]) => ({
|
export const getDefaultUiConfig = (colors?: string[], csp?: { nonce?: string }) => ({
|
||||||
colors: pick({
|
colors: pick({
|
||||||
primary: 'green',
|
primary: 'green',
|
||||||
secondary: 'blue',
|
secondary: 'blue',
|
||||||
@@ -12,7 +12,10 @@ export const getDefaultUiConfig = (colors?: string[]) => ({
|
|||||||
error: 'red',
|
error: 'red',
|
||||||
neutral: 'slate'
|
neutral: 'slate'
|
||||||
}, [...(colors || []), 'neutral' as any]),
|
}, [...(colors || []), 'neutral' as any]),
|
||||||
icons
|
icons,
|
||||||
|
csp: csp || {
|
||||||
|
nonce: ''
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export const defaultOptions = {
|
export const defaultOptions = {
|
||||||
@@ -22,6 +25,9 @@ export const defaultOptions = {
|
|||||||
theme: {
|
theme: {
|
||||||
colors: undefined,
|
colors: undefined,
|
||||||
transitions: true
|
transitions: true
|
||||||
|
},
|
||||||
|
csp: {
|
||||||
|
nonce: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,19 @@ export interface ModuleOptions {
|
|||||||
*/
|
*/
|
||||||
colorMode?: boolean
|
colorMode?: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure Content Security Policy for Nuxt UI
|
||||||
|
* @defaultValue `{ nonce: '' }`
|
||||||
|
* @link https://ui.nuxt.com/getting-started/installation/nuxt#csp
|
||||||
|
*/
|
||||||
|
csp?: {
|
||||||
|
/**
|
||||||
|
* Enable nonce for inline styles.
|
||||||
|
* @defaultValue ``
|
||||||
|
*/
|
||||||
|
nonce?: string
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Customize how the theme is generated
|
* Customize how the theme is generated
|
||||||
* @link https://ui.nuxt.com/getting-started/theme
|
* @link https://ui.nuxt.com/getting-started/theme
|
||||||
@@ -70,7 +83,7 @@ export default defineNuxtModule<ModuleOptions>({
|
|||||||
|
|
||||||
nuxt.options.alias['#ui'] = resolve('./runtime')
|
nuxt.options.alias['#ui'] = resolve('./runtime')
|
||||||
|
|
||||||
nuxt.options.appConfig.ui = defu(nuxt.options.appConfig.ui || {}, getDefaultUiConfig(options.theme.colors))
|
nuxt.options.appConfig.ui = defu(nuxt.options.appConfig.ui || {}, getDefaultUiConfig(options.theme.colors, options.csp))
|
||||||
|
|
||||||
// Isolate root node from portaled components
|
// Isolate root node from portaled components
|
||||||
nuxt.options.app.rootAttrs = nuxt.options.app.rootAttrs || {}
|
nuxt.options.app.rootAttrs = nuxt.options.app.rootAttrs || {}
|
||||||
|
|||||||
@@ -21,9 +21,11 @@ export { default as hy } from './hy'
|
|||||||
export { default as id } from './id'
|
export { default as id } from './id'
|
||||||
export { default as it } from './it'
|
export { default as it } from './it'
|
||||||
export { default as ja } from './ja'
|
export { default as ja } from './ja'
|
||||||
export { default as km } from './km'
|
|
||||||
export { default as kk } from './kk'
|
export { default as kk } from './kk'
|
||||||
|
export { default as km } from './km'
|
||||||
export { default as ko } from './ko'
|
export { default as ko } from './ko'
|
||||||
|
export { default as lt } from './lt'
|
||||||
|
export { default as ms } from './ms'
|
||||||
export { default as nb_no } from './nb_no'
|
export { default as nb_no } from './nb_no'
|
||||||
export { default as nl } from './nl'
|
export { default as nl } from './nl'
|
||||||
export { default as pl } from './pl'
|
export { default as pl } from './pl'
|
||||||
@@ -37,8 +39,8 @@ export { default as sv } from './sv'
|
|||||||
export { default as th } from './th'
|
export { default as th } from './th'
|
||||||
export { default as tj } from './tj'
|
export { default as tj } from './tj'
|
||||||
export { default as tr } from './tr'
|
export { default as tr } from './tr'
|
||||||
export { default as uk } from './uk'
|
|
||||||
export { default as ug_cn } from './ug_cn'
|
export { default as ug_cn } from './ug_cn'
|
||||||
|
export { default as uk } from './uk'
|
||||||
export { default as ur } from './ur'
|
export { default as ur } from './ur'
|
||||||
export { default as uz } from './uz'
|
export { default as uz } from './uz'
|
||||||
export { default as vi } from './vi'
|
export { default as vi } from './vi'
|
||||||
|
|||||||
56
src/runtime/locale/lt.ts
Normal file
56
src/runtime/locale/lt.ts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import type { Messages } from '../types'
|
||||||
|
import { defineLocale } from '../composables/defineLocale'
|
||||||
|
|
||||||
|
export default defineLocale<Messages>({
|
||||||
|
name: 'Lietuvių',
|
||||||
|
code: 'lt',
|
||||||
|
messages: {
|
||||||
|
inputMenu: {
|
||||||
|
noMatch: 'Nėra atitinkančių duomenų',
|
||||||
|
noData: 'Nėra duomenų',
|
||||||
|
create: 'Sukurti „{label}“'
|
||||||
|
},
|
||||||
|
calendar: {
|
||||||
|
prevYear: 'Ankstesni metai',
|
||||||
|
nextYear: 'Kiti metai',
|
||||||
|
prevMonth: 'Ankstesnis mėnuo',
|
||||||
|
nextMonth: 'Kitas mėnuo'
|
||||||
|
},
|
||||||
|
inputNumber: {
|
||||||
|
increment: 'Padidinti',
|
||||||
|
decrement: 'Sumažinti'
|
||||||
|
},
|
||||||
|
commandPalette: {
|
||||||
|
placeholder: 'Įveskite komandą arba ieškokite...',
|
||||||
|
noMatch: 'Nėra atitinkančių duomenų',
|
||||||
|
noData: 'Nėra duomenų',
|
||||||
|
close: 'Uždaryti'
|
||||||
|
},
|
||||||
|
selectMenu: {
|
||||||
|
noMatch: 'Nėra atitinkančių duomenų',
|
||||||
|
noData: 'Nėra duomenų',
|
||||||
|
create: 'Sukurti „{label}“',
|
||||||
|
search: 'Ieškoti...'
|
||||||
|
},
|
||||||
|
toast: {
|
||||||
|
close: 'Uždaryti'
|
||||||
|
},
|
||||||
|
carousel: {
|
||||||
|
prev: 'Atgal',
|
||||||
|
next: 'Pirmyn',
|
||||||
|
goto: 'Eiti į skaidrę {slide}'
|
||||||
|
},
|
||||||
|
modal: {
|
||||||
|
close: 'Uždaryti'
|
||||||
|
},
|
||||||
|
slideover: {
|
||||||
|
close: 'Uždaryti'
|
||||||
|
},
|
||||||
|
alert: {
|
||||||
|
close: 'Uždaryti'
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
noData: 'Nėra duomenų'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
56
src/runtime/locale/ms.ts
Normal file
56
src/runtime/locale/ms.ts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import type { Messages } from '../types'
|
||||||
|
import { defineLocale } from '../composables/defineLocale'
|
||||||
|
|
||||||
|
export default defineLocale<Messages>({
|
||||||
|
name: 'Melayu',
|
||||||
|
code: 'ms',
|
||||||
|
messages: {
|
||||||
|
inputMenu: {
|
||||||
|
noMatch: 'Tiada data yang sepadan',
|
||||||
|
noData: 'Tiada data',
|
||||||
|
create: 'Cipta "{label}"'
|
||||||
|
},
|
||||||
|
calendar: {
|
||||||
|
prevYear: 'Tahun sebelum',
|
||||||
|
nextYear: 'Tahun seterusnya',
|
||||||
|
prevMonth: 'Bulan sebelum',
|
||||||
|
nextMonth: 'Bulan seterusnya'
|
||||||
|
},
|
||||||
|
inputNumber: {
|
||||||
|
increment: 'Naikkan',
|
||||||
|
decrement: 'Kurangkan'
|
||||||
|
},
|
||||||
|
commandPalette: {
|
||||||
|
placeholder: 'Taip arahan atau carian...',
|
||||||
|
noMatch: 'Tiada data yang sepadan',
|
||||||
|
noData: 'Tiada data',
|
||||||
|
close: 'Tutup'
|
||||||
|
},
|
||||||
|
selectMenu: {
|
||||||
|
noMatch: 'Tiada data yang sepadan',
|
||||||
|
noData: 'Tiada data',
|
||||||
|
create: 'Cipta "{label}"',
|
||||||
|
search: 'Cari...'
|
||||||
|
},
|
||||||
|
toast: {
|
||||||
|
close: 'Tutup'
|
||||||
|
},
|
||||||
|
carousel: {
|
||||||
|
prev: 'Sebelum',
|
||||||
|
next: 'Seterusnya',
|
||||||
|
goto: 'Pergi ke slaid {slide}'
|
||||||
|
},
|
||||||
|
modal: {
|
||||||
|
close: 'Tutup'
|
||||||
|
},
|
||||||
|
slideover: {
|
||||||
|
close: 'Tutup'
|
||||||
|
},
|
||||||
|
alert: {
|
||||||
|
close: 'Tutup'
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
noData: 'Tiada data'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -23,6 +23,8 @@ export default defineNuxtPlugin(() => {
|
|||||||
const appConfig = useAppConfig()
|
const appConfig = useAppConfig()
|
||||||
const nuxtApp = useNuxtApp()
|
const nuxtApp = useNuxtApp()
|
||||||
|
|
||||||
|
const nonce = computed(() => appConfig.ui?.csp?.nonce)
|
||||||
|
|
||||||
const root = computed(() => {
|
const root = computed(() => {
|
||||||
const { neutral, ...colors } = appConfig.ui.colors
|
const { neutral, ...colors } = appConfig.ui.colors
|
||||||
|
|
||||||
@@ -44,7 +46,8 @@ export default defineNuxtPlugin(() => {
|
|||||||
style: [{
|
style: [{
|
||||||
innerHTML: () => root.value,
|
innerHTML: () => root.value,
|
||||||
tagPriority: -2,
|
tagPriority: -2,
|
||||||
id: 'nuxt-ui-colors'
|
id: 'nuxt-ui-colors',
|
||||||
|
...(nonce.value ? { nonce: nonce.value } : {})
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,10 +57,15 @@ export default defineNuxtPlugin(() => {
|
|||||||
|
|
||||||
style.innerHTML = root.value
|
style.innerHTML = root.value
|
||||||
style.setAttribute('data-nuxt-ui-colors', '')
|
style.setAttribute('data-nuxt-ui-colors', '')
|
||||||
|
|
||||||
|
if (nonce.value) {
|
||||||
|
style.setAttribute('nonce', nonce.value)
|
||||||
|
}
|
||||||
document.head.appendChild(style)
|
document.head.appendChild(style)
|
||||||
|
|
||||||
headData.script = [{
|
headData.script = [{
|
||||||
innerHTML: 'document.head.removeChild(document.querySelector(\'[data-nuxt-ui-colors]\'))'
|
innerHTML: 'document.head.removeChild(document.querySelector(\'[data-nuxt-ui-colors]\'))',
|
||||||
|
...(nonce.value ? { nonce: nonce.value } : {})
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -165,6 +165,9 @@ type AppConfigUI = {
|
|||||||
}
|
}
|
||||||
icons?: Partial<typeof icons>
|
icons?: Partial<typeof icons>
|
||||||
tv?: typeof defaultConfig
|
tv?: typeof defaultConfig
|
||||||
|
csp?: {
|
||||||
|
nonce?: string
|
||||||
|
}
|
||||||
} & TVConfig<typeof ui>
|
} & TVConfig<typeof ui>
|
||||||
|
|
||||||
declare module '@nuxt/schema' {
|
declare module '@nuxt/schema' {
|
||||||
|
|||||||
Reference in New Issue
Block a user