Style Customization
Vue 3 Widget provides multi-level style customization capabilities, from simple class name overrides to fully custom rendering.
Customization Levels
| Level | Method | Use Case |
|---|---|---|
| 1 | CSS class name override | Adjust colors, spacing, fonts, etc. |
| 2 | style property | Inline styles for individual components |
| 3 | Custom icons (slots) | Replace built-in icons |
| 4 | scoped slots rendering | Fully custom component structure |
CSS Class Name Override
Naming Convention
All components use BEM naming convention, prefixed with apk- (AaaS Pilot Kit):
.apk-{component-name} /* Block */
.apk-{component-name}__{element-name} /* Element */
.apk-{component-name}--{modifier} /* Modifier */
Example
/* Modify control panel background */
.apk-control-panel {
background: rgba(0, 0, 0, 0.8);
}
/* Modify input style */
.apk-control-panel__input {
border: 2px solid #007bff;
border-radius: 25px;
}
/* Modify mobile button size */
.apk-control-panel--mobile .apk-control-panel__mic-btn {
width: 60px;
height: 60px;
}
Component Class Name Quick Reference
PilotKit
| Class Name | Description |
|---|---|
.apk-pilot-kit | Root container |
.apk-pilot-kit__content | Content area |
ConversationList
| Class Name | Description |
|---|---|
.apk-conversation-list | Root container |
.apk-conversation-list--mobile | Mobile style |
.apk-conversation-list--desktop | Desktop style |
.apk-conversation-list__inner | Inner scroll container |
.apk-conversation-list__follow-button | Scroll follow button |
Conversation
| Class Name | Description |
|---|---|
.apk-conversation | Root container |
.apk-conversation--client | User message |
.apk-conversation--ai | AI message |
.apk-conversation__content-text | Text content |
ControlPanel
| Class Name | Description |
|---|---|
.apk-control-panel | Root container |
.apk-control-panel--mobile | Mobile style |
.apk-control-panel__inner | Inner container |
.apk-control-panel__mode-btn | Mode switch button |
.apk-control-panel__input | Input |
.apk-control-panel__send-btn | Send button |
.apk-control-panel__mic-btn | Microphone button |
.apk-control-panel__hangup-btn | Hangup button |
Input
| Class Name | Description |
|---|---|
.apk-input | Root container |
.apk-input--mobile | Mobile style |
.apk-input--desktop | Desktop style |
.apk-input__field | Input field |
.apk-input__send-icon | Send icon |
.apk-input--error | Error state |
.apk-input--disabled | Disabled state |
More Class Names
See each component documentation's "Style Customization" section for details.
class Property
Each component supports class property, used to add custom class names:
<template>
<ControlPanel class="my-control-panel" />
</template>
<style>
.my-control-panel {
margin-bottom: 20px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
</style>
style Property
Use style property to set inline styles:
<template>
<ConversationList
:style="{
maxHeight: '400px',
borderRadius: '16px',
backgroundColor: 'rgba(255, 255, 255, 0.9)'
}"
/>
</template>
Custom Icons (Slots)
Multiple components support customizing icons through slots:
ControlPanel Icons
<template>
<ControlPanel>
<template #muteIcon><MuteIcon /></template>
<template #unmuteIcon><UnmuteIcon /></template>
<template #hangupIcon><HangupIcon /></template>
<template #asrIcon><MicIcon /></template>
<template #keyboardIcon><KeyboardIcon /></template>
<template #sendIcon><SendIcon /></template>
</ControlPanel>
</template>
ConversationList Icons
<template>
<ConversationList>
<template #closeIcon><CloseIcon /></template>
</ConversationList>
</template>
RecommendedQuestions Icons
<template>
<RecommendedQuestions>
<template #arrowIcon><ArrowIcon /></template>
</RecommendedQuestions>
</template>
Scoped Slots Rendering
You can fully customize component rendering through scoped slots:
ConversationList
<template>
<ConversationList v-slot="{conversations, latestConversation}">
<div class="my-conversation-list">
<h3>Conversation History</h3>
<div
v-for="conv in conversations"
:key="conv.id"
:class="['my-message', `my-message--${conv.type}`]"
>
<span class="speaker">
{{ conv.type === 'client' ? 'Me' : 'AI' }}
</span>
<p>{{ conv.text }}</p>
</div>
</div>
</ConversationList>
</template>
Conversation
<template>
<Conversation
:conversation="conv"
v-slot="{contents, fullText, type, isCompleted}"
>
<div :class="['custom-bubble', type]">
<p>{{ fullText }}</p>
<span v-if="!isCompleted" class="typing-indicator">...</span>
</div>
</Conversation>
</template>
Subtitle
<template>
<Subtitle v-slot="{speakerName, fullText, isExpanded, toggleExpand}">
<div class="custom-subtitle">
<strong>{{ speakerName }}:</strong>
<span>{{ fullText }}</span>
<button @click="toggleExpand">
{{ isExpanded ? 'Collapse' : 'Expand' }}
</button>
</div>
</Subtitle>
</template>
Input
<template>
<Input v-slot="{value, setValue, handleSend, disabled, loading}">
<div class="custom-input">
<textarea
:value="value"
@input="e => setValue(e.target.value)"
:disabled="disabled"
placeholder="Enter message..."
/>
<button @click="handleSend" :disabled="loading || !value">
{{ loading ? 'Sending...' : 'Send' }}
</button>
</div>
</Input>
</template>
StartupScreen
<template>
<StartupScreen :show="showStartup" v-slot="{onStart, isActivating}">
<div class="custom-startup">
<img src="/logo.png" alt="Logo" />
<h1>Welcome to Digital Employee</h1>
<button @click="onStart" :disabled="isActivating">
{{ isActivating ? 'Activating...' : 'Start Conversation' }}
</button>
</div>
</StartupScreen>
</template>
CSS Variables (Planned)
CSS variable support is being planned, future versions will provide more convenient theme customization methods.
Expected variable examples:
:root {
--apk-primary-color: #007bff;
--apk-background-color: rgba(255, 255, 255, 0.9);
--apk-text-color: #333;
--apk-border-radius: 20px;
--apk-font-family: -apple-system, BlinkMacSystemFont, sans-serif;
}
Theme Examples
Dark Theme
/* Dark theme */
.dark-theme .apk-conversation-list {
background: rgba(30, 30, 30, 0.95);
}
.dark-theme .apk-conversation--ai {
background: rgba(50, 50, 50, 0.9);
color: #fff;
}
.dark-theme .apk-conversation--client {
background: #007bff;
color: #fff;
}
.dark-theme .apk-control-panel {
background: rgba(40, 40, 40, 0.9);
}
.dark-theme .apk-control-panel__input {
background: rgba(60, 60, 60, 0.9);
color: #fff;
border-color: rgba(100, 100, 100, 0.5);
}
Rounded Theme
/* Rounded theme */
.rounded-theme .apk-conversation {
border-radius: 24px;
}
.rounded-theme .apk-control-panel__input {
border-radius: 30px;
}
.rounded-theme .apk-control-panel__mic-btn,
.rounded-theme .apk-control-panel__send-btn {
border-radius: 50%;
}
Corporate Theme
/* Corporate brand theme */
.corporate-theme .apk-conversation--ai {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #fff;
}
.corporate-theme .apk-control-panel__mic-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.corporate-theme .apk-subtitle {
border-left: 3px solid #667eea;
padding-left: 12px;
}
Best Practices
1. Use Scoped Styles
Vue SFC scoped styles avoid global pollution:
<template>
<ControlPanel class="my-control-panel" />
</template>
<style scoped>
.my-control-panel {
/* Styles */
}
/* Deep selectors for overriding child component styles */
:deep(.apk-control-panel__input) {
border-color: #007bff;
}
</style>
2. Keep Original Class Names
When overriding styles, keep original class names to ensure responsive and other features work correctly:
<template>
<!-- ✅ Recommended -->
<ControlPanel class="my-custom-class" />
<!-- ❌ Avoid: Completely replacing internal structure causing feature loss -->
</template>
3. Prioritize CSS Overrides
For simple style adjustments, prioritize CSS overrides over scoped slots rendering:
/* ✅ Recommended: Simple style adjustments */
.apk-conversation--ai {
background: #f0f0f0;
}
<template>
<!-- ❌ Overused: Simple styles don't need custom rendering -->
<Conversation :conversation="conv" v-slot="{fullText}">
<div style="background: #f0f0f0">{{ fullText }}</div>
</Conversation>
</template>
4. Progressive Customization
Start with the simplest approach, upgrade as needed:
- First try
class+ CSS - If not enough, try
styleproperty - Use scoped slots rendering when structural changes are needed
Related
- Responsive Adaptation - Responsive style customization
- PilotKit - Core component styles
- Control Components - Control panel styles
- Message Components - Message component styles