MeoNode UI
  • MUI Integration
  • Components
  • Hooks

Material UI Integration

Overview

@meonode/mui is a comprehensive wrapper library that makes all Material-UI components compatible with MeoNode UI's function-based architecture. Instead of manually wrapping components, you can directly import pre-wrapped versions from @meonode/mui and its subpackages.

Installation

Install the wrapper package along with the MUI packages you need:

# Core installation (required)
npm install @meonode/mui @mui/material @emotion/react @emotion/styled

# Optional: Install additional MUI packages as needed
npm install @mui/lab
npm install @mui/x-data-grid
npm install @mui/x-tree-view
npm install @mui/x-date-pickers
npm install @mui/x-charts

Available Packages

@meonode/mui provides wrappers for the entire Material-UI ecosystem:

Import PathMUI PackageDescription
@meonode/mui@mui/materialAll core Material-UI components (Button, TextField, etc.)
@meonode/mui/lab@mui/labExperimental components
@meonode/mui/x-data-grid@mui/x-data-gridDataGrid component
@meonode/mui/x-data-grid-pro@mui/x-data-grid-proDataGrid Pro features
@meonode/mui/x-data-grid-premium@mui/x-data-grid-premiumDataGrid Premium features
@meonode/mui/x-tree-view@mui/x-tree-viewTreeView components
@meonode/mui/x-tree-view-pro@mui/x-tree-view-proTreeView Pro features
@meonode/mui/x-date-pickers@mui/x-date-pickersDate and time picker components
@meonode/mui/x-charts@mui/x-chartsChart components
@meonode/mui/x-charts-pro@mui/x-charts-proChart Pro features

Usage

Basic Components

All Material-UI components are pre-wrapped and ready to use:

import { Button, TextField, Card, CardContent, Typography } from '@meonode/mui'
import { Column } from '@meonode/ui'

const LoginForm = () =>
  Card({
    sx: { maxWidth: 400, margin: 'auto', padding: 2 },
    children: CardContent({
      children: Column({
        gap: 2,
        children: [
          Typography({
            variant: 'h5',
            children: 'Login'
          }),
          TextField({
            label: 'Email',
            type: 'email',
            fullWidth: true
          }),
          TextField({
            label: 'Password',
            type: 'password',
            fullWidth: true
          }),
          Button({
            variant: 'contained',
            fullWidth: true,
            children: 'Sign In'
          })
        ]
      })
    })
  }).render()

Grid Layout

Use Material-UI's Grid component for responsive layouts:

import { Grid, Card, CardContent, Typography } from '@meonode/mui'

const Dashboard = () =>
  Grid({
    props: {
      container: true, // since `container` is CSS-like property, we need to put it in `props`
    },
    spacing: 3,
    padding: 2,
    children: [
      Grid({
        size: { xs: 12, md: 4 },
        children: Card({
          children: CardContent({
            children: Typography({
              variant: 'h6',
              children: 'Total Users',
            }),
          }),
        }),
      }),
      Grid({
        size: { xs: 12, md: 4 },
        children: Card({
          children: CardContent({
            children: Typography({
              variant: 'h6',
              children: 'Active Sessions',
            }),
          }),
        }),
      }),
      Grid({
        size: { xs: 12, md: 4 },
        children: Card({
          children: CardContent({
            children: Typography({
              variant: 'h6',
              children: 'Revenue',
            }),
          }),
        }),
      }),
    ],
  }).render()

Lab Components

Access experimental components from the lab package:

import { Masonry } from '@meonode/mui/lab'
import { Card, CardContent } from '@meonode/mui'

const images = [/* your image data */]

const Gallery = () =>
  Masonry({
    columns: 3,
    spacing: 2,
    children: images.map(img =>
      Card({
        key: img.id,
        children: CardContent({
          children: /* image content */
        })
      })
    )
  }).render()

Data Grid

Use the powerful DataGrid component:

import { DataGrid } from '@meonode/mui/x-data-grid'

const columns = [
  { field: 'id', headerName: 'ID', width: 90 },
  { field: 'firstName', headerName: 'First name', width: 150 },
  { field: 'lastName', headerName: 'Last name', width: 150 }
]

const rows = [
  { id: 1, lastName: 'Snow', firstName: 'Jon' },
  { id: 2, lastName: 'Lannister', firstName: 'Cersei' }
]

const UserTable = () =>
  DataGrid({
    rows,
    columns,
    initialState: {
      pagination: { paginationModel: { pageSize: 5 } }
    },
    pageSizeOptions: [5, 10, 25],
    checkboxSelection: true
  }).render()

Tree View

Build hierarchical navigation:

import { SimpleTreeView, TreeItem } from '@meonode/mui/x-tree-view'

const FileExplorer = () =>
  SimpleTreeView({
    children: [
      TreeItem({
        itemId: 'src',
        label: 'src',
        children: [
          TreeItem({ itemId: 'components', label: 'components' }),
          TreeItem({ itemId: 'utils', label: 'utils' })
        ]
      }),
      TreeItem({ itemId: 'package.json', label: 'package.json' })
    ]
  }).render()

Date Pickers

Use date and time selection components:

import { DatePicker, LocalizationProvider } from '@meonode/mui/x-date-pickers'
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'
import { Node } from '@meonode/ui'

const DateSelector = () =>
  LocalizationProvider({
    dateAdapter: AdapterDayjs,
    children: DatePicker({
      label: 'Select Date',
      onChange: (newValue) => console.log(newValue)
    })
  }).render()

Charts

Create data visualizations:

import { LineChart } from '@meonode/mui/x-charts'

const SalesChart = () =>
  LineChart({
    width: 500,
    height: 300,
    series: [{ data: [1, 5, 3, 4, 2], label: 'Sales' }],
    xAxis: [{ scaleType: 'point', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'] }]
  }).render()

Conditional Rendering

When conditionally rendering MUI components that use hooks, follow the Rules of Hooks:

import { Component } from '@meonode/ui'
import { Card, CardContent, Typography } from '@meonode/mui'
import { useState } from 'react'

// Component using hooks
const UserCard = Component<{ userId: number }>(({ userId }) => {
  const [data, setData] = useState(null) // Uses hooks!

  return Card({
    children: CardContent({
      children: Typography({
        children: `User ${userId}`
      })
    })
  })
})

const App = Component(() => {
  const [showCard, setShowCard] = useState(true)

  return Column({
    children: [
      Button({
        onClick: () => setShowCard(!showCard),
        children: 'Toggle Card'
      }),
      // ✅ Correct: Using Component wrapper ensures hooks work properly
      showCard && UserCard({ userId: 1 })
    ]
  })
})

Styling

All wrapped components support MUI's sx prop for styling:

Button({
  variant: 'contained',
  sx: {
    backgroundColor: 'primary.main',
    '&:hover': {
      backgroundColor: 'primary.dark'
    },
    borderRadius: 2,
    textTransform: 'none'
  },
  children: 'Styled Button'
})

Theme Integration

@meonode/mui components work seamlessly with MUI's theme system:

import { createTheme } from '@mui/material/styles'
import { Button, ThemeProvider } from '@meonode/mui'
import { Node } from '@meonode/ui'

const theme = createTheme({
  palette: {
    primary: {
      main: '#1976d2'
    }
  }
})

const App = () =>
  ThemeProvide({
    theme,
    children: Button({
      variant: 'contained',
      color: 'primary',
      children: 'Themed Button'
    })
  }).render()

Advanced Usage: createMuiNode

If you need to wrap a custom MUI component not included in the package, use the createMuiNode utility:

import { createMuiNode } from '@meonode/mui'
import { Slider } from '@mui/material'

const MeoSlider = createMuiNode(Slider)

// Now use it like any other MeoNode component
const VolumeControl = () =>
  MeoSlider({
    value: 50,
    onChange: (e, newValue) => console.log(newValue)
  }).render()

Benefits

  1. Zero Manual Wrapping: All MUI components are pre-wrapped and ready to use
  2. Full Type Safety: TypeScript autocomplete works out of the box
  3. Consistent API: Use the same function-based composition across your entire app
  4. Complete Coverage: Access to Material-UI core, Lab, and all X packages
  5. Framework Agnostic: Works with Next.js, Vite, and any React setup

Resources

On this page