File tree Expand file tree Collapse file tree
chartlets.js/packages/lib/src/plugins/mui
chartlets.py/chartlets/components Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ /*
2+ * Copyright (c) 2019-2026 by Brockmann Consult Development team
3+ * Permissions are hereby granted under the terms of the MIT License:
4+ * https://opensource.org/licenses/MIT.
5+ */
6+
7+ import { render , screen , fireEvent } from "@testing-library/react" ;
8+ import { describe , expect , it } from "vitest" ;
9+
10+ import { Accordion } from "./Accordion" ;
11+ import { createChangeHandler } from "@/plugins/mui/common.test" ;
12+
13+ describe ( "Accordion" , ( ) => {
14+ it ( "should render the Accordion component" , ( ) => {
15+ render (
16+ < Accordion
17+ id = "acc"
18+ type = "Accordion"
19+ label = "My Accordion"
20+ onChange = { ( ) => { } }
21+ /> ,
22+ ) ;
23+
24+ expect ( screen . getByText ( "My Accordion" ) ) . not . toBeUndefined ( ) ;
25+ } ) ;
26+
27+ it ( "should fire 'expanded' property" , ( ) => {
28+ const { recordedEvents, onChange } = createChangeHandler ( ) ;
29+
30+ render (
31+ < Accordion
32+ id = "acc"
33+ type = "Accordion"
34+ expanded = { false }
35+ label = "My Accordion"
36+ onChange = { onChange }
37+ > </ Accordion > ,
38+ ) ;
39+
40+ // MUI Summary renders a button element
41+ fireEvent . click ( screen . getByRole ( "button" ) ) ;
42+
43+ expect ( recordedEvents . length ) . toEqual ( 1 ) ;
44+ expect ( recordedEvents [ 0 ] ) . toEqual ( {
45+ componentType : "Accordion" ,
46+ id : "acc" ,
47+ property : "expanded" ,
48+ value : true ,
49+ } ) ;
50+ } ) ;
51+ } ) ;
Original file line number Diff line number Diff line change 1+ /*
2+ * Copyright (c) 2019-2026 by Brockmann Consult Development team
3+ * Permissions are hereby granted under the terms of the MIT License:
4+ * https://opensource.org/licenses/MIT.
5+ */
6+
7+ import MuiAccordion from "@mui/material/Accordion" ;
8+ import MuiAccordionDetails from "@mui/material/AccordionDetails" ;
9+ import MuiAccordionSummary from "@mui/material/AccordionSummary" ;
10+ import MuiTypography from "@mui/material/Typography" ;
11+
12+ import type { ComponentState , ComponentProps } from "@/index" ;
13+ import { Children } from "@/index" ;
14+ import { Icon } from "./Icon" ;
15+ import type { SyntheticEvent } from "react" ;
16+
17+ interface AccordionState extends ComponentState {
18+ label ?: string ;
19+ icon ?: string ;
20+ expanded ?: boolean ;
21+ disabled ?: boolean ;
22+ }
23+
24+ interface AccordionProps extends ComponentProps , AccordionState { }
25+
26+ export const Accordion = ( {
27+ id,
28+ style,
29+ label,
30+ icon,
31+ expanded,
32+ disabled,
33+ children : nodes ,
34+ onChange,
35+ } : AccordionProps ) => {
36+ const handleChange = ( _event : SyntheticEvent , isExpanded : boolean ) => {
37+ if ( id ) {
38+ onChange ?.( {
39+ componentType : "Accordion" ,
40+ id,
41+ property : "expanded" ,
42+ value : isExpanded ,
43+ } ) ;
44+ }
45+ } ;
46+ return (
47+ < div >
48+ < MuiAccordion
49+ id = { id }
50+ style = { style }
51+ expanded = { expanded }
52+ disabled = { disabled }
53+ onChange = { handleChange }
54+ >
55+ < MuiAccordionSummary
56+ expandIcon = { icon ? < Icon iconName = { icon } /> : undefined }
57+ >
58+ { label ? (
59+ < MuiTypography component = "span" > { label } </ MuiTypography >
60+ ) : null }
61+ </ MuiAccordionSummary >
62+
63+ { nodes && (
64+ < MuiAccordionDetails >
65+ < Children nodes = { nodes } onChange = { onChange } />
66+ </ MuiAccordionDetails >
67+ ) }
68+ </ MuiAccordion >
69+ </ div >
70+ ) ;
71+ } ;
Original file line number Diff line number Diff line change 55 */
66
77import type { Plugin } from "@/index" ;
8+ import { Accordion } from "./Accordion" ;
89import { Box } from "./Box" ;
910import { Button } from "./Button" ;
1011import { Checkbox } from "./Checkbox" ;
@@ -25,6 +26,7 @@ import { Table } from "@/plugins/mui/Table";
2526export default function mui ( ) : Plugin {
2627 return {
2728 components : [
29+ [ "Accordion" , Accordion ] ,
2830 [ "Box" , Box ] ,
2931 [ "Button" , Button ] ,
3032 [ "Checkbox" , Checkbox ] ,
Original file line number Diff line number Diff line change 22# Permissions are hereby granted under the terms of the MIT License:
33# https://opensource.org/licenses/MIT.
44
5+ from .accordion import Accordion
56from .box import Box
67from .button import Button
78from .button import IconButton
Original file line number Diff line number Diff line change 1+ # Copyright (c) 2019-2026 by Brockmann Consult Development team
2+ # Permissions are hereby granted under the terms of the MIT License:
3+ # https://opensource.org/licenses/MIT.
4+
5+
6+ from dataclasses import dataclass , field
7+
8+ from chartlets import Component
9+
10+ @dataclass (frozen = True )
11+ class Accordion (Component ):
12+ """Accordion container."""
13+
14+ label : str | None = None
15+ """Header of the accordion."""
16+
17+ icon : str | None = None
18+ """Material icon name for the expand icon (e.g. 'expand_more')."""
19+
20+ expanded : bool = field (default = False )
21+ """If set, controls whether the accordion is expanded."""
22+
23+ disabled : bool | None = None
24+ """If set, controls whether the accordion is disabled."""
25+
26+ children : list [Component ] = field (default_factory = list )
27+ """Accordion content."""
You can’t perform that action at this time.
0 commit comments