UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

184 lines (183 loc) 6.8 kB
"use client"; import _extends from "@babel/runtime-corejs3/helpers/esm/extends"; var _AccordionHeader, _ChevronIcon, _ChevronIcon2, _Hr; import React, { createContext, useCallback, useContext, useEffect, useState } from 'react'; import classnames from 'classnames'; import useId from "../../shared/helpers/useId.js"; import { ListContext } from "./ListContext.js"; import ItemContent from "./ItemContent.js"; import FlexItem from "../flex/Item.js"; import HeightAnimation from "../height-animation/HeightAnimation.js"; import Hr from "../../elements/Hr.js"; import { ChevronIcon } from "./ItemAction.js"; import Space from "../space/Space.js"; import { omitSpacingProps, pickSpacingProps } from "../flex/utils.js"; import ItemIcon from "./ItemIcon.js"; import ItemTitle from "./ItemTitle.js"; import { createSkeletonClass } from "../skeleton/SkeletonHelper.js"; import { warn } from "../../shared/component-helper.js"; import Context from "../../shared/Context.js"; const ItemAccordionContext = createContext(undefined); function ItemAccordion(props) { var _useContext; const { className, onClick, onChange, children, variant, pending, disabled, skeleton, open = false, keepInDOM = false, chevronPosition = 'right', icon, title, id: idProp, ...rest } = props; const [openState, setOpen] = useState(open); const accordionId = useId(idProp); const inheritedDisabled = (_useContext = useContext(ListContext)) === null || _useContext === void 0 ? void 0 : _useContext.disabled; const appliedDisabled = disabled !== null && disabled !== void 0 ? disabled : inheritedDisabled; const childArray = React.Children.toArray(children); const hasExplicitHeader = childArray.some(child => React.isValidElement(child) && child.type === AccordionHeader); useEffect(() => { setOpen(open); }, [open]); const handleToggle = useCallback(event => { if (!pending) { setOpen(prev => { const next = !prev; onChange === null || onChange === void 0 || onChange({ expanded: next }); return next; }); onClick === null || onClick === void 0 || onClick(event); } }, [onClick, onChange, pending]); return React.createElement(ItemAccordionContext.Provider, { value: { openState, pending, disabled: appliedDisabled, keepInDOM, chevronPosition, accordionId, icon, title, handleToggle } }, React.createElement(ItemContent, _extends({ className: classnames('dnb-list__item__accordion', className, openState && 'dnb-list__item__accordion--open'), direction: "vertical", pending: pending, disabled: appliedDisabled, skeleton: skeleton, variant: variant }, rest), !hasExplicitHeader ? _AccordionHeader || (_AccordionHeader = React.createElement(AccordionHeader, null)) : null, children)); } ItemAccordion._supportsSpacingProps = true; function AccordionHeader(props) { var _useContext2; const { className, children, ...rest } = props; const accordionContext = useContext(ItemAccordionContext); const context = useContext(Context); const inheritedSkeleton = (_useContext2 = useContext(ListContext)) === null || _useContext2 === void 0 ? void 0 : _useContext2.skeleton; const isInactive = (accordionContext === null || accordionContext === void 0 ? void 0 : accordionContext.pending) || (accordionContext === null || accordionContext === void 0 ? void 0 : accordionContext.disabled); const handleClick = useCallback(event => { if (!isInactive && accordionContext) { accordionContext.handleToggle(event); } }, [accordionContext, isInactive]); const handleKeyDown = useCallback(event => { if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); handleClick(event); } }, [handleClick]); if (!accordionContext) { warn('List.Item.Accordion.Header should be used inside List.Item.Accordion.'); return null; } const { chevronPosition, accordionId, openState, icon, title } = accordionContext; const content = React.createElement(FlexItem, _extends({ className: classnames('dnb-list__item__accordion__header', className, inheritedSkeleton && createSkeletonClass('font', true), chevronPosition === 'left' && 'dnb-list__item--chevron-left'), id: `${accordionId}-header`, role: "button", "aria-controls": `${accordionId}-content`, "aria-expanded": openState, "aria-disabled": isInactive ? true : undefined, tabIndex: isInactive ? -1 : 0, onClick: handleClick, onKeyDown: handleKeyDown }, rest), chevronPosition === 'left' && (_ChevronIcon || (_ChevronIcon = React.createElement(ChevronIcon, null))), icon && React.createElement(ItemIcon, null, icon), title !== undefined && React.createElement(ItemTitle, null, title), children, chevronPosition === 'right' && (_ChevronIcon2 || (_ChevronIcon2 = React.createElement(ChevronIcon, null)))); if (inheritedSkeleton) { return React.createElement(Context.Provider, { value: { ...context, skeleton: inheritedSkeleton } }, content); } return content; } ItemAccordion.Header = AccordionHeader; AccordionHeader._supportsSpacingProps = true; function AccordionContent(props) { var _useContext3; const { className, children, ...rest } = props; const context = useContext(Context); const accordionContext = useContext(ItemAccordionContext); const inheritedSkeleton = (_useContext3 = useContext(ListContext)) === null || _useContext3 === void 0 ? void 0 : _useContext3.skeleton; if (!accordionContext) { warn('List.Item.Accordion.Content should be used inside List.Item.Accordion.'); return null; } const { openState, accordionId, keepInDOM } = accordionContext; const spacingProps = pickSpacingProps(rest); const content = React.createElement(FlexItem, _extends({ className: classnames('dnb-list__item__accordion__content', className, inheritedSkeleton && createSkeletonClass('font', true)), id: `${accordionId}-content`, "aria-labelledby": `${accordionId}-header`, "aria-hidden": !openState }, omitSpacingProps(rest)), React.createElement(HeightAnimation, { open: openState, keepInDOM: keepInDOM }, _Hr || (_Hr = React.createElement(Hr, { bottom: false })), React.createElement(Space, spacingProps, children))); if (inheritedSkeleton) { return React.createElement(Context.Provider, { value: { ...context, skeleton: inheritedSkeleton } }, content); } return content; } ItemAccordion.Content = AccordionContent; AccordionContent._supportsSpacingProps = true; export default ItemAccordion; //# sourceMappingURL=ItemAccordion.js.map