样式随心定制:TinyRobot 样式覆写与 CSS 变量实战解析

样式随心定制:TinyRobot 样式覆写与 CSS 变量实战解析

一个优秀的组件库不仅要提供功能完备的 API,还要提供灵活的样式定制能力。TinyRobot 基于 CSS 变量构建了完整的样式体系,每个组件都有详细的变量列表,开发者只需覆写对应的 CSS 变量,即可实现从微调到全面改版的样式定制。

本文将从 Sender、Container、Prompts、Feedback 四个核心组件的 CSS 变量出发,结合实战案例,全面解析 TinyRobot 的样式覆写体系。

Sender CSS 变量完整列表

Sender 是样式变量最丰富的组件之一,覆盖了背景、文字、间距、按钮等各个方面。

基础颜色

变量名 说明 典型值
--tr-sender-bg-color 背景颜色 #ffffff
--tr-sender-text-color 文本颜色 #333333
--tr-sender-placeholder-color 占位符颜色 #999999
--tr-sender-button-hover-bg 按钮悬停背景 #f5f5f5

基础颜色变量是最常用的定制点。通过覆写这四个变量,可以快速改变 Sender 的整体色调:

css 复制代码
/* 暗色风格 */
.my-sender-dark {
  --tr-sender-bg-color: #1a1a2e;
  --tr-sender-text-color: #e0e0e0;
  --tr-sender-placeholder-color: #666666;
  --tr-sender-button-hover-bg: #2a2a4e;
}

/* 蓝色品牌风格 */
.my-sender-brand {
  --tr-sender-bg-color: #f0f7ff;
  --tr-sender-text-color: #1a365d;
  --tr-sender-placeholder-color: #90cdf4;
  --tr-sender-button-hover-bg: #bee3f8;
}

尺寸和间距

变量名 说明 典型值
--tr-sender-font-size 字体大小 14px
--tr-sender-line-height 行高 1.5
--tr-sender-border-radius 圆角大小 8px
--tr-sender-padding 内边距 12px
--tr-sender-gap 元素间距 8px
--tr-sender-footer-gap 底部元素间距 8px

间距变量控制 Sender 的空间节奏。通过调整这些变量,可以让 Sender 从紧凑到宽松切换:

css 复制代码
/* 紧凑布局 */
.my-sender-compact {
  --tr-sender-padding: 8px;
  --tr-sender-gap: 4px;
  --tr-sender-footer-gap: 4px;
  --tr-sender-font-size: 13px;
  --tr-sender-line-height: 1.4;
}

/* 宽松布局 */
.my-sender-relaxed {
  --tr-sender-padding: 16px;
  --tr-sender-gap: 12px;
  --tr-sender-footer-gap: 12px;
  --tr-sender-font-size: 16px;
  --tr-sender-line-height: 1.6;
  --tr-sender-border-radius: 12px;
}

Header 区域

变量名 说明
--tr-sender-header-padding 头部内边距
--tr-sender-header-divider-inset 头部分割线缩进
--tr-sender-multi-main-padding 多行模式主区域内边距

Header 区域变量用于定制 Sender 上方的提示区域。当使用 header 插槽或 Template 扩展时,这些变量会影响 Header 的空间布局:

css 复制代码
.my-sender {
  --tr-sender-header-padding: 12px 16px;
  --tr-sender-header-divider-inset: 16px;
  --tr-sender-multi-main-padding: 12px 16px;
}
变量名 说明
--tr-sender-footer-padding 底部内边距

Footer 区域是放置功能按钮(VoiceButton、UploadButton 等)的区域:

css 复制代码
.my-sender {
  --tr-sender-footer-padding: 8px 12px;
}

前缀和操作区

变量名 说明
--tr-sender-prefix-padding-right 前缀区域右内边距
--tr-sender-actions-padding-right 操作区域右内边距

这两个变量控制输入框内部左侧前缀和右侧操作区与文本之间的间距:

css 复制代码
.my-sender {
  --tr-sender-prefix-padding-right: 8px;
  --tr-sender-actions-padding-right: 8px;
}

按钮

变量名 说明 典型值
--tr-sender-button-size 按钮尺寸 32px
--tr-sender-button-size-submit 提交按钮尺寸 32px

按钮尺寸变量可以单独调整提交按钮的大小,使其比其他按钮更大或更小:

css 复制代码
/* 大提交按钮 */
.my-sender {
  --tr-sender-button-size: 32px;
  --tr-sender-button-size-submit: 40px;
}

/* 小按钮紧凑风格 */
.my-sender {
  --tr-sender-button-size: 24px;
  --tr-sender-button-size-submit: 28px;
}

尺寸变体:size="small"

当 Sender 设置 size="small" 时,所有尺寸相关的 CSS 变量会自动切换到对应的 -small 变体:

css 复制代码
/* size="normal" (默认) */
--tr-sender-font-size          → 14px
--tr-sender-padding            → 12px
--tr-sender-button-size        → 32px

/* size="small" (自动切换) */
--tr-sender-font-size-small    → 13px
--tr-sender-padding-small      → 8px
--tr-sender-button-size-small  → 28px

每个变量都有对应的 -small 版本,组件内部通过 CSS 选择器自动切换:

css 复制代码
/* 组件内部实现(伪代码) */
.tr-sender {
  font-size: var(--tr-sender-font-size);
  padding: var(--tr-sender-padding);
}

.tr-sender--small {
  font-size: var(--tr-sender-font-size-small);
  padding: var(--tr-sender-padding-small);
}

开发者可以覆写 -small 变体来定制紧凑模式下的样式:

css 复制代码
/* 自定义紧凑模式的样式 */
.my-sender {
  --tr-sender-font-size-small: 12px;
  --tr-sender-padding-small: 6px;
  --tr-sender-button-size-small: 24px;
  --tr-sender-button-size-submit-small: 28px;
}

Container CSS 变量

Container 作为聊天界面的容器框架,其样式变量覆盖了标题、边框、宽度等属性。

全局变量

变量名 说明
--tr-container-bg-color 容器背景色
--tr-container-border-color 容器边框色
--tr-container-border-width 容器边框宽度
--tr-container-header-operations-gap 操作按钮间距
--tr-container-header-padding 头部内边距
--tr-container-title-color 标题文字颜色
--tr-container-title-font-size 标题字体大小
--tr-container-title-font-weight 标题字体粗细
--tr-container-title-line-height 标题行高
--tr-container-width 容器宽度

全屏模式变量

变量名 说明
--tr-container-header-padding-fullscreen 全屏模式头部内边距
--tr-container-title-font-size-fullscreen 全屏模式标题字体大小
--tr-container-title-line-height-fullscreen 全屏模式标题行高

全屏模式下,Container 会加上 fullscreen 类名,使用专用的 CSS 变量:

css 复制代码
/* 非全屏模式 */
:root {
  --tr-container-width: 600px;
  --tr-container-title-font-size: 16px;
  --tr-container-bg-color: #ffffff;
  --tr-container-border-color: #e5e7eb;
}

/* 全屏模式 */
:root {
  --tr-container-title-font-size-fullscreen: 20px;
  --tr-container-header-padding-fullscreen: 0 200px 24px;
  --tr-container-bg-color: #f8f9fa;
}

Prompts CSS 变量

Prompts 组件的 CSS 变量非常丰富,覆盖了提示项、标题、描述、徽章的各个方面。

Prompt 根元素

变量名 说明
--tr-prompt-bg 提示项背景色
--tr-prompt-bg-hover 提示项悬停背景色
--tr-prompt-bg-active 提示项激活背景色
--tr-prompt-bg-disabled 提示项禁用背景色
--tr-prompt-border-radius 圆角大小
--tr-prompt-shadow 阴影效果
--tr-prompt-width 提示项宽度
--tr-prompt-padding 内边距
--tr-prompt-gap 图标与内容间距

Title 标题

变量名 说明
--tr-prompt-title-color 标题文字颜色
--tr-prompt-title-font-size 标题字号
--tr-prompt-title-line-height 标题行高
--tr-prompt-title-font-weight 标题字重

Description 描述

变量名 说明
--tr-prompt-description-color 描述文字颜色
--tr-prompt-description-font-size 描述字号
--tr-prompt-description-line-height 描述行高

Badge 徽章

变量名 说明
--tr-prompt-badge-bg 徽章背景色
--tr-prompt-badge-color 徽章文字颜色
--tr-prompt-badge-padding 徽章内边距
--tr-prompt-badge-font-size 徽章字号
--tr-prompt-badge-line-height 徽章行高

尺寸变体

Prompts 的 size 属性支持 smallmediumlarge 三种尺寸。与 Sender 不同,Prompts 使用 -small-medium-large 后缀:

css 复制代码
/* 不同尺寸的内边距 */
--tr-prompt-padding-small
--tr-prompt-padding-medium
--tr-prompt-padding-large

/* 不同尺寸的标题字号 */
--tr-prompt-title-font-size-small
--tr-prompt-title-font-size-medium
--tr-prompt-title-font-size-large

Prompts 容器变量

变量名 说明
--tr-prompts-gap 提示项之间的间距

Feedback CSS 变量

Feedback 组件主要用于气泡消息的操作反馈,其 CSS 变量控制操作按钮和动作按钮的样式。

由于 Feedback 的样式变量在官方文档中没有完整列出,开发者可以通过浏览器开发者工具(F12)检查 Feedback 组件的 DOM 结构,找到对应的 CSS 变量名称。TinyRobot 的所有组件都遵循 --tr-组件名-属性名 的命名规范。

CSS 变量覆写实战

实战1:自定义品牌色 Sender

vue 复制代码
<template>
  <tr-sender
    class="brand-sender"
    v-model="text"
    @submit="handleSubmit"
  >
    <template #footer="{ disabled, loading }">
      <tr-voice-button :disabled="disabled || loading" />
    </template>
  </tr-sender>
</template>

<style>
.brand-sender {
  /* 品牌蓝色背景 */
  --tr-sender-bg-color: #f0f7ff;
  --tr-sender-text-color: #1a365d;
  --tr-sender-placeholder-color: #a0aec0;

  /* 更大的圆角 */
  --tr-sender-border-radius: 16px;

  /* 适中间距 */
  --tr-sender-padding: 14px;
  --tr-sender-gap: 10px;

  /* 大提交按钮 */
  --tr-sender-button-size: 36px;
  --tr-sender-button-size-submit: 44px;

  /* 悬停效果 */
  --tr-sender-button-hover-bg: #bee3f8;
}
</style>

实战2:暗色主题全组件覆写

结合 ThemeProvider,实现暗色主题下的全组件样式定制:

css 复制代码
/* 暗色模式全局覆写 */
[data-tr-color-mode='dark'] {
  /* Sender */
  --tr-sender-bg-color: #1e1e2e;
  --tr-sender-text-color: #cdd6f4;
  --tr-sender-placeholder-color: #585b70;
  --tr-sender-button-hover-bg: #313244;
  --tr-sender-border-radius: 12px;

  /* Container */
  --tr-container-bg-color: #181825;
  --tr-container-border-color: #313244;
  --tr-container-title-color: #cdd6f4;

  /* Prompts */
  --tr-prompt-bg: #313244;
  --tr-prompt-bg-hover: #45475a;
  --tr-prompt-title-color: #cdd6f4;
  --tr-prompt-description-color: #a6adc8;

  /* Bubble */
  --tr-bubble-box-bg: #313244;
  --tr-bubble-text-color: #cdd6f4;
}
vue 复制代码
<template>
  <theme-provider v-model:color-mode="colorMode">
    <tr-container title="AI 助手">
      <tr-bubble-list :messages="messages" />
      <template #footer>
        <tr-sender @submit="handleSubmit" />
      </template>
    </tr-container>
  </theme-provider>
</template>

<script setup>
import { ref } from 'vue'
const colorMode = ref('dark')
</script>

实战3:Prompts 卡片化风格

将默认的条状提示项改为卡片风格:

css 复制代码
.card-prompts {
  --tr-prompt-bg: #ffffff;
  --tr-prompt-bg-hover: #f8f9fa;
  --tr-prompt-border-radius: 12px;
  --tr-prompt-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  --tr-prompt-padding: 16px;
  --tr-prompt-gap: 12px;

  --tr-prompt-title-font-size: 15px;
  --tr-prompt-title-font-weight: 600;
  --tr-prompt-title-color: #1a365d;

  --tr-prompt-description-color: #718096;
  --tr-prompt-description-font-size: 13px;

  --tr-prompts-gap: 12px;
}

实战4:紧凑移动端布局

针对移动端空间受限的场景,使用 size="small" + 自定义 -small 变量:

css 复制代码
/* 移动端紧凑布局 */
.mobile-sender {
  --tr-sender-font-size-small: 12px;
  --tr-sender-padding-small: 8px;
  --tr-sender-gap-small: 4px;
  --tr-sender-footer-gap-small: 4px;
  --tr-sender-border-radius-small: 8px;
  --tr-sender-button-size-small: 28px;
  --tr-sender-button-size-submit-small: 32px;
}
vue 复制代码
<template>
  <tr-sender class="mobile-sender" v-model="text" size="small" />
</template>

主题继承与 ThemeProvider 联动

Sender 的 CSS 变量会根据父级 ThemeProvider 的配置自动继承。这意味着:

  1. 包裹在 ThemeProvider 中的 Sender 无需额外设置主题
  2. ThemeProvider 切换主题后,Sender 的样式自动跟随
  3. 嵌套 ThemeProvider 时,Sender 使用最近的 ThemeProvider 的配置
vue 复制代码
<template>
  <!-- 外层:默认主题 -->
  <theme-provider color-mode="light">
    <tr-sender />  <!-- 继承 light 主题 -->

    <!-- 内层:自定义主题 -->
    <theme-provider theme="brand" color-mode="dark">
      <tr-sender />  <!-- 继承 brand + dark 主题 -->
    </theme-provider>
  </theme-provider>
</template>

CSS 变量的覆写优先级遵循标准 CSS 规则:

  1. 直接类名覆写 (如 .my-sender { --tr-sender-bg-color: ... })------ 最高优先级
  2. 属性选择器覆写 (如 [data-tr-color-mode='dark'] { ... })------ ThemeProvider 驱动
  3. 组件默认值 ------ 最低优先级
css 复制代码
/* 直接类名覆写优先级最高 */
.my-sender {
  --tr-sender-bg-color: #f0f7ff;  /* 即使 ThemeProvider 设置了 dark,这里仍然生效 */
}

/* 属性选择器覆写------由 ThemeProvider 驱动 */
[data-tr-color-mode='dark'] {
  --tr-sender-bg-color: #1e1e2e;  /* 仅在 dark 模式下生效 */
}

ShadowDOM 兼容注意事项

如果你的应用使用 ShadowDOM(如 Web Components),需要注意:

  1. CSS 变量可以穿透 ShadowDOM 边界------:host:host-context() 选择器可以访问外部 CSS 变量
  2. 但 ThemeProvider 设置的 data-tr-themedata-tr-color-mode 属性在 ShadowDOM 外部的 html 元素上,:host-context() 可以匹配
  3. 如果 targetElement 设置为 ShadowDOM 内部的元素,需要确保属性选择器能匹配到
css 复制代码
/* ShadowDOM 内部样式 */
:host {
  --tr-sender-bg-color: var(--external-sender-bg, #ffffff);
}

:host-context([data-tr-color-mode='dark']) {
  --tr-sender-bg-color: var(--external-sender-bg-dark, #1e1e2e);
}

小结

TinyRobot 的 CSS 变量体系遵循一致的命名规范(--tr-组件名-属性名),覆盖了从颜色、间距到按钮尺寸的各个方面。关键设计特点:

  1. 完整覆盖:每个组件都有详细的变量列表,满足从微调到全面改版的定制需求
  2. 尺寸变体 :通过 -small(Sender)或 -small/-medium/-large(Prompts)后缀,自动适配不同尺寸
  3. 主题联动:CSS 变量与 ThemeProvider 的属性选择器无缝联动,切换主题自动生效
  4. ShadowDOM 兼容:CSS 变量天然穿透 ShadowDOM 边界,但需注意属性选择器的匹配范围

样式定制不再是"改源码"或"写全局覆盖"的粗糙操作------通过 CSS 变量,TinyRobot 让样式定制变得精确、可控、可维护。


🔗 TinyRobot 官网tiny-robot.opentiny.design

🔗 GitHub 仓库github.com/opentiny/ti...

相关推荐
疯狂的魔鬼1 小时前
多角色督办任务详情页:从权限矩阵到组件拆分的完整实现
前端·vue.js·架构
英勇无比的消炎药1 小时前
拆解内核:深入分析 TinyRobot 输入区组件设计与实现原理
vue.js
Cc_Debugger2 小时前
开发环境使用https配置
javascript·vue.js·https
触底反弹2 小时前
🎨 通义万相实战:用 Qwen 多模态 API 实现 AI 换装换姿势,10 行代码搞定!
vue.js·人工智能
零瓶水Herwt2 小时前
代替vue-currency-input使用原生货币符号
前端·vue.js
Cobyte3 小时前
20.Vue Vapor 的应用初始化
前端·javascript·vue.js
vx-Biye_Design3 小时前
springboot安阳地区研学旅游服务小程序-计算机毕业设计源码12785
java·vue.js·windows·spring boot·tomcat·maven·mybatis
云浪3 小时前
手把手教你用 fetch 读取 SSE 流,给 AI 聊天加上打字机效果
前端·javascript·vue.js