UNPKG

9.8 kBJavaScriptView Raw
1'use client';
2
3import * as React from 'react';
4import { isFragment } from 'react-is';
5import PropTypes from 'prop-types';
6import clsx from 'clsx';
7import chainPropTypes from '@mui/utils/chainPropTypes';
8import composeClasses from '@mui/utils/composeClasses';
9import { styled } from "../zero-styled/index.js";
10import memoTheme from "../utils/memoTheme.js";
11import { useDefaultProps } from "../DefaultPropsProvider/index.js";
12import Collapse from "../Collapse/index.js";
13import Paper from "../Paper/index.js";
14import AccordionContext from "./AccordionContext.js";
15import useControlled from "../utils/useControlled.js";
16import useSlot from "../utils/useSlot.js";
17import accordionClasses, { getAccordionUtilityClass } from "./accordionClasses.js";
18import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
19const useUtilityClasses = ownerState => {
20 const {
21 classes,
22 square,
23 expanded,
24 disabled,
25 disableGutters
26 } = ownerState;
27 const slots = {
28 root: ['root', !square && 'rounded', expanded && 'expanded', disabled && 'disabled', !disableGutters && 'gutters'],
29 heading: ['heading'],
30 region: ['region']
31 };
32 return composeClasses(slots, getAccordionUtilityClass, classes);
33};
34const AccordionRoot = styled(Paper, {
35 name: 'MuiAccordion',
36 slot: 'Root',
37 overridesResolver: (props, styles) => {
38 const {
39 ownerState
40 } = props;
41 return [{
42 [`& .${accordionClasses.region}`]: styles.region
43 }, styles.root, !ownerState.square && styles.rounded, !ownerState.disableGutters && styles.gutters];
44 }
45})(memoTheme(({
46 theme
47}) => {
48 const transition = {
49 duration: theme.transitions.duration.shortest
50 };
51 return {
52 position: 'relative',
53 transition: theme.transitions.create(['margin'], transition),
54 overflowAnchor: 'none',
55 // Keep the same scrolling position
56 '&::before': {
57 position: 'absolute',
58 left: 0,
59 top: -1,
60 right: 0,
61 height: 1,
62 content: '""',
63 opacity: 1,
64 backgroundColor: (theme.vars || theme).palette.divider,
65 transition: theme.transitions.create(['opacity', 'background-color'], transition)
66 },
67 '&:first-of-type': {
68 '&::before': {
69 display: 'none'
70 }
71 },
72 [`&.${accordionClasses.expanded}`]: {
73 '&::before': {
74 opacity: 0
75 },
76 '&:first-of-type': {
77 marginTop: 0
78 },
79 '&:last-of-type': {
80 marginBottom: 0
81 },
82 '& + &': {
83 '&::before': {
84 display: 'none'
85 }
86 }
87 },
88 [`&.${accordionClasses.disabled}`]: {
89 backgroundColor: (theme.vars || theme).palette.action.disabledBackground
90 }
91 };
92}), memoTheme(({
93 theme
94}) => ({
95 variants: [{
96 props: props => !props.square,
97 style: {
98 borderRadius: 0,
99 '&:first-of-type': {
100 borderTopLeftRadius: (theme.vars || theme).shape.borderRadius,
101 borderTopRightRadius: (theme.vars || theme).shape.borderRadius
102 },
103 '&:last-of-type': {
104 borderBottomLeftRadius: (theme.vars || theme).shape.borderRadius,
105 borderBottomRightRadius: (theme.vars || theme).shape.borderRadius,
106 // Fix a rendering issue on Edge
107 '@supports (-ms-ime-align: auto)': {
108 borderBottomLeftRadius: 0,
109 borderBottomRightRadius: 0
110 }
111 }
112 }
113 }, {
114 props: props => !props.disableGutters,
115 style: {
116 [`&.${accordionClasses.expanded}`]: {
117 margin: '16px 0'
118 }
119 }
120 }]
121})));
122const AccordionHeading = styled('h3', {
123 name: 'MuiAccordion',
124 slot: 'Heading',
125 overridesResolver: (props, styles) => styles.heading
126})({
127 all: 'unset'
128});
129const Accordion = /*#__PURE__*/React.forwardRef(function Accordion(inProps, ref) {
130 const props = useDefaultProps({
131 props: inProps,
132 name: 'MuiAccordion'
133 });
134 const {
135 children: childrenProp,
136 className,
137 defaultExpanded = false,
138 disabled = false,
139 disableGutters = false,
140 expanded: expandedProp,
141 onChange,
142 square = false,
143 slots = {},
144 slotProps = {},
145 TransitionComponent: TransitionComponentProp,
146 TransitionProps: TransitionPropsProp,
147 ...other
148 } = props;
149 const [expanded, setExpandedState] = useControlled({
150 controlled: expandedProp,
151 default: defaultExpanded,
152 name: 'Accordion',
153 state: 'expanded'
154 });
155 const handleChange = React.useCallback(event => {
156 setExpandedState(!expanded);
157 if (onChange) {
158 onChange(event, !expanded);
159 }
160 }, [expanded, onChange, setExpandedState]);
161 const [summary, ...children] = React.Children.toArray(childrenProp);
162 const contextValue = React.useMemo(() => ({
163 expanded,
164 disabled,
165 disableGutters,
166 toggle: handleChange
167 }), [expanded, disabled, disableGutters, handleChange]);
168 const ownerState = {
169 ...props,
170 square,
171 disabled,
172 disableGutters,
173 expanded
174 };
175 const classes = useUtilityClasses(ownerState);
176 const backwardCompatibleSlots = {
177 transition: TransitionComponentProp,
178 ...slots
179 };
180 const backwardCompatibleSlotProps = {
181 transition: TransitionPropsProp,
182 ...slotProps
183 };
184 const externalForwardedProps = {
185 slots: backwardCompatibleSlots,
186 slotProps: backwardCompatibleSlotProps
187 };
188 const [AccordionHeadingSlot, accordionProps] = useSlot('heading', {
189 elementType: AccordionHeading,
190 externalForwardedProps,
191 className: classes.heading,
192 ownerState
193 });
194 const [TransitionSlot, transitionProps] = useSlot('transition', {
195 elementType: Collapse,
196 externalForwardedProps,
197 ownerState
198 });
199 return /*#__PURE__*/_jsxs(AccordionRoot, {
200 className: clsx(classes.root, className),
201 ref: ref,
202 ownerState: ownerState,
203 square: square,
204 ...other,
205 children: [/*#__PURE__*/_jsx(AccordionHeadingSlot, {
206 ...accordionProps,
207 children: /*#__PURE__*/_jsx(AccordionContext.Provider, {
208 value: contextValue,
209 children: summary
210 })
211 }), /*#__PURE__*/_jsx(TransitionSlot, {
212 in: expanded,
213 timeout: "auto",
214 ...transitionProps,
215 children: /*#__PURE__*/_jsx("div", {
216 "aria-labelledby": summary.props.id,
217 id: summary.props['aria-controls'],
218 role: "region",
219 className: classes.region,
220 children: children
221 })
222 })]
223 });
224});
225process.env.NODE_ENV !== "production" ? Accordion.propTypes /* remove-proptypes */ = {
226 // ┌────────────────────────────── Warning ──────────────────────────────┐
227 // │ These PropTypes are generated from the TypeScript type definitions. │
228 // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
229 // └─────────────────────────────────────────────────────────────────────┘
230 /**
231 * The content of the component.
232 */
233 children: chainPropTypes(PropTypes.node.isRequired, props => {
234 const summary = React.Children.toArray(props.children)[0];
235 if (isFragment(summary)) {
236 return new Error("MUI: The Accordion doesn't accept a Fragment as a child. " + 'Consider providing an array instead.');
237 }
238 if (! /*#__PURE__*/React.isValidElement(summary)) {
239 return new Error('MUI: Expected the first child of Accordion to be a valid element.');
240 }
241 return null;
242 }),
243 /**
244 * Override or extend the styles applied to the component.
245 */
246 classes: PropTypes.object,
247 /**
248 * @ignore
249 */
250 className: PropTypes.string,
251 /**
252 * If `true`, expands the accordion by default.
253 * @default false
254 */
255 defaultExpanded: PropTypes.bool,
256 /**
257 * If `true`, the component is disabled.
258 * @default false
259 */
260 disabled: PropTypes.bool,
261 /**
262 * If `true`, it removes the margin between two expanded accordion items and the increase of height.
263 * @default false
264 */
265 disableGutters: PropTypes.bool,
266 /**
267 * If `true`, expands the accordion, otherwise collapse it.
268 * Setting this prop enables control over the accordion.
269 */
270 expanded: PropTypes.bool,
271 /**
272 * Callback fired when the expand/collapse state is changed.
273 *
274 * @param {React.SyntheticEvent} event The event source of the callback. **Warning**: This is a generic event not a change event.
275 * @param {boolean} expanded The `expanded` state of the accordion.
276 */
277 onChange: PropTypes.func,
278 /**
279 * The props used for each slot inside.
280 * @default {}
281 */
282 slotProps: PropTypes.shape({
283 heading: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
284 transition: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
285 }),
286 /**
287 * The components used for each slot inside.
288 * @default {}
289 */
290 slots: PropTypes.shape({
291 heading: PropTypes.elementType,
292 transition: PropTypes.elementType
293 }),
294 /**
295 * If `true`, rounded corners are disabled.
296 * @default false
297 */
298 square: PropTypes.bool,
299 /**
300 * The system prop that allows defining system overrides as well as additional CSS styles.
301 */
302 sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
303 /**
304 * The component used for the transition.
305 * [Follow this guide](https://mui.com/material-ui/transitions/#transitioncomponent-prop) to learn more about the requirements for this component.
306 */
307 TransitionComponent: PropTypes.elementType,
308 /**
309 * Props applied to the transition element.
310 * By default, the element is based on this [`Transition`](https://reactcommunity.org/react-transition-group/transition/) component.
311 */
312 TransitionProps: PropTypes.object
313} : void 0;
314export default Accordion;
\No newline at end of file