feat: replace nuxt icons with unocss icons

This commit is contained in:
Zoe
2026-02-26 14:51:07 -06:00
parent 3ff0bcce19
commit 97afa1cbe1
30 changed files with 107 additions and 114 deletions
+2 -2
View File
@@ -195,8 +195,8 @@ onUnmounted(() => {
: 'text-[var(--text-dim)]',
loading && 'bg-[var(--color-hover)] hover:bg-[var(--color-active)]',
]">
<Icon v-if="loading" name="mynaui:stop-solid" class="text-6.5" />
<Icon v-else name="mynaui:send-solid" class="text-5" />
<span v-if="loading" class="text-6.5 i-mynaui-stop-solid"></span>
<span v-else class="text-5 i-mynaui-send-solid"></span>
</button>
</div>
</div>
+6 -6
View File
@@ -11,23 +11,23 @@ const { providers } = useModels();
const PAGES_CONFIG = {
general: {
label: 'General',
icon: 'mynaui:cog-four',
icon: 'i-mynaui-cog-four',
component: GeneralSettings
},
appearance: {
label: 'Appearance',
icon: 'tabler:palette',
icon: 'i-tabler-palette',
component: AppearanceSettings
},
providers: {
label: 'AI Providers',
icon: 'mynaui:api',
icon: 'i-mynaui-api',
component: ProviderSettings,
sidebar: ProviderSidebar
},
systemAssistants: {
label: 'System Assistants',
icon: 'mynaui:sparkles',
icon: 'i-mynaui-sparkles',
component: SystemAssistants
},
} as const;
@@ -79,7 +79,7 @@ const runtimePage = computed(() => {
<button v-else v-for="(config, id) in PAGES_CONFIG" :key="id" @click="setOptions({ page: id })"
:class="[page === id ? 'bg-[var(--color-hover)]' : 'hover:bg-[var(--color-hover)]', 'flex justify-between items-center shrink-0 px-1 rounded-lg transition-colors cursor-pointer h-9']">
<div class="flex items-center gap-2 max-w-full flex-1">
<Icon :name="config.icon" class="w-5 h-5" />
<span :class="['w-5 h-5 text-5', config.icon]"></span>
{{ config.label }}
</div>
</button>
@@ -93,7 +93,7 @@ const runtimePage = computed(() => {
<button
class="hover:bg-[var(--color-hover)] p-1.5 rounded-md transition-colors duration-200 ease-[cubic-bezier(0,0.55,0.45,1)]"
@click="close">
<Icon name="mynaui:x-solid" />
<span class="i-mynaui-x-solid"></span>
</button>
</header>
<component @navigate="(p: string, params?: string) => setOptions({ page: p, params })"
+2 -2
View File
@@ -21,9 +21,9 @@ useClickOutside(menuRef, closeDropdown);
<button v-for="item in currentItems" @click="item.onClick(); closeDropdown()" :disabled="item.disabled"
class="disabled:opacity-50 disabled:cursor-not-allowed items-center gap-1 text-left px-3 py-1.5 text-sm hover:bg-[var(--color-hover)] rounded-lg transition-colors duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]"
:class="{ 'text-red-600 hover:bg-red-600/20': item.danger, 'text-primary bg-[var(--color-hover)]': item.active }">
<Icon v-if="item.icon" :name="item.icon" class="w-4 h-4 flex-shrink-0" />
<span v-if="item.icon" :class="['w-4 h-4 shrink-0', item.icon]"></span>
<span class="text-sm whitespace-nowrap text-ellipsis max-w-full overflow-hidden">{{ item.label
}}</span>
}}</span>
</button>
</div>
</Transition>
+6 -5
View File
@@ -74,15 +74,16 @@ console.log("shiki codeblock rendered in", Date.now() - start);
<div class="flex gap-2">
<button @click="copyCode()"
class="flex items-center px-1 gap-0.5 rounded-md hover:bg-[var(--color-hover)] transition-colors duration-150 ease-[cubic-bezier(0.5,_1,_0.89,_1)]">
Copy
<Icon v-if="!copied" name="mynaui:copy" class="text-4 text-[var(--text-secondary)]" />
<Icon v-else name="mynaui:check" class="text-4 text-emerald-500" />
{{ copied ? 'Copied' : 'Copy' }}
<span v-if="!copied" class="i-mynaui-copy text-4 text-[var(--text-secondary)]"></span>
<span v-else class="i-mynaui-check text-4 text-emerald-500"></span>
</button>
<button @click="collapsed = !collapsed"
class="flex items-center justify-center h-5.5 w-5.5 rounded-md hover:bg-[var(--color-hover)] transition-colors duration-150 ease-[cubic-bezier(0.5,_1,_0.89,_1)]">
<Icon name="mynaui:chevron-down"
:class="['text-4 h-4 w-4 text-[var(--text-secondary)] transition-transform duration-150 ease-[cubic-bezier(0.5,_1,_0.89,_1)]', collapsed ? '-rotate-90' : '']" />
<span
class="i-mynaui-chevron-down text-4 h-4 w-4 text-[var(--text-secondary)] transition-transform duration-150 ease-[cubic-bezier(0.5,_1,_0.89,_1)]"
:class="collapsed ? '-rotate-90' : ''"></span>
</button>
</div>
</div>
+3 -2
View File
@@ -59,11 +59,12 @@ const toggleReasoning = async () => {
<span class="flex items-center gap-1">
<span
class="w-[24px] h-[24px] flex-shrink-0 rounded-lg overflow-hidden bg-[var(--bg-surface)] flex items-center justify-center">
<Icon name="mynaui:atom" class="w-3 h-3 text-[var(--reasoning-accent)]" />
<span class="i-mynaui-atom text-2.5 text-[var(--reasoning-accent)]"></span>
</span>
Deep Thinking
</span>
<Icon name="mynaui:chevron-down" :class="['w-4 h-4', reasoningOpen ? '' : '-rotate-90']" />
<span class="i-mynaui-chevron-down w-4 h-4 text-[var(--text-secondary)]"
:class="reasoningOpen ? '' : '-rotate-90'"></span>
</button>
<div v-if="reasoningOpen" ref="containerRef" @scroll="handleScroll"
:class="['reasoning-contaizner max-h-[min(40vh,320px)] overflow-y-auto [scrollbar-width:thin] [scrollbar-color:#888_transparent] [scrollbar-gutter:stable]', scrollState]">
+4 -4
View File
@@ -117,7 +117,7 @@ watch(
]">
<div
class="w-[24px] h-[24px] flex-shrink-0 rounded-lg overflow-hidden flex items-center justify-center">
<Icon name="mynaui:code" class="w-4.5 h-4.5" />
<span class="i-mynaui-code w-4.5 h-4.5"></span>
</div>
Input
</button>
@@ -128,7 +128,7 @@ watch(
]">
<div
class="w-[24px] h-[24px] flex-shrink-0 rounded-lg overflow-hidden flex items-center justify-center">
<Icon name="mynaui:arrow-down-square" class="w-4.5 h-4.5" />
<span class="i-mynaui-arrow-down-square w-4.5 h-4.5"></span>
</div>
Output
</button>
@@ -138,7 +138,7 @@ watch(
]">
<div
class="w-[24px] h-[24px] flex-shrink-0 rounded-lg overflow-hidden flex items-center justify-center">
<Icon name="mynaui:danger-triangle" class="w-4.5 h-4.5" />
<span class="i-mynaui-danger-triangle w-4.5 h-4.5"></span>
</div>
Error
</button>
@@ -148,7 +148,7 @@ watch(
]">
<div
class="w-[24px] h-[24px] flex-shrink-0 rounded-lg overflow-hidden flex items-center justify-center">
<Icon name="mynaui:flask" class="w-4.5 h-4.5" />
<span class="i-mynaui-flask w-4.5 h-4.5"></span>
</div>
Function call
</button>
+6 -7
View File
@@ -22,12 +22,11 @@ const toggleDebugToolCall = () => {
<div class="flex items-center gap-1">
<div
class="w-[24px] h-[24px] flex-shrink-0 rounded-lg overflow-hidden bg-[var(--bg-surface)] flex items-center justify-center">
<!-- Explicityly avoid setting the name via a reactive value, otherwise you risk corrupting the icon with that name globally -->
<Icon v-if="toolCall.status === 'pending'" name="svg-spinners:180-ring-with-bg"
class="w-3 h-3 text-[var(--text-secondary)]" />
<Icon v-else-if="toolCall.status === 'failed'" name="mynaui:x-solid"
class="w-3 h-3 text-[#ff3b3b]" />
<Icon v-else name="mynaui:tool" class="w-3 h-3 text-[var(--text-secondary)]" />
<span class="w-3 h-3" :class="{
'i-svg-spinners-180-ring-with-bg': toolCall.status === 'pending',
'i-mynaui-x-solid text-[#ff3b3b]': toolCall.status === 'failed',
'i-mynaui-tool': toolCall.status !== 'pending' && toolCall.status !== 'failed',
}"></span>
</div>
{{ toolCall.toolName }}
</div>
@@ -36,7 +35,7 @@ const toggleDebugToolCall = () => {
class="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]">
<button @click="toggleDebugToolCall"
class="w-[24px] h-[24px] flex-shrink-0 rounded-lg overflow-hidden hover:bg-[var(--color-hover)] flex items-center justify-center transition-colors duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]">
<Icon name="mynaui:search" class="w-3 h-3 text-[var(--text-secondary)]" />
<span class="i-mynaui-search w-3 h-3 text-[var(--text-secondary)]"></span>
</button>
</div>
</div>
+2 -2
View File
@@ -23,7 +23,7 @@ defineProps<{
<span class="flex items-center gap-1"
v-if="message.generation?.status === 'pending' && (message.parts || []).length === 0">
<Icon name="svg-spinners:pulse-2" class="text-4" />
<span class="i-svg-spinners-pulse-2 text-4"></span>
<span class="text-sm text-[var(--text-secondary)]">
Preparing generating...
</span>
@@ -42,7 +42,7 @@ defineProps<{
<div class="flex gap-2">
<span class="flex gap-1 items-center" v-if="message.generation.tokens?.output">
<Icon name="tabler:coins" />
<span class="i-tabler-coins"></span>
{{ message.generation?.tokens?.output }}
</span>
+8 -7
View File
@@ -139,14 +139,15 @@ const messageCount = computed(() => {
<div>
<div v-if="messageCount > 1" class="flex gap-1">
<button :inert="focusedIndex === 0" @click="focusedIndex = focusedIndex! - 1">
<Icon name="mynaui:chevron-left" :class="['w-4 h-4', focusedIndex === 0 ? 'opacity-0' : '']" />
<span class="i-mynaui-chevron-left w-4 h-4 text-[var(--text-secondary)]"
:class="focusedIndex === 0 ? 'opacity-0' : ''"></span>
</button>
<span class="text-xs text-[var(--text-secondary)]">
{{ focusedIndex + 1 }} / {{ messageCount }}
</span>
<button :inert="focusedIndex + 1 === messageCount" @click="focusedIndex = focusedIndex + 1">
<Icon name="mynaui:chevron-right"
:class="['w-4 h-4', focusedIndex + 1 === messageCount ? 'opacity-0' : '']" />
<span class="i-mynaui-chevron-right w-4 h-4 text-[var(--text-secondary)]"
:class="focusedIndex + 1 === messageCount ? 'opacity-0' : ''"></span>
</button>
</div>
</div>
@@ -155,19 +156,19 @@ const messageCount = computed(() => {
class="self-end mt-1 w-fit bg-[var(--bg-container)] text-[var(--text-secondary)] gap-px flex items-center rounded-md overflow-hidden opacity-0 group-hover:opacity-100 transition-opacity duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]">
<button @click="regenerateMessage"
class="flex justify-center items-center w-7 h-6 hover:bg-[var(--color-hover)]">
<Icon name="mynaui:refresh" class="text-4.5" />
<span class="i-mynaui-refresh text-4.5"></span>
</button>
<button v-if="message.role === 'user'" @click="handleEdit"
class="flex justify-center items-center w-7 h-6 hover:bg-[var(--color-hover)]">
<Icon name="mynaui:pencil" class="text-4.5" />
<span class="i-mynaui-pencil text-4.5"></span>
</button>
<button @click="copyMessage" :class="{ 'text-emerald-500': copied }"
class="flex justify-center items-center w-7 h-6 hover:bg-[var(--color-hover)]">
<Icon :name="copied ? 'mynaui:check' : 'mynaui:copy'" class="text-4.5" />
<span :class="copied ? 'i-mynaui-check text-emerald-500' : 'i-mynaui-copy text-4.5'"></span>
</button>
<button @click="deleteMessage"
class="flex justify-center items-center w-7 h-6 text-red-500 hover:bg-[var(--color-hover)]">
<Icon name="mynaui:trash" class="text-5" />
<span class="i-mynaui-trash text-5"></span>
</button>
</div>
</div>
+1 -1
View File
@@ -18,7 +18,7 @@ const config = computed(() => getModelConfig(props.modelId));
<!-- Fallback if no logo matches -->
<div v-else :style="{ width: `${props.size}px`, height: `${props.size}px` }"
class="bg-[var(--bg-container)] rounded-md flex items-center justify-center">
<Icon name="tabler:brain" class="text-5 text-[var(--text-secondary)]" />
<span class="i-tabler-brain text-5 text-[var(--text-secondary)]"></span>
</div>
</div>
</template>
+4 -4
View File
@@ -72,7 +72,7 @@ const deleteModel = async () => {
<div v-if="showEdit" class="flex items-center gap-2">
<button @click="deleteModel"
class="rounded h-5 w-5 flex items-center justify-center opacity-0 group-hover:opacity-100 hover:bg-red-500/30 text-red-500 trannsition-all duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]">
<Icon name="mynaui:trash" class="text-3.5" />
<span class="i-mynaui-trash text-3.5"></span>
</button>
</div>
</div>
@@ -104,15 +104,15 @@ const deleteModel = async () => {
<div class="flex items-center gap-0.5">
<div v-if="hasInputModality('image')"
class="w-4.5 h-4.5 bg-emerald/10 rounded flex items-center justify-center">
<Icon name="mynaui:image" class="text-2.5 text-emerald" title="Vision" />
<span class="i-mynaui-image text-2.5 text-emerald" title="Vision"></span>
</div>
<div v-if="hasCapability('reasoning')"
class="w-4.5 h-4.5 bg-[color-mix(in_srgb,_transparent_90%,_var(--reasoning-accent)_10%)] rounded flex items-center justify-center">
<Icon name="mynaui:atom" class="text-2.5 text-[var(--reasoning-accent)]" title="Reasoning" />
<span class="i-mynaui-atom text-2.5 text-[var(--reasoning-accent)]" title="Reasoning"></span>
</div>
<div v-if="hasCapability('tools')"
class="w-4.5 h-4.5 bg-emerald/10 rounded flex items-center justify-center">
<Icon name="mynaui:tool" class="text-2.5 text-sky" title="Tools" />
<span class="i-mynaui-tool text-2.5 text-sky" title="Tools"></span>
</div>
</div>
+7 -7
View File
@@ -239,8 +239,8 @@ onUnmounted(() => {
<span class="max-w-fulltruncate">
{{ selectedModel ? selectedModel.name : 'Select a model' }}
</span>
<Icon name="mynaui:chevron-down" class="text-3.5 transition-transform duration-200"
:class="{ 'rotate-180': modelSelectorState.open }" />
<span class="i-mynaui-chevron-down text-3.5 transition-transform duration-200"
:class="{ 'rotate-180': modelSelectorState.open }"></span>
</div>
@@ -263,8 +263,8 @@ onUnmounted(() => {
:class="modelSelectorState.direction === 'up' ? 'transform-origin-bottom-center' : 'transform-origin-top-center'">
<div>
<div class="relative">
<Icon name="mynaui:search"
class="absolute left-3 top-1/2 -translate-y-1/2 text-4 text-[var(--text-secondary)]" />
<span
class="i-mynaui-search absolute left-3 top-1/2 -translate-y-1/2 text-4 text-[var(--text-secondary)]"></span>
<input ref="searchInputRef" v-model="searchQuery" autocomplete="off" name="search"
@keydown="handleSearchKeyDown" type="text" placeholder="Search models..."
class="placeholder:text-[var(--text-tertiary)] w-full pl-9 pr-3 py-2 text-sm text-[var(--text-primary)] bg-transparent placeholder-[var(--text-secondary)] outline-none" />
@@ -285,7 +285,7 @@ onUnmounted(() => {
<button
@click="modelSelectorState.open = true; openDialog(DialogType.Settings, undefined, { page: 'providers', params: provider.id })"
class="flex h-5 w-5 items-center justify-center hover:bg-[var(--color-hover)] rounded transition-colors duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]">
<Icon name="mynaui:cog-four" class="text-4" />
<span class="i-mynaui-cog-four text-4"></span>
</button>
</div>
@@ -307,9 +307,9 @@ onUnmounted(() => {
<button
class="flex w-full items-center gap-2 px-3 py-2 text-sm text-[var(--text-secondary)] hover:text-[var(--text-primary)] hover:bg-[var(--color-hover)] rounded-lg transition-colors duration-150"
@click="modelSelectorState.open = false; openDialog(DialogType.Settings, undefined, { page: 'providers' });">
<Icon name="mynaui:cog-four" class="text-4.5" />
<span class="i-mynaui-cog-four text-4.5"></span>
<span>Manage Providers</span>
<Icon name="mynaui:arrow-right" class="text-4 ml-auto" />
<span class="i-mynaui-arrow-right text-4 ml-auto"></span>
</button>
</div>
</div>
@@ -210,7 +210,7 @@ defineEmits(['navigate']);
@input="updateApiKey(($event.target! as HTMLInputElement).value)" />
<button @click="apiKeyVisible = !apiKeyVisible"
class="text-sm p-2 text-[var(--text-secondary)] hover:text-[var(--text-primary)]">
<Icon :name="apiKeyVisible ? 'mynaui:eye' : 'mynaui:eye-slash'" class="text-4 min-h-4 min-w-4" />
<span class="text-4" :class="apiKeyVisible ? 'i-mynaui-eye' : 'i-mynaui-eye-slash'"></span>
</button>
</div>
</div>
@@ -227,8 +227,8 @@ defineEmits(['navigate']);
<div class="flex flex-row justify-center text-xs">
<p class="text-[var(--text-secondary)]">
<Icon name="mynaui:lock" /> Your API key is encrypted using <a
href="https://datatracker.ietf.org/doc/html/draft-ietf-avt-srtp-aes-gcm-01">AES-GCM</a> encryption.
<span class="i-mynaui-lock inline-block"></span> Your API key is encrypted using
<a href="https://datatracker.ietf.org/doc/html/draft-ietf-avt-srtp-aes-gcm-01">AES-GCM</a> encryption.
</p>
</div>
@@ -240,7 +240,7 @@ defineEmits(['navigate']);
{{ provider?.models.length }} models available <button
class="p-0.5 hover:bg-[var(--color-hover)] rounded transition-colors duration-200"
@click="deleteModels">
<Icon name="mynaui:x-solid" />
<span class="i-mynaui-x-solid"></span>
</button>
</span>
</h4>
@@ -251,20 +251,20 @@ defineEmits(['navigate']);
type="text" placeholder="Search models..." />
<button :class="modelSearch.length > 0 ? 'visible' : 'invisible'" @click="modelSearch = ''"
class="right-1 hover:bg-[var(--color-hover)] rounded transition-colors duration-200 p-0.5">
<Icon name="mynaui:x" class="text-3.5 block text-[var(--text-secondary)]" />
<span class="i-mynaui-x-solid text-3.5 block text-[var(--text-secondary)]"></span>
</button>
</div>
<button @click="fetchModels"
class="whitespace-nowrap flex bg-[var(--bg-container)] hover:bg-[var(--color-hover)] text-sm rounded-md items-center px-2 py-0.5 gap-2 transition-colors duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]">
<Icon :class="[fetchingModels ? 'animate-rotate' : '']" name="mynaui:refresh" />
<span class="i-mynaui-refresh" :class="{ 'animate-rotate': fetchingModels }"></span>
fetch models
</button>
</div>
</div>
<div v-if="provider?.models?.length === 0" class="flex flex-row items-center justify-center gap-2 mt-2">
<Icon name="mynaui:info-circle" class="text-4" />
<span class="i-mynaui-info-circle text-4"></span>
<span class="text-sm text-[var(--text-secondary)]">
No models found
</span>
@@ -29,19 +29,19 @@ defineEmits(['navigate']);
<button @click="updateSettings({ appearance: { colorScheme: 'system' } })"
class="flex items-center gap-1 px-1 rounded-md hover:bg-[var(--color-hover)] transition-[background-color] duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]"
:class="colorScheme.preference.value === 'system' ? 'bg-[var(--color-hover)]' : ''">
<Icon name="tabler:device-desktop" class="text-4" />
<span class="i-tabler-device-desktop text-4"></span>
<span>System</span>
</button>
<button @click="updateSettings({ appearance: { colorScheme: 'dark' } })"
class="flex items-center gap-1 px-1 rounded-md hover:bg-[var(--color-hover)] transition-[background-color] duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]"
:class="colorScheme.preference.value === 'dark' ? 'bg-[var(--color-hover)]' : ''">
<Icon name="mynaui:moon" class="text-4" />
<span class="i-mynaui-moon text-4"></span>
<span>Dark</span>
</button>
<button @click="updateSettings({ appearance: { colorScheme: 'light' } })"
class="flex items-center gap-1 px-1 rounded-md hover:bg-[var(--color-hover)] transition-[background-color] duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]"
:class="colorScheme.preference.value === 'light' ? 'bg-[var(--color-hover)]' : ''">
<Icon name="mynaui:sun" class="text-4" />
<span class="i-mynaui-sun text-4"></span>
<span>Light</span>
</button>
</div>
+2 -2
View File
@@ -13,12 +13,12 @@ defineEmits(['navigate']);
<div class="flex flex-col gap-1 overflow-auto">
<button @click="$emit('navigate', 'general')"
class="flex items-center gap-2 p-2 rounded-lg text-sm hover:bg-[var(--color-hover)] transition-colors duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]">
<Icon name="mynaui:chevron-left" class="text-4" /> Back to General
<span class="i-mynaui-chevron-left text-4"></span> Back to General
</button>
<button @click="$emit('navigate', 'providers')"
class="flex items-center gap-2 p-2 rounded-lg text-sm hover:bg-[var(--color-hover)] transition-colors duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]">
<Icon name="mynaui:envelope-open" class="text-4" /> All
<span class="i-mynaui-envelope-open text-4"></span> All
</button>
<div class="px-2 py-4 font-bold text-xs uppercase opacity-50">Enabled Providers</div>
+5 -17
View File
@@ -43,7 +43,7 @@ useClickOutside(dropdownRef, () => {
<div
:class="['w-[28px] h-[28px] flex-shrink-0 rounded-lg overflow-hidden bg-[var(--bg-surface)] flex items-center justify-center', user?.image ? '' : 'border border-[var(--color-border)]']">
<img v-if="cachedUser?.image" :src="cachedUser.image" class="w-full h-full object-cover" />
<Icon v-else name="mynaui:user" class="w-4 h-4 text-[var(--text-secondary)]" />
<span v-else class="i-mynaui-user text-4 text-[var(--text-secondary)]"></span>
</div>
<span
class="text-sm font-medium text-ellipsis overflow-hidden text-[var(--text-primary)] whitespace-nowrap">
@@ -52,8 +52,8 @@ useClickOutside(dropdownRef, () => {
<div :class="['transform-origin-left-center flex-shrink-0 w-4 h-4 text-[var(--text-secondary)] transition-all duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)] overflow-hidden transform-origin-center-left',
isHovered ? 'opacity-100 scale-100' : 'opacity-0 scale-40'
]">
<Icon class="text-4 transition-transform duration-250 ease-in-out"
:class="dropdownOpen ? 'rotate-180' : ''" name="mynaui:chevron-down" />
<span class="i-mynaui-chevron-down inline-block text-4 transition-transform duration-250 ease-in-out"
:class="dropdownOpen ? 'rotate-180' : ''"></span>
</div>
</button>
@@ -65,28 +65,16 @@ useClickOutside(dropdownRef, () => {
class="w-full top-full text-sm mt-1 absolute z-50 bg-[var(--bg-surface)] border border-[var(--color-border)] rounded-xl p-1.5 flex flex-col gap-2">
<button @click="dropdownOpen = false; toggleSettings()"
class="text-left px-3 py-1.5 items-center gap-1 hover:bg-[var(--color-hover)] rounded-lg transition-colors duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]">
<Icon name="mynaui:cog-four" class="text-4.5" />
<span class="i-mynaui-cog-four text-4.5"></span>
<span>Settings</span>
</button>
<hr class="border-t border-[var(--color-border)]" />
<button @click="handleLogout"
class="text-left px-3 py-1.5 items-center gap-1 hover:bg-[var(--color-hover)] rounded-lg transition-colors duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]">
<Icon name="mynaui:logout" class="text-4.5" />
<span class="i-mynaui-logout text-4.5"></span>
<span>Log out</span>
</button>
</div>
</Transition>
<!-- <Dropdown class="overflow-hidden" v-model="profileOpen" :items="profileItems" placement="left"
verticality="descending" width="100%">
<template #trigger="{ toggle }">
<button aria-label="open user dropdown"
class="flex items-center gap-1.5 pr-2 rounded-xl hover:bg-[var(--color-hover)] focus-visible:bg-[var(--color-hover)] cursor-pointer transition-colors max-w-full"
@click="toggle">
</button>
</template>
</Dropdown> -->
</header>
</template>
+5 -6
View File
@@ -21,7 +21,7 @@ const toggleDropdown = (e: MouseEvent) => {
for (const agent of agents.value || []) {
items.push({
label: agent.name,
icon: 'mynaui:check-hexagon',
icon: 'i-mynaui-check-hexagon',
active: activeAgent.value?.id === agent.id,
onClick: () => navigateTo(`/agent/${agent.id}`)
});
@@ -39,7 +39,7 @@ const toggleDropdown = (e: MouseEvent) => {
:class="['flex flex-shrink-0 transform-origin-left-center items-center overflow-hidden transition-all duration-150 ease-[cubic-bezier(0.5,_1,_0.89,_1)]', isHovered ? 'opacity-100 scale-100' : 'opacity-0 scale-95']">
<NuxtLink to="/"
class="flex hover:bg-[var(--color-hover)] focus-visible:bg-[var(--color-hover)] rounded-lg decoration-none transition-inherit text-[var(--text-secondary)] p-1.5">
<Icon name="mynaui:chevron-left" class="w-4.5 h-4.5" />
<span class="i-mynaui-chevron-left text-4.5"></span>
</NuxtLink>
</div>
@@ -50,16 +50,15 @@ const toggleDropdown = (e: MouseEvent) => {
<div
:class="['w-[28px] h-[28px] flex-shrink-0 rounded-lg overflow-hidden bg-[var(--bg-surface)] flex items-center justify-center', activeAgent?.imageUrl ? '' : 'border border-[var(--color-border)]']">
<img v-if="activeAgent?.imageUrl" :src="activeAgent.imageUrl" class="w-full h-full object-cover" />
<Icon v-else name="mynaui:check-hexagon" class="w-4 h-4 text-[var(--color-accent)]" />
<span v-else class="h-4 w-4 i-mynaui-check-hexagon text-[var(--color-accent)]"></span>
</div>
<span
class="min-w-0 text-sm font-medium text-ellipsis overflow-hidden text-[var(--text-primary)] whitespace-nowrap">
{{ activeAgent?.name }}
</span>
<div class="shrink-0 w-4 h-4 text-[var(--text-secondary)]">
<Icon
class="text-4 transform-origin-center-left duration-150 ease-[cubic-bezier(0.5,_1,_0.89,_1)] transition-all"
name="mynaui:chevron-up-down" />
<span
class="i-mynaui-chevron-up-down inline-block text-4 transform-origin-center-left duration-150 ease-[cubic-bezier(0.5,_1,_0.89,_1)] transition-all"></span>
</div>
</div>
</button>
+2 -2
View File
@@ -17,7 +17,7 @@ const props = defineProps<{
]">
<div class="flex items-center gap-2 max-w-full flex-1">
<div v-if="props.icon" class="h-7 w-7 flex items-center justify-center">
<Icon class="text-4.5" :name="props.icon" />
<span class="text-4.5" :class="props.icon"></span>
</div>
<div class="flex justify-between items-center w-full">
<span class="text-sm font-medium overflow-hidden text-ellipsis whitespace-nowrap">{{ props.name
@@ -35,7 +35,7 @@ const props = defineProps<{
]">
<div class="flex items-center gap-2 max-w-full flex-1">
<div v-if="props.icon" class="h-7 w-7 flex items-center justify-center">
<Icon class="text-4.5" :name="props.icon" />
<span class="text-4.5" :class="props.icon"></span>
</div>
<div class="flex justify-between items-center w-full">
<span class="text-sm font-medium overflow-hidden text-ellipsis whitespace-nowrap">{{ props.name
+6 -4
View File
@@ -170,14 +170,16 @@ onMounted(() => {
<!-- Agent Info Link -->
<div class="mt-2 flex flex-col">
<SidenavItem :to="`/agent/${agentId}/profile`" name="Agent Info" icon="mynaui:info-square"
<SidenavItem :to="`/agent/${agentId}/profile`" name="Agent Info" icon="i-mynaui-info-square"
:active="route.path.endsWith('/profile')" />
<!-- Topics Section -->
<button @click="topicsOpen = !topicsOpen"
class="flex items-center justify-between gap-2 px-2 py-2 rounded-lg bg-transparent hover:bg-[var(--color-hover)] focus-visible:bg-[var(--color-hover)] transition-colors w-full text-left">
<span class="text-sm font-medium">Topics</span>
<Icon name="mynaui:chevron-down" :class="['w-4 h-4', topicsOpen ? '' : '-rotate-90']" />
<span
class="i-mynaui-chevron-down inline-block text-4 transition-transform duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]"
:class="topicsOpen ? '' : '-rotate-90'"></span>
</button>
<Collapsible :is-open="topicsOpen">
@@ -194,7 +196,7 @@ onMounted(() => {
@blur="saveRename"
class="flex-1 bg-transparent border-none outline-none text-sm font-medium text-[var(--text-primary)] px-0 min-w-0" />
<div v-else-if="topic.renaming" class="flex w-full">
<Icon name="svg-spinners:3-dots-fade" class="text-6" />
<span class="i-svg-spinners-3-dots-fade text-6"></span>
</div>
<span v-else
class="text-sm font-medium overflow-hidden text-ellipsis whitespace-nowrap">
@@ -203,7 +205,7 @@ onMounted(() => {
<div data-action="toggle-dropdown"
class="text-[var(--text-secondary)] shrink-0 opacity-0 group-hover:opacity-100 p-1 flex items-center justify-center rounded-md hover:bg-[var(--color-hover)] focus-visible:bg-[var(--color-hover)] transition-opacity duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]">
<span class="h-4.5 w-4.5 i-tabler:dots"></span>
<span class="h-4.5 w-4.5 i-tabler-dots"></span>
</div>
</a>
</template>
+8 -7
View File
@@ -99,16 +99,17 @@ onMounted(() => {
<template>
<nav ref="navRef" class="flex flex-col gap-1 overflow-auto">
<SidenavItem name="Search" icon="mynaui:search" />
<SidenavItem to="/" name="Home" icon="mynaui:home" />
<SidenavItem name="Search" icon="i-mynaui-search" />
<SidenavItem to="/" name="Home" icon="i-mynaui-home" />
<!-- Header Toggle -->
<button
class="flex items-center justify-between gap-2 px-2 py-2 rounded-lg hover:bg-[var(--color-hover)] transition-colors w-full"
@click="toggleAgentsList">
<span class="text-sm">Agents</span>
<Icon name="mynaui:chevron-down" class="w-4 h-4 transition-transform duration-200"
:class="{ '-rotate-90': !agentsOpen }" />
<span
class="i-mynaui-chevron-down inline-block text-4 transition-transform duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]"
:class="{ '-rotate-90': !agentsOpen }"></span>
</button>
<!-- Animated Section -->
@@ -117,8 +118,8 @@ onMounted(() => {
<button @click="newAgent" :disabled="creatingAgent"
class="flex items-center gap-2 px-1 h-9 shrink-0 rounded-lg text-sm text-[var(--text-secondary)] hover:bg-[var(--color-hover)] transition-colors disabled:opacity-50 w-full">
<div class="h-7 w-7 flex items-center justify-center">
<Icon v-if="creatingAgent" class="text-4.5" name="svg-spinners:ring-resize" />
<Icon v-else class="text-4.5" name="mynaui:plus" />
<span v-if="creatingAgent" class="i-svg-spinners-ring-resize text-4.5"></span>
<span v-else class="i-mynaui-plus text-4.5"></span>
</div>
<span>New Agent</span>
</button>
@@ -140,7 +141,7 @@ onMounted(() => {
<div data-action="toggle-dropdown"
class="text-[var(--text-secondary)] shrink-0 opacity-0 group-hover:opacity-100 p-1 flex items-center justify-center rounded-md hover:bg-[var(--color-hover)] focus-visible:bg-[var(--color-hover)] transition-opacity duration-200 ease-[cubic-bezier(0.5,_1,_0.89,_1)]">
<span class="h-4.5 w-4.5 i-tabler:dots"></span>
<span class="h-4.5 w-4.5 i-tabler-dots"></span>
</div>
</a>
</template>
+5 -4
View File
@@ -122,15 +122,16 @@ const navKind = computed(() => {
<button aria-label="close sidebar" @click="closeSidebar" :class="[
'flex text-5 h-8 w-8 items-center justify-center hover:bg-[var(--color-hover)] focus-visible:bg-[var(--color-hover)] bg-transparent transition-inherit',
]">
<Icon name="mynaui:panel-left-close"
:class="['transition-inherit transform-origin-right-center', isHovering ? 'opacity-100 scale-100' : 'opacity-0 scale-95']" />
<span
class="i-mynaui-panel-left-close text-5 transition-inherit transform-origin-right-center"
:class="isHovering ? 'opacity-100 scale-100' : 'opacity-0 scale-95'"></span>
</button>
</div>
<div v-if="navKind === 'agent'" class="flex-shrink-0 overflow-hidden rounded-lg">
<NuxtLink aria-label="Start a new topic" :to="`/agent/${route.params.id}`" :class="[
'flex text-5 h-8 w-8 items-center justify-center hover:bg-[var(--color-hover)] focus-visible:bg-[var(--color-hover)] bg-transparent text-inherit',
]">
<Icon name="mynaui:book-plus" />
<span class="i-mynaui-book-plus text-5"></span>
</NuxtLink>
</div>
</div>
@@ -145,7 +146,7 @@ const navKind = computed(() => {
<div class="flex">
<button @click="openDialog(DialogType.Settings)"
class="flex items-center justify-center h-7 w-7 cursor-pointer hover:bg-[var(--color-hover)] focus-visible:bg-[var(--color-hover)] rounded-lg transition-colors text-[var(--text-secondary)] active:text-[var(--text-primary)]">
<Icon name="mynaui:cog-four" class="text-5" />
<span class="i-mynaui-cog-four text-5"></span>
</button>
</div>
+4 -4
View File
@@ -11,9 +11,9 @@ const selectTheme = (colorScheme: Theme) => {
};
const themeOptions: DropdownItem[] = [
{ id: 'light', label: 'Light', icon: 'mynaui:sun', onClick: () => selectTheme('light') },
{ id: 'dark', label: 'Dark', icon: 'mynaui:moon', onClick: () => selectTheme('dark') },
{ id: 'system', label: 'System', icon: 'mynaui:desktop', onClick: () => selectTheme('system') },
{ id: 'light', label: 'Light', icon: 'i-mynaui-sun', onClick: () => selectTheme('light') },
{ id: 'dark', label: 'Dark', icon: 'i-mynaui-moon', onClick: () => selectTheme('dark') },
{ id: 'system', label: 'System', icon: 'i-mynaui-desktop', onClick: () => selectTheme('system') },
];
const currentOption = computed(
@@ -35,6 +35,6 @@ const toggleDropdown = (e: MouseEvent) => {
<template>
<button aria-label="Open theme switcher" @click="toggleDropdown"
class="h-7 w-7 flex items-center justify-center rounded-lg hover:bg-[var(--color-hover)] focus-visible:bg-[var(--color-hover)] transition-colors active:text-[var(--text-primary)]">
<Icon :name="currentOption!.icon!" class="text-5 pointer-events-none" />
<span :class="['text-5 pointer-events-none', currentOption!.icon]"></span>
</button>
</template>
+1 -1
View File
@@ -82,7 +82,7 @@ const handleSubmit = async (message: string, model: ModelWithProvider | null) =>
<div class="flex items-center gap-2 max-w-full">
<button v-if="!sidebarOpen" @click="openSidebar"
class="flex p-2 rounded-lg text-[var(--text-primary)] bg-transparent hover:bg-[var(--color-hover)] transition-colors">
<Icon class="text-5" name="mynaui:panel-left-open" />
<span class="i-mynaui-panel-left-open text-5"></span>
</button>
<h4 class="text-lg text-ellipsis overflow-hidden whitespace-nowrap">
{{ agent?.name }}
+2 -2
View File
@@ -38,7 +38,7 @@ const changeSystemPrompt = async (e: Event) => {
<div class="flex items-center gap-2">
<button v-if="!sidebarOpen" @click="openSidebar"
class="flex p-2 rounded-lg text-[var(--text-primary)] bg-transparent hover:bg-[var(--color-hover)] transition-colors">
<Icon class="text-5" name="mynaui:panel-left-open" />
<span class="i-mynaui-panel-left-open text-5"></span>
</button>
</div>
</div>
@@ -47,7 +47,7 @@ const changeSystemPrompt = async (e: Event) => {
<div class="flex items-center gap-4">
<div>
<img v-if="agent?.imageUrl" :src="agent.imageUrl" class="w-16 h-16 rounded-full object-cover" />
<Icon v-else name="mynaui:check-hexagon" class="text-16" />
<span class="text-16 i-mynaui-check-hexagon"></span>
</div>
<input @input="handleInput" placeholder="Agent Name..."
class="placeholder:text-[var(--text-tertiary)] w-full bg-transparent rounded-none border-b-4 border-b-[var(--color-border)] text-12 p-0"
+1 -1
View File
@@ -365,7 +365,7 @@ onUnmounted(() => {
<div class="flex items-center gap-2 max-w-full">
<button v-if="!sidebarOpen" @click="openSidebar"
class="flex p-2 rounded-lg text-[var(--text-primary)] bg-transparent hover:bg-[var(--color-hover)] transition-colors">
<Icon class="text-5" name="mynaui:panel-left-open" />
<span class="i-mynaui-panel-left-open text-5"></span>
</button>
<h4 class="text-lg text-ellipsis overflow-hidden whitespace-nowrap">
{{ topic?.name }}
+1 -1
View File
@@ -111,7 +111,7 @@ const submit = async () => {
<input required minlength="8" maxlength="128" ref="passwordInputEl" type="password"
autocomplete="current-password" id="password" v-model="form.password" />
<button :disabled="!hydrated" class="accent" type="submit">
<Icon v-if="loading" class="text-6 h-6" name="svg-spinners:90-ring-with-bg" />
<span v-if="loading" class="i-svg-spinners-90-ring-with-bg text-6"></span>
<span v-else>Login</span>
</button>
</form>
+1 -1
View File
@@ -152,7 +152,7 @@ const submit = async () => {
<input required minlength="8" maxlength="128" ref="confirmPasswordInputEl" type="password"
autocomplete="new-password" id="confirmPassword" v-model="form.confirmPassword" />
<button :disabled="!hydrated" class="accent" type="submit">
<Icon v-if="loading" class="text-6 h-6" name="svg-spinners:90-ring-with-bg" />
<span v-if="loading" class="i-svg-spinners-90-ring-with-bg text-6"></span>
<span v-else>Register</span>
</button>
</form>
+1 -1
View File
@@ -162,7 +162,7 @@ onUnmounted(() => {
<div class="flex items-center gap-2">
<button v-if="!sidebarOpen" @click="openSidebar"
class="flex p-2 rounded-lg text-[var(--text-primary)] bg-transparent hover:bg-[var(--color-hover)] transition-colors">
<Icon class="text-5" name="mynaui:panel-left-open" />
<span class="i-mynaui-panel-left-open text-5"></span>
</button>
</div>
</div>
-1
View File
@@ -155,7 +155,6 @@ export default defineNuxtConfig({
modules: [
'@nuxt/hints',
'@nuxt/icon',
'@unocss/nuxt',
'triplit-nuxt',
// '@sentry/nuxt/module',
+2 -1
View File
@@ -1,4 +1,4 @@
import { defineConfig, presetMini, presetWebFonts } from 'unocss';
import { defineConfig, presetMini, presetIcons } from 'unocss';
export default defineConfig({
rules: [
@@ -8,5 +8,6 @@ export default defineConfig({
],
presets: [
presetMini(),
presetIcons()
],
});