-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
698 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import Typography from '@mui/material/Typography'; | ||
import AccordionDetails from '@mui/material/AccordionDetails'; | ||
import Accordion from '@/components/Accordion/Accordion'; | ||
import AccordionSummary from '@/components/Accordion/AccordionSummary'; | ||
|
||
export default function AccordionExpandDefault() { | ||
return ( | ||
<div style={{ padding: '10px' }}> | ||
<Accordion defaultExpanded> | ||
<AccordionSummary aria-controls="panel1-content" id="panel1-header"> | ||
<Typography>Expanded by default</Typography> | ||
</AccordionSummary> | ||
<AccordionDetails> | ||
<Typography> | ||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, | ||
sit amet blandit leo lobortis eget. | ||
</Typography> | ||
</AccordionDetails> | ||
</Accordion> | ||
<Accordion> | ||
<AccordionSummary aria-controls="panel2-content" id="panel2-header"> | ||
<Typography>Header</Typography> | ||
</AccordionSummary> | ||
<AccordionDetails> | ||
<Typography> | ||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, | ||
sit amet blandit leo lobortis eget. | ||
</Typography> | ||
</AccordionDetails> | ||
</Accordion> | ||
</div> | ||
); | ||
} |
315 changes: 315 additions & 0 deletions
315
apps/zero-runtime-next-app/src/components/Accordion/Accordion.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,315 @@ | ||
'use client'; | ||
import * as React from 'react'; | ||
import { isFragment } from 'react-is'; | ||
import PropTypes from 'prop-types'; | ||
import clsx from 'clsx'; | ||
import chainPropTypes from '@mui/utils/chainPropTypes'; | ||
import composeClasses from '@mui/utils/composeClasses'; | ||
import { styled } from '@mui/zero-runtime'; | ||
import { useThemeProps } from '@mui/material/styles'; | ||
import Collapse from '@mui/material/Collapse'; | ||
import Paper from '@mui/material/Paper'; | ||
/* eslint-disable-next-line no-restricted-imports */ | ||
import AccordionContext from '@mui/material/Accordion/AccordionContext'; | ||
import { useControlled } from '@mui/material/utils'; | ||
/* eslint-disable-next-line no-restricted-imports */ | ||
import useSlot from '@mui/material/utils/useSlot'; | ||
import { accordionClasses, getAccordionUtilityClass } from '@mui/material/Accordion'; | ||
|
||
const useUtilityClasses = (ownerState) => { | ||
const { classes, square, expanded, disabled, disableGutters } = ownerState; | ||
|
||
const slots = { | ||
root: [ | ||
'root', | ||
!square && 'rounded', | ||
expanded && 'expanded', | ||
disabled && 'disabled', | ||
!disableGutters && 'gutters', | ||
], | ||
region: ['region'], | ||
}; | ||
|
||
return composeClasses(slots, getAccordionUtilityClass, classes); | ||
}; | ||
|
||
const AccordionRoot = styled(Paper, { | ||
name: 'MuiAccordion', | ||
slot: 'Root', | ||
overridesResolver: (props, styles) => { | ||
const { ownerState } = props; | ||
|
||
return [ | ||
{ [`& .${accordionClasses.region}`]: styles.region }, | ||
styles.root, | ||
!ownerState.square && styles.rounded, | ||
!ownerState.disableGutters && styles.gutters, | ||
]; | ||
}, | ||
})( | ||
({ theme }) => { | ||
const transition = { | ||
duration: theme.transitions.duration.shortest, | ||
}; | ||
|
||
return { | ||
position: 'relative', | ||
transition: theme.transitions.create(['margin'], transition), | ||
overflowAnchor: 'none', // Keep the same scrolling position | ||
'&::before': { | ||
position: 'absolute', | ||
left: 0, | ||
top: -1, | ||
right: 0, | ||
height: 1, | ||
content: '""', | ||
opacity: 1, | ||
backgroundColor: (theme.vars || theme).palette.divider, | ||
transition: theme.transitions.create(['opacity', 'background-color'], transition), | ||
}, | ||
'&:first-of-type': { | ||
'&::before': { | ||
display: 'none', | ||
}, | ||
}, | ||
[`&.${accordionClasses.expanded}`]: { | ||
'&::before': { | ||
opacity: 0, | ||
}, | ||
'&:first-of-type': { | ||
marginTop: 0, | ||
}, | ||
'&:last-of-type': { | ||
marginBottom: 0, | ||
}, | ||
'& + &': { | ||
'&::before': { | ||
display: 'none', | ||
}, | ||
}, | ||
}, | ||
[`&.${accordionClasses.disabled}`]: { | ||
backgroundColor: (theme.vars || theme).palette.action.disabledBackground, | ||
}, | ||
}; | ||
}, | ||
({ theme }) => ({ | ||
variants: [ | ||
{ | ||
props: (props) => !props.square, | ||
style: { | ||
borderRadius: 0, | ||
'&:first-of-type': { | ||
borderTopLeftRadius: (theme.vars || theme).shape.borderRadius, | ||
borderTopRightRadius: (theme.vars || theme).shape.borderRadius, | ||
}, | ||
'&:last-of-type': { | ||
borderBottomLeftRadius: (theme.vars || theme).shape.borderRadius, | ||
borderBottomRightRadius: (theme.vars || theme).shape.borderRadius, | ||
// Fix a rendering issue on Edge | ||
'@supports (-ms-ime-align: auto)': { | ||
borderBottomLeftRadius: 0, | ||
borderBottomRightRadius: 0, | ||
}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
props: (props) => !props.disableGutters, | ||
style: { | ||
[`&.${accordionClasses.expanded}`]: { | ||
margin: '16px 0', | ||
}, | ||
}, | ||
}, | ||
], | ||
}), | ||
); | ||
|
||
const Accordion = React.forwardRef(function Accordion(inProps, ref) { | ||
const props = useThemeProps({ props: inProps, name: 'MuiAccordion' }); | ||
const { | ||
children: childrenProp, | ||
className, | ||
defaultExpanded = false, | ||
disabled = false, | ||
disableGutters = false, | ||
expanded: expandedProp, | ||
onChange, | ||
square = false, | ||
slots = {}, | ||
slotProps = {}, | ||
TransitionComponent: TransitionComponentProp, | ||
TransitionProps: TransitionPropsProp, | ||
...other | ||
} = props; | ||
|
||
const [expanded, setExpandedState] = useControlled({ | ||
controlled: expandedProp, | ||
default: defaultExpanded, | ||
name: 'Accordion', | ||
state: 'expanded', | ||
}); | ||
|
||
const handleChange = React.useCallback( | ||
(event) => { | ||
setExpandedState(!expanded); | ||
|
||
if (onChange) { | ||
onChange(event, !expanded); | ||
} | ||
}, | ||
[expanded, onChange, setExpandedState], | ||
); | ||
|
||
const [summary, ...children] = React.Children.toArray(childrenProp); | ||
const contextValue = React.useMemo( | ||
() => ({ expanded, disabled, disableGutters, toggle: handleChange }), | ||
[expanded, disabled, disableGutters, handleChange], | ||
); | ||
|
||
const ownerState = { | ||
...props, | ||
square, | ||
disabled, | ||
disableGutters, | ||
expanded, | ||
}; | ||
|
||
const classes = useUtilityClasses(ownerState); | ||
|
||
const backwardCompatibleSlots = { transition: TransitionComponentProp, ...slots }; | ||
const backwardCompatibleSlotProps = { transition: TransitionPropsProp, ...slotProps }; | ||
|
||
const [TransitionSlot, transitionProps] = useSlot('transition', { | ||
elementType: Collapse, | ||
externalForwardedProps: { | ||
slots: backwardCompatibleSlots, | ||
slotProps: backwardCompatibleSlotProps, | ||
}, | ||
ownerState, | ||
}); | ||
|
||
return ( | ||
<AccordionRoot | ||
className={clsx(classes.root, className)} | ||
ref={ref} | ||
ownerState={ownerState} | ||
square={square} | ||
{...other} | ||
> | ||
<AccordionContext.Provider value={contextValue}>{summary}</AccordionContext.Provider> | ||
<TransitionSlot in={expanded} timeout="auto" {...transitionProps}> | ||
<div | ||
aria-labelledby={summary.props.id} | ||
id={summary.props['aria-controls']} | ||
role="region" | ||
className={classes.region} | ||
> | ||
{children} | ||
</div> | ||
</TransitionSlot> | ||
</AccordionRoot> | ||
); | ||
}); | ||
|
||
Accordion.propTypes /* remove-proptypes */ = { | ||
// ┌────────────────────────────── Warning ──────────────────────────────┐ | ||
// │ These PropTypes are generated from the TypeScript type definitions. │ | ||
// │ To update them, edit the d.ts file and run `pnpm proptypes`. │ | ||
// └─────────────────────────────────────────────────────────────────────┘ | ||
/** | ||
* The content of the component. | ||
*/ | ||
children: chainPropTypes(PropTypes.node.isRequired, (props) => { | ||
const summary = React.Children.toArray(props.children)[0]; | ||
if (isFragment(summary)) { | ||
return new Error( | ||
"MUI: The Accordion doesn't accept a Fragment as a child. " + | ||
'Consider providing an array instead.', | ||
); | ||
} | ||
|
||
if (!React.isValidElement(summary)) { | ||
return new Error('MUI: Expected the first child of Accordion to be a valid element.'); | ||
} | ||
|
||
return null; | ||
}), | ||
/** | ||
* Override or extend the styles applied to the component. | ||
*/ | ||
classes: PropTypes.object, | ||
/** | ||
* @ignore | ||
*/ | ||
className: PropTypes.string, | ||
/** | ||
* If `true`, expands the accordion by default. | ||
* @default false | ||
*/ | ||
defaultExpanded: PropTypes.bool, | ||
/** | ||
* If `true`, the component is disabled. | ||
* @default false | ||
*/ | ||
disabled: PropTypes.bool, | ||
/** | ||
* If `true`, it removes the margin between two expanded accordion items and the increase of height. | ||
* @default false | ||
*/ | ||
disableGutters: PropTypes.bool, | ||
/** | ||
* If `true`, expands the accordion, otherwise collapse it. | ||
* Setting this prop enables control over the accordion. | ||
*/ | ||
expanded: PropTypes.bool, | ||
/** | ||
* Callback fired when the expand/collapse state is changed. | ||
* | ||
* @param {React.SyntheticEvent} event The event source of the callback. **Warning**: This is a generic event not a change event. | ||
* @param {boolean} expanded The `expanded` state of the accordion. | ||
*/ | ||
onChange: PropTypes.func, | ||
/** | ||
* The props used for each slot inside. | ||
* @default {} | ||
*/ | ||
slotProps: PropTypes.shape({ | ||
transition: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), | ||
}), | ||
/** | ||
* The components used for each slot inside. | ||
* @default {} | ||
*/ | ||
slots: PropTypes.shape({ | ||
transition: PropTypes.elementType, | ||
}), | ||
/** | ||
* If `true`, rounded corners are disabled. | ||
* @default false | ||
*/ | ||
square: PropTypes.bool, | ||
/** | ||
* The system prop that allows defining system overrides as well as additional CSS styles. | ||
*/ | ||
sx: PropTypes.oneOfType([ | ||
PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), | ||
PropTypes.func, | ||
PropTypes.object, | ||
]), | ||
/** | ||
* The component used for the transition. | ||
* [Follow this guide](/material-ui/transitions/#transitioncomponent-prop) to learn more about the requirements for this component. | ||
* @deprecated Use `slots.transition` instead. This prop will be removed in v7. [How to migrate](/material-ui/migration/migrating-from-deprecated-apis/). | ||
*/ | ||
TransitionComponent: PropTypes.elementType, | ||
/** | ||
* Props applied to the transition element. | ||
* By default, the element is based on this [`Transition`](https://reactcommunity.org/react-transition-group/transition/) component. | ||
* @deprecated Use `slotProps.transition` instead. This prop will be removed in v7. [How to migrate](/material-ui/migration/migrating-from-deprecated-apis/). | ||
*/ | ||
TransitionProps: PropTypes.object, | ||
}; | ||
|
||
export default Accordion; |
Oops, something went wrong.