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
+1
View File
@@ -88,3 +88,4 @@ export { heatmap } from './heatmap.js';
export { progressRing } from './progressRing.js';
export { noticeBar } from './noticeBar.js';
export { sortableList } from './sortableList.js';
export { masonry } from './masonry.js';
+21
View File
@@ -0,0 +1,21 @@
import { h } from '@ui-arch/frame';
import type { MasonryProps } from './types.js';
/*** 瀑布流:CSS 多列布局,列数按容器宽度自适应或显式指定;每项单独包一层才能 break-inside 不拆断 ***/
export function masonry(props: MasonryProps): HTMLElement {
// —— 状态集中声明 ——
const adaptive = !props.columns; // 未指定列数即自适应(column-width 让浏览器自己算列数)
const width = props.minColumnWidth ?? 240; // 自适应时的最小列宽(像素)
const gap = props.gap ?? 'var(--ua-space-3)'; // 列间距与行间距同源,避免两处各写一份
const root = h('div', { class: 'ua-masonry' }) as HTMLElement;
root.style.columnGap = gap;
if (adaptive) root.style.columnWidth = `${width}px`; // 自适应:容器越宽列数越多,窄屏自动降到一列
else root.style.columnCount = String(props.columns); // 显式列数:与 column-width 互斥,固定几列就几列
props.items.forEach((item) => {
const cell = h('div', { class: 'ua-masonry-item' }, item);
cell.style.marginBottom = gap; // 行间距与列间距同值,视觉上才是均匀网格
root.append(cell);
});
return root;
}
+8
View File
@@ -1146,3 +1146,11 @@ export interface SortableListHandle {
move: (from: number, to: number) => void; // 程序化搬位:下标越界或禁用时静默忽略
order: () => string[]; // 读取当前顺序(以 DOM 为唯一真相)
}
/*** 瀑布流入参 ***/
export interface MasonryProps {
items: unknown[]; // 每个卡片内容(字符串 / DOM / 响应式值),按数组顺序铺进最短列
columns?: number; // 固定列数;传了即不随容器宽度变化,与 minColumnWidth 互斥
minColumnWidth?: number; // 自适应列宽下限(像素);缺省 240,容器越宽列数越多
gap?: string; // 列间距与行间距(CSS 长度或令牌值);缺省 var(--ua-space-3)
}