Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | 176x 176x 176x 176x 16x 16x 16x 2x 2x 16x 26x 2x 176x 176x 176x 176x 176x 176x 176x | import _ from 'lodash';
import React from 'react';
import PropTypes from 'react-peek/prop-types';
import { lucidClassNames } from '../../util/style-helpers';
import { buildModernHybridComponent } from '../../util/state-management';
import { ExpanderPanelDumb as ExpanderPanel } from '../ExpanderPanel/ExpanderPanel';
import {
findTypes,
omitProps,
StandardProps,
} from '../../util/component-types';
import * as reducers from '../Accordion/Accordion.reducers';
const cx = lucidClassNames.bind('&-Accordion');
const { func, object, number, string } = PropTypes;
interface IAccordionProps extends StandardProps {
/**
* Indicates which item is expanded
* */
selectedIndex?: number | null;
/**
* Called when the user clicks on the component's header of an item.
* */
onSelect: (
selectedIndex: number | null,
{ event, props }: { event: React.MouseEvent; props: IAccordionProps }
) => void;
}
export interface IAccordionState {
selectedIndex: number | null;
}
const defaultProps = {
onSelect: _.noop,
};
const Accordion = (props: IAccordionProps): React.ReactElement => {
const { style, className, selectedIndex, ...passThroughs } = props;
const itemChildProps = _.map(findTypes(props, Accordion.Item), 'props');
const handleToggle = (
isExpanded: boolean,
index: number,
event: React.MouseEvent
) => {
const selectedIndex = isExpanded ? index : null;
props.onSelect(selectedIndex, {
event,
props,
});
};
return (
<div
{...omitProps(passThroughs, undefined, _.keys(Accordion.propTypes))}
className={cx('&', className)}
style={style}
>
{_.map(itemChildProps, (itemChildProp, index: number) => {
return (
<ExpanderPanel
key={index}
{...itemChildProp}
className={cx('&-Item', itemChildProp.className)}
onToggle={(isExpanded, { event }) =>
handleToggle(isExpanded, index, event)
}
isExpanded={!itemChildProp.isDisabled && selectedIndex === index}
/>
);
})}
</div>
);
};
Accordion.displayName = 'Accordion';
Accordion.propTypes = {
className: string`
Appended to the component-specific class names set on the root element.
`,
selectedIndex: number`
Indicates which item is expanded
`,
onSelect: func`
Called when the user clicks on the component's header of an item.
`,
style: object`
Passed through to the root element.
`,
};
Accordion.peek = {
description: `
Accordion is a container that renders panels and controls their
expansion or collapse.
`,
categories: ['layout'],
madeFrom: ['ExpanderPanel'],
};
Accordion.defaultProps = defaultProps;
Accordion.reducers = reducers;
Accordion.Item = ExpanderPanel;
Accordion.Header = ExpanderPanel.Header;
export default buildModernHybridComponent<
IAccordionProps,
IAccordionState,
typeof Accordion
>(Accordion, { reducers });
export { Accordion as AccordionDumb };
|