| @@ -4,7 +4,6 @@ class WBAccordion extends Component { | |||||
| constructor(...args) { | constructor(...args) { | ||||
| super(...args); | super(...args); | ||||
| this.setupIds(); | this.setupIds(); | ||||
| console.log('WBAccordion() : domId=' + this.state.domId); | |||||
| } | } | ||||
| setupIds() { | setupIds() { | ||||
| @@ -13,68 +12,52 @@ class WBAccordion extends Component { | |||||
| const { state } = this; | const { state } = this; | ||||
| state.headerDomIds = names.map(() => ('accordion-' + uuid.v4())); | state.headerDomIds = names.map(() => ('accordion-' + uuid.v4())); | ||||
| state.collapseDomIds = names.map(() => ('accordion-' + uuid.v4())); | state.collapseDomIds = names.map(() => ('accordion-' + uuid.v4())); | ||||
| state.isOpen = Array(names.length).fill(false); | |||||
| state.collapseClass = Array(names.length).fill('collapse'); | |||||
| state.ariaExpanded = Array(names.length).fill(false); | |||||
| state.buttonClass = Array(names.length).fill('btn btn-link collapsed'); | |||||
| state.collapseElements = null; | 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'); | |||||
| } | |||||
| setup() { | |||||
| componentWillReceiveProps(nextProps) { | |||||
| this.props = nextProps; | |||||
| this.setupIds(); | this.setupIds(); | ||||
| this.setupEvents(); | |||||
| } | } | ||||
| componentDidMount() { | |||||
| console.log('WBAccordion.componentDidMount()'); | |||||
| this.setupEvents(); | |||||
| toggle(idx) { | |||||
| const { ariaExpanded, collapseClass, buttonClass } = this.state; | |||||
| const isOpen = ariaExpanded[idx]; | |||||
| for (let i = 0; i < ariaExpanded.length; i++) { | |||||
| ariaExpanded[i] = false; | |||||
| collapseClass[i] = 'collapse'; | |||||
| buttonClass[i] = 'btn btn-link collapsed'; | |||||
| } | |||||
| if (!isOpen) { | |||||
| ariaExpanded[idx] = true; | |||||
| collapseClass[idx] = 'collapse show'; | |||||
| buttonClass[idx] = 'btn btn-link'; | |||||
| } | |||||
| this.setState({ ariaExpanded, collapseClass, buttonClass }); | |||||
| } | } | ||||
| 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, collapseClass, ariaExpanded, buttonClass }) { | |||||
| render({ children, names, cardHeaderClass }, { domId, headerDomIds, collapseDomIds, isOpen }) { | |||||
| return ( | return ( | ||||
| <div class="accordion" id={ domId }> | <div class="accordion" id={ domId }> | ||||
| { children.map((_, i) => ( | { children.map((_, i) => ( | ||||
| <div class="card"> | <div class="card"> | ||||
| <div class={ cardHeaderClass} id={ headerDomIds[i] }> | |||||
| <div class={ cardHeaderClass } id={ headerDomIds[i] }> | |||||
| <h2 class="mb-0"> | <h2 class="mb-0"> | ||||
| <button class="btn btn-link" type="button" data-toggle="collapse" data-target={ '#' + collapseDomIds[i] } aria-expanded={ isOpen[i] } aria-controls={ collapseDomIds[i] }> | |||||
| <button class={ buttonClass[i] } type="button" | |||||
| aria-expanded={ ariaExpanded[i] } aria-controls={ collapseDomIds[i] } | |||||
| onclick={ () => this.toggle(i) }> | |||||
| { names[i] } | { names[i] } | ||||
| </button> | </button> | ||||
| </h2> | </h2> | ||||
| </div> | </div> | ||||
| <div id={ collapseDomIds[i] } class={ 'collapse' + (isOpen[i] ? ' show' : '') } | |||||
| aria-labelledby={ headerDomIds[i] } data-parent={ '#' + domId }> | |||||
| <div id={ collapseDomIds[i] } class={ collapseClass[i] } | |||||
| aria-labelledby={ headerDomIds[i] }> | |||||
| <div class="card-body"> | <div class="card-body"> | ||||
| { children[i] } | { children[i] } | ||||
| </div> | </div> | ||||