UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

243 lines (242 loc) 8.92 kB
"use client"; import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties"; const _excluded = ["children"], _excluded2 = ["children"], _excluded3 = ["children"], _excluded4 = ["icon_size"], _excluded5 = ["children", "className", "left_component", "expanded", "title", "description", "icon", "icon_size", "disabled"]; import "core-js/modules/web.dom-collections.iterator.js"; 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; } import React, { useContext, useState } from 'react'; import { validateDOMAttributes, extendPropsWithContext } from '../../shared/component-helper'; import IconPrimary from '../icon-primary/IconPrimary'; import classnames from 'classnames'; import AccordionContext from './AccordionContext'; import { createSpacingClasses } from '../space/SpacingHelper'; import { skeletonDOMAttributes, createSkeletonClass } from '../skeleton/SkeletonHelper'; function AccordionHeaderTitle(_ref) { let { children = null } = _ref, rest = _objectWithoutProperties(_ref, _excluded); return React.createElement("span", { className: classnames('dnb-accordion__header__title', createSpacingClasses(rest)) }, children); } function AccordionHeaderDescription(_ref2) { let { children = null } = _ref2, rest = _objectWithoutProperties(_ref2, _excluded2); return children ? React.createElement("span", { className: classnames('dnb-accordion__header__description', createSpacingClasses(rest)) }, children) : null; } function AccordionHeaderContainer(_ref3) { let { children = null } = _ref3, rest = _objectWithoutProperties(_ref3, _excluded3); return children ? React.createElement("span", { className: classnames('dnb-accordion__header__container', createSpacingClasses(rest)) }, children) : null; } function AccordionHeaderIcon(_ref4) { let { icon: iconProp, expanded, size = 'medium', icon_position } = _ref4; const icon = iconProp && typeof iconProp === 'object' && 'expanded' in iconProp && typeof (iconProp === null || iconProp === void 0 ? void 0 : iconProp.expanded) !== 'undefined' ? iconProp[expanded ? 'expanded' : 'closed'] : iconProp || 'chevron-down'; return React.createElement("span", { className: 'dnb-accordion__header__icon' + (icon_position ? ` dnb-accordion__header__icon--${icon_position}` : "") }, React.createElement(IconPrimary, { size: size, icon: icon, "aria-hidden": true })); } const accordionHeaderDefaultProps = { icon_size: 'medium' }; export const AccordionHeader = _ref5 => { let { icon_size: icon_size_default = 'medium' } = _ref5, restOfProps = _objectWithoutProperties(_ref5, _excluded4); const props = _objectSpread({ icon_size: icon_size_default }, restOfProps); const [isHovering, setIsHovering] = useState(false); const [hasClicked, setHasClicked] = useState(false); const context = useContext(AccordionContext); function onKeyDownHandler(event) { const keyPressed = event.key; if (keyPressed === 'Enter' || keyPressed === ' ') { event.preventDefault(); onClickHandler(event); } } function onClickHandler(event) { const { id, group } = context; if (canClick()) { const expanded = !context.expanded; context.callOnChange({ id, group, expanded, event }); setHasClicked(true); } } function onMouseOverHandler() { setIsHovering(true); } function onMouseOutHandler() { setIsHovering(false); setHasClicked(false); } function canClick() { const { expanded, allow_close_all, group } = context; return !group || group && !expanded || allow_close_all; } const extendedProps = extendPropsWithContext(props, accordionHeaderDefaultProps, context); const { id, left_component, expanded, title, description, element, heading, heading_level, icon, icon_size, disabled, skeleton, no_animation, variant } = extendedProps; let { icon_position } = extendedProps; const { children, className, left_component: _left_component, expanded: _expanded, title: _title, description: _description, icon: _icon, icon_size: _icon_size, disabled: _disabled } = props, rest = _objectWithoutProperties(props, _excluded5); const defaultParts = [React.createElement(AccordionHeaderIcon, { key: "icon", icon: icon, size: icon_size, expanded: context.expanded, icon_position: icon_position }), React.createElement(AccordionHeaderContainer, { key: "container" }, left_component), React.createElement(AccordionHeaderTitle, { key: "title" }, title || (Array.isArray(children) ? children.filter(cur => !React.isValidElement(cur)) : children)), React.createElement(AccordionHeaderDescription, { key: "description" }, description)]; if (Array.isArray(children)) { const removeParts = []; children.forEach(cur => { if (React.isValidElement(cur)) { const part = defaultParts.find(c => c.type === cur.type); if (part) { removeParts.push(part); } defaultParts.push(cur); } }); removeParts.forEach(part => { const index = defaultParts.findIndex(c => c === part); if (index > -1) { defaultParts.splice(index, 1); } }); } const partsToRender = []; const wrapperParts = []; const wrapperComp = React.createElement("span", { className: "dnb-accordion__header__wrapper", key: "wrapper" }, wrapperParts); defaultParts.forEach(part => { if (React.isValidElement(part) && (part.type === AccordionHeaderTitle || part.type === AccordionHeaderDescription)) { wrapperParts.push(part); if (partsToRender.findIndex(c => c === wrapperComp) === -1) { partsToRender.push(wrapperComp); } } else { partsToRender.push(part); } }); if (icon_position === undefined) { const iconIndex = partsToRender.findIndex(c => c.type === AccordionHeaderIcon); if (iconIndex > 1) { icon_position = 'right'; } if (left_component) { icon_position = 'right'; } } const headerParams = _objectSpread({ id: `${id}-header`, 'aria-controls': `${id}-content`, 'aria-expanded': context.expanded, role: 'button', tabIndex: 0, className: classnames('dnb-accordion__header', createSkeletonClass('font', skeleton, context), createSpacingClasses(rest), className, context.expanded && 'dnb-accordion__header--expanded' + (isHovering && hasClicked ? " dnb-accordion__header--after-click" : ""), variant && `dnb-accordion__header--${variant}`, icon_position && `dnb-accordion__header--icon-${icon_position}`, !canClick() && 'dnb-accordion__header--prevent-click', description && 'dnb-accordion__header--description', no_animation && 'dnb-accordion__header--no-animation'), disabled }, rest); if (disabled || skeleton) { headerParams.tabIndex = -1; headerParams.disabled = true; headerParams['aria-disabled'] = true; } else { headerParams.onClick = onClickHandler; headerParams.onKeyDown = onKeyDownHandler; headerParams.onMouseOver = onMouseOverHandler; headerParams.onMouseOut = onMouseOutHandler; } skeletonDOMAttributes(headerParams, skeleton, context); validateDOMAttributes(props, headerParams); let Element = 'div'; if (heading && (String(heading) === 'true' || String(heading) === '1')) { headerParams.role = 'heading'; headerParams['aria-level'] = heading_level ? Number(heading_level) : 2; } else if (heading) { headerParams.role = null; Element = heading; } else if (element) { headerParams.role = null; Element = element; } return React.createElement(Element, headerParams, partsToRender); }; AccordionHeader.Container = AccordionHeaderContainer; AccordionHeader.Icon = AccordionHeaderIcon; AccordionHeader.Title = AccordionHeaderTitle; AccordionHeader.Description = AccordionHeaderDescription; AccordionHeader._supportsSpacingProps = true; export default AccordionHeader; //# sourceMappingURL=AccordionHeader.js.map