补充css修改

This commit is contained in:
2026-04-03 13:44:35 +08:00
parent 6375f9759c
commit f90ad8dc13
11 changed files with 240 additions and 174 deletions

View File

@@ -14,9 +14,7 @@ function App() {
{/* 主内容容器 */}
<div className="main-container">
{/* 左侧栏 - 预设面板 */}
<div className="sidebar-left">
<SideBarLeft />
</div>
{/* 中间栏:聊天框 */}
<div className="chat-area">
@@ -24,9 +22,7 @@ function App() {
</div>
{/* 右侧栏 */}
<div className="sidebar-right">
<SideBarRight />
</div>
</div>
</div>
);

View File

@@ -0,0 +1,16 @@
import { create } from 'zustand';
const useSideBarLeftStore = create((set) => ({
activeTab: 'gallery',
tabs: [
{ id: 'gallery', label: '🖼️ 画廊' },
{ id: 'api', label: '🔌 API' },
{ id: 'presets', label: '📋 预设' },
{ id: 'worldbook', label: '🌍 世界书' }
],
setActiveTab: (tab) => set({ activeTab: tab })
}));
export default useSideBarLeftStore;

View File

@@ -0,0 +1,34 @@
import { create } from 'zustand';
const useSideBarRightStore = create((set) => ({
selectedTabs: ['dice', 'macros'],
allTabs: [
{ id: 'dice', label: '🎲 骰子与工具', component: null },
{ id: 'debug', label: '🔍 上下文调试', component: null },
{ id: 'macros', label: '🔧 快捷宏', component: null },
{ id: 'table', label: '📊 动态表格', component: null }
],
handleTabClick: (tabId) => set((state) => {
if (state.selectedTabs.includes(tabId)) {
// 如果已选中,则取消选中
return { selectedTabs: state.selectedTabs.filter(id => id !== tabId) };
} else if (state.selectedTabs.length < 2) {
// 如果未选中且少于2个则添加
return { selectedTabs: [...state.selectedTabs, tabId] };
} else {
// 如果已有2个则替换最早选中的
return { selectedTabs: [...state.selectedTabs.slice(1), tabId] };
}
}),
// 设置特定标签的组件
setTabComponent: (tabId, component) => set((state) => ({
allTabs: state.allTabs.map(tab =>
tab.id === tabId ? { ...tab, component } : tab
)
}))
}));
export default useSideBarRightStore;

View File

@@ -1,2 +1,5 @@
// frontend-react/src/store/index.js
export { default as useRoleSelectorStore } from './roleSelectorStore';
export { default as useRoleSelectorStore } from './Slices/RoleSelectorSlice';
export { default as useSideBarLeftStore } from './Slices/SideBarLeftSlice';
export { default as useSideBarRightStore } from './Slices/SideBarRightSlice';
export { default as useChatBoxStore } from './Slices/ChatBoxSlice';

View File

@@ -145,7 +145,7 @@
flex-direction: column;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
overflow: hidden;
min-height: 140px;
height: 200px; /* 设置固定高度 */
position: relative;
/* 添加微妙的边框效果 */
border: 1px solid rgba(0, 0, 0, 0.05);
@@ -167,7 +167,8 @@
display: flex;
justify-content: space-between;
align-items: center;
flex: 1;
flex: 0 0 auto; /* 不再自动伸缩,使用固定高度 */
height: 60px; /* 设置固定高度 */
}
.role-header .role-name {
@@ -177,12 +178,16 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 80%; /* 限制名称最大宽度 */
}
.role-item.active .role-header .role-name {
color: #667eea;
font-size: 16px; /* 激活状态时字体稍大 */
}
.role-actions {
display: flex;
gap: 4px;
@@ -191,8 +196,10 @@
right: 12px;
opacity: 0;
transition: opacity 0.2s ease;
z-index: 10; /* 确保操作按钮在最上层 */
}
.role-item:hover .role-actions {
opacity: 1;
}
@@ -227,13 +234,17 @@
border-top: 1px solid #f0f0f0;
padding: 8px 0;
background-color: #fafbfc;
max-height: 140px;
height: 120px; /* 设置固定高度 */
overflow-y: auto;
/* 自定义滚动条样式 */
scrollbar-width: thin;
scrollbar-color: #cbd5e1 transparent;
flex: 1; /* 让聊天列表占据剩余空间 */
display: flex;
flex-direction: column;
}
/* Webkit浏览器滚动条样式 */
.chat-list::-webkit-scrollbar {
width: 4px;

View File

@@ -1,42 +1,91 @@
/* frontend-react/src/components/SideBarLeft/SideBarLeft.css */
.sidebar-left {
width: 250px;
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
background-color: #ffffff;
box-shadow: 2px 0 5px rgba(0, 0, 0, 0.05);
border-right: 1px solid #e8e8e8;
transition: width 0.3s ease;
}
.sidebar-tabs {
display: flex;
border-bottom: 1px solid #e0e0e0;
border-bottom: 1px solid #e8e8e8;
background-color: #fafafa;
padding: 0 10px;
}
.tab-button {
flex: 1;
padding: 10px 5px;
padding: 12px 5px;
background: none;
border: none;
cursor: pointer;
transition: background-color 0.3s;
transition: all 0.3s ease;
font-size: 14px;
color: #555;
position: relative;
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
}
.tab-button:hover {
background-color: #f5f5f5;
background-color: #f0f0f0;
color: #333;
}
.tab-button.active {
border-bottom: 2px solid #4a90e2;
font-weight: bold;
color: #4a90e2;
font-weight: 600;
}
.tab-button.active::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 3px;
background-color: #4a90e2;
border-radius: 3px 3px 0 0;
}
.sidebar-content {
flex: 1;
overflow-y: auto;
padding: 10px;
padding: 15px;
}
.tab-content {
height: 100%;
flex: 1;
overflow-y: auto;
padding: 15px;
border-bottom: 1px solid #f0f0f0;
}
/* 自定义滚动条样式 */
.sidebar-content::-webkit-scrollbar,
.tab-content::-webkit-scrollbar {
width: 6px;
}
.sidebar-content::-webkit-scrollbar-track,
.tab-content::-webkit-scrollbar-track {
background: #f1f1f1;
}
.sidebar-content::-webkit-scrollbar-thumb,
.tab-content::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 3px;
}
.sidebar-content::-webkit-scrollbar-thumb:hover,
.tab-content::-webkit-scrollbar-thumb:hover {
background: #a8a8a8;
}

View File

@@ -1,40 +1,30 @@
// frontend-react/src/components/SideBarLeft/SideBarLeft.jsx
import React, { useState } from 'react';
import React from 'react';
import './SideBarLeft.css';
import { useSideBarLeftStore } from '../../Store/indexStore';
import useSideBarRightStore from '../../Store/Slices/SideBarLeftSlice';
const SideBarLeft = () => {
const [activeTab, setActiveTab] = useState('gallery');
const handleTabChange = (tab) => {
setActiveTab(tab);
};
const { activeTab, tabs, setActiveTab } = useSideBarLeftStore();
return (
<div className="sidebar-left">
<div className="sidebar-tabs">
<button
className={`tab-button ${activeTab === 'gallery' ? 'active' : ''}`}
onClick={() => handleTabChange('gallery')}
>
🖼 画廊
</button>
<button
className={`tab-button ${activeTab === 'config' ? 'active' : ''}`}
onClick={() => handleTabChange('config')}
>
配置
</button>
<button
className={`tab-button ${activeTab === 'worldbook' ? 'active' : ''}`}
onClick={() => handleTabChange('worldbook')}
>
🌍 世界书
</button>
{tabs.map(tab => (
<button
key={tab.id}
className={`tab-button ${activeTab === tab.id ? 'active' : ''}`}
onClick={() => setActiveTab(tab.id)}
>
{tab.label}
</button>
))}
</div>
<div className="sidebar-content">
{activeTab === 'gallery' && <div className="tab-content">画廊内容</div>}
{activeTab === 'config' && <div className="tab-content">配置内容</div>}
{activeTab === 'api' && <div className="tab-content">API配置内容</div>}
{activeTab === 'presets' && <div className="tab-content">预设配置内容</div>}
{activeTab === 'worldbook' && <div className="tab-content">世界书内容</div>}
</div>
</div>

View File

@@ -1,56 +1,102 @@
/* frontend-react/src/components/SideBarRight/SideBarRight.css */
.sidebar-right {
width: 300px;
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
.right-top, .right-bottom {
display: flex;
flex-direction: column;
overflow: hidden;
}
.right-top {
flex: 1;
}
.right-bottom {
height: 200px;
background-color: #ffffff;
box-shadow: -2px 0 5px rgba(0, 0, 0, 0.05);
border-left: 1px solid #e8e8e8;
transition: width 0.3s ease;
}
.sidebar-tabs {
display: flex;
border-bottom: 1px solid #e0e0e0;
border-bottom: 1px solid #e8e8e8;
flex-shrink: 0;
background-color: #fafafa;
padding: 0 10px;
}
.tab-button {
flex: 1;
padding: 10px 5px;
padding: 12px 5px;
background: none;
border: none;
cursor: pointer;
transition: background-color 0.3s;
transition: all 0.3s ease;
font-size: 14px;
color: #555;
position: relative;
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
}
.tab-button:hover {
background-color: #f5f5f5;
background-color: #f0f0f0;
color: #333;
}
.tab-button.active {
border-bottom: 2px solid #4a90e2;
font-weight: bold;
color: #4a90e2;
font-weight: 600;
}
.tab-button.active::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 3px;
background-color: #4a90e2;
border-radius: 3px 3px 0 0;
}
.sidebar-content {
flex: 1;
overflow-y: auto;
padding: 10px;
display: flex;
flex-direction: column;
}
.tab-content {
height: 100%;
flex: 1;
overflow-y: auto;
padding: 15px;
border-bottom: 1px solid #f0f0f0;
}
.tab-content:last-child {
border-bottom: none;
}
.tab-content.full-height {
flex: 1;
}
/* 自定义滚动条样式 */
.sidebar-content::-webkit-scrollbar,
.tab-content::-webkit-scrollbar {
width: 6px;
}
.sidebar-content::-webkit-scrollbar-track,
.tab-content::-webkit-scrollbar-track {
background: #f1f1f1;
}
.sidebar-content::-webkit-scrollbar-thumb,
.tab-content::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 3px;
}
.sidebar-content::-webkit-scrollbar-thumb:hover,
.tab-content::-webkit-scrollbar-thumb:hover {
background: #a8a8a8;
}

View File

@@ -1,65 +1,41 @@
// frontend-react/src/components/SideBarRight/SideBarRight.jsx
import React, { useState } from 'react';
import React, { useEffect } from 'react';
import './SideBarRight.css';
import DicePanel from '../DicePanel/DicePanel';
import ImageDisplay from '../ImageDisplay/ImageDisplay';
import useSideBarRightStore from '../../Store/Slices/SideBarRightSlice';
const SideBarRight = () => {
const [topActiveTab, setTopActiveTab] = useState('dice');
const [bottomActiveTab, setBottomActiveTab] = useState('macros');
const { selectedTabs, allTabs, handleTabClick, setTabComponent } = useSideBarRightStore();
const handleTopTabChange = (tab) => {
setTopActiveTab(tab);
};
const handleBottomTabChange = (tab) => {
setBottomActiveTab(tab);
};
// 设置标签组件
useEffect(() => {
setTabComponent('dice', DicePanel);
// 可以在这里设置其他标签的组件
}, [setTabComponent]);
return (
<div className="sidebar-right">
<div className="right-top">
<div className="sidebar-tabs">
<div className="sidebar-tabs">
{allTabs.map(tab => (
<button
className={`tab-button ${topActiveTab === 'dice' ? 'active' : ''}`}
onClick={() => handleTopTabChange('dice')}
key={tab.id}
className={`tab-button ${selectedTabs.includes(tab.id) ? 'active' : ''}`}
onClick={() => handleTabClick(tab.id)}
>
🎲 骰子与工具
{tab.label}
</button>
<button
className={`tab-button ${topActiveTab === 'debug' ? 'active' : ''}`}
onClick={() => handleTopTabChange('debug')}
>
🔍 上下文调试
</button>
</div>
<div className="sidebar-content">
{topActiveTab === 'dice' && <DicePanel />}
{topActiveTab === 'debug' && <div className="tab-content">上下文调试内容</div>}
</div>
))}
</div>
<div className="right-bottom">
<div className="sidebar-tabs">
<button
className={`tab-button ${bottomActiveTab === 'macros' ? 'active' : ''}`}
onClick={() => handleBottomTabChange('macros')}
>
🔧 快捷宏
</button>
<button
className={`tab-button ${bottomActiveTab === 'table' ? 'active' : ''}`}
onClick={() => handleBottomTabChange('table')}
>
📊 动态表格
</button>
</div>
<div className="sidebar-content">
{bottomActiveTab === 'macros' && <div className="tab-content">快捷宏内容</div>}
{bottomActiveTab === 'table' && <div className="tab-content">动态表格内容</div>}
</div>
<div className="sidebar-content">
{selectedTabs.map(tabId => {
const tab = allTabs.find(t => t.id === tabId);
return (
<div key={tabId} className={`tab-content ${selectedTabs.length === 1 ? 'full-height' : ''}`}>
{tab.component ? <tab.component /> : <div className="tab-content">{tab.label}内容</div>}
</div>
);
})}
</div>
</div>
);

View File

@@ -65,7 +65,7 @@ const Toolbar = () => {
<div className="toolbar-icons">
<div
className="toolbar-icon"
title="当前角色"
title="玩家角色"
onClick={() => handlePanelToggle('currentRole')}
>
👤
@@ -82,11 +82,11 @@ const Toolbar = () => {
<div className="toolbar-icons">
<div
className={`toolbar-icon ${activePanel === 'role' ? 'active' : ''}`}
title="角色管理"
title="ai角色"
onClick={() => handlePanelToggle('role')}
>
🎭
<span className="icon-label">全局世界书</span>
<span className="icon-label">角色管理</span>
</div>
<div className="toolbar-display-box">
{truncateText(getDisplayText())}

View File

@@ -1,76 +1,21 @@
/* frontend-react/src/index.css */
html, body {
margin: 0;
padding: 0;
height: 100vh;
width: 100%;
}
.app {
height: 100%;
display: flex;
flex-direction: column;
}
#root {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
}
/* 重置样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body, .app {
height: 100%;
width: 100%;
overflow: hidden;
}
.app {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
overflow: hidden;
}
/* 主内容区域 */
.main-container {
flex: 1;
display: flex;
overflow: hidden;
}
/* 左侧栏 */
.sidebar-left {
width: 250px;
width: 22.5%; /* 修改为30% */
height: 100%;
overflow: hidden;
}
/* 中间聊天区域 */
.chat-area {
flex: 1;
flex: 55%; /* 修改为0.4 */
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
/* 右侧栏 */
.sidebar-right {
width: 300px;
width: 22.5%; /* 修改为30% */
height: 100%;
overflow: hidden;
}
.toolbar {
height: 60px;
flex-shrink: 0;
}