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.

79 lines
2.4KB

  1. import { h, Component } from 'preact';
  2. class WBAccordion extends Component {
  3. constructor(...args) {
  4. super(...args);
  5. this.setupIds();
  6. }
  7. setupIds() {
  8. this.state.domId = 'accordion-' + uuid.v4();
  9. const { names } = this.props;
  10. const { state } = this;
  11. state.headerDomIds = names.map(() => ('accordion-' + uuid.v4()));
  12. state.collapseDomIds = names.map(() => ('accordion-' + uuid.v4()));
  13. state.collapseClass = Array(names.length).fill('collapse');
  14. state.ariaExpanded = Array(names.length).fill(false);
  15. state.buttonClass = Array(names.length).fill('btn btn-link collapsed');
  16. state.collapseElements = null;
  17. }
  18. componentWillReceiveProps(nextProps) {
  19. this.props = nextProps;
  20. this.setupIds();
  21. }
  22. toggle(idx) {
  23. const { ariaExpanded, collapseClass, buttonClass } = this.state;
  24. const isOpen = ariaExpanded[idx];
  25. for (let i = 0; i < ariaExpanded.length; i++) {
  26. ariaExpanded[i] = false;
  27. collapseClass[i] = 'collapse';
  28. buttonClass[i] = 'btn btn-link collapsed';
  29. }
  30. if (!isOpen) {
  31. ariaExpanded[idx] = true;
  32. collapseClass[idx] = 'collapse show';
  33. buttonClass[idx] = 'btn btn-link';
  34. }
  35. this.setState({ ariaExpanded, collapseClass, buttonClass });
  36. }
  37. render({ children, names, extraHeaderUi, cardHeaderClass }, { domId, headerDomIds,
  38. collapseDomIds, collapseClass, ariaExpanded, buttonClass }) {
  39. return (
  40. <div class="accordion" id={ domId }>
  41. { children.map((_, i) => (
  42. <div class="card">
  43. <div class={ cardHeaderClass } id={ headerDomIds[i] }>
  44. <h2 class="mb-0">
  45. <button class={ buttonClass[i] } type="button"
  46. aria-expanded={ ariaExpanded[i] } aria-controls={ collapseDomIds[i] }
  47. onclick={ () => this.toggle(i) }>
  48. { names[i] }
  49. </button>
  50. { extraHeaderUi[i] }
  51. </h2>
  52. </div>
  53. <div id={ collapseDomIds[i] } class={ collapseClass[i] }
  54. aria-labelledby={ headerDomIds[i] }>
  55. <div class="card-body">
  56. { children[i] }
  57. </div>
  58. </div>
  59. </div>
  60. )) }
  61. </div>
  62. );
  63. }
  64. };
  65. WBAccordion.defaultProps = {
  66. cardHeaderClass: 'card-header',
  67. extraHeaderUi: []
  68. };
  69. export default WBAccordion;