tdesign-react
Version:
TDesign Component for React
808 lines (664 loc) • 17.1 kB
text/less
// 组件允许单个组件打包,因此默认引入公共基础样式
@import "../../base.less";
@import "./_var.less";
@import "./_mixin.less";
@import "./_doc.less";
@import "../../mixins/_reset.less";
.@{prefix}-chat {
.reset;
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
color: @comment-text-color-default;
// 聊天列表
&__list {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
&:hover {
&::-webkit-scrollbar-thumb {
background-color: @scrollbar-color;
}
}
&::-webkit-scrollbar {
width: 4px;
background: transparent;
}
&::-webkit-scrollbar-thumb {
border-radius: 6px;
border: 4px solid transparent;
background-clip: border-box;
background-color: transparent;
}
&--reverse {
display: flex;
flex-direction: column-reverse;
}
.place-holder {
flex-grow: 1;
flex-shrink: 1;
}
.clear-btn {
color: @text-color-secondary;
font-size: @font-size-s;
cursor: pointer;
.@{prefix}-divider__inner-text {
display: flex;
align-items: center;
}
.clear-btn-text {
margin-left: @comp-margin-xs;
}
&:hover {
color: @text-color-primary;
}
}
}
// 输入框插槽
&__footer {
position: relative;
&__content {
width: 100%;
position: relative;
display: flex;
padding-right: 0;
}
.@{prefix}-chat__footer__content {
margin-top: @comp-margin-xl;
}
&__textarea {
flex-grow: 1;
position: relative;
border-radius: @border-radius-round;
.@{prefix}-textarea {
width: 100%;
padding: 0 @comp-paddingLR-xxs;
box-sizing: border-box;
.@{prefix}-textarea__inner {
background: @bg-color-secondarycontainer;
padding: @comp-size-xxs @comp-size-xxxxxl @comp-size-xxs @comp-size-xs;
border-radius: 32px;
scrollbar-width: none;
}
.@{prefix}-textarea__inner:hover {
box-shadow: @chat-input-hover;
}
.@{prefix}-textarea__inner.@{prefix}-is-focused {
border-color: @brand-color;
background: @bg-color-container;
box-shadow: @chat-textarea-shadow-active;
}
.@{prefix}-textarea__inner::placeholder {
color: @text-color-secondary;
}
}
&__icon {
position: absolute;
bottom: @comp-paddingTB-s;
right: @comp-paddingLR-s;
text-align: center;
cursor: pointer;
height: @comp-size-xxl;
display: flex;
align-items: center;
justify-content: center;
& &__default {
transform: rotate(-90deg);
width: @comp-size-xxl;
height: @comp-size-xxl;
border-radius: @border-radius-circle;
color: @text-color-disabled;
}
& &--focus {
background: @brand-color;
color: @text-color-anti;
}
.@{prefix}-button.@{prefix}-size-s .@{prefix}-icon {
font-size: @font-size-xl;
}
}
}
&__stopbtn {
flex: 0 0 auto;
margin-left: @comp-margin-l;
.@{prefix}-button {
width: 100px;
height: @comp-size-xxxxl;
border-radius: @border-radius-round;
background: @bg-color-secondarycontainer;
color: @text-color-primary;
font-size: @font-size-l;
&__text {
align-items: center;
}
.@{prefix}-icon {
font-size: @font-size-xl;
margin-right: @comp-margin-s;
}
}
}
}
// sender输入框样式
&-sender {
position: relative;
width: 100%;
padding: 0 @comp-paddingLR-xxs;
box-sizing: border-box;
&__header {
border: 1px solid @component-border;
border-radius: @chat-sender-radius @chat-sender-radius 0 0;
margin-bottom: calc(0px - @comp-margin-l);
padding-bottom: @pop-padding-xxl;
&:empty {
display: none;
}
}
&__inner-header {
border-radius: @chat-sender-radius @chat-sender-radius @border-radius-medium @border-radius-medium;
&:empty {
margin-bottom: @comp-margin-s;
}
}
&__upload {
margin-right: @comp-margin-m;
width: @comp-size-s;
height: @comp-size-s;
}
&__textarea {
position: relative;
border: 1px solid @border-level-2-color;
border-radius: @chat-sender-radius;
padding: @comp-paddingLR-xs;
background-color: @bg-color-secondarycontainer;
&--focus {
border-color: @brand-color;
background-color: @bg-color-container;
box-shadow: @chat-textarea-shadow-active;
}
}
&__textarea:hover {
border-color: @brand-color;
box-shadow: @shadow-1;
}
&__textarea--focus:hover {
box-shadow: @chat-textarea-shadow-active;
}
.@{prefix}-textarea {
width: 100%;
margin-bottom: @comp-margin-m;
padding: 0 @comp-paddingLR-s;
.@{prefix}-textarea__inner {
background-color: rgba(0, 0, 0, 0%);
padding: 0;
border: 0;
scrollbar-width: none;
font: @font-body-large;
color: @text-color-primary;
}
.@{prefix}-textarea__inner.@{prefix}-is-focused {
border: 0;
}
.@{prefix}-textarea__inner::placeholder {
font: @font-body-large;
color: @text-color-disabled;
}
.@{prefix}-textarea__inner:hover {
box-shadow: none;
}
.@{prefix}-textarea__inner:focus {
box-shadow: none;
}
}
&__footer {
display: flex;
justify-content: space-between;
padding: 0 @comp-paddingLR-s @comp-paddingTB-s;
}
&__button {
display: flex;
align-items: center;
&__actions {
margin-right: @comp-margin-m;
}
& &__default {
padding: 0;
transform: rotate(-90deg);
color: @text-color-anti;
width: @comp-size-s;
height: @comp-size-s;
border-radius: @border-radius-circle;
background-color: @brand-color;
}
& &--disabled {
background-color: @bg-color-secondarycomponent;
color: @bg-color-container;
}
&__stopicon {
width: @size-4;
height: @size-4;
border: 1px solid @bg-color-container;
background: @bg-color-container;
}
}
}
&__inner {
display: flex;
margin-bottom: @comp-margin-l;
.@{prefix}-chat__avatar {
flex: 0 0 auto;
}
.@{prefix}-chat__content {
display: flex;
justify-content: center;
flex: 1 1 auto;
width: 100%;
&--base {
padding-top: @comp-paddingTB-xl;
}
>.@{prefix}-chat-loading {
padding: 0 @comp-paddingLR-m;
}
}
.@{prefix}-chat__detail {
max-width: calc(100% - @comp-size-xl);
box-sizing: border-box;
}
&.model-change {
justify-content: center;
margin-top: @comp-margin-xxl;
// 模型切换在chat-content中渲染居中对齐覆写样式
.@{prefix}-chat__content {
align-items: center;
}
.@{prefix}-chat__text {
padding: 0;
font-size: @font-size-s;
color: @text-color-disabled;
}
.@{prefix}-chat__notice {
// 模型切换为content插槽需要覆盖样式
.@{prefix}-chat__text {
padding: 0;
font-size: @font-size-s;
color: @text-color-disabled;
}
background: @bg-color-secondarycontainer;
padding: @comp-paddingTB-xxs @comp-paddingLR-s;
font-size: @font-size-s;
color: @text-color-disabled;
border-radius: @border-radius-default;
box-sizing: border-box;
line-height: 20px;
text-align: center;
span {
color: @text-color-placeholder;
}
}
}
&.error {
.@{prefix}-chat__text__content {
color: @error-color;
}
}
}
// chat布局
&--normal {
.@{prefix}-chat__inner.user {
flex-direction: row-reverse;
.@{prefix}-chat__avatar {
margin-right: 0;
}
.@{prefix}-chat__content {
align-items: flex-end;
.@{prefix}-chat__base {
justify-content: flex-end;
}
}
}
.@{prefix}-chat__detail {
max-width: ~"min(calc(100% - 40px), 800px)";
}
}
&__avatar {
flex-shrink: 0;
cursor: pointer;
display: flex;
margin: 0 @comp-margin-xs;
padding-top: @comp-paddingTB-xl;
&__box {
padding-top: @pop-padding-m;
}
&-image {
width: @comp-size-m;
height: @comp-size-m;
border-radius: @border-radius-circle;
}
}
&__content {
font: @comment-content-text-size;
display: flex;
flex-direction: column;
align-items: flex-start;
.@{prefix}-skeleton {
width: 100%;
padding: @pop-padding-xxl;
}
.@{prefix}-chat__text--model-change {
background: @bg-color-secondarycontainer;
padding: @comp-paddingTB-xxs @comp-paddingLR-s;
font-size: @font-size-s;
color: @text-color-disabled;
border-radius: @border-radius-default;
box-sizing: border-box;
line-height: 20px;
text-align: center;
span {
color: @text-color-placeholder;
}
}
}
&__base {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
align-items: baseline;
font: @font-body-medium;
color: @text-color-placeholder;
padding-left: @pop-padding-xxl;
}
&__name {
padding-right: @comp-margin-s;
cursor: pointer;
}
// 消息样式
&__text {
padding: @comp-paddingTB-m @comp-paddingLR-l;
font: @font-body-large;
word-break: break-all;
& &--user pre {
color: @text-color-secondary;
font: @font-body-large;
margin: 0;
white-space: pre-wrap;
}
&__assistant {
color: @text-color-primary;
line-height: 2;
p,
ul,
ol {
line-height: 1.5;
}
ol {
padding-inline-start: 20px;
}
img {
max-width: 100%;
margin: @comp-margin-xs 0;
border-radius: @border-radius-default;
}
:where(code):not(:where(pre *)) {
color: @error-color;
background: @error-color-1;
border-radius: @border-radius-default;
padding: @comp-paddingTB-xxs @pop-padding-m;
font-size: @font-size-s;
word-break: break-word;
margin: 0 @comp-margin-xxs;
}
blockquote {
border-left: 2px solid @gray-color-3;
background: @gray-color-1;
color: @font-gray-1;
padding: @comp-paddingTB-m @comp-paddingTB-m @comp-paddingTB-m @comp-size-xs;
margin: @comp-margin-l 0;
}
hr {
opacity: 1;
border: 1px solid @border-level-1-color;
}
}
& &__assistant &__content .hljs {
background-color: @code-bg-color-page;
border-radius: @border-radius-large;
}
&--error {
color: @error-color;
}
&--variant--base {
.@{prefix}-chat__text {
background-color: @bg-color-secondarycontainer;
border-radius: @border-radius-extraLarge;
}
}
}
&__actions-margin {
margin-left: @comp-margin-l;
}
&__actions {
margin-top: @comp-margin-xs;
display: flex;
list-style: none;
padding: @chat-action-icon-padding;
background-color: @bg-color-secondarycontainer;
border-radius: @border-radius-medium;
border: 1px solid @border-level-2-color;
overflow: hidden;
& .@{prefix}-button {
padding: @comp-paddingTB-xs @comp-paddingLR-xs;
width: @comp-size-xxxs;
height: @comp-size-xxxs;
box-sizing: content-box;
color: @text-color-primary;
background-color: @bg-color-secondarycontainer;
border: 0;
margin-right: @comp-margin-xs;
.@{prefix}-icon {
font-size: @font-size-l;
}
}
& .@{prefix}-chat-button--active {
color: @brand-color;
}
& .@{prefix}-button:hover {
background-color: @bg-color-secondarycontainer-hover;
}
& .@{prefix}-space .@{prefix}-space-item {
height: @comp-size-xs;
}
}
&__refresh {
display: flex;
align-items: center;
&-line {
width: 1px;
height: @comp-size-xxxs;
background-color: @chat-refresh-line;
margin-right: @comp-margin-xs;
}
}
&__code-header {
display: flex;
padding: 0 @pop-padding-xl;
padding-top: @pop-padding-xl;
justify-content: space-between;
}
&__language-txt {
color: @code-font-color-base;
}
&__copy-btn {
color: @code-font-color-base;
cursor: pointer;
}
}
// 思维链样式
.@{prefix}-chat__detail {
.@{prefix}-chat__text--variant--outline & {
border: 1px solid @component-border;
border-radius: @border-radius-extraLarge;
}
.model-change.@{prefix}-chat__text--variant--outline & {
border: none;
}
&-reasoning {
.@{prefix}-chat__text--variant--text & {
padding-top: @comp-paddingTB-m;
~.@{prefix}-chat__text {
padding-right: 0;
}
}
.@{prefix}-chat__text--variant--outline & {
.@{prefix}-collapse {
background: none;
}
}
.@{prefix}-collapse {
background: none;
}
.@{prefix}-collapse-panel {
margin-left: @comp-margin-l;
.@{prefix}-chat__text--variant--outline & {
margin-left: 0;
padding: @comp-paddingTB-m @comp-paddingLR-l;
// 移除 t-chat__text 的边框
.@{prefix}-chat__text {
border: none;
}
}
&__icon {
width: 24px;
height: 24px;
display: flex;
align-items: center;
}
&__header {
padding: @comp-paddingTB-s @comp-paddingTB-m;
font: @font-body-medium;
}
&__wrapper {
background-color: @bg-color-secondarycontainer;
border-radius: @border-radius-medium;
.@{prefix}-fake-arrow {
color: @text-color-secondary;
transform: rotate(180deg) scale(1.125);
}
}
&__icon--active {
.@{prefix}-fake-arrow {
transform: rotate(0deg) scale(1.125);
}
}
&__content {
background-color: @bg-color-secondarycontainer;
padding: 0 @comp-paddingTB-m @comp-paddingTB-s @comp-paddingTB-m;
.@{prefix}-chat__text {
padding: 0;
.@{prefix}-chat__text__assistant {
color: @text-color-placeholder;
font-weight: 400;
font-size: @font-size-base;
.@{prefix}-chat__text__content {
p {
.reset();
}
}
}
}
}
}
}
}
.@{prefix}-chat-loading {
display: flex;
align-items: center;
&__indicator {
&--moving {
position: relative;
width: 14px;
height: 14px;
.@{prefix}-chat-loading__dot {
position: absolute;
width: 8px;
height: 8px;
border-radius: @border-radius-circle;
background-color: @brand-color;
&--top {
top: -4px;
left: 3px;
animation: dot-moving-top .6s ease-in-out alternate infinite;
}
&--left {
bottom: -5px;
left: -5px;
animation: dot-moving-left .6s ease-in-out alternate infinite;
}
&--right {
bottom: -5px;
right: -5px;
animation: dot-moving-right .6s ease-in-out alternate infinite;
}
}
}
&--gradient {
width: 14px;
height: 14px;
background-color: transparent;
border-radius: @border-radius-circle;
border: 1.5px solid @brand-color;
animation: border-gradient-color .6s ease-in-out alternate infinite;
box-sizing: border-box;
}
@keyframes border-gradient-color {
0% {
border-color: @brand-color;
border-width: 1.5px;
}
50% {
border-color: @brand-color-8;
border-width: 3px;
}
100% {
border-color: @brand-color-6;
border-width: 4px;
}
}
@keyframes dot-moving-top {
0% {
transform: scale(1);
top: -4px;
}
100% {
transform: scale(1.75);
top: 3px;
}
}
@keyframes dot-moving-left {
0% {
transform: scale(1);
bottom: -4px;
left: -4px;
}
100% {
transform: scale(1.75);
bottom: 3px;
left: 3px;
}
}
@keyframes dot-moving-right {
0% {
transform: scale(1);
bottom: -4px;
right: -4px;
}
100% {
transform: scale(1.75);
bottom: 3px;
right: 3px;
}
}
}
&__text {
margin-left: 8px;
}
}