@wix/design-system
Version:
@wix/design-system
104 lines • 4.35 kB
JavaScript
import React, { PureComponent } from 'react';
import { st, classes } from './Accordion.st.css.js';
import AccordionItem from './components/AccordionItem';
import { horizontalPaddings, skins } from './constants';
import SectionHeader from '../SectionHeader';
import deprecationLog from '../utils/deprecationLog';
export class Accordion extends PureComponent {
constructor(props) {
super(props);
this._findOpenIndexes = (items = [], initial = false) => {
return items
.map((item, index) => (initial && item.initiallyOpen) || item.open ? index : null)
.filter(index => index !== null)
.flatMap(index => (!!index || index === 0 ? [index] : []));
};
this._compareOpenItems = (currentItems = [], prevItems = []) => {
if (prevItems.length !== currentItems.length) {
return false;
}
for (let i = 0; i < prevItems.length; i++) {
if (prevItems[i].open !== currentItems[i].open) {
return false;
}
}
return true;
};
this.componentDidUpdate = (prevProps) => {
if (!this._compareOpenItems(this.props.items, prevProps.items)) {
this.setState({
openIndexes: this._findOpenIndexes(this.props.items),
});
}
};
this._toggle = (index) => () => this.setState(({ openIndexes }) => ({
openIndexes: openIndexes.includes(index)
? openIndexes.filter(i => i !== index)
: this.props.multiple
? [...openIndexes, index]
: [index],
}));
this.state = {
openIndexes: this._findOpenIndexes(this.props.items, true),
};
if (props.items?.some(item => typeof item.icon !== 'undefined')) {
deprecationLog('<Accordion/> - item prop "icon" is deprecated and will be removed in next major release, please use "prefix" instead.');
}
}
render() {
const { openIndexes } = this.state;
const { dataHook, items, skin, hideShadow, size, horizontalPadding, contentPadding, transitionSpeed, onAnimationEnter, onAnimationExit, titleSize, } = this.props;
return (React.createElement("div", { "data-hook": dataHook, className: classes.accordion, "data-transition-speed": transitionSpeed, "data-horizontal-padding": horizontalPadding, "data-content-padding": contentPadding, "data-skin": skin }, items?.map((item, index, allItems) => {
const uncontrolledProps = {
onToggle: this._toggle(index),
open: openIndexes.includes(index),
onAnimationEnter,
onAnimationExit,
};
const last = index === allItems.length - 1;
const internalProps = {
className: st(classes.item, { last }),
key: item.key || index,
skin,
hideShadow,
size,
horizontalPadding,
contentPadding,
last,
transitionSpeed,
titleSize,
};
if (typeof item.render === 'function') {
return item.render(uncontrolledProps, internalProps);
}
else {
return (React.createElement(AccordionItem, { ...uncontrolledProps, ...item, ...internalProps }));
}
})));
}
}
Accordion.displayName = 'Accordion';
Accordion.defaultProps = {
items: [],
multiple: false,
skin: skins.standard,
horizontalPadding: horizontalPaddings.large,
hideShadow: false,
transitionSpeed: 'medium',
size: 'small',
titleSize: 'medium',
};
export const accordionItemBuilder = (item) => {
return {
...item,
render: (uncontrolledProps, internalProps) => React.createElement(AccordionItem, { ...uncontrolledProps, ...item, ...internalProps }),
};
};
export const accordionSectionItemBuilder = (item) => {
return {
...item,
render: (_, internalProps) => (React.createElement(SectionHeader, { title: item.title ?? internalProps.title, skin: "neutral" })),
};
};
export default Accordion;
//# sourceMappingURL=Accordion.js.map