hx-collapsible.vue 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. <template>
  2. <div
  3. class="hx-collapsible"
  4. :class="{active:state.active}">
  5. <button
  6. class="hx-collapsible__header"
  7. @click.stop.prevent="toggle">
  8. <slot name="header"/>
  9. <div v-if="icon">
  10. <hx-toggle-arrow :active="state.active"/>
  11. </div>
  12. </button>
  13. <div class="hx-collapsible__content">
  14. <slot/>
  15. </div>
  16. </div>
  17. </template>
  18. <script>
  19. import HxToggleArrow from './hx-toggle-arrow'
  20. export default {
  21. components: {HxToggleArrow},
  22. props: {
  23. active: {type: Boolean, default: true},
  24. icon: {type: Boolean, default: true}
  25. },
  26. data () {
  27. return {
  28. state: {
  29. active: this.active
  30. }
  31. }
  32. },
  33. watch: {
  34. active (value) {
  35. this.state.active = this.active
  36. }
  37. },
  38. methods: {
  39. toggle (ev) {
  40. this.state.active = !this.state.active
  41. }
  42. }
  43. }
  44. </script>
  45. <style>
  46. .hx-collapsible {
  47. position:relative;
  48. display:flex;
  49. flex-direction: column;
  50. }
  51. /* header */
  52. .hx-collapsible__header {
  53. display:flex;
  54. justify-content:space-between;
  55. align-items:center;
  56. align-content:center;
  57. user-select:none;
  58. cursor: pointer;
  59. }
  60. /*content*/
  61. .hx-collapsible__content{
  62. overflow:hidden;
  63. opacity:0;
  64. max-height:0px;
  65. flex-basis: 0px;
  66. flex-grow:0;
  67. transition: all 300ms;
  68. }
  69. .hx-collapsible.active .hx-collapsible__content{
  70. flex-basis:100%;
  71. flex-grow:1;
  72. opacity:1;
  73. max-height:900px;
  74. transition: all 300ms;
  75. }
  76. </style>