Files
rhema-claw/web/claw/app/components/AgentAvatar.vue
T
vhaudiquet 81da26b955 feat(rhema-code): add the colors setting with four palettes
The stored `colors` key names a palette — rhema (the default,
Jadeite), aquamarine, black-and-white, or dracula — and the
Appearance page of /settings cycles it live, like the theme and
icon toggles beside it. Each palette carries a dark and a light
appearance under the existing `theme` key; dracula's light side is
derived, the official palette ships only dark.

The appearance decision moves off token comparison: Theme now
answers is_dark() from the ground/text luminance, so palettes
beyond the original two get the right per-profile fallback tones.
2026-10-17 04:28:31 +08:00

66 lines
1.6 KiB
Vue

<script setup lang="ts">
// The agent's face at one size. Two voices: `initials` (the chat, the
// sidebar, the rail's bottom — the avatar image when there is one, the
// initials when not) and `mark` (the rail's brand slot — the avatar
// image when there is one, the mark or emoji, ῥ by default). The
// precedence lives here and nowhere else.
const props = withDefaults(
defineProps<{
variant?: 'initials' | 'mark'
/** The uploaded avatar's object URL, when the claw has one. */
avatarUrl?: string | null
/** The glyph or emoji; the mark voice defaults to ῥ. */
mark?: string | null
/** The initials voice's fallback, first letter of the name or R. */
initials?: string | null
size?: number
}>(),
{
variant: 'initials',
avatarUrl: null,
mark: null,
initials: null,
size: 32,
},
)
const glyph = computed(() =>
props.variant === 'mark'
? props.mark?.trim() || 'ῥ'
: props.initials?.trim() || 'R',
)
</script>
<template>
<img
v-if="avatarUrl"
:src="avatarUrl"
:style="{ width: `${size}px`, height: `${size}px` }"
class="agent-avatar"
alt=""
/>
<span
v-else
class="agent-avatar agent-square"
:style="{ width: `${size}px`, height: `${size}px`, fontSize: `${Math.round(size * 0.5)}px` }"
aria-hidden="true"
>{{ glyph }}</span>
</template>
<style scoped>
.agent-avatar {
display: grid;
place-items: center;
flex: none;
border-radius: 25%;
object-fit: cover;
}
.agent-square {
background: var(--accent);
color: var(--on-accent);
font-weight: 700;
line-height: 1;
}
</style>