IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an email to s dot adaszewski at gmail dot com. User accounts are meant only to report issues and/or generate pull requests. This is a purpose-specific Git hosting for ADARED projects. Thank you for your understanding!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
2.8KB

  1. import { h, Component } from 'preact';
  2. class WBAccordion extends Component {
  3. constructor(...args) {
  4. super(...args);
  5. this.setupIds();
  6. console.log('WBAccordion() : domId=' + this.state.domId);
  7. }
  8. setupIds() {
  9. this.state.domId = 'accordion-' + uuid.v4();
  10. const { names } = this.props;
  11. const { state } = this;
  12. state.headerDomIds = names.map(() => ('accordion-' + uuid.v4()));
  13. state.collapseDomIds = names.map(() => ('accordion-' + uuid.v4()));
  14. state.isOpen = Array(names.length).fill(false);
  15. state.collapseElements = null;
  16. }
  17. setupEvents() {
  18. const { collapseDomIds, isOpen } = this.state;
  19. const accordion = this;
  20. const collapseElements = $(collapseDomIds.map(a => '#' + a).join(','));
  21. this.state.collapseElements = collapseElements;
  22. collapseElements.on('hidden.bs.collapse shown.bs.collapse', function(ev) {
  23. // console.log(this.id);
  24. const el = this;
  25. const idx = collapseDomIds.findIndex(a => (a === el.id));
  26. isOpen[idx] = (ev.type === 'shown');
  27. accordion.setState({ isOpen });
  28. });
  29. }
  30. removeEvents() {
  31. const { collapseElements } = this.state;
  32. collapseElements.off('hidden.bs.collapse shown.bs.collapse');
  33. }
  34. setup() {
  35. this.setupIds();
  36. this.setupEvents();
  37. }
  38. componentDidMount() {
  39. console.log('WBAccordion.componentDidMount()');
  40. this.setupEvents();
  41. }
  42. componentWillUnmount() {
  43. console.log('WBAccordion.componentWillUnmount()');
  44. this.removeEvents();
  45. }
  46. componentWillReceiveProps(nextProps) {
  47. console.log('WBAccordion.componentWillReceiveProps()');
  48. this.props = nextProps;
  49. this.removeEvents();
  50. this.setupIds();
  51. this.setState({}); // render
  52. this.setupEvents();
  53. }
  54. render({ children, names, cardHeaderClass }, { domId, headerDomIds, collapseDomIds, isOpen }) {
  55. return (
  56. <div class="accordion" id={ domId }>
  57. { children.map((_, i) => (
  58. <div class="card">
  59. <div class={ cardHeaderClass} id={ headerDomIds[i] }>
  60. <h2 class="mb-0">
  61. <button class="btn btn-link" type="button" data-toggle="collapse" data-target={ '#' + collapseDomIds[i] } aria-expanded={ isOpen[i] } aria-controls={ collapseDomIds[i] }>
  62. { names[i] }
  63. </button>
  64. </h2>
  65. </div>
  66. <div id={ collapseDomIds[i] } class={ 'collapse' + (isOpen[i] ? ' show' : '') }
  67. aria-labelledby={ headerDomIds[i] } data-parent={ '#' + domId }>
  68. <div class="card-body">
  69. { children[i] }
  70. </div>
  71. </div>
  72. </div>
  73. )) }
  74. </div>
  75. );
  76. }
  77. };
  78. WBAccordion.defaultProps = {
  79. 'cardHeaderClass': 'card-header'
  80. };
  81. export default WBAccordion;