Skip to main content
Version: 3.xx.xx

Theme

http://localhost:3000
Live previews only work with the latest documentation.
import { useNavigation, useRouterContext } from '@pankod/refine-core'
import {
List,
Edit,
Create,
TableContainer,
Table,
Thead,
Tbody,
Tr,
Th,
Td,
Text,
EditButton,
FormControl,
FormErrorMessage,
FormLabel,
Input,
} from '@pankod/refine-chakra-ui'
import { useTable, ColumnDef, flexRender } from '@pankod/refine-react-table'
import { useForm } from '@pankod/refine-react-hook-form'

const PostList: React.FC = () => {
const columns = React.useMemo<ColumnDef<IPost>[]>(
() => [
{
id: 'id',
header: 'ID',
accessorKey: 'id',
},
{
id: 'title',
header: 'Title',
accessorKey: 'title',
},
{
id: 'actions',
header: 'Actions',
accessorKey: 'id',
cell: function render({ getValue }) {
return <EditButton hideText recordItemId={getValue() as number} />
},
},
],
[],
)

const { getHeaderGroups, getRowModel } = useTable({
columns,
refineCoreProps: {
initialPageSize: 5,
},
})

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 && (
<Text>
{flexRender(
header.column.columnDef.header,
header.getContext(),
)}
</Text>
)}
</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>
)
}

const PostEdit: React.FC = () => {
const {
refineCore: { formLoading },
saveButtonProps,
register,
formState: { errors },
} = useForm<IPost>()

return (
<Edit isLoading={formLoading} saveButtonProps={saveButtonProps}>
<FormControl mb="3" isInvalid={!!errors?.title}>
<FormLabel>Title</FormLabel>
<Input {...register('title', { required: 'Title is required' })} />
<FormErrorMessage>{`${errors.title?.message}`}</FormErrorMessage>
</FormControl>
</Edit>
)
}

const PostCreate = () => {
const {
refineCore: { formLoading },
saveButtonProps,
register,
formState: { errors },
} = useForm<IPost>()

return (
<Create isLoading={formLoading} saveButtonProps={saveButtonProps}>
<FormControl mb="3" isInvalid={!!errors?.title}>
<FormLabel>Title</FormLabel>
<Input {...register('title', { required: 'Title is required' })} />
<FormErrorMessage>{`${errors.title?.message}`}</FormErrorMessage>
</FormControl>
</Create>
)
}

interface IPost {
id: number
title: string
}

The theme object is where you define your application's color palette, type scale, font stacks, breakpoints, border radius values, and more. You can either create your own theme object or use theme that provide from refine. You can find more information about theme in Chakra UI documentation.

Refer to the Chakra UI documentation for more information about theme. &#8594

Theme customization

<ChakraProvider/> component can be used to change theme and other global settings. It is not required if you decide to use the default theme. You can also use refineTheme provided by refine.

http://localhost:3000
Live previews only work with the latest documentation.
import { Refine } from '@pankod/refine-core'
import routerProvider from '@pankod/refine-react-router-v6'
import dataProvider from '@pankod/refine-simple-rest'
import {
ChakraProvider,
ErrorComponent,
Layout,
ReadyPage,
notificationProvider,
refineTheme,
extendTheme,
} from '@pankod/refine-chakra-ui'

import { PostCreate, PostEdit, PostList } from './pages'

const App = () => {
const customTheme = extendTheme({
...refineTheme,
colors: {
sider: {
background: '#4A5568',
collapseButton: '#1a202c',
},
},
})

return (
<ChakraProvider theme={customTheme}>
<Refine
routerProvider={routerProvider}
dataProvider={dataProvider('https://api.fake-rest.refine.dev')}
notificationProvider={notificationProvider()}
ReadyPage={ReadyPage}
Layout={Layout}
resources={[
{
name: 'posts',
list: PostList,
edit: PostEdit,
create: PostCreate,
},
]}
/>
</ChakraProvider>
)
}

Theme switching

Chakra UI comes with built-in support for managing color mode in your apps. You can manage the color mode on refine applications such as Chakra UI applications.

tip

Chakra stores the color mode in localStorage and appends a className to the body to ensure the color mode is persistent.

Refer to the Chakra UI documentation for more information about color mode. &#8594

http://localhost:3000
Live previews only work with the latest documentation.
import { Refine } from '@pankod/refine-core'
import routerProvider from '@pankod/refine-react-router-v6'
import dataProvider from '@pankod/refine-simple-rest'
import {
ChakraProvider,
ErrorComponent,
Layout,
ReadyPage,
notificationProvider,
Box,
IconButton,
Icon,
useColorMode,
refineTheme,
extendTheme,
} from '@pankod/refine-chakra-ui'
import { IconSun, IconMoonStars } from '@tabler/icons'

import { PostCreate, PostEdit, PostList } from './pages'

const Header = () => {
const { colorMode, toggleColorMode } = useColorMode()
return (
<Box
py="2"
px="4"
display="flex"
justifyContent="flex-end"
w="full"
bg="chakra-body-bg"
>
<IconButton
variant="ghost"
aria-label="Toggle theme"
onClick={toggleColorMode}
>
<Icon
as={colorMode === 'light' ? IconMoonStars : IconSun}
w="18px"
h="18px"
/>
</IconButton>
</Box>
)
}

const App = () => {
const customTheme = extendTheme({
...refineTheme,
config: {
initialColorMode: 'dark',
useSystemColorMode: false,
},
})

return (
<ChakraProvider theme={customTheme}>
<Refine
routerProvider={routerProvider}
dataProvider={dataProvider('https://api.fake-rest.refine.dev')}
notificationProvider={notificationProvider()}
ReadyPage={ReadyPage}
Layout={Layout}
Header={Header}
resources={[
{
name: 'posts',
list: PostList,
edit: PostEdit,
create: PostCreate,
},
]}
/>
</ChakraProvider>
)
}