UNPKG

@nex-ui/react

Version:

🎉 A beautiful, modern, and reliable React component library.

261 lines (255 loc) • 8.94 kB
"use client"; 'use strict'; var jsxRuntime = require('react/jsx-runtime'); var m = require('motion/react-m'); var hooks = require('@nex-ui/hooks'); var icons = require('@nex-ui/icons'); var react$1 = require('motion/react'); var react = require('react'); var AccordionContext = require('./AccordionContext.cjs'); var useDefaultProps = require('../utils/useDefaultProps.cjs'); var useStyles = require('../utils/useStyles.cjs'); var useSlotClasses = require('../utils/useSlotClasses.cjs'); var useSlot = require('../utils/useSlot.cjs'); var ButtonBase = require('../buttonBase/ButtonBase.cjs'); var index = require('../utils/motionFeatures/index.cjs'); var accordion = require('../../theme/recipes/accordion.cjs'); function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var m__namespace = /*#__PURE__*/_interopNamespace(m); const contentMotionVariants = { expanded: { opacity: 1, height: 'auto', transition: { opacity: { delay: 0.1 }, ease: 'easeInOut', duration: 0.2 } }, collapsed: { opacity: 0, height: 0, transition: { ease: 'easeInOut', duration: 0.2 } } }; const indicatorMotionVariants = { expanded: { rotate: 180, transition: { duration: 0.2 } }, collapsed: { rotate: 0, transition: { duration: 0.2 } } }; const slots = [ 'root', 'heading', 'trigger', 'content', 'indicator' ]; const useSlotAriaProps = (ownerState)=>{ const { itemKey, expanded, slotProps } = ownerState; const id = react.useId(); return react.useMemo(()=>{ const triggerProps = slotProps?.trigger || {}; const contentProps = slotProps?.content || {}; const indicatorProps = slotProps?.indicator || {}; const triggerId = triggerProps.id ?? id; const contentId = contentProps.id ?? `panel-${itemKey}-content`; const trigger = { id: triggerId, 'aria-expanded': triggerProps['aria-expanded'] ?? expanded, 'aria-controls': triggerProps['aria-controls'] ?? contentId }; const content = { id: contentId, role: contentProps.role ?? 'region', 'aria-labelledby': contentProps['aria-labelledby'] ?? triggerId }; const indicator = { 'aria-hidden': indicatorProps['aria-hidden'] ?? true }; return { trigger, content, indicator }; }, [ expanded, id, itemKey, slotProps?.content, slotProps?.indicator, slotProps?.trigger ]); }; const AccordionItem = (inProps)=>{ const defaultKey = react.useId(); const props = useDefaultProps.useDefaultProps({ name: 'AccordionItem', props: inProps }); const { variant, toggleExpandedKey, expandedKeys, disabledKeys, disabled: defaultDisabled, indicator: defaultIndicator, motionProps: defaultMotionProps, keepMounted: defaultKeepMounted, hideIndicator: defaultHideIndicator, indicatorMotionProps: defaultIndicatorMotionProps } = AccordionContext.useAccordionGroup(); const { children, title, slotProps, classNames, indicatorMotionProps = defaultIndicatorMotionProps, motionProps = defaultMotionProps, hideIndicator = defaultHideIndicator, keepMounted = defaultKeepMounted, indicator = defaultIndicator, itemKey = defaultKey, disabled = disabledKeys.includes(itemKey) || defaultDisabled, ...remainingProps } = props; const expanded = expandedKeys.includes(itemKey); const ownerState = { ...props, variant, itemKey, expanded, indicator, keepMounted, hideIndicator, disabled, motionProps }; const styles = useStyles.useStyles({ name: 'AccordionItem', ownerState, recipe: accordion.accordionItemRecipe }); const slotClasses = useSlotClasses.useSlotClasses({ name: 'AccordionItem', slots, classNames }); const slotAriaProps = useSlotAriaProps(ownerState); const animate = expanded ? 'expanded' : 'collapsed'; // Skip initial animation when first rendering and the item is expanded const motionInitialRef = react.useRef(animate); if (motionInitialRef.current === 'expanded' && !expanded) { // Restore open animation for subsequent renders motionInitialRef.current = 'collapsed'; } const contentMotionProps = keepMounted ? { animate, initial: motionInitialRef.current, variants: contentMotionVariants, style: { overflow: 'hidden' } } : { variants: contentMotionVariants, initial: motionInitialRef.current, animate: 'expanded', exit: 'collapsed', style: { overflow: 'hidden' } }; const [AccordionItemRoot, getAccordionItemRootProps] = useSlot.useSlot({ elementType: 'div', externalForwardedProps: remainingProps, style: styles.root, classNames: slotClasses.root, dataAttrs: { keepMounted, hideIndicator, disabled, state: animate } }); const [AccordionItemHeading, getAccordionItemHeadingProps] = useSlot.useSlot({ elementType: 'h3', externalSlotProps: slotProps?.heading, style: styles.heading, classNames: slotClasses.heading }); const handleClick = hooks.useEvent(()=>{ toggleExpandedKey(itemKey); }); const [AccordionItemTrigger, getAccordionItemTriggerProps] = useSlot.useSlot({ elementType: ButtonBase.ButtonBase, externalSlotProps: slotProps?.trigger, style: styles.trigger, classNames: slotClasses.trigger, a11y: slotAriaProps.trigger, shouldForwardComponent: false, additionalProps: { disabled, onClick: handleClick } }); const [AccordionItemContent, getAccordionItemContentProps] = useSlot.useSlot({ elementType: 'div', externalSlotProps: slotProps?.content, style: styles.content, classNames: slotClasses.content, a11y: slotAriaProps.content }); const [AccordionItemIndicator, getAccordionItemIndicatorProps] = useSlot.useSlot({ elementType: m__namespace.span, externalSlotProps: slotProps?.indicator, style: styles.indicator, classNames: slotClasses.indicator, a11y: slotAriaProps.indicator, additionalProps: { animate, variants: indicatorMotionVariants, initial: animate, ...indicatorMotionProps } }); return /*#__PURE__*/ jsxRuntime.jsx(react$1.LazyMotion, { features: index.motionFeatures, children: /*#__PURE__*/ jsxRuntime.jsxs(AccordionItemRoot, { ...getAccordionItemRootProps(), children: [ /*#__PURE__*/ jsxRuntime.jsx(AccordionItemHeading, { ...getAccordionItemHeadingProps(), children: /*#__PURE__*/ jsxRuntime.jsxs(AccordionItemTrigger, { ...getAccordionItemTriggerProps(), children: [ /*#__PURE__*/ jsxRuntime.jsx("span", { children: title }), !hideIndicator && /*#__PURE__*/ jsxRuntime.jsx(AccordionItemIndicator, { ...getAccordionItemIndicatorProps(), children: indicator ?? /*#__PURE__*/ jsxRuntime.jsx(icons.ChevronDownOutlined, {}) }) ] }) }), /*#__PURE__*/ jsxRuntime.jsx(react$1.AnimatePresence, { children: (keepMounted || expanded) && /*#__PURE__*/ jsxRuntime.jsx(m__namespace.div, { ...contentMotionProps, ...motionProps, children: /*#__PURE__*/ jsxRuntime.jsx(AccordionItemContent, { ...getAccordionItemContentProps(), children: children }) }) }) ] }) }); }; AccordionItem.displayName = 'AccordionItem'; exports.AccordionItem = AccordionItem;