下面是我写的一个基于react的Flexible layout 组件:
import React, { useMemo } from "react";
import PropTypes from "prop-types";
import Box from "@mui/material/Box";
const ResponsiveVerticalStack = ({
children,
sxProps,
lastItemSxProps,
stickyBottom = false,
fillRemaining = true,
overflow = "hidden",
breakpoints,
otherProps,
}) => {
const childrenArray = useMemo(() => React.Children.toArray(children), [children]);
const modifiedChildren = useMemo(() => {
return childrenArray.map((child, index) => {
if (child && React.isValidElement(child)) {
const isLastChild = index === childrenArray.length - 1;
const lastItemStyles = isLastChild
? {
flex: fillRemaining ? 1 : "none",
overflow: overflow,
...(stickyBottom ? { position: "sticky", bottom: 0 } : {}),
...lastItemSxProps,
}
: {};
return React.cloneElement(child, {
style: {
...child.props.style,
...lastItemStyles,
},
});
}
return child;
});
}, [childrenArray, fillRemaining, overflow, stickyBottom, lastItemSxProps]);
return (
<Box
className="responsive-vertical-stack"
sx={{
display: "flex",
flexDirection: "column",
height: "100%",
...sxProps,
...(breakpoints || {}), // 应用断点配置
}}
{...otherProps}
>
{modifiedChildren}
</Box>
);
};
ResponsiveVerticalStack.propTypes = {
children: PropTypes.node.isRequired,
sxProps: PropTypes.object,
lastItemSxProps: PropTypes.object,
stickyBottom: PropTypes.bool,
fillRemaining: PropTypes.bool,
overflow: PropTypes.oneOf(["visible", "hidden", "scroll", "auto"]),
breakpoints: PropTypes.object,
otherProps: PropTypes.object,
};
ResponsiveVerticalStack.defaultProps = {
sxProps: {},
lastItemSxProps: {},
stickyBottom: false,
fillRemaining: true,
overflow: "hidden",
breakpoints: {},
otherProps: {},
};
export default ResponsiveVerticalStack;