@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
274 lines (270 loc) • 12.2 kB
JavaScript
'use client';
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import { LazyMotion, m } from 'framer-motion';
import { memo, useCallback, useMemo } from 'react';
import { Flexbox } from 'react-layout-kit';
import Block from "../Block";
import Text from "../Text";
import ArrowIcon from "./ArrowIcon";
import { useAccordionContext } from "./context";
import { useStyles } from "./style";
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
import { Fragment as _Fragment } from "react/jsx-runtime";
var loadFeatures = function loadFeatures() {
return import('framer-motion').then(function (res) {
return res.domAnimation;
});
};
var AccordionItem = /*#__PURE__*/memo(function (_ref) {
var _ref2, _ref3;
var itemKey = _ref.itemKey,
title = _ref.title,
children = _ref.children,
action = _ref.action,
_ref$disabled = _ref.disabled,
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
itemHideIndicator = _ref.hideIndicator,
itemIndicatorPlacement = _ref.indicatorPlacement,
customIndicator = _ref.indicator,
classNames = _ref.classNames,
_ref$paddingInline = _ref.paddingInline,
paddingInline = _ref$paddingInline === void 0 ? 16 : _ref$paddingInline,
_ref$paddingBlock = _ref.paddingBlock,
paddingBlock = _ref$paddingBlock === void 0 ? 8 : _ref$paddingBlock,
padding = _ref.padding,
ref = _ref.ref,
customVariant = _ref.variant,
customStyles = _ref.styles,
headerWrapper = _ref.headerWrapper;
var _useStyles = useStyles(),
cx = _useStyles.cx,
styles = _useStyles.styles;
var context = useAccordionContext();
var isExpanded = context.isExpanded,
onToggle = context.onToggle,
contextHideIndicator = context.hideIndicator,
contextIndicatorPlacement = context.indicatorPlacement,
keepContentMounted = context.keepContentMounted,
disableAnimation = context.disableAnimation,
contextMotionProps = context.motionProps,
_context$variant = context.variant,
variant = _context$variant === void 0 ? 'filled' : _context$variant;
var isOpen = isExpanded(itemKey);
var hideIndicatorFinal = (_ref2 = itemHideIndicator !== null && itemHideIndicator !== void 0 ? itemHideIndicator : contextHideIndicator) !== null && _ref2 !== void 0 ? _ref2 : false;
var indicatorPlacementFinal = (_ref3 = itemIndicatorPlacement !== null && itemIndicatorPlacement !== void 0 ? itemIndicatorPlacement : contextIndicatorPlacement) !== null && _ref3 !== void 0 ? _ref3 : 'start';
var handleToggle = useCallback(function () {
if (!disabled) {
onToggle(itemKey);
}
}, [disabled, itemKey, onToggle]);
var handleKeyDown = useCallback(function (e) {
if (disabled) return;
switch (e.key) {
case 'Enter':
case ' ':
{
e.preventDefault();
handleToggle();
break;
}
}
}, [disabled, handleToggle]);
// Build indicator
var indicator = useMemo(function () {
if (hideIndicatorFinal) return null;
if (customIndicator) {
if (typeof customIndicator === 'function') {
return /*#__PURE__*/_jsx("span", {
"aria-hidden": "true",
className: cx(styles.indicator, classNames === null || classNames === void 0 ? void 0 : classNames.indicator),
style: customStyles === null || customStyles === void 0 ? void 0 : customStyles.indicator,
children: customIndicator({
isDisabled: disabled,
isOpen: isOpen
})
});
}
return /*#__PURE__*/_jsx("span", {
"aria-hidden": "true",
className: cx(styles.indicator, classNames === null || classNames === void 0 ? void 0 : classNames.indicator),
style: customStyles === null || customStyles === void 0 ? void 0 : customStyles.indicator,
children: customIndicator
});
}
return /*#__PURE__*/_jsx("span", {
"aria-hidden": "true",
className: cx(styles.indicator, classNames === null || classNames === void 0 ? void 0 : classNames.indicator),
style: customStyles === null || customStyles === void 0 ? void 0 : customStyles.indicator,
children: /*#__PURE__*/_jsx(ArrowIcon, {
className: cx(styles.icon, isOpen && styles.iconRotate)
})
});
}, [hideIndicatorFinal, customIndicator, disabled, isOpen, cx, styles, classNames, customStyles]);
// Animation variants
var motionProps = useMemo(function () {
return _objectSpread({
animate: isOpen ? 'enter' : 'exit',
exit: 'exit',
initial: false,
variants: {
enter: {
height: 'auto',
opacity: 1,
transition: {
duration: 0.2,
ease: [0.4, 0, 0.2, 1]
}
},
exit: {
height: 0,
opacity: 0,
transition: {
duration: 0.2,
ease: [0.4, 0, 0.2, 1]
}
}
}
}, contextMotionProps);
}, [isOpen, contextMotionProps]);
// Render content
var contentElement = useMemo(function () {
if (disableAnimation || !keepContentMounted) {
if (keepContentMounted) {
return /*#__PURE__*/_jsx("div", {
className: cx('accordion-content', styles.content, classNames === null || classNames === void 0 ? void 0 : classNames.content),
role: "region",
style: _objectSpread({
display: isOpen ? 'block' : 'none'
}, customStyles === null || customStyles === void 0 ? void 0 : customStyles.content),
children: /*#__PURE__*/_jsx("div", {
className: styles.contentInner,
children: children
})
});
}
return isOpen && /*#__PURE__*/_jsx("div", {
className: cx('accordion-content', styles.content, classNames === null || classNames === void 0 ? void 0 : classNames.content),
role: "region",
style: customStyles === null || customStyles === void 0 ? void 0 : customStyles.content,
children: /*#__PURE__*/_jsx("div", {
className: styles.contentInner,
children: children
})
});
}
return /*#__PURE__*/_jsx(LazyMotion, {
features: loadFeatures,
children: /*#__PURE__*/_jsx(m.div, _objectSpread(_objectSpread({}, motionProps), {}, {
style: {
overflow: 'hidden'
},
children: /*#__PURE__*/_jsx("div", {
className: cx('accordion-content', styles.content, classNames === null || classNames === void 0 ? void 0 : classNames.content),
role: "region",
style: customStyles === null || customStyles === void 0 ? void 0 : customStyles.content,
children: /*#__PURE__*/_jsx("div", {
className: styles.contentInner,
children: children
})
})
}))
});
}, [disableAnimation, keepContentMounted, isOpen, cx, styles, classNames, customStyles, children, motionProps]);
var titleNode = useMemo(function () {
return typeof title === 'string' ? /*#__PURE__*/_jsx(Text, {
className: classNames === null || classNames === void 0 ? void 0 : classNames.title,
ellipsis: true,
style: customStyles === null || customStyles === void 0 ? void 0 : customStyles.title,
children: title
}) : title;
}, [title, classNames === null || classNames === void 0 ? void 0 : classNames.title, customStyles === null || customStyles === void 0 ? void 0 : customStyles.title]);
var actionNode = useMemo(function () {
return action && /*#__PURE__*/_jsx(Flexbox, {
align: 'center',
className: cx('accordion-action', styles.action, classNames === null || classNames === void 0 ? void 0 : classNames.action),
flex: 'none',
gap: 4,
horizontal: true,
onClick: function onClick(e) {
return e.stopPropagation();
},
style: customStyles === null || customStyles === void 0 ? void 0 : customStyles.action,
children: action
});
}, [action, cx, styles, classNames === null || classNames === void 0 ? void 0 : classNames.action, customStyles === null || customStyles === void 0 ? void 0 : customStyles.action]);
var headerElement = useMemo(function () {
var header = /*#__PURE__*/_jsx(Block, {
className: cx('accordion-header', styles.header, classNames === null || classNames === void 0 ? void 0 : classNames.header),
clickable: !disabled,
gap: 4,
horizontal: true,
justify: 'space-between',
onClick: handleToggle,
onKeyDown: handleKeyDown,
padding: padding,
paddingBlock: paddingBlock,
paddingInline: paddingInline,
ref: ref,
style: {
alignItems: 'center',
cursor: disabled ? 'not-allowed' : 'pointer',
opacity: disabled ? 0.5 : undefined,
overflow: 'hidden',
width: '100%'
},
variant: customVariant || variant,
children: indicatorPlacementFinal === 'start' ? /*#__PURE__*/_jsxs(_Fragment, {
children: [/*#__PURE__*/_jsxs(Flexbox, {
align: 'center',
flex: 1,
gap: 2,
horizontal: true,
style: {
overflow: 'hidden'
},
children: [titleNode, indicator]
}), /*#__PURE__*/_jsx(Flexbox, {
align: 'center',
flex: 'none',
gap: 4,
horizontal: true,
children: actionNode
})]
}) : /*#__PURE__*/_jsxs(_Fragment, {
children: [/*#__PURE__*/_jsx(Flexbox, {
align: 'center',
flex: 1,
gap: 2,
horizontal: true,
style: {
overflow: 'hidden'
},
children: titleNode
}), /*#__PURE__*/_jsxs(Flexbox, {
align: 'center',
flex: 'none',
gap: 4,
horizontal: true,
children: [actionNode, indicator]
})]
})
});
if (headerWrapper) {
return headerWrapper(header);
}
return header;
}, [cx, styles, classNames, disabled, handleToggle, handleKeyDown, padding, paddingBlock, paddingInline, ref, customVariant, variant, indicatorPlacementFinal, titleNode, indicator, actionNode, headerWrapper]);
return /*#__PURE__*/_jsxs("div", {
className: cx('accordion-item', styles.item, classNames === null || classNames === void 0 ? void 0 : classNames.base),
style: customStyles === null || customStyles === void 0 ? void 0 : customStyles.base,
children: [headerElement, contentElement]
});
});
AccordionItem.displayName = 'AccordionItem';
export default AccordionItem;