UNPKG

@onesy/ui-react

Version:
253 lines (252 loc) 17 kB
"use strict"; 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;