React admin pass a className to custom component

Viewed 187

I got a datagrid in a react admin project with a custom button, and since it's in a a datagrid, the button is wrapped into a td tag, how can I target this td wrapping my button, I tried giving him a className1 but it's telling me I can't because type '{ className: string; }' is not assignable to type 'IntrinsicAttributes & CreateOrganizationButtonProps, how is the rule in react? Can't I assign a component of mine a className? And how to target this special td` created by react admin?

import {
  List,
  Datagrid,
  TextField,
  TopToolbar,
  CreateButton,
  ExportButton,
  TextInput,
  useRecordContext,
  useListController,
  ListContextProvider,
} from "react-admin";

import OrganizationsPanel from "./components/organizations-list-panel";
import CreateOrganizationButton from "./components/create-organization-button";
import { useEffect, useRef, useState } from "react";

const ListActions = () => (
  <TopToolbar>
    <CreateButton />
    <ExportButton />
  </TopToolbar>
);
const organizationsFilters = [<TextInput label="Search" source="q" alwaysOn />];

export const OrganizationsList = (props: any) => {
  return (
    <List
      className="custom-list"
      {...props}
      filters={organizationsFilters}
      filter={{ parentOrganizationId: localStorage.getItem("oid") }}
      sx={{
        "& .RaList-content": {
          boxShadow: "none",
        },
      }}
      actions={<ListActions />}
    >
      <Datagrid
        className="custom-list-grid"
        rowClick="edit"
        sx={{
          "& .RaDatagrid-row": {
            border: "none",
            width: "100%",
          },
          "& .RaDatagrid-row:hover .create-organization-button": {
            visibility: "inherit",
          },
          "& .RaDatagrid-row .create-organization-button": {
            visibility: "inherit",
          },
        }}
        bulkActionButtons={false}
        expand={<OrganizationsPanel />}
      >
        <TextField source="name" />
        <CreateOrganizationButton className='salut'/>
      </Datagrid>
    </List>
  );
};
import React, { useState } from "react";
import { IconButton } from "@mui/material";
import { Link } from "react-router-dom";
import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline";
import { useRecordContext } from "react-admin";

const CreateOrganizationButton: React.FC<CreateOrganizationButtonProps> =
  () => {
    const record = useRecordContext();
    return (
      <IconButton
        className="create-organization-button"
        component={Link}
        to={{
          pathname: "/organizations/create",
          search: `?source=${JSON.stringify({
            parentOrganizationId: record.id,
          })}`,
        }}
        sx={{
          position: "relative",
          top: 0,
        }}
        onClick={(event: any) => event.stopPropagation()}
      >
        <AddCircleOutlineIcon color="primary" />
      </IconButton>
    );
  };

interface CreateOrganizationButtonProps {}

export default CreateOrganizationButton;
1 Answers

In your CreateOrganizationButton component, you have defined what props are expected to be passed in.

const CreateOrganizationButton: React.FC<CreateOrganizationButtonProps>

The above line means that CreateOrganizationButton is of type React.FC and it expects to receive CreateOrganizationButtonProps.

You've defined CreateOrganizationButtonProps as:

interface CreateOrganizationButtonProps {}

The above line means CreateOrganizationButtonProps is expected to be an empty object. You probably want to change it to something like this:

interface CreateOrganizationButtonProps {
    className: string;
}

Now you should stop getting the error you were seeing. But there's one more step to actually make the className you are passing in do something.

You will want to use the className you are passing in somehow.

First we want to get the className from the props in CreateOrganizationButton. You can do that using prop destructuring:

const CreateOrganizationButton: React.FC<CreateOrganizationButtonProps> =
  ({ className }) => {
...

Currently the <IconButton> inside your CreateOrganizationButton already has a className of "create-organization-button". You can change this to the className you are passing in to use that instead:

      <IconButton
        className={className}
      ...
Related