@refinedev/mantine
v2.35.1
Published
refine is a React-based framework for building internal tools, rapidly.
Downloads
3,984
Keywords
Readme
It eliminates repetitive tasks in CRUD operations and provides industry-standard solutions for critical project components like authentication, access control, routing, networking, state management, and i18n.
Mantine UI integration for Refine
Mantine is a React components library focused on providing great user and developer experience.
Refine is headless by design, offering unlimited styling and customization options. Moreover, Refine ships with ready-made integrations for Ant Design, Material UI, Mantine, and Chakra UI for convenience.
Refine has connectors for 15+ backend services, including REST API, GraphQL, and popular services like Airtable, Strapi, Supabase, Firebase, and NestJS.
Installation
To use Refine with Mantine, you need to install the following package @refinedev/mantine
along with the Mantine packages:
npm install @refinedev/mantine @refinedev/react-table @mantine/core@5 @mantine/hooks@5 @mantine/form@5 @mantine/notifications@5 @emotion/react @tabler/icons
⚡ Try Refine
Start a new project with Refine in seconds using the following command:
npm create refine-app@latest my-refine-app
Or you can create a new project on your browser:
Quick Start
Here's Refine in action, the below code is an example of a simple CRUD application using Refine + React Router + Mantine:
import React from "react";
import { Refine } from "@refinedev/core";
import {
ErrorComponent,
ThemedLayoutV2,
useNotificationProvider,
RefineThemes,
} from "@refinedev/mantine";
import dataProvider from "@refinedev/simple-rest";
import routerBindings from "@refinedev/react-router";
import { BrowserRouter, Outlet, Route, Routes } from "react-router";
import { NotificationsProvider } from "@mantine/notifications";
import { MantineProvider, Global } from "@mantine/core";
import { ProductList } from "./pages/products/list";
export default function App() {
return (
<BrowserRouter>
<MantineProvider
theme={RefineThemes.Blue}
withNormalizeCSS
withGlobalStyles
>
<Global styles={{ body: { WebkitFontSmoothing: "auto" } }} />{" "}
<NotificationsProvider position="top-right">
<Refine
routerProvider={routerBindings}
dataProvider={dataProvider("https://api.fake-rest.refine.dev")}
notificationProvider={useNotificationProvider}
resources={[
{
name: "products",
list: "/products",
},
]}
options={{
syncWithLocation: true,
warnWhenUnsavedChanges: true,
}}
>
<Routes>
<Route
element={
<ThemedLayoutV2>
<Outlet />
</ThemedLayoutV2>
}
>
<Route path="/products">
<Route index element={<ProductList />} />
</Route>
<Route path="*" element={<ErrorComponent />} />
</Route>
</Routes>
</Refine>
</NotificationsProvider>
</MantineProvider>
</BrowserRouter>
);
}
// src/pages/products/list.tsx
import React from "react";
import { type GetManyResponse, useMany } from "@refinedev/core";
import { List } from "@refinedev/mantine";
import { useTable } from "@refinedev/react-table";
import { type ColumnDef, flexRender } from "@tanstack/react-table";
import { Box, Group, ScrollArea, Table, Pagination } from "@mantine/core";
export const ProductList = () => {
const columns = React.useMemo<ColumnDef<IPost>[]>(
() => [
{
id: "id",
header: "ID",
accessorKey: "id",
},
{
id: "name",
header: "Name",
accessorKey: "name",
},
{
id: "category",
header: "Category",
accessorKey: "category",
cell: function render({ getValue, table }) {
const meta = table.options.meta as TableMeta;
const loading = meta.loading;
const categoriesData = meta.categoriesData;
const category = categoriesData?.data.find(
(item) => item?.id === getValue<IPost["category"]>()?.id,
);
if (loading) {
return "Loading...";
}
return category?.title ?? "-";
},
},
],
[],
);
const {
getHeaderGroups,
getRowModel,
setOptions,
refineCore: {
setCurrent,
pageCount,
current,
tableQuery: { data: tableData, isLoading: tableIsLoading },
},
} = useTable({
columns,
meta: {
categoriesData: [],
loading: true,
},
refineCoreProps: {
sorters: {
initial: [
{
field: "id",
order: "desc",
},
],
},
},
});
const categoryIds = tableData?.data?.map((item) => item.category?.id) ?? [];
const { data: categoriesData, isLoading: categoriesIsLoading } =
useMany<ICategory>({
resource: "categories",
ids: categoryIds,
queryOptions: {
enabled: categoryIds.length > 0,
},
});
const loading = tableIsLoading || categoriesIsLoading;
setOptions((prev) => ({
...prev,
meta: {
...prev.meta,
loading,
categoriesData,
},
}));
return (
<ScrollArea>
<List>
<Table highlightOnHover>
<thead>
{getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<th key={header.id}>
{!header.isPlaceholder && (
<Group spacing="xs" noWrap>
<Box>
{flexRender(
header.column.columnDef.header,
header.getContext(),
)}
</Box>
</Group>
)}
</th>
);
})}
</tr>
))}
</thead>
<tbody>
{getRowModel().rows.map((row) => {
return (
<tr key={row.id}>
{row.getVisibleCells().map((cell) => {
return (
<td key={cell.id}>
{flexRender(
cell.column.columnDef.cell,
cell.getContext(),
)}
</td>
);
})}
</tr>
);
})}
</tbody>
</Table>
<br />
<Pagination
position="right"
total={pageCount}
page={current}
onChange={setCurrent}
/>
</List>
</ScrollArea>
);
};
type TableMeta = {
loading: boolean;
categoriesData: GetManyResponse<ICategory>;
};
type ICategory = {
id: number;
title: string;
};
type IPost = {
id: number;
title: string;
content: string;
status: "published" | "draft" | "rejected";
category: { id: number };
};
The result will look like this:
Documentation
- For more detailed information and usage, refer to the Refine Mantine documentation.
- Refer to documentation for more info about Refine.
- Step up to Refine tutorial.