@refinedev/chakra-ui
TypeScript icon, indicating that this package has built-in type declarations

2.35.1 • Public • Published


Refine is an open-source, headless React framework for developers building enterprise internal tools, admin panels, dashboards, B2B applications.

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.

Chakra UI integration for Refine

Chakra UI is a simple, modular and accessible component library that gives you the building blocks you need to build your React applications.

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 Chakra UI, you need to install the following package @refinedev/chakra-ui along with the Chakra UI packages:

npm install @refinedev/chakra-ui @chakra-ui/react @emotion/react @emotion/styled framer-motion

⚡ 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 + Chakra UI:

import React from "react";
import { Refine } from "@refinedev/core";
import {
  ErrorComponent,
  ThemedLayoutV2,
  RefineThemes,
  useNotificationProvider,
} from "@refinedev/chakra-ui";
import dataProvider from "@refinedev/simple-rest";
import routerBindings from "@refinedev/react-router";
import { BrowserRouter, Outlet, Route, Routes } from "react-router";

import { ProductList } from "./pages/products/list";

export default function App() {
  return (
    <BrowserRouter>
      <ChakraProvider theme={RefineThemes.Blue}>
        <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>
      </ChakraProvider>
    </BrowserRouter>
  );
}

// src/pages/products/list.tsx

import React from "react";
import { type GetManyResponse, useMany } from "@refinedev/core";
import { useTable } from "@refinedev/react-table";
import { List } from "@refinedev/chakra-ui";
import { type ColumnDef, flexRender } from "@tanstack/react-table";
import {
  Table,
  Thead,
  Tbody,
  Tr,
  Th,
  Td,
  TableContainer,
  HStack,
  Text,
} from "@chakra-ui/react";

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: {
      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 (
    <List>
      <TableContainer whiteSpace="pre-line">
        <Table variant="simple">
          <Thead>
            {getHeaderGroups().map((headerGroup) => (
              <Tr key={headerGroup.id}>
                {headerGroup.headers.map((header) => (
                  <Th key={header.id}>
                    {!header.isPlaceholder && (
                      <HStack spacing="2">
                        <Text>
                          {flexRender(
                            header.column.columnDef.header,
                            header.getContext(),
                          )}
                        </Text>
                      </HStack>
                    )}
                  </Th>
                ))}
              </Tr>
            ))}
          </Thead>
          <Tbody>
            {getRowModel().rows.map((row) => (
              <Tr key={row.id}>
                {row.getVisibleCells().map((cell) => (
                  <Td key={cell.id}>
                    {flexRender(cell.column.columnDef.cell, cell.getContext())}
                  </Td>
                ))}
              </Tr>
            ))}
          </Tbody>
        </Table>
      </TableContainer>
    </List>
  );
};

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:

Refine + Chakra UI Example

Documentation

Readme

Keywords

none

Package Sidebar

Install

npm i @refinedev/chakra-ui

Weekly Downloads

742

Version

2.35.1

License

MIT

Unpacked Size

1.05 MB

Total Files

508

Last publish

Collaborators

  • omerfarukaplak
  • pankodbot
  • aliemirsen
  • willico
  • alicanerdurmaz