diff --git a/stash-web/src/App.css b/stash-web/src/App.css index 3477ded..b881d65 100644 --- a/stash-web/src/App.css +++ b/stash-web/src/App.css @@ -975,22 +975,51 @@ gap: var(--su-space-2); } +/* 折叠箭头:与前台侧栏 Menu 的 caret 同一套画法(CSS 画的 6px 角标) */ .group-caret { - width: 20px; + display: inline-flex; flex: none; + align-items: center; + justify-content: center; + width: 20px; + height: 20px; padding: 0; border: none; background: none; color: var(--su-text-muted); - font-size: var(--su-font-size-sm); - line-height: 1; cursor: pointer; } +.group-caret::before { + content: ''; + width: 6px; + height: 6px; + border-left: 1px solid currentColor; + border-bottom: 1px solid currentColor; + opacity: 0.4; + transform: rotate(315deg); + transition: + transform var(--su-duration-base) var(--su-ease-in-out), + opacity var(--su-duration-base) var(--su-ease-in-out); +} + +.group-caret:hover::before { + opacity: 0.7; +} + +.group-caret-open::before { + opacity: 0.7; + transform: rotate(135deg); +} + .group-caret-empty { cursor: default; } +.group-caret-empty::before { + display: none; +} + /* 分组图标选择:搜索 + 图标网格 */ .icon-picker { display: flex; @@ -1080,12 +1109,16 @@ } .group-action { + display: inline-flex; + align-items: center; + gap: var(--su-space-1); padding: 0; border: none; background: none; color: var(--su-color-primary); font-size: var(--su-font-size-sm); cursor: pointer; + white-space: nowrap; } .group-action:hover { diff --git a/stash-web/src/components/admin/AdminNext.tsx b/stash-web/src/components/admin/AdminNext.tsx index 54c5ab7..b9f33e2 100644 --- a/stash-web/src/components/admin/AdminNext.tsx +++ b/stash-web/src/components/admin/AdminNext.tsx @@ -22,7 +22,7 @@ import { toast, type IconName, } from '@stash/ui' -import { useEffect, useMemo, useState } from 'react' +import { useEffect, useMemo, useRef, useState } from 'react' import { changePassword, fetchSession, logout, type SessionState } from '../../auth' import { LoginDialog } from '../auth/LoginDialog' import { GroupMark as GroupGlyph } from '../common/GroupMark' @@ -495,6 +495,24 @@ function GroupsPanel({ const [collapsed, setCollapsed] = useState>(new Set()) const [dialog, setDialog] = useState(null) + // 默认全部收起:数据第一次到位时,把所有有子节点的分组塞进 collapsed + const seeded = useRef(false) + useEffect(() => { + if (seeded.current || groups.length === 0) return + seeded.current = true + const keys = new Set() + const walk = (nodes: GroupNode[]) => { + for (const node of nodes) { + if (node.children.length > 0) { + keys.add(node.key) + walk(node.children) + } + } + } + walk(groups) + setCollapsed(keys) + }, [groups]) + const rows = useMemo(() => { const result: { node: GroupNode; level: number }[] = [] const walk = (nodes: GroupNode[], level: number) => { @@ -529,7 +547,7 @@ function GroupsPanel({ return ( - 分组用于控制前台侧边栏与卡片;可多层嵌套,根分组决定格式。内容(条目)只挂在分组上。 + 说明:分组用于控制前台侧边栏与卡片;可多层嵌套,根分组决定格式。内容(条目)只挂在分组上。
@@ -563,12 +581,11 @@ function GroupsPanel({ {hasChildren ? ( + /> ) : (