import React, { useMemo, useState } from 'react';
import { getStyleObjectFromString } from "../../utils";
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { mapToCssModules, tagPropType } from 'reactstrap/src/utils';
import { AccordionContext } from 'reactstrap/src/AccordionContext';
/**
* Componente que renderiza un Accordion de Bootstrap.
* @name Reactor.Components.Layout.Accordion
* @param {string} default_open panel que estarĂ¡ abierto por defecto
* @class
* @example
<accordion default_open="1">
<accordion_item options='{"className":"card card-style"}'>
<div class="card-header d-flex">
<div class="align-self-center">
<h6 class="pt-1 font-14 font-600">Factura 0000-111111</h6>
</div>
<div class="align-self-center ms-auto text-end">
<h6 class="pt-1 font-14 font-600">10/03/2022</h6>
</div>
</div>
<accordion_header target="1">
<!-- header -->
<div class="card-body d-flex mb-2" style="height: auto; padding: 0.5rem 1rem;">
<div class="align-self-center" style="max-width: 240px">
<h6 class="mb-n1 font-12 opacity-60">Heladera con Freezer Gafa 282 Litros</h6>
<h6 class="pt-1 mb-n1 font-12 opacity-60">Smart TV 43" Samsung</h6>
<h6 class="pt-1 mb-n1 font-12 opacity-60">Aire Acondicionado Split</h6>
</div>
<div class="align-self-center ms-auto text-end pt-1">
<p class="mb-0 font-11 opacity-70" style="line-height: 10px">Monto a pagar</p>
<p class="mb-0 font-15 color-blue-dark font-700">$20.000,00</p>
<p class="mb-0 font-11 opacity-70" style="line-height: 10px">Vence</p>
<p class="mb-0 font-13 color-blue-dark font-700">19/03/2022</p>
</div>
</div>
<!-- comprobante fin -->
</accordion_header>
<accordion_body id="1">
<strong>
This is the second item's accordion body.
</strong>
You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the{' '}
<code>
.accordion-body
</code>
, though the transition does limit overflow.
</accordion_body>
</accordion_item>
<accordion_item>
<accordion_header target="2">
Titulo 2
</accordion_header>
<accordion_body id="2">
<strong>
This is the second item's accordion body.
</strong>
You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the{' '}
<code>
.accordion-body
</code>
, though the transition does limit overflow.
</accordion_body>
</accordion>
<style>
.accordion-item:first-of-type .accordion-button {
border-top-left-radius: 0px !important;
border-top-right-radius: 0px !important;
}
</style>
*/
export const Accordion = ({children, default_open, options}) => {
return <UncontrolledAccordionBs defaultOpen={default_open} {...(options ? JSON.parse(options) : {})}>{children}</UncontrolledAccordionBs>;
}
const propTypesAccordionBs = {
tag: tagPropType,
className: PropTypes.string,
cssModule: PropTypes.object,
innerRef: PropTypes.oneOfType([
PropTypes.object,
PropTypes.string,
PropTypes.func,
]),
children: PropTypes.node,
flush: PropTypes.bool,
open: PropTypes.oneOfType([PropTypes.array, PropTypes.string]).isRequired,
toggle: PropTypes.func.isRequired,
};
const defaultPropsAccordionBs = {
tag: 'div'
};
const AccordionBs = (props) => {
const {
flush,
open,
toggle,
className,
cssModule,
tag: Tag,
innerRef,
...attributes
} = props;
const classes = mapToCssModules(classNames(
className,
'accordion',
{
'accordion-flush': flush
}
), cssModule);
const accordionContext = useMemo(() => ({
open,
toggle,
}));
return (
<AccordionContext.Provider value={accordionContext}>
<Tag {...attributes} className={classes} ref={innerRef} />
</AccordionContext.Provider>
);
};
AccordionBs.propTypes = propTypesAccordionBs;
AccordionBs.defaultProps = defaultPropsAccordionBs;
const propTypesUncontrolledAccordionBs = {
tag: tagPropType,
className: PropTypes.string,
cssModule: PropTypes.object,
innerRef: PropTypes.oneOfType([
PropTypes.object,
PropTypes.string,
PropTypes.func,
]),
children: PropTypes.node,
defaultOpen: PropTypes.oneOfType([PropTypes.array, PropTypes.string]),
stayOpen: PropTypes.bool,
};
const defaultPropsUncontrolledAccordionBs = {
tag: 'div'
};
const UncontrolledAccordionBs = ({ defaultOpen, stayOpen, ...props }) => {
const [open, setOpen] = useState(defaultOpen || (stayOpen ? [] : undefined));
const toggle = (id) => {
if (stayOpen) {
open.includes(id) ? setOpen(open.filter(accordionId => accordionId !== id)) : setOpen([...open, id]);
} else {
open === id ? setOpen(undefined) : setOpen(id);
}
};
return <AccordionBs {...props} open={open} toggle={toggle} />;
};
UncontrolledAccordionBs.propTypes = propTypesUncontrolledAccordionBs;
UncontrolledAccordionBs.defaultProps = defaultPropsUncontrolledAccordionBs;