Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A draggable and resizable grid layout with responsive breakpoints, for React.

License

NotificationsYou must be signed in to change notification settings

react-grid-layout/react-grid-layout

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

travis buildCDNJSnpm packagenpm downloads

React-Grid-Layout is a grid layout system much likePackery orGridster, for React.

Unlike those systems, it is responsive and supports breakpoints. Breakpoint layouts can be provided by the useror autogenerated.

RGL is React-only and does not require jQuery.

BitMEX UI

GIF from production usage onBitMEX.com

[Demo |Changelog |CodeSandbox Editable demo]

Table of Contents

Demos

  1. Showcase
  2. Basic
  3. No Dragging/Resizing (Layout Only)
  4. Messy Layout Autocorrect
  5. Layout Defined on Children
  6. Static Elements
  7. Adding/Removing Elements
  8. Saving Layout to LocalStorage
  9. Saving a Responsive Layout to LocalStorage
  10. Minimum and Maximum Width/Height
  11. Dynamic Minimum and Maximum Width/Height
  12. No Vertical Compacting (Free Movement)
  13. Prevent Collision
  14. Error Case
  15. Toolbox
  16. Drag From Outside
  17. Bounded Layout
  18. Responsive Bootstrap-style Layout
  19. Scaled Containers
  20. Allow Overlap
  21. All Resizable Handles
  22. Single Row Horizontal

Projects Using React-Grid-Layout

Know of others? Create a PR to let me know!

Features

  • 100% React - no jQuery
  • Compatible with server-rendered apps
  • Draggable widgets
  • Resizable widgets
  • Static widgets
  • Configurable packing: horizontal, vertical, or off
  • Bounds checking for dragging and resizing
  • Widgets may be added or removed without rebuilding grid
  • Layout can be serialized and restored
  • Responsive breakpoints
  • Separate layouts per responsive breakpoint
  • Grid Items placed using CSS Transforms
    • Performance with CSS Transforms:on /off, note paint (green) as % of time
  • Compatibility with<React.StrictMode>
VersionCompatibility
>= 0.17.0React 16 & 17
>= 0.11.3React 0.14 & 15
>= 0.10.0React 0.14
0.8. - 0.9.2React 0.13
< 0.8React 0.12

Installation

Install the React-Grid-Layoutpackage usingnpm:

npm install react-grid-layout

Include the following stylesheets in your application:

/node_modules/react-grid-layout/css/styles.css/node_modules/react-resizable/css/styles.css

Usage

Use ReactGridLayout like any other component. The following example below willproduce a grid with three items where:

  • users will not be able to drag or resize itema
  • itemb will be restricted to a minimum width of 2 grid blocks and a maximum width of 4 grid blocks
  • users will be able to freely drag and resize itemc
importGridLayoutfrom"react-grid-layout";classMyFirstGridextendsReact.Component{render(){// layout is an array of objects, see the demo for more complete usageconstlayout=[{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(<GridLayoutclassName="layout"layout={layout}cols={12}rowHeight={30}width={1200}><divkey="a">a</div><divkey="b">b</div><divkey="c">c</div></GridLayout>);}}

You may also choose to set layout properties directly on the children:

importGridLayoutfrom"react-grid-layout";classMyFirstGridextendsReact.Component{render(){return(<GridLayoutclassName="layout"cols={12}rowHeight={30}width={1200}><divkey="a"data-grid={{x:0,y:0,w:1,h:2,static:true}}>          a</div><divkey="b"data-grid={{x:1,y:0,w:3,h:2,minW:2,maxW:4}}>          b</div><divkey="c"data-grid={{x:4,y:0,w:1,h:2}}>          c</div></GridLayout>);}}

Usage without Browserify/Webpack

A module usable in a<script> tag is includedhere. It uses a UMD shim andexcludesReact, so it must be otherwise available in your application, either via RequireJS or onwindow.React.

Responsive Usage

To make RGL responsive, use the<ResponsiveReactGridLayout> element:

import{ResponsiveasResponsiveGridLayout}from"react-grid-layout";classMyResponsiveGridextendsReact.Component{render(){// {lg: layout1, md: layout2, ...}constlayouts=getLayoutsFromSomewhere();return(<ResponsiveGridLayoutclassName="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}}><divkey="1">1</div><divkey="2">2</div><divkey="3">3</div></ResponsiveGridLayout>);}}

When in responsive mode, you should supply at least one breakpoint via thelayouts property.

When usinglayouts, it is best to supply as many breakpoints as possible, especially the largest one.If the largest is provided, RGL will attempt to interpolate the rest.

You will also need to provide awidth, when using<ResponsiveReactGridLayout> it is suggested you use the HOCWidthProvider as per the instructions below.

It is possible to supply default mappings via thedata-grid property on individualitems, so that they would be taken into account within layout interpolation.

Providing Grid Width

Both<ResponsiveReactGridLayout> and<ReactGridLayout> takewidth to calculatepositions on drag events. In simple cases a HOCWidthProvider can be used to automatically determinewidth upon initialization and window resize events.

import{Responsive,WidthProvider}from"react-grid-layout";constResponsiveGridLayout=WidthProvider(Responsive);classMyResponsiveGridextendsReact.Component{render(){// {lg: layout1, md: layout2, ...}varlayouts=getLayoutsFromSomewhere();return(<ResponsiveGridLayoutclassName="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}}><divkey="1">1</div><divkey="2">2</div><divkey="3">3</div></ResponsiveGridLayout>);}}

This allows you to easily replaceWidthProvider with your own Provider HOC if you need more sophisticated logic.

WidthProvider accepts a single prop,measureBeforeMount. Iftrue,WidthProvider will measure thecontainer's width before mounting children. Use this if you'd like to completely eliminate any resizing animationon application/component mount.

Have a more complicated layout?WidthProvideris very simple and onlylistens to window'resize' events. If you need more power and flexibility, try theSizeMe React HOC as an alternative to WidthProvider.

Grid Layout Props

RGL supports the following properties (see the source for the final word on this):

//// Basic props//// This allows setting the initial width on the server side.// This is required unless using the HOC <WidthProvider> or similarwidth:number,// If true, the container height swells and contracts to fit contentsautoSize: ?boolean=true,// Number of columns in this layout.cols: ?number=12,// A CSS selector for tags that will not be draggable.// For example: draggableCancel:'.MyNonDraggableAreaClassName'// If you forget the leading . it will not work.// .react-resizable-handle" is always prepended to this value.draggableCancel: ?string='',// A CSS selector for tags that will act as the draggable handle.// For example: draggableHandle:'.MyDragHandleClassName'// If you forget the leading . it will not work.draggableHandle: ?string='',// Compaction type.compactType: ?('vertical'|'horizontal'|null)='vertical';// Layout is an array of objects with the format:// The index into the layout must match the key used on each item component.// If you choose to use custom keys, you can specify that key in the layout// array objects using the `i` prop.layout: ?Array<{i?:string,x:number,y:number,w:number,h:number}>=null,// If not provided, use data-grid props on children// Margin between items [x, y] in px.margin: ?[number,number]=[10,10],// Padding inside the container [x, y] in pxcontainerPadding: ?[number,number]=margin,// Rows have a static height, but you can change this based on breakpoints// if you like.rowHeight: ?number=150,// Configuration of a dropping element. Dropping element is a "virtual" element// which appears when you drag over some element from outside.// It can be changed by passing specific parameters://  i - id of an element//  w - width of an element//  h - height of an elementdroppingItem?:{i:string,w:number,h:number}//// Flags//isDraggable: ?boolean=true,isResizable: ?boolean=true,isBounded: ?boolean=false,// Uses CSS3 translate() instead of position top/left.// This makes about 6x faster paint performanceuseCSSTransforms: ?boolean=true,// If parent DOM node of ResponsiveReactGridLayout or ReactGridLayout has "transform: scale(n)" css property,// we should set scale coefficient to avoid render artefacts while dragging.transformScale: ?number=1,// If true, grid can be placed one over the other.// If set, implies `preventCollision`.allowOverlap: ?boolean=false,// If true, grid items won't change position when being// dragged over. If `allowOverlap` is still false,// this simply won't allow one to drop on an existing object.preventCollision: ?boolean=false,// If true, droppable elements (with `draggable={true}` attribute)// can be dropped on the grid. It triggers "onDrop" callback// with position and event object as parameters.// It can be useful for dropping an element in a specific position//// NOTE: In case of using Firefox you should add// `onDragStart={e => e.dataTransfer.setData('text/plain', '')}` attribute// along with `draggable={true}` otherwise this feature will work incorrect.// onDragStart attribute is required for Firefox for a dragging initialization//@see https://bugzilla.mozilla.org/show_bug.cgi?id=568313isDroppable: ?boolean=false,// Defines which resize handles should be rendered.// Allows for any combination of:// 's' - South handle (bottom-center)// 'w' - West handle (left-center)// 'e' - East handle (right-center)// 'n' - North handle (top-center)// 'sw' - Southwest handle (bottom-left)// 'nw' - Northwest handle (top-left)// 'se' - Southeast handle (bottom-right)// 'ne' - Northeast handle (top-right)//// Note that changing this property dynamically does not work due to a restriction in react-resizable.resizeHandles: ?Array<'s'|'w'|'e'|'n'|'sw'|'nw'|'se'|'ne'>=['se'],// Custom component for resize handles// See `handle` as used in https://github.com/react-grid-layout/react-resizable#resize-handle// Your component should have the class `.react-resizable-handle`, or you should add your custom// class to the `draggableCancel` prop.resizeHandle?:ReactElement<any>|((resizeHandleAxis:ResizeHandleAxis,ref:ReactRef<HTMLElement>)=>ReactElement<any>),//// Callbacks//// Callback so you can save the layout.// Calls back with (currentLayout) after every drag or resize stop.onLayoutChange:(layout:Layout)=>void,//// All callbacks below have signature (layout, oldItem, newItem, placeholder, e, element).// 'start' and 'stop' callbacks pass `undefined` for 'placeholder'.//typeItemCallback=(layout:Layout,oldItem:LayoutItem,newItem:LayoutItem,placeholder:LayoutItem,e:MouseEvent,element:HTMLElement)=>void,// Calls when drag starts.onDragStart:ItemCallback,// Calls on each drag movement.onDrag:ItemCallback,// Calls when drag is complete.onDragStop:ItemCallback,// Calls when resize starts.onResizeStart:ItemCallback,// Calls when resize movement happens.onResize:ItemCallback,// Calls when resize is complete.onResizeStop:ItemCallback,//// Dropover functionality//// Calls when an element has been dropped into the grid from outside.onDrop:(layout:Layout,item: ?LayoutItem,e:Event)=>void,// Calls when an element is being dragged over the grid from outside as above.// This callback should return an object to dynamically change the droppingItem size// Return false to short-circuit the dragoveronDropDragOver:(e:DragOverEvent)=> ?({|w?:number,h?:number|}|false),// Ref for getting a reference for the grid's wrapping div.// You can use this instead of a regular ref and the deprecated `ReactDOM.findDOMNode()`` function.// Note that this type is React.Ref<HTMLDivElement> in TypeScript, Flow has a bug here// https://github.com/facebook/flow/issues/8671#issuecomment-862634865innerRef:{current:null|HTMLDivElement},

Responsive Grid Layout Props

The responsive grid layout can be used instead. It supports all of the props above, exceptinglayout.The new properties and changes are:

// {name: pxVal}, e.g. {lg: 1200, md: 996, sm: 768, xs: 480}// Breakpoint names are arbitrary but must match in the cols and layouts objects.breakpoints: ?Object={lg:1200,md:996,sm:768,xs:480,xxs:0},// # of cols. This is a breakpoint -> cols map, e.g. {lg: 12, md: 10, ...}cols: ?Object={lg:12,md:10,sm:6,xs:4,xxs:2},// margin (in pixels). Can be specified either as horizontal and vertical margin, e.g. `[10, 10]` or as a breakpoint -> margin map, e.g. `{lg: [10, 10], md: [10, 10], ...}.margin:[number,number]|{[breakpoint:$Keys<breakpoints>]:[number,number]},// containerPadding (in pixels). Can be specified either as horizontal and vertical padding, e.g. `[10, 10]` or as a breakpoint -> containerPadding map, e.g. `{lg: [10, 10], md: [10, 10], ...}.containerPadding:[number,number]|{[breakpoint:$Keys<breakpoints>]:[number,number]},// layouts is an object mapping breakpoints to layouts.// e.g. {lg: Layout, md: Layout, ...}layouts:{[key:$Keys<breakpoints>]:Layout},//// Callbacks//// Calls back with breakpoint and new # colsonBreakpointChange:(newBreakpoint:string,newCols:number)=>void,// Callback so you can save the layout.// AllLayouts are keyed by breakpoint.onLayoutChange:(currentLayout:Layout,allLayouts:{[key:$Keys<breakpoints>]:Layout})=>void,// Callback when the width changes, so you can modify the layout as needed.onWidthChange:(containerWidth:number,margin:[number,number],cols:number,containerPadding:[number,number])=>void;

Grid Item Props

RGL supports the following properties on grid items or layout items. When initializing a grid,build a layout array (as in the first example above), or attach this object as thedata-grid propertyto each of your child elements (as in the second example).

Ifdata-grid is provided on an item, it will take precedence over an item in thelayout with the same key (i).

Note that if a grid item is provided but incomplete (missing one ofx, y, w, or h), an errorwill be thrown so you can correct your layout.

If no properties are provided for a grid item, one will be generated with a width and height of1.

You can set minimums and maximums for each dimension. This is for resizing; it of course has no effect if resizingis disabled. Errors will be thrown if your mins and maxes overlap incorrectly, or your initial dimensionsare out of range.

Any<GridItem> properties defined directly will take precedence over globally-set options. Forexample, if the layout has the propertyisDraggable: false, but the grid item has the propisDraggable: true, the itemwill be draggable, even if the item is markedstatic: true.

{// A string corresponding to the component keyi:string,// These are all in grid units, not pixelsx:number,y:number,w:number,h:number,minW: ?number=0,maxW: ?number=Infinity,minH: ?number=0,maxH: ?number=Infinity,// If true, equal to `isDraggable: false, isResizable: false`.static: ?boolean=false,// If false, will not be draggable. Overrides `static`.isDraggable: ?boolean=true,// If false, will not be resizable. Overrides `static`.isResizable: ?boolean=true,// By default, a handle is only shown on the bottom-right (southeast) corner.// As of RGL >= 1.4.0, resizing on any corner works just fine!resizeHandles?: ?Array<'s'|'w'|'e'|'n'|'sw'|'nw'|'se'|'ne'>=['se']// If true and draggable, item will be moved only within grid.isBounded: ?boolean=false}

Grid Item Heights and Widths

Grid item widths are based on container and number of columns. The size of a grid unit's height is based onrowHeight.

Note that an item that hash=2 isnot exactly twice as tall as one withh=1 unless you have nomargin!

In order for the grid to not be ragged, when an item spans grid units, it must also span margins. So you must add the height or width or the margin you are spanning for each unit. So actual pixel height is(rowHeight * h) + (marginH * (h - 1).

For example, withrowHeight=30,margin=[10,10] and a unit with height 4, the calculation is(30 * 4) + (10 * 3)

margin

If this is a problem for you, setmargin=[0,0] and handle visual spacing between your elements inside the elements' content.

Performance

<ReactGridLayout> hasan optimizedshouldComponentUpdate implementation, but it relies on the user memoizing thechildren array:

// lib/ReactGridLayout.jsx// ...shouldComponentUpdate(nextProps:Props,nextState:State){return(// NOTE: this is almost always unequal. Therefore the only way to get better performance// from SCU is if the user intentionally memoizes children. If they do, and they can// handle changes properly, performance will increase.this.props.children!==nextProps.children||!fastRGLPropsEqual(this.props,nextProps,isEqual)||!isEqual(this.state.activeDrag,nextState.activeDrag));}// ...

If you memoize your children, you can take advantage of this, and reap faster rerenders. For example:

functionMyGrid(props){constchildren=React.useMemo(()=>{returnnewArray(props.count).fill(undefined).map((val,idx)=>{return<divkey={idx}data-grid={{x:idx,y:1,w:1,h:1}}/>;});},[props.count]);return<ReactGridLayoutcols={12}>{children}</ReactGridLayout>;}

Because thechildren prop doesn't change between rerenders, updates to<MyGrid> won't result in new renders, improving performance.

React Hooks Performance

Using hooks to save your layout state on change will cause the layouts to re-render as the ResponsiveGridLayout will change it's value on every render.To avoid this you should wrap your WidthProvider in a useMemo:

constResponsiveReactGridLayout=useMemo(()=>WidthProvider(Responsive),[]);

Custom Child Components and Draggable Handles

If you use React Components as grid children, they need to do a few things:

  1. Forward refs to an underlying DOM node, and
  2. Forwardstyle,className,onMouseDown,onMouseUp andonTouchEnd to that same DOM node.

For example:

constCustomGridItemComponent=React.forwardRef(({style, className, onMouseDown, onMouseUp, onTouchEnd, children, ...props},ref)=>{return(<divstyle={{/* styles */, ...style}}className={className}ref={ref}onMouseDown={onMouseDown}onMouseUp={onMouseUp}onTouchEnd={onTouchEnd}>{/* Some other content */}{children}{/* Make sure to include children to add resizable handle */}</div>);})

The same is true of custom elements as draggable handles using thedraggableHandle prop. This is so thatthe underlyingreact-draggable library can get a reference to the DOM node underneath, manipulatepositioning viastyle, and set classes.

Contribute

If you have a feature request, please add it as an issue or make a pull request.

If you have a bug to report, please reproduce the bug inCodeSandbox to helpus easily isolate it.

TODO List

  • Basic grid layout
  • Fluid grid layout
  • Grid packing
  • Draggable grid items
  • Live grid packing while dragging
  • Resizable grid items
  • Layouts per responsive breakpoint
  • Define grid attributes on children themselves (data-grid key)
  • Static elements
  • Persistent id per item for predictable localstorage restores, even when # items changes
  • Min/max w/h per item
  • Resizable handles on other corners
  • Configurable w/h per breakpoint

[8]ページ先頭

©2009-2025 Movatter.jp