@composy/grid-core
v0.0.2
Published
High-performance, framework-agnostic grid layout engine
Maintainers
Readme
@composy/grid-core
高性能、框架无关的网格布局引擎,支持拖拽、调整大小、碰撞检测、undo/redo、键盘导航和响应式断点。
安装
pnpm add @composy/grid-core快速开始
import { createGrid } from '@composy/grid-core'
const grid = createGrid('#container', {
column: 12,
cellHeight: 80,
gap: 10
})
grid.addWidget({ x: 0, y: 0, w: 4, h: 2, content: '<div>Widget 1</div>' })
grid.addWidget({ x: 4, y: 0, w: 4, h: 2, content: '<div>Widget 2</div>' })核心 API
createGrid / Grid 类
| 方法 | 说明 |
| --------------------------- | --------------- |
| addWidget(data) | 添加网格项 |
| addWidgets(items) | 批量添加 |
| removeWidget(id) | 移除指定项 |
| removeAll() | 移除全部 |
| getWidget(id) | 获取指定项 |
| getWidgets() | 获取所有项 |
| updateWidget(id, updates) | 更新项属性 |
| moveWidget(id, x, y) | 移动项位置 |
| resizeWidget(id, w, h) | 调整项大小 |
| load(items) | 加载布局 |
| save() | 保存当前布局 |
| compact() | 自动压缩 |
| enable() / disable() | 启用/禁用 |
| undo() / redo() | 撤销/重做 |
| canUndo() / canRedo() | 是否可撤销/重做 |
| select(id) / deselect() | 选中/取消选中 |
| batchUpdate(fn) | 批量更新 |
事件
dragstart · drag · dragend · resizestart · resize · resizeend · change · added · removed · undo · redo · select · deselect · breakpoint · init · destroy · enable · disable · ready · compact
类名规范
所有运行时 class 使用 ldesign-grid 前缀,遵循 BEM 规范:
- 块级:
ldesign-grid、ldesign-grid__container - 元素:
ldesign-grid__item、ldesign-grid__item-content、ldesign-grid__item-inner、ldesign-grid__placeholder - 修饰符:
ldesign-grid--disabled、ldesign-grid--dragging、ldesign-grid--resizing、ldesign-grid--static、ldesign-grid--dark、ldesign-grid--dragover、ldesign-grid--drop-in
CSS 变量
所有样式通过 --ldesign-grid-* CSS 变量控制,颜色默认引用 packages/color 的 --ld-* 变量,尺寸默认引用 packages/size 的 --ld-* 变量。
:root {
--ldesign-grid-background-color: var(--ld-bg-page);
--ldesign-grid-surface-color: var(--ld-bg-surface);
--ldesign-grid-text-color: var(--ld-text-primary);
--ldesign-grid-border-color: var(--ld-border);
--ldesign-grid-placeholder-background-color: ...;
--ldesign-grid-item-border-radius: var(--ld-radius-md);
--ldesign-grid-gap: var(--ld-spacing-sm);
/* ... */
}可通过 options.theme 传入自定义主题变量覆盖默认值。
功能特性
- 拖拽 & 调整大小:鼠标 + 触摸支持,8 方向调整手柄
- 碰撞检测:push / swap / none 模式
- 自动压缩:紧凑布局算法
- undo/redo:完整历史栈,可配置最大深度
- 键盘导航:Arrow/Tab/Delete/Escape 键操控
- 响应式断点:按 viewport 宽度自动切换列数/间距
- 外部拖入:支持从外部元素拖入网格
- 主题化:CSS 变量 + color/size token 桥接
构建产物
| 目录 | 格式 | 入口 |
| ------- | --------------------- | ------------------------------------ |
| dist/ | UMD | dist/index.js、dist/index.min.js |
| es/ | ESM (preserveModules) | es/index.js |
| esm/ | ESM (preserveModules) | esm/index.js |
| lib/ | CJS | lib/index.cjs |
开发
pnpm run type-check # 类型检查
pnpm run build # 构建
pnpm run test:run # 运行测试增强能力与使用约定
深度更新配置
setOptions 接受 DeepPartial<GridOptions>,嵌套配置会合并而不是整体替换;数组会复制,数值配置会在进入布局引擎前归一化。getOptions 返回独立快照,调用方可以安全地修改返回值而不会改变运行中的网格。
grid.setOptions({
scroll: { enabled: true, sensitivity: 24 },
animate: { enabled: true, duration: 180 },
theme: { itemBorderRadius: 'var(--ld-radius-md)' }
})
const snapshot = grid.getOptions()
snapshot.scroll = { enabled: false }原子化加载与批量更新
load(items) 会先校验重复 ID、规范化尺寸和位置,再一次性替换布局;输入不合法时不会留下半加载状态。batchUpdate 支持嵌套调用,批量期间延迟布局计算,并在最外层结束时统一刷新。
grid.batchUpdate(() => {
grid.updateWidget('sales', { w: 6, h: 3 })
grid.updateWidget('trend', { x: 6, y: 0, w: 6, h: 3 })
})外部拖入
可以把网格外部的卡片、模板列表或文件入口注册为拖入源。setupExternalDrag 返回清理函数,重复配置前应先调用它;网格销毁时会自动解绑源元素和文档级监听器。
grid.setupExternalDrag({
source: '.widget-palette [data-widget]',
defaultSize: { w: 3, h: 2 },
createItem: el => ({
id: `widget-${el.dataset.widget}`,
content: el.dataset.label ?? 'New widget'
}),
helper: 'clone',
removeOnDrop: false
})
stop()Web Component、SSR 与多文档环境
Web Component 注册过程会检查自定义元素是否已经存在,异步初始化在元素断开后会被忽略。Core 的 DOM 工具、样式表和监听器均以容器所属的 ownerDocument 为边界,适合 iframe、测试文档和 SSR 后再挂载的场景。
事件与可观察性
除原有的 change、拖拽、缩放、撤销和响应式断点事件外,批量操作会保留单项 added、removed 等领域事件,并在批量结束时发出最终布局变更。持久化层建议在最外层 change 事件中调用 save(),不要在每个像素级 drag 事件中写入远端存储。
