The layout engine for React

Overview

Responsive, sortable, filterable and draggable grid layouts with React

npm React: Component Circle Ci Code style: Prettier Typescript: Codebase

Design Principles πŸ‘¨πŸ»β€πŸ«

Muuri-React is the React implementation of the amazing Muuri layout engine. This library allows you to build all kinds of layouts with React and make them responsive, sortable, filterable, draggable and/or animated.
All Muuri features are implemented in a React-friendly way, with custom components and hooks, to guarantee the simplest developer experience.

Features πŸ’Ž

  • Fully customizable layout πŸ“
  • Drag-and-drop (even between grids) βœ‹
  • Simple, Powerful, and Intuitive API ⚑️
  • Extremely performant πŸš€
  • Custom hooks πŸ”Œ
  • Nested grids πŸ“Ž
  • Scrollable grids πŸ–±οΈ
  • Filtering βœ”
  • Sorting πŸ—ƒ
  • Support IE9+ (with polyfills) 🌐
  • Touch support πŸ“±
  • Typescript ✍️
  • Fully open source β€βš–οΈ

Documentation πŸ“–

You can find the full documentation here.

Examples πŸ’‘

All examples have been created to explain one or more features of Muuri-react in an easy and direct way.

Motivation πŸ‘¨πŸ»β€πŸ«

You can build pretty amazing layouts without a single line of JavaScript these days. However, sometimes CSS just isn't enough, and that's where Muuri comes along. At it's very core Muuri is a layout engine which is limited only by your imagination πŸ’­ . You can build any kind of layout, asynchronously in web workers if you wish.

Layouts aside, you might need to sprinkle some flare (animations ⚑ ) and interactivity (filtering, sorting, drag and drop βœ‹ ) on your layout. Stuff gets complex pretty fast and most of us probably reach for existing libraries to handle the complexity at that point. This is why most of these extra features are built into Muuri's core, so you don't have to go hunting for additional libraries or re-inventing the wheel for the nth time.

The long-term goal of Muuri is to provide a simple (and as low-level as possible) API for building amazing layouts with unmatched performance πŸš€ and most of the complexity πŸ“¦ abstracted away.

Help us grow ❀️

Muuri-react was born recently but is already very stable and full of features as it is based on the amazing Muuri layout engine. If you like πŸ‘ this project you can help us grow by starring ⭐ the repository.

Contributing πŸŽ—οΈ

Contributions are always welcome. Before contributing, please read our Guidlines.

Credits 🀝

Thanks to Niklas RΓ€mΓΆ for the amazing work with Muuri.

License Β©

Copyright Β© 2020 Paolo Longo β€’ MIT license.

Comments
  • onSend doesn't seem to be firing when trying to reparent.

    onSend doesn't seem to be firing when trying to reparent.

    I'm trying to reparent and the onSend doesn't seem to be firing. I have two MuuriComponents and have set everything up as per the tutorial (https://paol-imi.github.io/muuri-react/#/usage/reparenting) as seem below, but I must be missing something.

    export const layoutOptions = {
      dragReleaseDuration: 200,
      dragSortHeuristics: {
        sortInterval: 60
      },
      layoutDuration: 200,
      dragReleaseEasing: "ease",
      layoutEasing: "ease",
      dragEnabled: true,
      dragContainer: document.body,
      // The placeholder of an item that is being dragged.
      dragPlaceholder: {
        enabled: true,
        duration: 200,
        createElement: (item) => {
          return item.getElement().cloneNode();
        }
      },
    };
    
    const items = {
    
      target: [
        { id: "1", text: "Item 1", height: 1, width: 1, color: "blue" },
        { id: "2", text: "Item 2", height: 1, width: 1, color: "blue" },
        { id: "3", text: "Item 3", height: 2, width: 1, color: "blue" },
        { id: "4", text: "Item 4", height: 1, width: 1, color: "blue" },
        { id: "5", text: "Item 5", height: 1, width: 3, color: "blue" },
        { id: "6", text: "Item 6", height: 1, width: 1, color: "blue" },
        { id: "7", text: "Item 7", height: 1, width: 1, color: "blue" },
        { id: "8", text: "Item 8", height: 1, width: 2, color: "blue" },
        { id: "9", text: "Item 9", height: 2, width: 1, color: "blue" },
        { id: "10", text: "Item 10", height: 1, width: 1, color: "blue" },
        { id: "11", text: "Item 11", height: 1, width: 1, color: "blue" },
        { id: "12", text: "Item 12", height: 1, width: 1, color: "blue" },
      ],
      source: [
        { id: "13", text: "Extra", height: 1, width: 1, color: "blue" },
      ],
    }
    
    const MuuriTest = props => {
    
      const [cards, setCards] = useState(items);
      
      const targetChildren = cards.target.map(item => <DraggableCard key={item.id} {...item} />);
      const sourceChildren = cards.source.map(item => <DraggableCard key={item.id} {...item} />);
      return (
        <div>
          <MuuriComponent 
            {...layoutOptions} 
            dragEnabled
            id={"SOURCE"}
            onSend={({ key }) => {
              console.log('onSend source')
              // The sent item.
              const sentItem = cards.source.find(item => item.key === key)
              // The cards categories.
              const source = cards.source.filter(item => item !== sentItem)
              const target = cards.target.concat(sentItem)
    
              // Set the state.
              setCards({ source, target })
            }}
          >
            {sourceChildren}
          </MuuriComponent>
          <MuuriComponent 
            {...layoutOptions} 
            dragEnabled
            id={"TARGET"}
            onSend={({ key }) => {
              console.log('onSend target')
              // The sent item.
              const sentItem = cards.target.find(item => item.key === key)
              // The cards categories.
              const target = cards.target.filter(item => item !== sentItem)
              const source = cards.source.concat(sentItem)
    
              // Set the state.
              setCards({ source, target })
            }}
           >
            {targetChildren}
          </MuuriComponent>
        </div>
      );
    };
    
    export default MuuriTest;
    

    The console.log() isn't even showing up. Any help on this would be much appreciated.

    question πŸ€” 
    opened by Davenporten 13
  • Cannot read property 'key' of null

    Cannot read property 'key' of null

    In my scenario, I dynamically create grids (multiple MuuriComponents) using some state of my items. My items have a button to change the state, so in the UI they should immediately be moved to another grid by pressing this button (no dragging involved).

    Most of the time this throws an Uncaught TypeError: Cannot read property 'key' of null since item._component is null in handleArray coming from GridComponent.

    Since this does not always happen, I guess there is some timing problem, in which the item is not properly removed from the old grid (the item is still present, but its component is null). Maybe it's related that vars.itemsToRemove is [].

    Do you have any ideas on how to resolve that?

    bug 🐞 ready βœ”οΈ 
    opened by tschneid 10
  • "window" is not available during server side rendering.

    Hey there,

    Gatsby throws me this error when I want to run 'gatsby build' Do you know any workaround for this ?

    Thanks !

     ERROR #95312 
    
    "window" is not available during server side rendering.
    
    See our docs page for more info on this error: https://gatsby.dev/debug-html
    
    
      216 | 
      217 |   // Find the supported transform prop and style names.
    > 218 |   var docElemStyle = window.document.documentElement.style;
          | ^
      219 |   var style = 'transform';
      220 |   var styleCap = 'Transform';
      221 |   var found = false;
    
    
      WebpackError: ReferenceError: window is not defined
      
      - muuri.js:218 
        node_modules/muuri/dist/muuri.js:218:1
      
      - muuri.js:19 
        node_modules/muuri/dist/muuri.js:19:63
      
      - muuri.js:22 Object../node_modules/muuri/dist/muuri.js
        node_modules/muuri/dist/muuri.js:22:2
      
      - index.js:1 Object../node_modules/muuri-react/build/index.js
        node_modules/muuri-react/build/index.js:1:1034
      
      - index.js:1 n
        node_modules/muuri-react/build/index.js:1:112
      
      - index.js:1 Module.<anonymous>
        node_modules/muuri-react/build/index.js:1:15762
      
      - index.js:1 n
        node_modules/muuri-react/build/index.js:1:112
      
      - index.js:1 ./node_modules/muuri-react/build/index.js
        node_modules/muuri-react/build/index.js:1:915
      
      - index.js:1 Object../node_modules/muuri-react/build/index.js
        node_modules/muuri-react/build/index.js:1:932
      
      - realisations.js:1 Module../src/pages/realisations.js
        src/pages/realisations.js:1:1
      
    
    
    question πŸ€” 
    opened by pmarxbraun 7
  • Updating state with new items causes

    Updating state with new items causes "Uncaught TypeError: Cannot read property '_component' of undefined"

    image

    After I initialize the grid with initial items, I try to update the muuri grid by updating the state of the items with new items. If I step through it I can see that the grid does get updated with the new items (although they are stacked on each other), somewhere down the line I get the errors above.

    Searching around has suggested using import * as React from 'react'; but I already have that setup.

    Any ideas on what could be going wrong?

    question πŸ€” 
    opened by kennyt6 7
  • Cannot find the __reactInternalInstance$

    Cannot find the __reactInternalInstance$

    Hi Paolo,

    I'm trying to use muuri-react while I'm learning react. I keep getting this error Uncaught Invariant: Invariant failed: Cannot find the __reactInternalInstance$

    https://github.com/Paol-imi/muuri-react/blob/f31c84771cf9fa2d66c12cf5b0dde6d6e090b400/src/controllers/fiberController.ts#L150

    While debugging if I change the key to the one that starts with __reactFiber$ the code doesn't seem to throw any errors. Without this it blanks out my entire app. My dependencies are as below, (I have downgraded muuri to 0.8.0 coz I thought 0.9.3 doesnt work well with this)

      "dependencies": {
        "@material-ui/core": "^4.11.0",
        "@material-ui/icons": "^4.9.1",
        "@testing-library/jest-dom": "^5.11.5",
        "@testing-library/react": "^11.1.1",
        "@testing-library/user-event": "^12.2.0",
        "i18next": "^19.8.3",
        "muuri": "^0.8.0",
        "muuri-react": "^3.1.6",
        "react": "^17.0.1",
        "react-dom": "^17.0.1",
        "react-i18next": "^11.7.3",
        "react-scripts": "4.0.0",
        "web-animations-js": "^2.3.2",
        "web-vitals": "^0.2.4"
      },
    
    question πŸ€” 
    opened by XEonAX 6
  • layout problems when items have a dynamic height

    layout problems when items have a dynamic height

    Hi! IΒ΄m having some layout problems when items have a dynamic height. I started from your kanban example, and added a button to toggle the height size to items. Here you can see the code: https://codesandbox.io/s/muuri-react-kanban-mdmt7?file=/style.css:2702-2721

    Changes I made: -I added a button and state to your index.js to toggle items between two heights. -I passed that state to the items through props. -I added a height className with a ternary operator to each item. -I added useRefresh on each item using the dependecy variable from props. -I modifified css (removed height and padding from .board-item & .board-item-content) -I created two classes with different height If I start to move items between columns (toggling the button between movements), I can see that layout breaks. Attached are some images. b a

    What am I doing wrong?

    question πŸ€” 
    opened by juanisimioli 5
  • muuri-react doesn't work with later version of muuri

    muuri-react doesn't work with later version of muuri

    Trying with muuri v. 0.9.x prevents any item from rendering on the screen. It appears that their display: block CSS property is never set and always stays at display:none.

    repro: Take this codesandbox - https://codesandbox.io/s/muuri-react-grid-1czo5 and change muuri version to 0.9 in the package.json file.

    question πŸ€” 
    opened by krsnaa 4
  • Use overflow: auto

    Use overflow: auto

    According to the docs, to use responsive styling, we need to use overflow: scroll: https://paol-imi.github.io/muuri-react/docs/usage/responsive-style

    Can this strict requirement be circumvented by recalculating the whole grid? I've tried to use overflow: auto and using the grid reference to .layout() everytime an item is added (and would cause the scrollbar to suddenly appear). But that did not work.

    Any other way to get overflow: auto to work? Having that scrollbar there all the whole time is not desirable for my use case.

    enhancement πŸ›  help wanted πŸ‘‹ Related to Muuri πŸ“¦ 
    opened by Vluf 4
  • Container has zero height in horizontal layout

    Container has zero height in horizontal layout

    Ciao, and thank you for your work!

    I'm trying to get muuri-react to work with my project and am experiencing an issue with horizontal layout. Not sure if it's a bug, as I'm very new to web development and might be missing something.

    Basically, when enabling the horizontal layout option, the container has zero height and I can't add any text at the bottom.

    Example: https://codesandbox.io/s/muuri-react-kanban-detv8?file=/index.js (I added a "This should be below" div that I want to stay below the kanban board)

    How do I make sure the container has the correct height?

    Thanks :)

    question πŸ€” 
    opened by ftruzzi 3
  • `Cannot read property 'child' of null` in prod env

    `Cannot read property 'child' of null` in prod env

    Here is some promble when I run in prod env but it can run in dev env

    here is my git store my store dev script npm run start then you can visit in localhost:8080

    build script npm run build then you can find the index.html in /dist/index.html please open it in browser it is the prod env and it has the problem

    Here is the error in browser console react-dom.production.min.js?ca5d:196 TypeError: Cannot read property 'child' of null

    the raw code in your store components/gridComponent.js store.itemsOwner = getItemsOwner(vars.grid);

    in the node_modules/muuri-react build/index.js function z(e){return e._owner.child}

    when I console.log(e) in prod env

    $$typeof: Symbol(react.element)
    key: null
    props: {value: {…}, children: Array(3)}
    ref: null
    type: {$$typeof: Symbol(react.provider), _context: {…}, displayName: "GridProvider"}
    _owner: null
    

    _owner is null

    when I console.log(e) in dev env

    $$typeof: Symbol(react.element)
    key: null
    props: {value: {…}, children: Array(3)}
    ref: null
    type: {$$typeof: Symbol(react.provider), _context: {…}, displayName: "GridProvider"}
    _owner: FiberNode {tag: 0, key: null, elementType: Ζ’, type: Ζ’, stateNode: null, …}
    _store: {validated: false}
    _self: null
    _source: null
    __proto__: Object
    

    _owner is FiberNode

    I try it in create-react-app too but after build it has same error

    bug 🐞 ready βœ”οΈ 
    opened by sunnyabc789 3
  • Reset to initial values after moved cards between different grids

    Reset to initial values after moved cards between different grids

    Hello! I'm working in a Trello-like application and I'm having some issues with the UI. In order to replicate the problem, I've used the codesandbox for your Kanban demo and just added a RESET button.

    The example begins like this image

    Then I move any item from any grid to the other (in this example Item four from todo -> working)

    image

    And finally, I clicked reset, expecting to go back to the initial state (with Item four in TODO list) and this happened

    image

    In order to do this, I am just updating the local state of the component, which has an array of items being displayed in the UI.

    From this point, if you try to do anything, the grid goes wild and everything works wrong.

    This is the link to the sandbox if you want to try it by yourself https://codesandbox.io/s/muuri-react-kanban-hlfxd?file=/index.js

    Thanks in advance

    question πŸ€” 
    opened by gafernandez87 2
  • Broken link in drag handle

    Broken link in drag handle

    There is a broken link in the drag handle section: https://paol-imi.github.io/muuri-react/docs/usage/drag-and-drop/ https://paol-imi.github.io/muuri-react/docs/usage/api-reference/muuricomponent#draghandle

    opened by MubashirWaheed 0
  • Getting element.getBoundingClientRect is not a function error, while doing Click and Drag in my Physical machine.

    Getting element.getBoundingClientRect is not a function error, while doing Click and Drag in my Physical machine.

    Getting element.getBoundingClientRect is not a function error while doing Click and Drag in my Physical machine.

    This error I'm not getting in my Code Sandbox

    I have installed React 16.13.1 and React-Dom 16.13.1

    What is the root cause for the issue, and how to resolve it?

    muuri.module.js:1324 Uncaught TypeError: element.getBoundingClientRect is not a function
        at getContentRect (muuri.module.js:1324:1)
        at push../node_modules/muuri/dist/muuri.module.js.AutoScroller._checkItemOverlap (muuri.module.js:1877:1)
        at push../node_modules/muuri/dist/muuri.module.js.AutoScroller._updateRequests (muuri.module.js:2127:1)
        at push../node_modules/muuri/dist/muuri.module.js.AutoScroller._readTick (muuri.module.js:1710:1)
        at push../node_modules/muuri/dist/muuri.module.js.Ticker._step (muuri.module.js:1035:1)
    

    image

    Previously I had React 17 version displaying a blank screen when I added the Muuri component! so I have downgraded it, then it worked!

    opened by rajath002 0
  • How to access the

    How to access the "grid" object from MuuriComponent to get the order of items?

    The docs mention grid.getItems() to get all the items. But in my use case, I would like to get the order of items after each drag & drop action.

    How could this be done?

    opened by gouterz 0
  • useReferesh example is not valid. Why do we even need it in this case which is shown in the example.

    useReferesh example is not valid. Why do we even need it in this case which is shown in the example.

    Here is the sandbox example of mine where I have achieved the same without using either useReferesh and useEffect.

    https://codesandbox.io/s/affectionate-carlos-bc2qe?file=/src/App.js

    It will work because whenever we change any sate using useState in function component or this.setState in-class component react update rerender the component automatically. Screenshot 2021-12-17 at 11 41 51 AM

    opened by yadavseetaram 0
  • Error: Can't resolve 'muuri' in '...\node_modules\muuri-react\dist'

    Error: Can't resolve 'muuri' in '...\node_modules\muuri-react\dist'

    Playing around to see if muuri can replace reac-grid-layout, because a lot of features seem more interesting. But project seems dead? Also getting error after installing yarn package:

    Error: Can't resolve 'muuri' in '...\node_modules\muuri-react\dist'

    opened by alex254 0
  • Fix React 17 crash due to internal key name change in getFiber

    Fix React 17 crash due to internal key name change in getFiber

    According to this stackoverflow answer:

    If you are using using React 17, you can try "__reactFiber" instead of "__reactInternalInstance". It seems React changed this property name in React 17.

    Update the logic in getFiber to be compatible with both v16 and v17 property names. Peer and test dependencies were updated to use v17 and appear to be functioning.

    Fixes Paol-imi/muuri-react#49

    opened by marcelchastain 0
Releases(3.0.0)
Owner
Paolo Longo
Italian student of computer engineering at the Milan Polytechnic.
Paolo Longo
🀸 Configurable grid and layout engine for React

gymnast is a configurable grid for React With gymnast, you can eliminate your layout css or reduce it to just a few lines. Learn how to use gymnast in

gymnast.js 38 May 7, 2022
React-Grid-Layout is a grid layout system much like Packery or Gridster, for React.

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

RGL 16.9k Jan 2, 2023
Layout-reactJS - Layout with React JS using NASA API

Layout with React JS using NASA API Website link on the web: Click Here Preview:

Anastacio Menezes 4 Feb 2, 2022
React-masonry - An easy to use and simple masonry layout for React Js based on flexbox column

React Masonry An easy to use and simple masonry layout for React Js based on fle

null 16 Dec 23, 2022
Auto Responsive Layout Library For React

autoresponsive-react Auto responsive grid layout library for React. Who are using ⭐ ⭐ ⭐ alibaba/ice ⭐ ⭐ ⭐ ice-lab/react-materials ⭐ ⭐ ⭐ ant-design/ant

θΎΎε³°ηš„ε€ε€© 1.5k Dec 15, 2022
A draggable and resizable grid layout with responsive breakpoints, for React.

React-Grid-Layout React-Grid-Layout is a grid layout system much like Packery or Gridster, for React. Unlike those systems, it is responsive and suppo

Samuel Reed 16.9k Jan 1, 2023
Resizable Flex layout container components for advanced React web applications

About Re-F|ex Re-F|ex is a React flex-based layout component library which I created because none of the components I found out there could satisfy my

Philippe Leefsma 532 Jan 8, 2023
Animated grid layout component for React

react-stonecutter Animated grid layout component for React, inspired by Masonry. Choose between CSS Transitions or React-Motion for animation. Demo In

Dan Train 1.2k Dec 24, 2022
FlexLayout is a layout manager that arranges React components in multiple tab sets, tabs can be resized and moved.

FlexLayout is a layout manager that arranges React components in multiple tab sets, tabs can be resized and moved.

Caplin 649 Jan 7, 2023
Resizable Flex layout container components for advanced React web applications

About Re-F|ex Re-F|ex is a React flex-based layout component library which I created because none of the components I found out there could satisfy my

Philippe Leefsma 530 Dec 21, 2022
Photo layout editor for react

react-photo-layout-editor 사진 λ ˆμ΄μ•„μ›ƒμ„ νŽΈμ§‘ν•˜λŠ” μ›Ή ν”„λ‘œκ·Έλž¨μž…λ‹ˆλ‹€. This is photo layout editor for react μ˜ˆμ „ Instagram blog( http://blog.instagram.com/ )에 μžˆλŠ” μ •λ ¬λœ μ΄λ―Έμ§€μ˜

redgoose 115 Oct 7, 2022
This react component resize the layout of HTML using a handle

react-resize-layout This react component resize the layout of HTML using a handle Demo View the demo page Example View the example demo page npm insta

null 36 Nov 3, 2022
XMasonry: Masonry Layout for React JS

Responsive, minimalistic and full-featured native masonry layout (grid) for React JS.

Nikita Savchenko 79 Dec 2, 2022
Physical representation of layout composition to create declarative responsive layouts in React.

Atomic Layout is a spatial distribution library for React. It uses CSS Grid to define layout areas and render them as React components. This pattern e

Artem Zakharchenko 1.1k Dec 26, 2022
A powerful React component to abstract over flexbox and create any layout on any browser

FlexView A powerful React component to abstract over flexbox and create any layout on any browser. Install yarn add react-flexview Why The flexbox AP

buildo 277 Nov 11, 2022
Kilvin is a set of universal & primitive Layout Components for React.

Kilvin is a set of universal & primitive Layout Components for React.

Robin Weser 21 May 26, 2022
Simple Layout Field to offer a variety possibilities to react-jsonschema-forms

react-jsonschema-form-layout Just a small custom field for the awesome react-jsonschema-form. see DEMO Key features: support bootstrap's grid add non-

Audibene Labs 67 Jun 16, 2022
Photo layout editor for react

react-photo-layout-editor 사진 λ ˆμ΄μ•„μ›ƒμ„ νŽΈμ§‘ν•˜λŠ” μ›Ή ν”„λ‘œκ·Έλž¨μž…λ‹ˆλ‹€. This is photo layout editor for react μ˜ˆμ „ Instagram blog( http://blog.instagram.com/ )에 μžˆλŠ” μ •λ ¬λœ μ΄λ―Έμ§€μ˜

redgoose 115 Oct 7, 2022
🦸 Motion Layout - Create beautiful immersive React hero animations using shared components.

Motion Layout Create beautiful immersive React hero animations using shared components. Docs React Motion Layout Docs About Motivation There are amazi

Jefferson Licet 584 Dec 25, 2022