如何实现 MUI 手风琴组的“展开全部”和“折叠全部”按钮?

huangapple go评论49阅读模式
英文:

How to implement 'Expand All' and 'Collapse All' buttons for MUI accordion group?

问题

我正在处理一个部分,该部分以 MUI 手风琴的形式显示日志。我已经使手风琴正常工作,即展开和折叠正常工作。然而,现在有人要求我添加全部展开全部折叠按钮,点击这些按钮将展开和折叠所有手风琴,同时保留手风琴的通常行为。

import Accordion from '@mui/material/Accordion';
import AccordionSummary from '@mui/material/AccordionSummary';
import AccordionDetails from '@mui/material/AccordionDetails';

const Logs = () => {
  const cards = fetch('from-API')

  return (
    <Box>
      <Button>Expand All</Button>
      <Button>Collapse All</Button>
      {cards.length > 0 &&
        cards.map(card, (i) => {
          return (
            <Accordion key={i}>
              <AccordionSummary>
                Accordion Summary
              </AccordionSummary>
              <AccordionDetails>
                Accordion Details
              </AccordionDetails>
            </Accordion>
          );
        })}
    </Box>
  );
};

export default Logs;
英文:

I'm working on a section which display logs in the form on MUI accordions. I have got the accordions working normally i.e. expand and collapse work. However, now I'm asked to add buttons Expand All and Collapse All, which when clicked will expand and collapse all of the said accordions, while still retaining the usual behavior of the accordions.

import Accordion from &#39;@mui/material/Accordion&#39;;
import AccordionSummary from &#39;@mui/material/AccordionSummary&#39;;
import AccordionDetails from &#39;@mui/material/AccordionDetails&#39;;

const Logs = () =&gt; {
  const cards = fetch(&#39;from-API&#39;)

  return (
    &lt;Box&gt;
      &lt;Button&gt;Expand All&lt;/Button&gt;
      &lt;Button&gt;Collapse All&lt;/Button&gt;
      {cards.length &gt; 0 &amp;&amp;
        cards.map(card, (i) =&gt; {
          return (
            &lt;Accordion key={i}&gt;
              &lt;AccordionSummary&gt;
                Accordion Summary
              &lt;/AccordionSummary&gt;
              &lt;AccordionDetails&gt;
                Accordion Details
              &lt;/AccordionDetails&gt;
            &lt;/Accordion&gt;
          );
        })}
    &lt;/Box&gt;
  );
};

export default Logs;

答案1

得分: 0

以下是翻译好的部分:

  • 维护一个包含已展开的每个手风琴的索引值的状态数组。将空数组 [] 作为初始值。
  • 将手风琴的 onClick 处理程序设置为将手风琴的索引添加到数组中(如果尚未存在),如果已存在,则将其从数组中移除。
  • 将手风琴的 expanded 属性设置为真,仅当手风琴的索引值属于状态数组时。
  • 对于“全部折叠”按钮,只需清空状态数组为 [],这将触发所有手风琴折叠。
  • 对于“全部展开”按钮,创建一个包含所有手风琴的索引值的新数组,然后将这个新数组设置为状态数组,这实际上意味着所有手风琴都被展开。
import {
  Accordion,
  AccordionSummary,
  AccordionDetails,
  Box,
  Container,
  Typography,
  Button,
} from "@mui/material";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import { useState } from "react";

const data = [
  {
    summary: "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
    details:
      "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit",
  },
  {
    summary: "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
    details:
      "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit",
  },
  {
    summary: "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
    details:
      "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit",
  },
];

const App = () => {
  const [logs, setLogs] = useState(data);

  const [expandedAccordions, setExpandedAccordions] = useState([]);

  const accordionClicked = (index) => {
    if (expandedAccordions.includes(index))
      setExpandedAccordions(
        expandedAccordions.filter((number) => number !== index)
      );
    else setExpandedAccordions([...expandedAccordions, index]);
  };

  const collapseAll = () => {
    setExpandedAccordions([]);
  };

  const expandAll = () => {
    const newArray = [];
    logs.forEach((log, index) => newArray.push(index));
    setExpandedAccordions(newArray);
  };

  return (
    <Container
      sx={{
        display: "flex",
        flexDirection: "column",
        alignItems: "center",
        gap: 4,
        my: 5,
        maxWidth: "700px",
      }}
    >
      <Typography variant="h4" align="center">
        Adding Expand/Collapse-All Buttons to MUI Accordions
      </Typography>
      <Box>{JSON.stringify(expandedAccordions)}</Box>
      <Box sx={{ display: "flex", gap: 3 }}>
        <Button variant="contained" onClick={expandAll}>
          Expand All
        </Button>
        <Button variant="contained" onClick={collapseAll}>
          Collapse All
        </Button>
        <Button variant="outlined" onClick={() => setLogs([...logs, logs[0]])}>
          Add item
        </Button>
        <Button
          variant="outlined"
          onClick={() => setLogs([...logs.slice(0, -1)])}
        >
          Remove item
        </Button>
      </Box>
      <Box sx={{ maxWidth: "600px" }}>
        {logs.map((log, index) => (
          <Accordion
            key={index}
            onChange={() => accordionClicked(index)}
            expanded={expandedAccordions.includes(index)}
          >
            <AccordionSummary expandIcon={<ExpandMoreIcon />} >
              <Typography variant="h6">{log.summary}</Typography>
            </AccordionSummary>
            <AccordionDetails>
              <Typography>{log.details}</Typography>
            </AccordionDetails>
          </Accordion>
        ))}
      </Box>
    </Container>
  );
};
export default App;
英文:

Steps to get it working.

  • Maintain a state array containing the index values of each of the accordions that are expanded. Set empty array [] as the initial value.
  • Set onClick handler of the accordions to add the index of accordion to the array if it's not already present, and remove it if it is.
  • Set expanded prop of the accordions to be truthy only if the index value of the accordion belongs to the state array.
  • For the Collapse All button, just clear the state array to [], which will trigger all the accordions to collapse.
  • For the Expand All button, create a new array containing index values of all the accordions and then set this new array to be the state array, which effectively means that all accordions are expanded.
import {
  Accordion,
  AccordionSummary,
  AccordionDetails,
  Box,
  Container,
  Typography,
  Button,
} from &quot;@mui/material&quot;;
import ExpandMoreIcon from &quot;@mui/icons-material/ExpandMore&quot;;
import { useState } from &quot;react&quot;;

const data = [
  {
    summary: &quot;Lorem ipsum dolor sit amet, consectetur adipiscing elit&quot;,
    details:
      &quot;Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit&quot;,
  },
  {
    summary: &quot;Lorem ipsum dolor sit amet, consectetur adipiscing elit&quot;,
    details:
      &quot;Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit&quot;,
  },
  {
    summary: &quot;Lorem ipsum dolor sit amet, consectetur adipiscing elit&quot;,
    details:
      &quot;Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit&quot;,
  },
];

const App = () =&gt; {
  const [logs, setLogs] = useState(data);

  const [expandedAccordions, setExpandedAccordions] = useState([]);

  const accordionClicked = (index) =&gt; {
    if (expandedAccordions.includes(index))
      setExpandedAccordions(
        expandedAccordions.filter((number) =&gt; number !== index)
      );
    else setExpandedAccordions([...expandedAccordions, index]);
  };

  const collapseAll = () =&gt; {
    setExpandedAccordions([]);
  };

  const expandAll = () =&gt; {
    const newArray = [];
    logs.forEach((log, index) =&gt; newArray.push(index));
    setExpandedAccordions(newArray);
  };

  return (
    &lt;Container
      sx={{
        display: &quot;flex&quot;,
        flexDirection: &quot;column&quot;,
        alignItems: &quot;center&quot;,
        gap: 4,
        my: 5,
        maxWidth: &quot;700px&quot;,
      }}
    &gt;
      &lt;Typography variant=&quot;h4&quot; align=&quot;center&quot;&gt;
        Adding Expand/Collapse-All Buttons to MUI Accordions
      &lt;/Typography&gt;
      &lt;Box&gt;{JSON.stringify(expandedAccordions)}&lt;/Box&gt;
      &lt;Box sx={{ display: &quot;flex&quot;, gap: 3 }}&gt;
        &lt;Button variant=&quot;contained&quot; onClick={expandAll}&gt;
          Expand All
        &lt;/Button&gt;
        &lt;Button variant=&quot;contained&quot; onClick={collapseAll}&gt;
          Collapse All
        &lt;/Button&gt;
        &lt;Button variant=&quot;outlined&quot; onClick={() =&gt; setLogs([...logs, logs[0]])}&gt;
          Add item
        &lt;/Button&gt;
        &lt;Button
          variant=&quot;outlined&quot;
          onClick={() =&gt; setLogs([...logs.slice(0, -1)])}
        &gt;
          Remove item
        &lt;/Button&gt;
      &lt;/Box&gt;
      &lt;Box sx={{ maxWidth: &quot;600px&quot; }}&gt;
        {logs.map((log, index) =&gt; (
          &lt;Accordion
            key={index}
            onChange={() =&gt; accordionClicked(index)}
            expanded={expandedAccordions.includes(index)}
          &gt;
            &lt;AccordionSummary expandIcon={&lt;ExpandMoreIcon /&gt;}&gt;
              &lt;Typography variant=&quot;h6&quot;&gt;{log.summary}&lt;/Typography&gt;
            &lt;/AccordionSummary&gt;
            &lt;AccordionDetails&gt;
              &lt;Typography&gt;{log.details}&lt;/Typography&gt;
            &lt;/AccordionDetails&gt;
          &lt;/Accordion&gt;
        ))}
      &lt;/Box&gt;
    &lt;/Container&gt;
  );
};
export default App;


huangapple
  • 本文由 发表于 2023年2月27日 18:32:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/75579311.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定