@onesy/ui-react
Version:
UI for React
253 lines (252 loc) • 17 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = __importDefault(require("react"));
const utils_1 = require("@onesy/utils");
const style_react_1 = require("@onesy/style-react");
const IconMaterialExpandMoreW100_1 = __importDefault(require("@onesy/icons-material-rounded-react/IconMaterialExpandMoreW100"));
const Surface_1 = __importDefault(require("../Surface"));
const Fade_1 = __importDefault(require("../Fade"));
const Expand_1 = __importDefault(require("../Expand"));
const IconButton_1 = __importDefault(require("../IconButton"));
const Grid_1 = __importDefault(require("../Grid"));
const Line_1 = __importDefault(require("../Line"));
const Type_1 = __importDefault(require("../Type"));
const utils_2 = require("../utils");
const useStyle = (0, style_react_1.style)(theme => ({
root: {
position: 'relative',
display: 'flex',
flexDirection: 'column',
transition: theme.methods.transitions.make(['margin', 'boxShadow']),
width: '100%',
'&:first-of-type': {
marginTop: '0px',
borderTopLeftRadius: `${theme.shape.radius.unit / 2}px`,
borderTopRightRadius: `${theme.shape.radius.unit / 2}px`
},
'&:last-of-type': {
marginBottom: '0px',
borderBottomLeftRadius: `${theme.shape.radius.unit / 2}px`,
borderBottomRightRadius: `${theme.shape.radius.unit / 2}px`
}
},
expanded_margin_vertical_start: { marginBlockStart: '16px' },
expanded_margin_vertical_both: { marginBlock: '16px' },
expanded_margin_vertical_end: { marginBlockEnd: '16px' },
expanded_margin_vertical_none: { marginBlock: '0px' },
wrapperHeader: {
cursor: 'pointer',
transition: theme.methods.transitions.make('padding'),
userSelect: 'none'
},
header: {},
expanded_header_padding_vertical_start: { paddingBlockStart: `${theme.methods.space.value(2, 'px')} !important` },
expanded_header_padding_vertical_both: { paddingBlock: `${theme.methods.space.value(2, 'px')} !important` },
expanded_header_padding_vertical_end: { paddingBlockEnd: `${theme.methods.space.value(2, 'px')} !important` },
expanded_header_padding_vertical_none: { paddingBlock: '0px !important' },
header_padding_vertical_start: { paddingBlockStart: theme.methods.space.value(1, 'px') },
header_padding_vertical_both: { paddingBlock: theme.methods.space.value(1, 'px') },
header_padding_vertical_end: { paddingBlockEnd: theme.methods.space.value(1, 'px') },
header_padding_vertical_none: { paddingBlock: '0px' },
header_padding_horizontal_start: { paddingInlineStart: theme.methods.space.value(2, 'px') },
header_padding_horizontal_both: { paddingInline: theme.methods.space.value(2, 'px') },
header_padding_horizontal_end: { paddingInlineEnd: theme.methods.space.value(2, 'px') },
header_padding_horizontal_none: { paddingInline: '0px' },
main: {
width: '100%'
},
main_padding_vertical_start: { paddingBlockStart: theme.methods.space.value(2, 'px') },
main_padding_vertical_both: { paddingBlock: theme.methods.space.value(2, 'px') },
main_padding_vertical_end: { paddingBlockEnd: theme.methods.space.value(2, 'px') },
main_padding_vertical_none: { paddingBlock: '0px' },
main_padding_horizontal_start: { paddingInlineStart: theme.methods.space.value(2, 'px') },
main_padding_horizontal_both: { paddingInline: theme.methods.space.value(2, 'px') },
main_padding_horizontal_end: { paddingInlineEnd: theme.methods.space.value(2, 'px') },
main_padding_horizontal_none: { paddingInline: '0px' },
secondary: {
opacity: theme.palette.visual_contrast.default.opacity.primary
},
icon: {
transition: theme.methods.transitions.make('transform')
},
icon_open: {
transform: 'rotate(-180deg)'
},
iconButton: {
flex: '0 0 auto'
},
noBackground: {
'&.onesy-Surface-root': {
background: 'transparent'
}
},
disabled: {
cursor: 'pointer',
pointerEvents: 'none',
opacity: theme.palette.visual_contrast.default.opacity.disabled
}
}), { name: 'onesy-Accordion' });
const AccordionDelays = {
Transition: {
enter: 70
}
};
const Accordion = react_1.default.forwardRef((props_, ref) => {
const theme = (0, style_react_1.useOnesyTheme)();
const props = react_1.default.useMemo(() => { var _a, _b, _c, _d, _e, _f, _g, _h; return (Object.assign(Object.assign(Object.assign({}, (_d = (_c = (_b = (_a = theme === null || theme === void 0 ? void 0 : theme.ui) === null || _a === void 0 ? void 0 : _a.elements) === null || _b === void 0 ? void 0 : _b.all) === null || _c === void 0 ? void 0 : _c.props) === null || _d === void 0 ? void 0 : _d.default), (_h = (_g = (_f = (_e = theme === null || theme === void 0 ? void 0 : theme.ui) === null || _e === void 0 ? void 0 : _e.elements) === null || _f === void 0 ? void 0 : _f.onesyAccordion) === null || _g === void 0 ? void 0 : _g.props) === null || _h === void 0 ? void 0 : _h.default), props_)); }, [props_]);
// Why
// By providing option for a theme to override an entire element
// with a value stored in elements
// we can override entire element's content
// not just customize an element using css
const Surface = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Surface) || Surface_1.default; }, [theme]);
const Fade = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Fade) || Fade_1.default; }, [theme]);
const Expand = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Expand) || Expand_1.default; }, [theme]);
const IconButton = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.IconButton) || IconButton_1.default; }, [theme]);
const Grid = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Grid) || Grid_1.default; }, [theme]);
const Line = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Line) || Line_1.default; }, [theme]);
const Type = react_1.default.useMemo(() => { var _a; return ((_a = theme === null || theme === void 0 ? void 0 : theme.elements) === null || _a === void 0 ? void 0 : _a.Type) || Type_1.default; }, [theme]);
const { tonal = true, color = 'primary', elevation = 0, primary, secondary, start, end, openDefault, open: open_, onChange, noBackground, noExpandButton, expandedMarginVertical = 'both', expandedHeaderPaddingVertical = 'both', headerPaddingVertical = 'both', headerPaddingHorizontal = 'both', mainPaddingVertical = 'both', mainPaddingHorizontal = 'both', noExpand, noTransition, disabled, ExpandIcon = IconMaterialExpandMoreW100_1.default, TransitionComponent: TransitionComponent_ = Fade, Component = 'div', ExpandProps, TransitionComponentProps: TransitionComponentProps_, WrapperHeaderProps, HeaderProps, IconButtonProps, StartProps, EndProps, className, children } = props, other = __rest(props, ["tonal", "color", "elevation", "primary", "secondary", "start", "end", "openDefault", "open", "onChange", "noBackground", "noExpandButton", "expandedMarginVertical", "expandedHeaderPaddingVertical", "headerPaddingVertical", "headerPaddingHorizontal", "mainPaddingVertical", "mainPaddingHorizontal", "noExpand", "noTransition", "disabled", "ExpandIcon", "TransitionComponent", "Component", "ExpandProps", "TransitionComponentProps", "WrapperHeaderProps", "HeaderProps", "IconButtonProps", "StartProps", "EndProps", "className", "children"]);
const [open, setOpen] = react_1.default.useState(openDefault !== undefined ? openDefault : open_);
const [parent, setParent] = react_1.default.useState();
const refs = {
root: react_1.default.useRef(undefined),
ids: {
button: react_1.default.useId(),
data: react_1.default.useId()
},
expandInProgress: react_1.default.useRef(null)
};
const { classes } = useStyle();
let TransitionComponent = TransitionComponent_;
let TransitionComponentProps = Object.assign({ add: true, delay: {
enter: AccordionDelays.Transition.enter
} }, TransitionComponentProps_);
react_1.default.useEffect(() => {
if (open_ !== undefined && open_ !== open)
setOpen(open_);
}, [open_, open]);
const onClick = react_1.default.useCallback(() => {
if (refs.expandInProgress.current)
return;
if (!disabled) {
const valueNew = !open;
// Update inner or controlled
if (!props.hasOwnProperty('open'))
setOpen(valueNew);
if ((0, utils_1.is)('function', onChange))
onChange(valueNew);
}
}, [open, disabled]);
if (!noTransition)
TransitionComponentProps.in = open;
else {
TransitionComponent = react_1.default.Fragment;
TransitionComponentProps = {};
}
const main = ((0, jsx_runtime_1.jsx)(Line, Object.assign({ className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Accordion', theme) && [
'onesy-Accordion-main'
],
classes.main,
classes[`main_padding_vertical_${mainPaddingVertical}`],
classes[`main_padding_horizontal_${mainPaddingHorizontal}`],
]) }, { children: children })));
return ((0, jsx_runtime_1.jsxs)(Surface, Object.assign({ ref: item => {
if (ref) {
if ((0, utils_1.is)('function', ref))
ref(item);
else if (ref === null || ref === void 0 ? void 0 : ref.current)
ref.current = item;
}
refs.root.current = item;
setParent(item);
}, tonal: tonal, color: color, elevation: elevation, Component: Component, className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Accordion', theme) && [
'onesy-Accordion-root',
disabled && `onesy-Accordion-disabled`
],
className,
classes.root,
open && classes[`expanded_margin_vertical_${expandedMarginVertical}`],
noBackground && classes.noBackground,
disabled && classes.disabled
]) }, other, { children: [(0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 3, direction: 'row', align: 'center', onClick: onClick }, WrapperHeaderProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Accordion', theme) && [
'onesy-Accordion-wrapper-header'
],
WrapperHeaderProps === null || WrapperHeaderProps === void 0 ? void 0 : WrapperHeaderProps.className,
classes.wrapperHeader,
classes[`header_padding_vertical_${headerPaddingVertical}`],
classes[`header_padding_horizontal_${headerPaddingHorizontal}`],
open && [
classes[`expanded_header_padding_vertical_${expandedHeaderPaddingVertical}`]
]
]) }, { children: [start, (0, jsx_runtime_1.jsxs)(Grid, Object.assign({ gap: {
default: 3,
700: 0.5
}, direction: {
default: 'row',
700: 'column'
} }, HeaderProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Accordion', theme) && [
'onesy-Accordion-header'
],
HeaderProps === null || HeaderProps === void 0 ? void 0 : HeaderProps.className,
classes.header
]) }, { children: [(0, jsx_runtime_1.jsx)(Grid, Object.assign({ values: { sm: !secondary ? 12 : 3 } }, { children: (0, utils_1.is)('simple', primary) ? ((0, jsx_runtime_1.jsx)(Type, Object.assign({ version: 'b1', className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Accordion', theme) && [
'onesy-Accordion-primary'
],
classes.primary
]) }, { children: primary }))) : (react_1.default.Children.toArray(primary)
.filter(Boolean)
.map((item, index) => {
if ((0, utils_1.is)('simple', item))
return item;
return (react_1.default.cloneElement(item, {
key: index
}));
})) })), secondary && ((0, jsx_runtime_1.jsx)(Grid, Object.assign({ values: { sm: 7 } }, { children: (0, utils_1.is)('simple', secondary) ? ((0, jsx_runtime_1.jsx)(Type, Object.assign({ version: 'b1', className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Accordion', theme) && [
'onesy-Accordion-secondary'
],
classes.secondary
]) }, { children: secondary }))) : (react_1.default.Children.toArray(secondary)
.filter(Boolean)
.map((item, index) => {
if ((0, utils_1.is)('simple', item))
return item;
return (react_1.default.cloneElement(item, {
key: index
}));
})) })))] })), (0, jsx_runtime_1.jsxs)(Line, Object.assign({ gap: 0, direction: 'row', align: 'center' }, EndProps, { children: [end, !noExpandButton && ((0, jsx_runtime_1.jsx)(IconButton, Object.assign({ color: 'inherit', "aria-label": primary || secondary, "aria-controls": refs.ids.data, "aria-expanded": open, id: refs.ids.button }, IconButtonProps, { className: (0, style_react_1.classNames)([
(0, utils_2.staticClassName)('Accordion', theme) && [
'onesy-Accordion-icon-button'
],
IconButtonProps === null || IconButtonProps === void 0 ? void 0 : IconButtonProps.className,
classes.iconButton
]) }, { children: (0, jsx_runtime_1.jsx)(ExpandIcon, { className: (0, style_react_1.classNames)([
classes.icon,
open && classes.icon_open
]) }) })))] }))] })), noExpand ? (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: open && main }) : ((0, jsx_runtime_1.jsx)(Expand, Object.assign({ in: open, parent: parent, onTransition: (element, status) => {
refs.expandInProgress.current = !['appended', 'entered', 'exited', 'removed'].includes(status);
}, role: 'region', "aria-labelledby": refs.ids.button, id: refs.ids.data }, ExpandProps, { children: (0, jsx_runtime_1.jsx)(TransitionComponent, Object.assign({}, TransitionComponentProps, { children: main })) })))] })));
});
Accordion.displayName = 'onesy-Accordion';
exports.default = Accordion;
;