@equinor/eds-core-react
Version:
The React implementation of the Equinor Design System
167 lines (164 loc) • 5.16 kB
JavaScript
import { forwardRef, Children, isValidElement, cloneElement } from 'react';
import styled, { css } from 'styled-components';
import { chevron_up, chevron_down } from '@equinor/eds-icons';
import { Icon } from '../Icon/index.js';
import { AccordionHeaderTitle } from './AccordionHeaderTitle.js';
import { AccordionHeaderActions } from './AccordionHeaderActions.js';
import { accordion } from './Accordion.tokens.js';
import { bordersTemplate, typographyTemplate, spacingsTemplate, outlineTemplate } from '@equinor/eds-utils';
import { jsx, jsxs } from 'react/jsx-runtime';
const {
entities: {
chevron: chevronToken
}
} = accordion;
const StyledAccordionHeader = styled.div.withConfig({
displayName: "AccordionHeader__StyledAccordionHeader",
componentId: "sc-cu2e95-0"
})(({
theme,
disabled,
$parentIndex
}) => {
const {
entities: {
header
},
border
} = theme;
return css(["margin:0;padding:0;height:", ";box-sizing:border-box;display:flex;flex-wrap:nowrap;justify-content:space-between;background-color:", ";", " border-top:", ";", ""], header.height, header.background, bordersTemplate(border), $parentIndex === 0 ? null : 'none', disabled ? css(["color:", ";cursor:not-allowed;"], header.states.disabled.typography.color) : css(["color:", ";cursor:pointer;@media (hover:hover) and (pointer:fine){&:hover{background:", ";}}"], header.typography.color, header.states.hover.background));
});
const StyledAccordionHeaderButton = styled.button.attrs(({
$panelId,
$isExpanded,
disabled
}) => ({
'aria-expanded': $isExpanded,
'aria-controls': $panelId,
'aria-disabled': $isExpanded && disabled,
tabIndex: disabled ? -1 : 0,
disabled
})).withConfig({
displayName: "AccordionHeader__StyledAccordionHeaderButton",
componentId: "sc-cu2e95-1"
})(({
theme,
disabled
}) => {
const {
entities: {
header,
icon: iconToken
}
} = theme;
return css(["", " ", " &[data-focus-visible-added]:focus{", "}&:focus-visible{", "}border:0;background-color:transparent;margin:0;display:flex;align-items:center;flex-grow:1;", " > svg{color:", ";}"], typographyTemplate(header.typography), spacingsTemplate(header.spacings), outlineTemplate(header.states.focus.outline), outlineTemplate(header.states.focus.outline), disabled ? css({
color: header.states.disabled.typography.color,
cursor: 'not-allowed'
}) : css({
color: header.typography.color,
cursor: 'pointer'
}), iconToken.typography.color);
});
const StyledIcon = styled(Icon).withConfig({
displayName: "AccordionHeader__StyledIcon",
componentId: "sc-cu2e95-2"
})(({
$chevronPosition
}) => {
return css(["flex-shrink:0;", ""], $chevronPosition === 'left' ? css({
marginRight: '32px'
}) : css({
marginLeft: '16px'
}));
});
const AccordionHeader = /*#__PURE__*/forwardRef(function AccordionHeader({
parentIndex,
headerLevel,
chevronPosition,
panelId,
id,
isExpanded = false,
children,
toggleExpanded,
disabled,
className,
style,
...props
}, ref) {
const handleClick = e => {
e.preventDefault();
e.stopPropagation();
if (!disabled) {
toggleExpanded();
if (props.onToggle) {
props.onToggle();
}
}
};
const handleKeyDown = e => {
const {
key
} = e;
if (key === 'Enter' || key === ' ') {
toggleExpanded();
if (props.onToggle) {
props.onToggle();
}
e.preventDefault();
e.stopPropagation();
}
};
const chevron = /*#__PURE__*/jsx(StyledIcon, {
data: isExpanded ? chevron_up : chevron_down,
size: 24,
$chevronPosition: chevronPosition,
color: disabled ? chevronToken.states.disabled.background : chevronToken.background
}, `${id}-icon`);
const headerChildren = Children.map(children, child => {
if (typeof child === 'string') {
return /*#__PURE__*/jsx(AccordionHeaderTitle, {
isExpanded: isExpanded,
disabled: disabled,
children: child
});
}
if (/*#__PURE__*/isValidElement(child) && child.type === AccordionHeaderTitle) {
return /*#__PURE__*/cloneElement(child, {
isExpanded,
disabled
});
}
if (child.type === AccordionHeaderActions) {
return;
}
return child;
});
const headerActions = Children.map(children, child => {
if (/*#__PURE__*/isValidElement(child) && child.type === AccordionHeaderActions) {
return /*#__PURE__*/cloneElement(child, {
isExpanded,
disabled
});
}
});
const newChildren = [chevron, headerChildren];
return /*#__PURE__*/jsxs(StyledAccordionHeader, {
disabled: disabled,
$parentIndex: parentIndex,
as: headerLevel,
className: className,
style: style,
children: [/*#__PURE__*/jsx(StyledAccordionHeaderButton, {
$isExpanded: isExpanded,
disabled: disabled,
$panelId: panelId,
onClick: handleClick,
onKeyDown: handleKeyDown,
ref: ref,
type: "button",
...props,
children: chevronPosition === 'left' ? newChildren : newChildren.reverse()
}), headerActions && headerActions]
});
});
export { AccordionHeader };