Custom Accordion - Not Consistant
I wrote a custom Accordion. If I render a single accordion, then I can click on it and it expands as expected ever time. However, if I render multiple Accordions in a for loop, then I can click on the Accordions in the list and sometimes they do nothing. After clicking on them a few times they finally expand.
import { createSignal, onCleanup } from "solid-js";
import { Paper, Box, IconButton } from "@suid/material";
import KeyboardArrowDownIcon from "@suid/icons-material/KeyboardArrowDown";
import { JSX } from "solid-js";
export interface AccordionProps {
header: JSX.Element;
content: JSX.Element;
}
export default function Accordion(props: AccordionProps) {
const [expanded, setExpanded] = createSignal(false);
let contentRef!: HTMLDivElement;
const handleToggle = () => {
setExpanded(!expanded());
};
return (
<Paper elevation={3} sx={{ p: 1 }}>
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
cursor: "pointer",
}}
onClick={handleToggle}
>
{props.header}
<IconButton color="primary" size="small">
<KeyboardArrowDownIcon
sx={{
transition: "transform 0.3s ease",
transform: expanded() ? "rotate(180deg)" : "rotate(0deg)",
}}
/>
</IconButton>
</Box>
<Box
ref={contentRef}
sx={{
overflow: "hidden",
transition: "max-height 0.3s ease",
maxHeight: expanded() ? `${contentRef.scrollHeight}px` : "0px",
}}
>
<Box sx={{ p: 2 }}>{props.content}</Box>
</Box>
</Paper>
);
}
import { createSignal, onCleanup } from "solid-js";
import { Paper, Box, IconButton } from "@suid/material";
import KeyboardArrowDownIcon from "@suid/icons-material/KeyboardArrowDown";
import { JSX } from "solid-js";
export interface AccordionProps {
header: JSX.Element;
content: JSX.Element;
}
export default function Accordion(props: AccordionProps) {
const [expanded, setExpanded] = createSignal(false);
let contentRef!: HTMLDivElement;
const handleToggle = () => {
setExpanded(!expanded());
};
return (
<Paper elevation={3} sx={{ p: 1 }}>
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
cursor: "pointer",
}}
onClick={handleToggle}
>
{props.header}
<IconButton color="primary" size="small">
<KeyboardArrowDownIcon
sx={{
transition: "transform 0.3s ease",
transform: expanded() ? "rotate(180deg)" : "rotate(0deg)",
}}
/>
</IconButton>
</Box>
<Box
ref={contentRef}
sx={{
overflow: "hidden",
transition: "max-height 0.3s ease",
maxHeight: expanded() ? `${contentRef.scrollHeight}px` : "0px",
}}
>
<Box sx={{ p: 2 }}>{props.content}</Box>
</Box>
</Paper>
);
}
2 Replies
Probably because of the condition inside the sx prop.
Have you tried to move this into a style tag?
It worked!
The old
The new
<Box
ref={contentRef}
sx={{
overflow: "hidden",
transition: "max-height 0.3s ease",
maxHeight: expanded() ? `${contentRef.scrollHeight}px` : "0px",
}}
>
<Box sx={{ p: 2 }}>{props.content}</Box>
</Box>
<Box
ref={contentRef}
sx={{
overflow: "hidden",
transition: "max-height 0.3s ease",
maxHeight: expanded() ? `${contentRef.scrollHeight}px` : "0px",
}}
>
<Box sx={{ p: 2 }}>{props.content}</Box>
</Box>
<div
ref={contentRef}
style={{
overflow: "hidden",
transition: "max-height 0.3s ease",
'max-height': expanded() ? `${contentRef.scrollHeight}px` : "0px",
}}
>
<Box sx={{ p: 2 }}>{props.content}</Box>
</div>
<div
ref={contentRef}
style={{
overflow: "hidden",
transition: "max-height 0.3s ease",
'max-height': expanded() ? `${contentRef.scrollHeight}px` : "0px",
}}
>
<Box sx={{ p: 2 }}>{props.content}</Box>
</div>