| @@ -3,34 +3,78 @@ import { h, Component } from 'preact'; | |||
| class WBAccordion extends Component { | |||
| constructor(...args) { | |||
| super(...args); | |||
| this.setupIds(); | |||
| console.log('WBAccordion() : domId=' + this.state.domId); | |||
| } | |||
| setupIds() { | |||
| this.state.domId = 'accordion-' + uuid.v4(); | |||
| this.state.headerDomIds = this.props.names.map(() => ('accordion-' + uuid.v4())); | |||
| this.state.collapseDomIds = this.props.names.map(() => ('accordion-' + uuid.v4())); | |||
| // console.log('WBAccordion() : domId=' + this.state.domId); | |||
| const { names } = this.props; | |||
| const { state } = this; | |||
| state.headerDomIds = names.map(() => ('accordion-' + uuid.v4())); | |||
| state.collapseDomIds = names.map(() => ('accordion-' + uuid.v4())); | |||
| state.isOpen = Array(names.length).fill(false); | |||
| state.collapseElements = null; | |||
| } | |||
| setupEvents() { | |||
| const { collapseDomIds, isOpen } = this.state; | |||
| const accordion = this; | |||
| const collapseElements = $(collapseDomIds.map(a => '#' + a).join(',')); | |||
| this.state.collapseElements = collapseElements; | |||
| collapseElements.on('hidden.bs.collapse shown.bs.collapse', function(ev) { | |||
| // console.log(this.id); | |||
| const el = this; | |||
| const idx = collapseDomIds.findIndex(a => (a === el.id)); | |||
| isOpen[idx] = (ev.type === 'shown'); | |||
| accordion.setState({ isOpen }); | |||
| }); | |||
| } | |||
| removeEvents() { | |||
| const { collapseElements } = this.state; | |||
| collapseElements.off('hidden.bs.collapse shown.bs.collapse'); | |||
| } | |||
| /* componentDidMount() { | |||
| setup() { | |||
| this.setupIds(); | |||
| this.setupEvents(); | |||
| } | |||
| componentDidMount() { | |||
| console.log('WBAccordion.componentDidMount()'); | |||
| this.setupEvents(); | |||
| } | |||
| componentWillUnmount() { | |||
| console.log('WBAccordion.componentWillUnmount()'); | |||
| this.removeEvents(); | |||
| } | |||
| componentWillReceiveProps(nextProps) { | |||
| console.log('WBAccordion.componentWillReceiveProps()'); | |||
| } */ | |||
| this.props = nextProps; | |||
| this.removeEvents(); | |||
| this.setupIds(); | |||
| this.setState({}); // render | |||
| this.setupEvents(); | |||
| } | |||
| render({ children, names, cardHeaderClass }, { domId, headerDomIds, collapseDomIds }) { | |||
| render({ children, names, cardHeaderClass }, { domId, headerDomIds, collapseDomIds, isOpen }) { | |||
| return ( | |||
| <div class="accordion" id={ domId }> | |||
| { children.map((_, i) => ( | |||
| <div class="card"> | |||
| <div class={ cardHeaderClass} id={ headerDomIds[i] }> | |||
| <h2 class="mb-0"> | |||
| <button class="btn btn-link" type="button" data-toggle="collapse" data-target={ '#' + collapseDomIds[i] } aria-expanded="false" aria-controls={ collapseDomIds[i] }> | |||
| <button class="btn btn-link" type="button" data-toggle="collapse" data-target={ '#' + collapseDomIds[i] } aria-expanded={ isOpen[i] } aria-controls={ collapseDomIds[i] }> | |||
| { names[i] } | |||
| </button> | |||
| </h2> | |||
| </div> | |||
| <div id={ collapseDomIds[i] } class="collapse" aria-labelledby={ headerDomIds[i] } data-parent={ '#' + domId }> | |||
| <div id={ collapseDomIds[i] } class={ 'collapse' + (isOpen[i] ? ' show' : '') } | |||
| aria-labelledby={ headerDomIds[i] } data-parent={ '#' + domId }> | |||
| <div class="card-body"> | |||
| { children[i] } | |||
| </div> | |||