Design Converter
Education
Developer Advocate
Last updated on Apr 12, 2024
Last updated on Apr 12, 2024
React Mosaic is an excellent React UI toolkit designed to provide developers with a simple and flexible API for creating complex and resizable layouts. It is particularly useful for building arbitrarily complex React components within a draggable and customizable interface. The library allows for a simple tiled interface that can be nested to create more interesting examples of user interfaces.
To get started with React Mosaic, you would typically install it via npm:
1npm install react-mosaic-component
Once installed, you can begin to create your first React Mosaic component. Here's a simple example of how to set up a basic mosaic instance:
1import { Mosaic, MosaicWindow } from 'react-mosaic-component'; 2import 'react-mosaic-component/react-mosaic-component.css'; 3 4const MyMosaic = () => ( 5 <Mosaic 6 renderTile={(id, path) => ( 7 <MosaicWindow path={path} createNode={() => 'New Window'}> 8 This is the content for window {id} 9 </MosaicWindow> 10 )} 11 initialTree={{ direction: 'row', first: 'a', second: 'b', splitPercentage: 50 }} 12 /> 13);
In this snippet, Mosaic is the main react mosaic component that manages the layout, while MosaicWindow is used for each pane within the layout. The initialTree prop defines the starting layout structure, which in this case is a simple binary tree with two panes labeled 'a' and 'b'.
React Mosaic provides a powerful way to build a layout that gives the user complete control over the arrangement of components. It leverages a controlled component pattern, where the consumer manages Mosaic's state, allowing for a high degree of customization. The library uses React Context to pass down state and callbacks to components, ensuring that the tree structure is maintained and updated correctly.
For example, the export interface MosaicBaseProps and export interface MosaicUncontrolledProps are part of the API that defines the props you can pass to the Mosaic component for controlled and uncontrolled behaviors, respectively.
React Mosaic's operations revolve around a tree structure that represents the layout. Each node in the tree corresponds to a pane in the UI, and the structure can be manipulated through various operations such as splitting, resizing, and dragging panes. The state of the layout is managed through a combination of React Context and internal state, ensuring that updates to the layout are efficiently rendered.
Here's an example of how a mosaic manages its state:
1import { MosaicNode } from 'react-mosaic-component'; 2 3const initialTree: MosaicNode<string> = { 4 direction: 'row', 5 first: 'leftPane', 6 second: { 7 direction: 'column', 8 first: 'topRightPane', 9 second: 'bottomRightPane', 10 splitPercentage: 25, 11 }, 12 splitPercentage: 40, 13};
In this code, initialTree defines a more complex layout with three panes. The direction property specifies whether the split is horizontal ('row') or vertical ('column'), and splitPercentage determines the size of each pane.
To create a basic React Mosaic component, you start by defining the layout tree and the components that will be rendered in each pane. Each pane is represented by a MosaicWindow, which can contain any React component. The Mosaic component itself acts as the layout manager, handling the resizing and repositioning of panes as the user interacts with them.
Here's a step-by-step example of creating a basic React Mosaic layout:
1import { Mosaic, MosaicWindow } from 'react-mosaic-component'; 2 3const App = () => ( 4 <Mosaic 5 renderTile={(id, path) => ( 6 <MosaicWindow path={path} createNode={() => 'New Window'}> 7 <div>This is the content for window {id}</div> 8 </MosaicWindow> 9 )} 10 initialTree={{ 11 direction: 'row', 12 first: 'pane1', 13 second: 'pane2', 14 splitPercentage: 50, 15 }} 16 /> 17); 18 19export default App;
In this example, pane1 and pane2 are the identifiers for the two initial panes.
React Mosaic is not limited to simple layouts or components. It can handle arbitrarily complex React components, allowing developers to create sophisticated user interfaces. The flexibility of React Mosaic means that each pane within the mosaic can contain a completely different component, whether it's a form, a chart, or even another React Mosaic instance for nested layouts.
Here's how you might include a more complex component within a React Mosaic window:
1import { MosaicWindow } from 'react-mosaic-component'; 2import ComplexComponent from './ComplexComponent'; 3 4const ComplexMosaicWindow = ({ path }) => ( 5 <MosaicWindow path={path} createNode={() => 'New Complex Window'}> 6 <ComplexComponent /> 7 </MosaicWindow> 8);
In this snippet, ComplexComponent represents an arbitrarily complex React component that you might want to include in your layout. The MosaicWindow wraps this component, integrating it seamlessly into the mosaic layout.
React Mosaic comes with a default theme, but it also supports customization through theming. The Mosaic Blueprint Theme provides a set of styles that can be applied to the React Mosaic components to match the Blueprint design system. Additionally, a dark theme mosaic can be applied for a darker color scheme, which is particularly useful for applications that require a dark mode.
To apply the Mosaic Blueprint Theme, you would include the relevant CSS class in your component:
1import { Mosaic } from 'react-mosaic-component'; 2import { mosaicBlueprintThemeClass } from 'react-mosaic-component/lib/util/mosaicBlueprintTheme'; 3 4const ThemedMosaic = () => ( 5 <div className={mosaicBlueprintThemeClass}> 6 <Mosaic 7 // ... other props 8 /> 9 </div> 10);
This code snippet wraps the Mosaic component in a div with the mosaicBlueprintThemeClass applied, which styles the mosaic according to the Blueprint theme.
React Mosaic's operations revolve around manipulating the layout tree to reflect the user's interactions. The API provides a set of props, known as API Mosaic Props, that control the behavior of the mosaic. These props include callbacks for events such as changing the size of a pane, dragging and dropping, and creating new panes.
For example, the onRelease prop is a callback that is called when the user finishes dragging a pane:
1<Mosaic 2 onRelease={(newTree) => console.log('Layout tree updated:', newTree)} 3 // ... other props 4/>
In this code, the onRelease callback logs the updated layout tree whenever the user completes a drag operation.
React Mosaic uses React Context to pass down state and callbacks to deeply nested components without having to manually pass props at every level. This is particularly useful when the state needs to be shared across many components within the mosaic.
Additionally, React Mosaic supports both controlled and uncontrolled components . In a controlled component, the consumer manages Mosaic's state, which allows for complete control over the mosaic's behavior. Here's an example of a controlled React Mosaic component:
1import { useState } from 'react'; 2import { Mosaic } from 'react-mosaic-component'; 3 4const ControlledMosaic = () => { 5 const [currentTree, setCurrentTree] = useState(null); 6 7 return ( 8 <Mosaic 9 value={currentTree} 10 onChange={setCurrentTree} 11 // ... other props 12 /> 13 ); 14};
In this example, currentTree is the state that represents the layout tree, and setCurrentTree is the updater function that modifies this state. The Mosaic component is controlled by these state values, ensuring that the layout is always in sync with the state.
Drag-and-drop is a key feature of React Mosaic, enhancing the user experience by allowing users to intuitively rearrange the layout. React Mosaic integrates with the React DnD provider (React Drag and Drop) to handle the drag-and-drop functionality.
Here's an example of how you might set up the React DnD provider with React Mosaic:
1import { DndProvider } from 'react-dnd'; 2import { HTML5Backend } from 'react-dnd-html5-backend'; 3import { Mosaic } from 'react-mosaic-component'; 4 5const AppWithDragAndDrop = () => ( 6 <DndProvider backend={HTML5Backend}> 7 <Mosaic 8 // ... other props 9 /> 10 </DndProvider> 11);
In the above code, DndProvider wraps the Mosaic component, and HTML5Backend is specified as the backend for the drag-and-drop functionality. This setup allows users to begin dragging a pane and see the drop functionality in action as they move it around the layout.
React Mosaic is not just limited to basic layouts; it can be extended with additional features such as toolbar elements and other advanced functionality. The MosaicWindow component can be customized to include a toolbar with buttons for actions like closing a pane, changing its size, or adding new panes.
Here's an example of how to add toolbar elements to a MosaicWindow:
1import { MosaicWindow } from 'react-mosaic-component'; 2 3const CustomToolbarMosaicWindow = ({ path, title }) => ( 4 <MosaicWindow 5 path={path} 6 title={title} 7 toolbarControls={[ 8 <button onClick={() => console.log('Toolbar button clicked!')}> 9 Click Me 10 </button>, 11 ]} 12 > 13 {/* Window content */} 14 </MosaicWindow> 15);
In this snippet, toolbarControls is an array of React elements that will be rendered in the toolbar of the MosaicWindow. This allows developers to add custom buttons or other toolbar elements to enhance the functionality of each pane.
When integrating React Mosaic into your own app, it's important to consider best practices for maintaining performance and usability. This includes managing the state of the mosaic effectively, using the provided hooks and props to control the layout, and customizing the appearance to match the rest of your application.
For instance, you might want to save the state of the layout to local storage so that users can pick up where they left off:
1import { useEffect, useState } from 'react'; 2import { Mosaic } from 'react-mosaic-component'; 3 4const PersistentMosaic = () => { 5 const [layout, setLayout] = useState(() => { 6 const savedLayout = localStorage.getItem('mosaicLayout'); 7 return savedLayout ? JSON.parse(savedLayout) : null; 8 }); 9 10 useEffect(() => { 11 localStorage.setItem('mosaicLayout', JSON.stringify(layout)); 12 }, [layout]); 13 14 return ( 15 <Mosaic 16 value={layout} 17 onChange={setLayout} 18 // ... other props 19 /> 20 ); 21};
In this example, the layout state is initialized from local storage, and any changes to the layout are saved back to local storage using the useEffect hook . This ensures that the user's layout preferences are preserved between sessions.
React Mosaic is a powerful tool for creating dynamic and responsive layouts in React applications. It provides a simple and flexible API that allows for the creation of complex layouts with drag-and-drop functionality. With the ability to customize themes and extend functionality with toolbar elements and other advanced features, React Mosaic is an excellent choice for developers looking to build sophisticated user interfaces.
Best use-cases for React Mosaic include applications that require a customizable workspace, such as IDEs, dashboards, and design tools. Its ability to handle arbitrarily complex React components makes it suitable for a wide range of applications, from simple admin panels to complex data visualization tools.
By leveraging the features of React Mosaic, developers can provide their users with a highly interactive and intuitive interface, giving them complete control over their workspace layout. Whether you're building a new application or looking to enhance an existing one, React Mosaic is a library worth considering for your front-end development toolkit.
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.