Expanded MUI collapsible table squeezed into a single cell

I'm experimenting with using the MUI table along with Collapse to expand and collapse rows. However, I've noticed that when utilizing collapse, the expanded rows get squished into one cell. How can I adjust the alignment of the cells within the parent table?

 export default function App() {
  const [expanded, setExpanded] = useState(false);

  return (
    <Table>
      <TableHead>
        <TableRow>
          <TableCell />
          <TableCell>Header 1</TableCell>
          <TableCell>Header 2</TableCell>
          <TableCell>Header 3</TableCell>
          <TableCell>Header 4</TableCell>
        </TableRow>
      </TableHead>
      <TableBody>
        <TableRow>
          <TableCell onClick={() => setExpanded(!expanded)}>Expand</TableCell>
          <TableCell>A</TableCell>
          <TableCell>B</TableCell>
          <TableCell>C</TableCell>
          <TableCell>D</TableCell>
        </TableRow>
        <Collapse in={expanded} timeout="auto" unmountOnExit>
          <TableRow>
            <TableCell />
            <TableCell>E</TableCell>
            <TableCell>F</TableCell>
            <TableCell>G</TableCell>
            <TableCell>H</TableCell>
          </TableRow>
        </Collapse>
      </TableBody>
    </Table>
  );
};

By removing the Collapse feature, the table displays in the correct format. e.g. current state is: https://i.sstatic.net/RMvNX.png

The desired result post-expansion would look like this:https://i.sstatic.net/HLtyX.png

Answer №1

My method for achieving this is as follows:

<Table>
    <TableHead>
        <TableRow>
          <TableCell padding="checkbox"/>
          <TableCell>Area name</TableCell>
          <TableCell>2011</TableCell>
          <TableCell>2012</TableCell>
          <TableCell>2013</TableCell>
          <TableCell>2014</TableCell>
        </TableRow>
      </TableHead>
      <TableBody>
        <TableRow>
          <TableCell padding="checkbox">
            <IconButton
              size="small"
              onClick={() => setOpen(prev => !prev)}
            >
              {open ? <KeyboardArrowUpIcon/> : <KeyboardArrowDownIcon/>}
            </IconButton>
          </TableCell>
          <TableCell component="th">Paris</TableCell>
          <TableCell>1000</TableCell>
          <TableCell>2000</TableCell>
          <TableCell>3000</TableCell>
          <TableCell>4000</TableCell>
        </TableRow>
        <TableRow sx={{ visibility: open ? 'visible' : 'collapse' }}>
          <TableCell padding="checkbox"/>
          <TableCell component="th">1st arrondissement</TableCell>
          <TableCell>100</TableCell>
          <TableCell>200</TableCell>
          <TableCell>300</TableCell>
          <TableCell>400</TableCell>
        </TableRow>
      </TableBody>
    </Table>

The key to making a TableRow collapsible is using

sx={{ visibility: open ? 'visible' : 'collapse' }}
.

Answer №2

The main issue here is that the <Collapse /> component is being used as a div, which cannot be wrapped around table rows. To resolve this, you should create a separate table within the Collapse element and ensure that the cells are aligned to maintain uniform size.

For a demonstration, check out this Codesandbox example.

Answer №3

I made some adjustments to the previous solution so that each row can now expand or collapse upon clicking.

import {
  Collapse,
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableRow,
} from '@mui/material'
import { useState } from 'react'

export default function App() {
  const Row = () => {
    const [expanded, setExpanded] = useState(false)

    return (
      <>
        <Table>
          <TableBody>
            <TableRow>
              <TableCell onClick={() => setExpanded(!expanded)}>Expand</TableCell>
              <TableCell colSpan={4}></TableCell>
            </TableRow>
          </TableBody>
        </Table>
        <Collapse in={expanded} timeout='auto' unmountOnExit>
          <Table>
            <TableBody>
              <TableRow>
                <TableCell></TableCell>
                <TableCell>E</TableCell>
                <TableCell>F</TableCell>
                <TableCell>G</TableCell>
                <TableCell>H</TableCell>
              </TableRow>
            </TableBody>
          </Table>
        </Collapse>
      </>
    )
  }

  return (
    <>
      <Table>
        <TableHead>
          <TableRow>
            <TableCell></TableCell>
            <TableCell>Header 1</TableCell>
            <TableCell>Header 2</TableCell>
            <TableCell>Header 3</TableCell>
            <TableCell>Header 4</TableCell>
          </TableRow>
        </TableHead>
      </Table>
      {Array(5)
        .fill()
        .map(item => (
          <Row />
        ))}
    </>
  )
}

Check out the Codesandbox demo here

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

obtain the string representation of the decimal HTML entity value

Similar Question: how to create iphone apps similar to ibeer, imilk, ibug, ibeer Using javascript to obtain raw html code Imagine having an html section like this: <div id="post_content"> <span>&#9654;<span> </div> ...

Refreshing the page causes TypeScript Redux to lose its state

custom/reducer/shoppingReducer.ts import { createSlice, PayloadAction } from "@reduxjs/toolkit"; import { ShoppingReducerInitialState } from "../../types/reducer-types"; import { ProductItem, ShippingDetails } from "../../types/typ ...

Select a Month and Year with Material UI React

Can we create a month and year picker using Material UI that displays only the month and year (e.g. 2020-09) in the output? ...

Restart the autoHideDuration counter for the Snackbar when there are updates to the component

I'm trying to set a timeout of 2 seconds for the snackbar, but I want it to reset if the component updates before the time is up. Here's the code snippet I have so far: useEffect(() => { setOpen(true) },[props.single_mes ...

Find the sum and subtotals for two different categories in a JavaScript array

Currently, I'm in the process of aggregating three totals: totalPoints, monthlyTotals, and monthlyByType by utilizing Array.prototype.reduce. So far, I've managed to successfully calculate totalPoints and monthlyTotals, but I'm encountering ...

Encountered an error while trying to find the Node JavaScript view

Whenever I attempt to render the URL for displaying index.js in the browser, an error arises: **Error:** Failed to locate view "index" in views directory "D:\NodeJs\Example\5expressnodjsexmp\views" Below is my application code: //Hea ...

Could one potentially generate new static files in Nextjs without needing to rebuild the entire app?

After recently beginning to utilize NextJs' getStaticProps feature, I have found that the static files generated at build time are quite impressive. However, my content is not static and requires updates without having to rebuild the entire app each t ...

Ways to streamline redundant code by creating a higher order function that accepts different parameter types in TypeScript

Recently, I've been exploring the idea of refactoring this code into a higher order function using TypeScript to enhance its cleanliness and reusability. However, I'm facing quite a challenge in getting it to work seamlessly. import { DocumentDef ...

Is there a way to trigger a Tab key click event while typing in a text field?

Can you show me how to capture the Tab key event in jQuery? I want to display an alert if a user clicks the Tab key while entering text in an input field. I have tried using the following code but it's not working... var myInput = document.getEleme ...

The absence of data in a c# web api controller is causing issues with jQuery AJAX post requests

When I am sending data to a c# web api controller, I use the following method: $.ajax({ type: "POST", url: "menuApi/menu/Cost", data: JSON.stringify(order), contentType: "application/json", success: function (data) { window.alert(&apo ...

Updating an HTML element by using the input value in a text field with JavaScript/jQuery

Although it may seem straightforward, I am new to Javascript and struggling to find or create the script I need. I have a list of BIN numbers for credit cards and want to extract the first 6 digits of the card number field to determine the type of card, an ...

I keep trying to retrieve a specific property from an object, but every time I do, it returns as undefined

I'm currently employing Javascript within a React component. My goal is to retrieve a specific property from an object. If I log this object out to the console as shown below: console.log("Engine: ", this.Engine); The output looks like th ...

Inspecting every element within an array and indicating a negative outcome if any item is not a string

I'm currently working on a function called 'every' that takes in an array and a callback function as arguments. The purpose of the callback function is to determine if all elements in the array meet a certain condition. In my case, I want th ...

I am having trouble executing a script as the steps I have followed are not yielding the desired results. I am wondering where I may have made a mistake

I am trying to execute a script provided by Maciej Caputa in response to this question: How to import CSV or JSON to firebase cloud firestore The objective is to utilize a JSON file for uploading data to Cloud Firestore. As a newcomer to running scripts, ...

What is the best way to list the choices associated with a specific category?

The Node.js package I'm currently working with requires an argument of a specific type, which I can see is defined through a TypeScript declaration as follows: export declare type ArgType = 'A' | 'B' | 'C'; I am interes ...

Is using the new Date function as a key prop in React a good

In my React code, I have been using new Date().getTime() as key props for some Input components. This may not be the best practice as keys should ideally be stable. However, I am curious to know why this approach is causing issues and why using Math.random ...

Issue with getting Bootstrap sticky-top to function on sidebar column

My goal is to implement a sticky sidebar on the right side of the page. The sidebar menu is contained within a grid column. I have attempted to utilize the sticky-top class, following the guidance provided in this question, but unfortunately, it does not s ...

Is there a way to display various data with an onClick event without overwriting the existing render?

In the process of developing a text-based RPG using React/Context API/UseReducer, I wanted to hone my skills with useState in order to showcase objects from an onclick event. So far, I've succeeded in displaying an object from an array based on button ...

Rearranging components in React does not automatically prompt a re-render of the page

I'm currently working on a project to display the update status of my Heroku apps. The issue I encountered was that the parent component (Herokus) was determining the order, but I wanted them sorted based on their update dates starting from the most r ...

Align pictures in the middle of two divisions within a segment

This is the current code: HTML: <section class="sponsorSection"> <div class="sponsorImageRow"> <div class="sponsorImageColumn"> <img src="img/kvadrat_logo.png" class="sponsorpicture1"/> </div& ...