iter(g305): 新增瀑布流布局 masonry

This commit is contained in:
HIsheR
2026-10-27 00:34:25 +08:00
parent adcd0f7dc5
commit 08f14ce0db
13 changed files with 182 additions and 10 deletions
+9
View File
@@ -3131,6 +3131,15 @@
"motivation": "sortableList 是句柄式组件(返回 { el, move, order }),与 form / virtualList 同类,但 18 条配方里没有一条演示句柄式拼装——Agent 照配方抄会把返回值直接当节点 append,页面一片空白;「顺序只存一份」「move 与拖拽同一条提交路径」这些约定也没人写下来。",
"acceptance": "① recipes.md 新增配方 19(编号连续、带代码块与要点),代码块里认出 sortableList / card / button / toast;② 要点覆盖句柄要 append(.el)、顺序唯一真相、move 与拖拽同路径、边缘不自动滚动、条目文案唯一;③ ua recipes 19 能取到该条,llms-full.txt 与 llms.txt 重生成;④ npm run verify / check 全绿。",
"notes": "recipes.md 新增配方 19:sortableList + card + button + toast 的可排序检查单,要点写清句柄要 append(.el)、顺序唯一真相、move 与拖拽同路径、边缘不自动滚动、文案唯一;ua recipes 19 可取出,llms.txt / llms-full.txt 重生成"
},
{
"id": "g305",
"domain": "new",
"status": "open",
"title": "新增瀑布流布局 masonry(89 个组件)",
"motivation": "库里有 grid(等宽等高的规则栅格)与 space(线性间距),但图片墙、评论流、看板这类「列高不等」的布局没有落点,业务侧只能自己写 column-width 与 break-inside,还要记住多列容器不能是 flex/grid 这个坑。",
"acceptance": "① masonry({ items, columns?, minColumnWidth?, gap? }) 走 CSS 多列:不传 columns 按 minColumnWidth 自适应,传了即固定列数;② 每项包 .ua-masonry-item 并 break-inside: avoid,卡片不在列边界拆断;③ gap 同时管列间距与行间距;④ 样式只消费 --ua-* 令牌,禁止新增硬编码阴影/时长/字号;⑤ manifest/docs/README/demo/llms-full 同步,组件 88→89,npm run check 全绿。",
"notes": ""
}
]
}
+42 -2
View File
@@ -1,6 +1,6 @@
{
"$schema": "ui-arch-registry-index/0.1",
"generatedAt": "2026-10-26T16:31:56.843Z",
"generatedAt": "2026-10-26T16:34:08.281Z",
"repoRoot": ".",
"packages": [
{
@@ -231,7 +231,8 @@
"heatmap(props):日历热力图,按周列 × 星期行铺格子、四档浓度表示当天数量,悬停看明细",
"progressRing(props):环形进度,SVG 双圆靠 dasharray 画弧 + 中心百分比,value 可传信号自动重绘",
"noticeBar(props):单行通知条,语义色 + 左侧符号 + 可选跑马灯与关闭,适合页顶常驻播报",
"sortableList(props):拖拽排序列表,整行可拖 + Alt+↑↓ 键盘搬位,返回 { el, move, order } 句柄"
"sortableList(props):拖拽排序列表,整行可拖 + Alt+↑↓ 键盘搬位,返回 { el, move, order } 句柄",
"masonry(props):瀑布流多列布局,列宽自适应或固定列数,卡片不被拆到两列"
],
"keyTypes": [
"ButtonProps",
@@ -4696,6 +4697,45 @@
"外部要按代码调整顺序用句柄 move(from, to),下标越界或禁用时静默忽略;order() 以 DOM 为唯一真相回读当前顺序",
"什么时候别用:条目超过一屏(拖到边缘不会自动滚动,改用筛选或上下按钮)、需要跨列表搬运(用两个实例并自己管状态)"
]
},
{
"id": "masonry",
"title": "瀑布流 Masonry",
"demo": "sec-masonry",
"props": [
{
"n": "items",
"t": "unknown[]",
"r": 1,
"d": "每个卡片内容(字符串 / DOM / 响应式值);数组顺序即铺放顺序,列高不等由内容自己决定"
},
{
"n": "columns",
"t": "number",
"d": "固定列数;传了即不随容器宽度变化,与 minColumnWidth 互斥"
},
{
"n": "minColumnWidth",
"t": "number",
"d": "自适应列宽下限(像素);缺省 240,容器越宽列数越多",
"df": "240"
},
{
"n": "gap",
"t": "string",
"d": "列间距与行间距(CSS 长度或令牌值);缺省 var(--ua-space-3)",
"df": "var(--ua-space-3)"
}
],
"example": "masonry({ minColumnWidth: 220, items: shots.map((s) => card({ title: s.title }, image({ src: s.url }))) })",
"steps": [
"items 里直接放 card / image / 任意 DOM:每项由组件包一层 .ua-masonry-item,只有这一层带 break-inside: avoid,卡片才不会在列边界断成两截",
"不传 columns 就按 minColumnWidth 自适应:容器变宽自动加列、窄屏自动降到一列,不需要自己监听 window.resize",
"要固定几列(比如大屏看板恒 4 列)就传 columns,此时 minColumnWidth 不再生效——两者互斥,别同时传指望它俩协商",
"间距传一次就够:gap 同时给 column-gap 与每项的 margin-bottom,列间距和行间距天然一致;改间距只改这一处",
"列高不等才是瀑布流的价值所在(图片墙、评论流、看板):等高内容请用 grid,瀑布流会把等高卡片铺成奇怪的错位",
"什么时候别用:需要严格的行对齐(表格化数据)、需要按列独立滚动(用 splitter / 多个 virtualList),以及首屏内容需要按阅读顺序严格横向(多列布局是竖向填充,读屏顺序与视觉列序一致但不等同于行序)"
]
}
]
},