Awesome
STRML/react-grid-layout
<!-- [![size-img]][size] -->「 React-Grid-Layout:网格布局(grid layout)系统,但专为 React 服务 」
校对 ✅
<!-- doc-templite START generated --> <!-- repo = 'STRML/react-grid-layout' --> <!-- commit = '80873c88b32755bd0ae028df20edc955c2c55d3e' --> <!-- time = '2019-02-02' -->翻译的原文 | 与日期 | 最新更新 | 更多 |
---|---|---|---|
commit | ⏰ 2019-02-02 | 中文翻译 |
- readme
- 1. 展示
- 2. 基本
- 3. 没有 拖放/调整大小 (仅是 布局)
- 4. 凌乱排版,自动更正
- 5. 在子级上,定义的布局
- 6. 静态元素
- 7. 添加/删除元素
- 8. 将布局保存到本地存储
- 9. 将响应布局,保存到本地存储(LocalStorage)
- 10. 最小和最大宽度/高度
- 11. 动态的,最小和最大宽度/高度
- 12. 无垂直紧凑(自由移动)
- 13. 防止碰撞
- 14. 错误案例
- 15. 工具箱
贡献
欢迎 👏 勘误/校对/更新贡献 😊 具体贡献请看
生活
If help, buy me coffee —— 营养跟不上了,给我来瓶营养快线吧! 💰
React grid layout
React-Grid-Layout 是一个非常类似Packery要么Gridster的网格布局(grid layout)系统,但专为 React 服务。
与那些系统不同,它具有响应性,并支持断点(breakpoints)。断点布局可由用户提供或自动生成。
RGL(React-Grid-Layout 的缩写) 是 React-only,且不需要 jQuery。
GIF 来自BitMEX.com的实际演示。
[Demo|Changelog|CodeSandbox 可编辑 DEmo]
目录
<!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> <!-- END doctoc generated TOC please keep comment here to allow auto update -->演示
- 展示
- 基本
- 没有 拖放/调整大小 (仅是 布局)
- 乱排版式,自动更正
- 在子级上,定义的布局
- 静态元素
- 添加/删除元素
- 将布局保存到本地存储
- 将响应布局保存到本地存储(LocalStorage)
- 最小和最大宽度/高度
- 动态的,最小和最大宽度/高度
- 无垂直紧凑(自由移动)
- 防止碰撞
- 错误案例
- 工具箱
使用 React-Grid-Layout 的项
- BitMEX
- AWS CloudFront Dashboards
- Grafana
- Metabase
- HubSpot
- ComNetViz
- Stoplight
- Reflect
- ez-Dashing
- Kibana
- Graphext
知道别的吗?创建个 PR,让我知道!
特征
- 100%React - 没有 jQuery
- 与服务器呈现的应用程序,兼容
- 可拖动的小部件
- 可调整大小的小部件
- 静态小部件
- 可配置砌砖:水平,垂直或关闭
- 拖动和调整大小的边缘检查
- 可以添加或删除小部件,而无需重建网格
- 布局可以序列化和恢复
- 响应 breakpoints
- 每个响应 breakpoint 的单独布局
- 使用 CSS Transforms 放置的网格项
- 性能:on/off,注意(绿色)油漆所占的时间百分比
版本 | 兼容性 |
---|---|
> = 0.11.3 | React 0.14 和 v15 |
> = 0.10.0 | React 0.14 |
0.8。- 0.9.2 | React 0.13 |
<0.8 | React 0.12 |
安装
安装 React-Grid-Layout package,使用npm:
npm install react-grid-layout
在您的应用程序中,包含以下样式表:
/node_modules/react-grid-layout/css/styles.css
/node_modules/react-resizable/css/styles.css
用法
像任何其他组件一样,使用 ReactGridLayout。以下示例将生成一个包含三个项的网格,其中:
- 用户将无法对
a
项拖动或调整大小 b
项将限制为最小宽度为 2 个网格块,最大宽度为 4 个网格块。- 用户将能够对
c
项,自由拖动和调整其大小
import GridLayout from 'react-grid-layout';
class MyFirstGrid extends React.Component {
render() {
// layout(布局) 为 一个具有多对象数组, 你可以看看Demo展示集合,里面有更完整的用法
var layout = [
{i: 'a', x: 0, y: 0, w: 1, h: 2, static: true},
{i: 'b', x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4},
{i: 'c', x: 4, y: 0, w: 1, h: 2}
];
return (
<GridLayout
className="layout"
layout={layout}
cols={12}
rowHeight={30}
width={1200}
>
<div key="a">a</div>
<div key="b">b</div>
<div key="c">c</div>
</GridLayout>
);
}
}
您也可以直接在子(children)项上,设置布局属性:
import GridLayout from 'react-grid-layout';
class MyFirstGrid extends React.Component {
render() {
return (
<GridLayout className="layout" cols={12} rowHeight={30} width={1200}>
<div key="a" data-grid={{x: 0, y: 0, w: 1, h: 2, static: true}}>
a
</div>
<div key="b" data-grid={{x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4}}>
b
</div>
<div key="c" data-grid={{x: 4, y: 0, w: 1, h: 2}}>
c
</div>
</GridLayout>
);
}
}
不使用 Browserify / Webpack 的用法
可用于<script>
标签的模块,包括在这里。它使用 UMD shim,并排除React
,因此必须通过 RequireJS 或提供window.React
,才能在你应用中工作。
响应模式的用法
应用 RGL 的响应模式,请使用<ResponsiveReactGridLayout>
元素:
import {Responsive as ResponsiveGridLayout} from 'react-grid-layout';
class MyResponsiveGrid extends React.Component {
render() {
// {lg: layout1, md: layout2, ...}
var layouts = getLayoutsFromSomewhere();
return (
<ResponsiveGridLayout
className="layout"
layouts={layouts}
breakpoints={{lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0}}
cols={{lg: 12, md: 10, sm: 6, xs: 4, xxs: 2}}
>
<div key="1">1</div>
<div key="2">2</div>
<div key="3">3</div>
</ResponsiveGridLayout>
);
}
}
在响应模式下,您应该通过layouts
属性提供至少一个断点(breakpoints)。
使用layouts
时,最好提供尽可能多的断点,尤其是最大的断点。如果最大值已提供,RGL 将尝试插入其余部分。
你还需要提供一个width
,在使用<ResponsiveReactGridLayout>
时,建议你使用 HOCWidthProvider
,按照以下说明。
目前,无法通过个别项的data-grid
属性,提供响应映射,但快到了。
提供网格宽度
<ResponsiveReactGridLayout>
和<ReactGridLayout>
两者,都采取width
,计算 drag 事件的位置。在简单的情况下,一个 HOCWidthProvider
可在初始化和窗口 resize 事件时,自动确定宽度。
import {Responsive, WidthProvider} from 'react-grid-layout';
const ResponsiveGridLayout = WidthProvider(Responsive);
class MyResponsiveGrid extends React.Component {
render() {
// {lg: layout1, md: layout2, ...}
var layouts = getLayoutsFromSomewhere();
return (
<ResponsiveGridLayout
className="layout"
layouts={layouts}
breakpoints={{lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0}}
cols={{lg: 12, md: 10, sm: 6, xs: 4, xxs: 2}}
>
<div key="1">1</div>
<div key="2">2</div>
<div key="3">3</div>
</ResponsiveGridLayout>
);
}
}
这使您可以轻松更换WidthProvider
,为您自己的 Provider HOC,如果您需要更复杂的逻辑的话。
WidthProvider
接受一个 Props,measureBeforeMount
。如果为true
,WidthProvider
将在安装(mount) children 之前,测量容器的宽度。如果您想完全消除 应用程序/组件 mount 上的,任何调整大小动画,请使用此选项。
有一个更复杂的布局?WidthProvider
是很简单的,并且只听监听'resize'
的窗口事件。如果您需要更多功能和灵活性,请尝试使用SizeMe React HOC,作为 WidthProvider 的替代品。
网格布局 Props
RGL 支持以下属性(请参阅,最终来源):
//
// 基础 props
//
// 设置 初始 width 在服务器端.
// 必须的,除非使用 HOC <WidthProvider> 或 类似的
width: number,
// 如果为 true ,容器高度会膨胀,并紧凑以适应内容物。
autoSize: ?boolean = true,
// 此布局中的列数。
cols: ?number = 12,
// 一个CSS选择器, 不能拖放
// 例如: draggableCancel:'.MyNonDraggableAreaClassName'
// 若你忘了加上 `.` ,那么就不会工作
draggableCancel: ?string = '',
// 一个CSS选择器, 能拖放处理.
// 例如: draggableHandle:'.MyDragHandleClassName'
// 若你忘了加上 `.` ,那么就不会工作
draggableHandle: ?string = '',
// 如果是 true, 这个布局 垂直紧凑
verticalCompact: ?boolean = true,
// 紧凑类型.
compactType: ?('vertical' | 'horizontal') = 'vertical';
// Layout 是由一定格式的对象所组成的数组:
// {x: number, y: number, w: number, h: number}
// layout的索引,必须匹配,用在每个组件项上的 key。
// 如果 你选择使用自定义的 keys, 你可以指定为,在 layout
// 数组中对象的 keys ,像这样( i 就是 key ):
// {i: string, x: number, y: number, w: number, h: number}
layout: ?array = null, // 如果 不提供, 那使用 children 的 data-grid props
// [x, y]项与项之间的 Margin ,px 单位.
margin: ?[number, number] = [10, 10],
// 容器 [x, y] 里面的 Padding ,px 单位.
containerPadding: ?[number, number] = margin,
// Rows 具有一个 静态 height, 但
// 如果你喜欢的话,你可以基于 breakpoints,改变它.
rowHeight: ?number = 150,
//
// 标志
//
isDraggable: ?boolean = true,
isResizable: ?boolean = true,
// 使用 CSS3 translate() 代替 position top/left.
// 会让性能提升 6 倍
useCSSTransforms: ?boolean = true,
// 若 true,当其被拖(放)起来时,网格项不会改变 position。
preventCollision: ?boolean = false;
//
// 回调函数
//
// 因为 回调函数, 所以你可以保存 layout.
// 在每次 drag 或 resize stop事件之后,用 (currentLayout) 回调。
onLayoutChange: (layout: Layout) => void,
//
// 所有下面的回调函数,都有同样的函数参数签名 (layout, oldItem, newItem, placeholder, e, element).
// 'start' 和 'stop' 函数会给它们的参数 'placeholder', 传递 `undefined`。
//
type ItemCallback = (layout: Layout, oldItem: LayoutItem, newItem: LayoutItem,
placeholder: LayoutItem, e: MouseEvent, element: HTMLElement) => void;
// 开始拖动时,调用。
onDragStart: ItemCallback,
// 每次拖动时,调用。
onDrag: ItemCallback,
// 拖动完成后,调用。
onDragStop: ItemCallback,
// 开始调整大小时,调用。
onResizeStart: ItemCallback,
// 当发生调整大小移动时,调用。
onResize: ItemCallback,
// 当调整大小完成后,调用。
onResizeStop: ItemCallback
响应式网格布局 Props
可以使用响应式网格布局。它支持上面的所有 Props,除了layout
。新属性和更改是:
// {name: pxVal}, 例如: {lg: 1200, md: 996, sm: 768, xs: 480}
// 断点名称是任意的,但必须在 cols和 layouts 对象中,匹配。
breakpoints: ?Object = {lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0},
#
// cols 的 #。这是一个断点 -> cols 的 map,例如:{lg: 12, md: 10, ...}
cols: ?Object = {lg: 12, md: 10, sm: 6, xs: 4, xxs: 2},
// 布局是将断点,映射到布局的对象。
// 例如: {lg: Layout, md: Layout, ...}
layouts: {[key: $Keys<breakpoints>]: Layout}
//
// 回调
//
// 使用断点和新 # 列回调
onBreakpointChange: (newBreakpoint: string, newCols: number) => void,
// 回调,以便保存布局。
// 所有布局都由断点,打上key。
onLayoutChange: (currentLayout: Layout, allLayouts: {[key: $Keys<breakpoints>]: Layout}) => void,
// 当宽度更改时回调,以便根据需要,修改布局。
onWidthChange: (containerWidth: number, margin: [number, number], cols: number, containerPadding: [number, number]) => void;
网格项 Props
RGL 的网格项或布局项支持以下属性。初始化网格时,构建一个布局数组(如上面的第一个示例中,所示),或者将此对象附加到,每个子元素的data-grid
属性(如第二个示例中,所示)。
请注意,如果提供的网格项不完整(缺少其中一个)x, y, w, or h
),将抛出错误,以便更正您的布局。
如果没有为网格项,提供属性,则将生成宽度和高度为1
的网格项。
您可以为每个层级,设置最小值和最大值。这是为了调整大小;如果禁用调整大小,它当然没有效果。如果您的最小值和最大值,重叠不正确,或者您的初始尺寸超出范围,则会引发错误。
<GridItem>
直接定义的任何属性,优先于全局设置选项。例如,如果布局具有isDraggable: false
属性,但网格项 Props 有 isDraggable: true
,该项将是可拖动的。
{
// 一个 字符串,对应组件的 key
i: string,
// 在 grid 单元中的所有, 不是 像素(px)
x: number,
y: number,
w: number,
h: number,
minW: ?number = 0,
maxW: ?number = Infinity,
minH: ?number = 0,
maxH: ?number = Infinity,
// 如果为 true, 等于`isDraggable: false, isResizable: false`.
static: ?boolean = false,
// 如果为 false, 则不能拖放 draggable. 被 `static` 覆盖.
isDraggable: ?boolean = true,
// 如果为 false, 则不能调整大小 resizable. 被 `static` 覆盖.
isResizable: ?boolean = true
}
帮助
如果您有功能请求,请将其添加为问题或提出拉取请求。
如果您有错误报告,请在CodeSandbox重现该错误,帮助我们轻松识别它。
TODO 清单
- 基本网格布局
- 流体(Fluid)网格布局
- 网格砌砖
- 可拖动的网格项
- 拖动时,实时网格砌砖
- 可调整大小的网格项
- 每个响应断点的布局
- children 自己,定义网格属性(
data-grid
key) - 静态元素
- 可预测的本地存储恢复,每个项的保留 ID,即使#项发生更改,也是如此
- 每项,都有 最小/最大限制的 w/h
- 其他角落,可调整大小的控制
- 每个断点,可配置 w/h