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.

77 lines
2.3KB

  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, 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. </h2>
  51. </div>
  52. <div id={ collapseDomIds[i] } class={ collapseClass[i] }
  53. aria-labelledby={ headerDomIds[i] }>
  54. <div class="card-body">
  55. { children[i] }
  56. </div>
  57. </div>
  58. </div>
  59. )) }
  60. </div>
  61. );
  62. }
  63. };
  64. WBAccordion.defaultProps = {
  65. 'cardHeaderClass': 'card-header'
  66. };
  67. export default WBAccordion;