feat(V0.2): 看板列内纵向滚动加固 + 滚动时右缘滚动条 (方案 B)
Docker Build and Push / build-image (push) Successful in 1m6s
Docker Build and Push / build-image (push) Successful in 1m6s
- 列体外包 .bcol-main (relative): 叠加自绘细滚动条, 滚动时出现、 停止约 700ms 后淡出, 宽 3px 不占卡片空间 - bcol-body 补 -webkit-overflow-scrolling/overscroll-behavior, 高度链显式化 (height:100%), 修真机列内滚不动的问题 - 列头保持固定不随滚动
This commit is contained in:
@@ -1,8 +1,39 @@
|
|||||||
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import TaskCard from '../../components/task/TaskCard.jsx'
|
import TaskCard from '../../components/task/TaskCard.jsx'
|
||||||
import useColumnDrag from '../../components/task/useColumnDrag.js'
|
import useColumnDrag from '../../components/task/useColumnDrag.js'
|
||||||
|
|
||||||
|
// 列体 + 右缘滚动条: 滚动时出现细滚动条, 停止约 700ms 后淡出
|
||||||
|
// (移动端 WebView 原生滚动条是即隐式的, 看板列窄、需要明确的滚动指示)
|
||||||
|
function ScrollBody({ children }) {
|
||||||
|
const ref = useRef(null)
|
||||||
|
const fade = useRef(null)
|
||||||
|
const [bar, setBar] = useState(null) // { h, y } 滚动条几何
|
||||||
|
|
||||||
|
useEffect(() => () => clearTimeout(fade.current), [])
|
||||||
|
|
||||||
|
function onScroll() {
|
||||||
|
const el = ref.current
|
||||||
|
if (!el) return
|
||||||
|
const max = el.scrollHeight - el.clientHeight
|
||||||
|
if (max <= 2) { setBar(null); return }
|
||||||
|
const h = Math.max(28, Math.round(el.clientHeight * (el.clientHeight / el.scrollHeight)))
|
||||||
|
const y = Math.round((el.scrollTop / max) * (el.clientHeight - h))
|
||||||
|
setBar({ h, y })
|
||||||
|
clearTimeout(fade.current)
|
||||||
|
fade.current = setTimeout(() => setBar(null), 700)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bcol-main">
|
||||||
|
<div className="bcol-body" ref={ref} onScroll={onScroll}>{children}</div>
|
||||||
|
<div className={'bcol-bar' + (bar ? ' on' : '')} style={bar ? { top: bar.y, height: bar.h } : undefined} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// 看板视图 (T-BD-01, T-UI-07)
|
// 看板视图 (T-BD-01, T-UI-07)
|
||||||
// 拖动 = 长按 400ms 激活, 卡片原位抬起, 指针划过列高亮, 松手落列 (重点设计 §7.1)
|
// 拖动 = 长按 400ms 激活, 卡片原位抬起, 指针划过列高亮, 松手落列 (重点设计 §7.1)
|
||||||
|
// 横向滚列; 列内独立纵向滚动, 列头固定, 滚动时右缘显示滚动条
|
||||||
// 不做"拖到卡片上转子任务" —— 统一走详情页「转为子任务」
|
// 不做"拖到卡片上转子任务" —— 统一走详情页「转为子任务」
|
||||||
export default function BoardView({
|
export default function BoardView({
|
||||||
tasks, columns, onMoveColumn, onOpen, onToggleSub, onToggle, onMore, onQuickAdd,
|
tasks, columns, onMoveColumn, onOpen, onToggleSub, onToggle, onMore, onQuickAdd,
|
||||||
@@ -33,7 +64,7 @@ export default function BoardView({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="bcol-body">
|
<ScrollBody>
|
||||||
{list.map((t) => (
|
{list.map((t) => (
|
||||||
<TaskCard
|
<TaskCard
|
||||||
key={t.id}
|
key={t.id}
|
||||||
@@ -48,7 +79,7 @@ export default function BoardView({
|
|||||||
))}
|
))}
|
||||||
{list.length === 0 && <div className="bcol-empty">暂无任务</div>}
|
{list.length === 0 && <div className="bcol-empty">暂无任务</div>}
|
||||||
<div className="badd" onClick={() => onQuickAdd?.(col.id)}>+ 添加任务</div>
|
<div className="badd" onClick={() => onQuickAdd?.(col.id)}>+ 添加任务</div>
|
||||||
</div>
|
</ScrollBody>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
+14
-3
@@ -1077,13 +1077,24 @@ body.me-safe-top .app-safe-top { height: 0; }
|
|||||||
display: flex; gap: 10px; padding: 0 12px 8px; overflow-x: auto; overflow-y: hidden;
|
display: flex; gap: 10px; padding: 0 12px 8px; overflow-x: auto; overflow-y: hidden;
|
||||||
flex: 1 1 auto; min-height: 0; align-items: stretch;
|
flex: 1 1 auto; min-height: 0; align-items: stretch;
|
||||||
}
|
}
|
||||||
.bcol { flex: 0 0 186px; display: flex; flex-direction: column; min-height: 0; }
|
.bcol { flex: 0 0 186px; display: flex; flex-direction: column; min-height: 0; }.bcol-head { display: flex; align-items: center; gap: 5px; padding: 0 2px 7px; flex-shrink: 0; }
|
||||||
.bcol-head { display: flex; align-items: center; gap: 5px; padding: 0 2px 7px; flex-shrink: 0; }
|
|
||||||
.bcol-name { font-size: 12px; font-weight: 700; color: #3d4450; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
.bcol-name { font-size: 12px; font-weight: 700; color: #3d4450; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||||
.bcol-cnt { font-size: 11px; color: #999; background: #e8ebef; border-radius: 999px; padding: 0 6px; line-height: 15px; }
|
.bcol-cnt { font-size: 11px; color: #999; background: #e8ebef; border-radius: 999px; padding: 0 6px; line-height: 15px; }
|
||||||
.bcol-bind { font-size: 10px; color: var(--color-primary); background: #f0f5ff; border-radius: 4px; padding: 0 4px; margin-left: auto; }
|
.bcol-bind { font-size: 10px; color: var(--color-primary); background: #f0f5ff; border-radius: 4px; padding: 0 4px; margin-left: auto; }
|
||||||
.bcol-bind.off { color: #999; background: #f2f3f5; }
|
.bcol-bind.off { color: #999; background: #f2f3f5; }
|
||||||
.bcol-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 7px; padding-bottom: 8px; }
|
.bcol-body {
|
||||||
|
flex: 1 1 auto; min-height: 0; height: 100%; overflow-y: auto;
|
||||||
|
display: flex; flex-direction: column; gap: 7px; padding-bottom: 8px;
|
||||||
|
-webkit-overflow-scrolling: touch; overscroll-behavior: contain;
|
||||||
|
}
|
||||||
|
/* 列体包裹层: 承载右缘滚动条 (滚动时出现, 停止后淡出) */
|
||||||
|
.bcol-main { flex: 1 1 auto; min-height: 0; position: relative; display: flex; }
|
||||||
|
.bcol-bar {
|
||||||
|
position: absolute; right: 1px; width: 3px; border-radius: 2px;
|
||||||
|
background: rgba(15, 23, 42, .3); opacity: 0; transition: opacity .25s ease;
|
||||||
|
pointer-events: none; z-index: 3;
|
||||||
|
}
|
||||||
|
.bcol-bar.on { opacity: 1; }
|
||||||
.bcol.dragover .bcol-body { background: #eaf2ff; border-radius: 8px; outline: 1.5px dashed var(--color-primary); }
|
.bcol.dragover .bcol-body { background: #eaf2ff; border-radius: 8px; outline: 1.5px dashed var(--color-primary); }
|
||||||
.bcol-empty { font-size: 11px; color: #c0c4cc; text-align: center; padding: 10px 0; }
|
.bcol-empty { font-size: 11px; color: #c0c4cc; text-align: center; padding: 10px 0; }
|
||||||
.bcard {
|
.bcard {
|
||||||
|
|||||||
Reference in New Issue
Block a user