feat: 完整实现手风琴效果与动态高度音乐列表

## 核心功能
- 手风琴效果:展开任意音乐时收起其他所有展开项
- 互斥展开:展开音乐时自动收起当前选中声音模块
- 动态高度:音乐展开时移除容器高度限制,完整展示所有内容

## UI优化
- 音乐信息横向布局:音乐名、声音名、按钮同排对齐
- 声音名称位置调整:优化垂直对齐,增加下移间距
- 平滑动画:添加容器高度过渡动画效果

## 技术实现
- 重构展开逻辑:统一状态管理,确保互斥性
- 动态CSS类:基于展开状态动态添加hasExpanded类
- 响应式设计:容器高度自适应内容变化

## 用户体验
- 界面整洁:同时只展开一个区域,避免视觉混乱
- 内容完整:展开时确保所有声音信息可见
- 交互流畅:平滑动画过渡,提升操作体验
This commit is contained in:
walle 2025-11-18 21:19:40 +08:00
parent aefa28ea99
commit c76d953142
2 changed files with 28 additions and 15 deletions

View file

@ -50,7 +50,7 @@ export function SelectedSoundsDisplay() {
Object.keys(state.sounds).filter(id => state.sounds[id].isSelected) Object.keys(state.sounds).filter(id => state.sounds[id].isSelected)
); );
// 独立展开逻辑:两个区域可以独立展开/收起 // 独立展开逻辑:展开当前选中声音时收起所有展开的音乐
const toggleExpandedCurrent = () => { const toggleExpandedCurrent = () => {
setExpandedCurrent(!expandedCurrent); setExpandedCurrent(!expandedCurrent);
if (!expandedCurrent) { if (!expandedCurrent) {
@ -101,12 +101,19 @@ export function SelectedSoundsDisplay() {
setExpandedMusic(prev => { setExpandedMusic(prev => {
const newSet = new Set(prev); const newSet = new Set(prev);
if (newSet.has(musicId)) { if (newSet.has(musicId)) {
// 如果点击已展开的音乐,直接收起
newSet.delete(musicId); newSet.delete(musicId);
} else { } else {
newSet.add(musicId); // 如果点击未展开的音乐,收起其他所有展开的项目,只展开当前这个
return new Set([musicId]);
} }
return newSet; return newSet;
}); });
// 展开音乐时,同时收起当前选中声音模块
if (!expandedMusic.has(musicId)) {
setExpandedCurrent(false);
}
}; };
// 根据选中的声音ID获取声音对象 // 根据选中的声音ID获取声音对象
@ -354,7 +361,7 @@ export function SelectedSoundsDisplay() {
{/* 音乐列表 - 展开时显示 */} {/* 音乐列表 - 展开时显示 */}
{expandedMyMusic && ( {expandedMyMusic && (
<div className={styles.musicList}> <div className={`${styles.musicList} ${expandedMusic.size > 0 ? styles.hasExpanded : ''}`}>
{console.log('🎵 渲染音乐列表:', { isLoadingMusic, listLength: savedMusicList.length })} {console.log('🎵 渲染音乐列表:', { isLoadingMusic, listLength: savedMusicList.length })}
{isLoadingMusic ? ( {isLoadingMusic ? (
<div className={styles.loading}>...</div> <div className={styles.loading}>...</div>

View file

@ -134,6 +134,12 @@
overflow-y: auto; overflow-y: auto;
border-radius: 6px; border-radius: 6px;
background: var(--color-component-bg); background: var(--color-component-bg);
transition: max-height 0.3s ease;
}
/* 当有展开的音乐项时,移除高度限制 */
.musicList.hasExpanded {
max-height: none;
} }
.musicItem { .musicItem {
@ -191,8 +197,9 @@
flex: 1; flex: 1;
min-width: 0; min-width: 0;
display: flex; display: flex;
flex-direction: column; flex-direction: row;
gap: 2px; align-items: center;
gap: 8px;
} }
/* 音乐操作按钮容器 - 右侧按钮 */ /* 音乐操作按钮容器 - 右侧按钮 */
@ -207,14 +214,13 @@
.soundNames { .soundNames {
font-size: 12px; font-size: 12px;
color: var(--color-foreground-subtle); color: var(--color-foreground-subtle);
line-height: 1.4; line-height: 1.2;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 2px; gap: 2px;
align-items: center; align-items: center;
padding: 1px 4px; padding: 6px 0;
flex: 1; margin: 0;
justify-content: flex-start;
} }
/* 展开按钮 */ /* 展开按钮 */
@ -223,14 +229,14 @@
border: 1px solid var(--color-border); border: 1px solid var(--color-border);
color: var(--color-foreground-subtle); color: var(--color-foreground-subtle);
border-radius: 4px; border-radius: 4px;
padding: 2px 6px; padding: 4px 8px;
font-size: 10px; font-size: 11px;
cursor: pointer; cursor: pointer;
transition: all 0.2s ease; transition: all 0.2s ease;
flex-shrink: 0; flex-shrink: 0;
height: 24px; height: auto;
line-height: 1; line-height: 1;
margin-left: 4px; margin: 0;
} }
.expandButton:hover { .expandButton:hover {
@ -287,8 +293,8 @@
font-size: 11px; font-size: 11px;
transition: all 0.2s ease; transition: all 0.2s ease;
flex-shrink: 0; flex-shrink: 0;
height: 24px; height: auto;
margin-top: 2px; margin: 0;
} }
.deleteButton:hover { .deleteButton:hover {