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 123 124 125 | 1x 1x 1x 1x 1x 16x 16x 16x 2x 2x 16x 26x 2x 1x 1x 1x 1x 1x 1x 1x | import _ from 'lodash';
import React from 'react';
import PropTypes from 'prop-types';
import { lucidClassNames } from '../../util/style-helpers';
import { buildModernHybridComponent } from '../../util/state-management';
import { ExpanderPanelDumb as ExpanderPanel } from '../ExpanderPanel/ExpanderPanel';
import { findTypes, StandardProps } from '../../util/component-types';
import * as reducers from '../Accordion/Accordion.reducers';
const cx = lucidClassNames.bind('&-Accordion');
const { func, object, number, string } = PropTypes;
export 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;
}
/** TODO: Remove the nonPassThroughs when the component is converted to a functional component */
const nonPassThroughs = ['selectedIndex', 'onSelect'];
export interface IAccordionState {
selectedIndex: number | null;
}
const defaultProps = {
onSelect: _.noop,
};
const Accordion = (props: IAccordionProps): React.ReactElement => {
const { style, className, onSelect, 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;
onSelect(selectedIndex, {
event,
props,
});
};
return (
<div
{...(_.omit(passThroughs, nonPassThroughs) as any)}
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 = {
/**
Appended to the component-specific class names set on the root element.
*/
className: string,
/**
Indicates which item is expanded
*/
selectedIndex: number,
/**
Called when the user clicks on the component's header of an item.
*/
onSelect: func,
/**
Passed through to the root element.
**/
style: object,
};
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 as any, { reducers });
export { Accordion as AccordionDumb };
|