import React, { Component, } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { SoftIcon, } from '../Icon';
import { SoftFlexGroup, SoftFlexItem, } from '../Flex';
import { SoftMutationObserver, } from '../Observer/mutation_observer';
const paddingSizeToClassNameMap = {
    none: null,
    xs: 'softAccordion__padding--xs',
    s: 'softAccordion__padding--s',
    m: 'softAccordion__padding--m',
    l: 'softAccordion__padding--l',
    xl: 'softAccordion__padding--xl',
};
export const PADDING_SIZES = Object.keys(paddingSizeToClassNameMap);
export class SoftAccordion extends Component {
    constructor(props) {
        super(props);
        this.state = {
            isOpen: this.props.initialIsOpen,
        };
        this.setChildContentHeight = () => {
            requestAnimationFrame(() => {
                const height = this.childContent && this.state.isOpen ? this.childContent.clientHeight : 0;
                this.childWrapper && this.childWrapper.setAttribute('style', `height: ${height}px`);
            });
        };
        this.setChildContentRef = (node) => {
            this.childContent = node;
        };
        this.onToggle = this.onToggle.bind(this);
    }
    componentDidMount() {
        this.setChildContentHeight();
    }
    componentDidUpdate() {
        this.setChildContentHeight();
    }
    onToggle() {
        this.setState((prevState) => ({
            isOpen: !prevState.isOpen
        }));
    }
    render() {
        const { children, buttonContent, className, id, buttonClassName, buttonContentClassName, extraAction, paddingSize, initialIsOpen, // eslint-disable-line no-unused-vars
        ...rest } = this.props;
        const classes = classNames('softAccordion', {
            'softAccordion-isOpen': this.state.isOpen,
        }, className);
        const paddingClass = classNames(paddingSizeToClassNameMap[paddingSize]);
        const buttonClasses = classNames('softAccordion__button', buttonClassName);
        const buttonContentClasses = classNames('softAccordion__buttonContent', buttonContentClassName);
        const icon = (React.createElement(SoftIcon, { type: this.state.isOpen ? 'arrowDown' : 'arrowRight', size: "m" }));
        let optionalAction = null;
        if (extraAction) {
            optionalAction = (React.createElement(SoftFlexItem, { grow: false }, extraAction));
        }
        return (React.createElement("div", Object.assign({ className: classes }, rest),
            React.createElement(SoftFlexGroup, { gutterSize: "none", alignItems: "center" },
                React.createElement(SoftFlexItem, null,
                    React.createElement("button", { "aria-controls": id, "aria-expanded": !!this.state.isOpen, onClick: this.onToggle, className: buttonClasses, type: "button" },
                        React.createElement(SoftFlexGroup, { gutterSize: "s", alignItems: "center", responsive: false },
                            React.createElement(SoftFlexItem, { grow: false, className: "softAccordion__iconWrapper" }, icon),
                            React.createElement(SoftFlexItem, { className: buttonContentClasses }, buttonContent)))),
                optionalAction),
            React.createElement("div", { className: "softAccordion__childWrapper", ref: node => {
                    this.childWrapper = node;
                }, id: id },
                React.createElement(SoftMutationObserver, { observerOptions: { childList: true, subtree: true }, onMutation: this.setChildContentHeight }, mutationRef => (React.createElement("div", { ref: ref => {
                        this.setChildContentRef(ref);
                        mutationRef(ref);
                    } },
                    React.createElement("div", { className: paddingClass }, children)))))));
    }
}
SoftAccordion.propTypes = {
    /**
     * The content of the exposed accordion.
     */
    children: PropTypes.node,
    id: PropTypes.string.isRequired,
    /**
     * Class that will apply to the entire accordion.
     */
    className: PropTypes.string,
    /**
     * Class that will apply to the trigger for the accordion.
     */
    buttonContentClassName: PropTypes.string,
    /**
     * The content of the clickable trigger
     */
    buttonContent: PropTypes.node,
    /**
     * Will appear right aligned against the button. Useful for separate actions like deletions.
     */
    extraAction: PropTypes.node,
    /**
     * The accordion will start in the open state.
     */
    initialIsOpen: PropTypes.bool,
    /**
     * The padding around the exposed accordion content.
     */
    paddingSize: PropTypes.oneOf(PADDING_SIZES),
};
SoftAccordion.defaultProps = {
    initialIsOpen: false,
    paddingSize: 'none',
};
//# sourceMappingURL=SoftAccordion.js.map