adazzle / react-data-grid

Feature-rich and customizable data grid React component
https://adazzle.github.io/react-data-grid/
Other
6.82k stars 2.17k forks source link

Make Cell Absolute #3509

Open fahadali503 opened 2 months ago

fahadali503 commented 2 months ago

Question: In a React application, I'm using the react-data-grid library to display tabular data. I have a column in the grid that contains multiple email addresses for each row. When a cell in this column is selected, I want the cell to expand and display all the email addresses vertically, similar to the behavior shown in the reference image. However, I'm encountering issues with the cell positioning, and it either gets hidden behind other cells or doesn't expand as expected.

Reference Image:

Screenshot 2024-05-07 at 3 08 07 AM

How can I ensure that the selected cell expands and displays its contents at the top layer, similar to the behavior shown in the reference image?

Below is my column code:

const columns: ColumnOrColumnGroup<IUserData>[] = [
        {
            key: "name",
            name: "Name",
            renderHeaderCell(props) {
                return <TableHeader
                    title={props.column.name as string}
                />
            },
            renderCell(props) {
                return <UserInfo
                    name='John Doe'
                    isInvited={props.row.isInvited}
                />
            },
            cellClass(...args) {
                return ''
            },

        },
        {
            key: "email",
            name: "Email",
            renderHeaderCell(props) {
                return <TableHeader
                    title={props.column.name as string}
                />
            },
            renderCell({ row, column, rowIdx, }) {
                const isSame = selectedCell?.rowIdx === rowIdx && selectedCell?.column.idx === column.idx;
                console.log({ isSame });
                return <div className={`flex w-full items-center h-full space-x-2  `}>
                    {row.email.map(mail => {
                        return <span key={mail} className='px-2.5 rounded py-1 bg-[#F6F7F9] text-xs leading-4 text-[#51566C]'>
                            {mail}
                        </span>
                    })}
                </div>
            },
            editable: true,
            editorOptions: {
                displayCellContent: false
            },
            minWidth: 200,
            renderEditCell({ row, onRowChange }) {
                return <EditableSelect
                    allowClear
                    placeholder="Email Address"
                    // showArrow={false}
                    suffixIcon={null}
                    value={row.email}
                    // mode='multiple'
                    mode="tags"
                    style={{
                        width: "100%",
                    }}
                    dropdownStyle={{
                        width: "300px",
                    }}
                    onChange={(value) => {
                        onRowChange({ ...row, email: value });
                    }}

                    maxTagCount={"responsive"}
                    options={emails.map((email) => ({ label: email, value: email }))}
                />
            },
        },
        {
            key: "type", name: "Type",
            renderHeaderCell(props) {
                return <TableHeader
                    title={props.column.name as string}
                />
            },
            editable: true,
            renderCell({ row }) {
                return <span className='text-xs leading-4 text-[#51566C]'>
                    {row.type}
                </span>
            },
            renderEditCell({ row, onRowChange, onClose }) {
                return <TypeInput
                    placeholder='Type'
                    value={row.type}
                    onChange={(e) => {
                        onRowChange({ ...row, type: e.target.value });
                    }}
                    onBlur={() => onClose(true, false)}
                />
            },
            editorOptions: {
                commitOnOutsideClick: true,
                displayCellContent: false
            }
        },
        {
            key: "companyName", name: "Company",
            renderHeaderCell(props) {
                return <TableHeader
                    title={props.column.name as string}
                />
            },
            cellClass: props => ``,
            renderCell(props) {
                return <div className='flex h-full items-center overflow-hidden space-x-2'>
                    {
                        props.row.companyName.map((company) => {
                            return <CompanyRender
                                key={company}
                                label={company}
                                avatar='https://picsum.photos/200/300'
                            />
                        })
                    }
                </div>
            },
            editable: true,
            renderEditCell({ row, onRowChange }) {
                return <EditableSelect
                    placeholder="Company Name"
                    value={row.companyName}
                    mode='multiple'
                    style={{
                        width: "100%",
                    }}
                    dropdownStyle={{
                        width: "300px",
                    }}
                    // showArrow={false}
                    suffixIcon={null}
                    onChange={(value) => {
                        onRowChange({ ...row, companyName: value });
                    }}
                    options={dummycompanies.map((company) => ({ label: company.name, value: company.name }))}
                    maxTagCount={"responsive"}
                />
            },
            editorOptions: {
                displayCellContent: false
            }
        },
        {
            key: "phone",
            name: "Phone",
            renderHeaderCell(props) {
                return <TableHeader
                    title={props.column.name as string}
                />
            },
            editable: true,
            renderCell({ row }) {
                return <div className='w-full h-full space-x-2 flex overflow-hidden items-center'>
                    {row.phone.map(phone => {
                        return <span key={phone} className='px-2.5 rounded py-1 bg-[#F6F7F9] text-xs leading-4 text-[#51566C]'>
                            {phone}
                        </span>
                    })}
                </div>
            },
            renderEditCell({ row, onRowChange, onClose }) {
                return <EditableSelect
                    placeholder="Phone Number"
                    value={row.phone}
                    mode="multiple"
                    style={{
                        width: "100%",
                    }}
                    dropdownStyle={{
                        width: "300px",
                    }}
                    // showArrow={false}
                    suffixIcon={null}
                    options={phonesData.map((ph) => ({ label: ph, value: ph }))}
                    onChange={(value) => {
                        onRowChange({
                            ...row,
                            phone: value,
                        });
                    }}
                    maxTagCount={"responsive"}

                />
            },
            editorOptions: {
                displayCellContent: false
            },

        },
    ]
truk commented 2 months ago

We had this issue with tooltips being cut off within the grid, but you can get around it by using a portal-based implementation, effectively breaking out of the editor's DOM location

fahadali503 commented 2 months ago

@truk Can you provide a sample code example?