feat(admin): make all sortable/repeater cards collapsible, collapsed by default
- Add useCollapsibleItems: key-based open state, clickable/keyboard head, aria-expanded - sortable items with sub-fields and every inline repeater/group row now collapse - Repeater head summary falls back to the first filled field when no listPreview - Drop per-schema collapsible/defaultCollapsed for repeater groups (JS + PHP) - Align FloatBtnItemPanel head with the shared collapse attrs Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8843ae4261
commit
116b6b2223
9 files changed
+114
-76
No files matched your search
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* 可排序卡片列表的折叠状态:所有带展开区的卡片默认收起,点击行头展开/收起。
|
||||
*
|
||||
* 状态按行的稳定 key 记录(而不是下标),拖拽换位后每张卡片保持自己的开合状态。
|
||||
* 行头属性统一由 collapseHeadAttrs 生成:可点击、可键盘操作(Enter / Space)、
|
||||
* 带 aria-expanded,样式见 styles/sortable-list.css。
|
||||
*/
|
||||
import { ref } from 'vue'
|
||||
|
||||
export function collapseHeadAttrs(open, toggle) {
|
||||
return {
|
||||
class: 'is-clickable',
|
||||
role: 'button',
|
||||
tabindex: 0,
|
||||
'aria-expanded': open ? 'true' : 'false',
|
||||
onClick: toggle,
|
||||
onKeydown: (event) => {
|
||||
// 只响应行头本身的按键,行内按钮 / 输入框的 Enter、空格不触发折叠。
|
||||
if (event.target !== event.currentTarget) return
|
||||
if (event.key !== 'Enter' && event.key !== ' ') return
|
||||
event.preventDefault()
|
||||
toggle()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export function useCollapsibleItems() {
|
||||
const openKeys = ref(new Set())
|
||||
|
||||
function isOpen(key) {
|
||||
return openKeys.value.has(key)
|
||||
}
|
||||
|
||||
function toggle(key) {
|
||||
const next = new Set(openKeys.value)
|
||||
if (next.has(key)) next.delete(key)
|
||||
else next.add(key)
|
||||
openKeys.value = next
|
||||
}
|
||||
|
||||
function headAttrs(key) {
|
||||
return collapseHeadAttrs(isOpen(key), () => toggle(key))
|
||||
}
|
||||
|
||||
return { isOpen, toggle, headAttrs }
|
||||
}
|
||||
Reference in new issue
Block a user