Back to Refine

Layout

documentation/versioned_docs/version-3.xx.xx/api-reference/antd/customization/layout.md

3.25.04.9 KB
Original Source

You can create custom layouts using <Refine> and <LayoutWrapper> components.

Both of these components can accept the listed props for customization. <Refine> being for global customization and the <LayoutWrapper> being for local.

:::info-tip Swizzle You can swizzle this component to customize it with the refine CLI :::

Creating a Custom Layout

Let's look at an example of modifying the default layout to have a top menu layout.

tsx
import { Refine } from "@pankod/refine-core";
import {
  AntdLayout,
  ReadyPage,
  useNotificationProvider,
  ErrorComponent,
} from "@pankod/refine-antd";
import routerProvider from "@pankod/refine-react-router-v6";
import dataProvider from "@pankod/refine-simple-rest";

import "@pankod/refine-antd/dist/reset.css";

import { PostList } from "pages/posts";
// highlight-next-line
import { CustomSider } from "components";

const { Link } = routerProvider;

const API_URL = "https://api.fake-rest.refine.dev";

const App: React.FC = () => {
  return (
    <Refine
      routerProvider={routerProvider}
      dataProvider={dataProvider(API_URL)}
      // highlight-start
      Layout={({ children, Footer, OffLayoutArea }) => (
        <AntdLayout>
          <AntdLayout.Header>
            <CustomSider />
          </AntdLayout.Header>
          <AntdLayout.Content>
            <AntdLayout.Content>
              <div style={{ padding: 24, minHeight: 360 }}>{children}</div>
            </AntdLayout.Content>
            {Footer && <Footer />}
          </AntdLayout.Content>
          {OffLayoutArea && <OffLayoutArea />}
        </AntdLayout>
      )}
      // highlight-end
      Title={() => (
        <Link to="/" style={{ float: "left", marginRight: "10px" }}>
          
        </Link>
      )}
      ReadyPage={ReadyPage}
      notificationProvider={useNotificationProvider}
      catchAll={<ErrorComponent />}
    />
  );
};

export default App;

Here, we override the <Title> and <Layout> components. When we override <Layout>, we put the <CustomSider> (insted of the <Sider> that was provided to <Layout> to render it by default) on top of <AntdLayout>.

So, we just provided a custom <Sider>. Here's our custom sider that looks horizontal, instead of the default vertical one:

tsx
import { useTitle, useMenu } from "@pankod/refine-core";
import { Menu } from "@pankod/refine-antd";
import routerProvider from "@pankod/refine-react-router-v6";

const { Link } = routerProvider;

export const CustomSider: React.FC = () => {
  // highlight-start
  const Title = useTitle();
  const { menuItems, selectedKey } = useMenu();
  // highlight-end

  return (
    <>
      // highlight-start
      {Title && <Title collapsed={false} />}
      <Menu selectedKeys={[selectedKey]} mode="horizontal">
        {menuItems.map(({ icon, route, label }) => (
          <Menu.Item key={route} icon={icon}>
            <Link to={route ?? ""}>{label}</Link>
          </Menu.Item>
        ))}
      </Menu>
      // highlight-end
    </>
  );
};

Here, we use useMenu hook to get the list of current resources and print it.

:::info By default, <Sider> is responsible for rendering <Title>. It gets this component (configured by <Refine> and/or <LayoutWrapper>) by useTitle hook. :::

:::info This example demonstrated how to configure a global layout. To learn how to use global layout in custom pages and make local modifications per page, refer to the <LayoutWrapper> docs. &#8594 :::

Example

Here's how it looks in the end:

<CodeSandboxExample path="customization-top-menu-layout" />