logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://hacktivis.me/git/pleroma-fe.git

tab_switcher.js (4201B)


  1. import Vue from 'vue'
  2. import { mapState } from 'vuex'
  3. import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome'
  4. import './tab_switcher.scss'
  5. export default Vue.component('tab-switcher', {
  6. name: 'TabSwitcher',
  7. props: {
  8. renderOnlyFocused: {
  9. required: false,
  10. type: Boolean,
  11. default: false
  12. },
  13. onSwitch: {
  14. required: false,
  15. type: Function,
  16. default: undefined
  17. },
  18. activeTab: {
  19. required: false,
  20. type: String,
  21. default: undefined
  22. },
  23. scrollableTabs: {
  24. required: false,
  25. type: Boolean,
  26. default: false
  27. },
  28. sideTabBar: {
  29. required: false,
  30. type: Boolean,
  31. default: false
  32. }
  33. },
  34. data () {
  35. return {
  36. active: this.$slots.default.findIndex(_ => _.tag)
  37. }
  38. },
  39. computed: {
  40. activeIndex () {
  41. // In case of controlled component
  42. if (this.activeTab) {
  43. return this.$slots.default.findIndex(slot => this.activeTab === slot.key)
  44. } else {
  45. return this.active
  46. }
  47. },
  48. settingsModalVisible () {
  49. return this.settingsModalState === 'visible'
  50. },
  51. ...mapState({
  52. settingsModalState: state => state.interface.settingsModalState
  53. })
  54. },
  55. beforeUpdate () {
  56. const currentSlot = this.$slots.default[this.active]
  57. if (!currentSlot.tag) {
  58. this.active = this.$slots.default.findIndex(_ => _.tag)
  59. }
  60. },
  61. methods: {
  62. clickTab (index) {
  63. return (e) => {
  64. e.preventDefault()
  65. this.setTab(index)
  66. }
  67. },
  68. setTab (index) {
  69. if (typeof this.onSwitch === 'function') {
  70. this.onSwitch.call(null, this.$slots.default[index].key)
  71. }
  72. this.active = index
  73. if (this.scrollableTabs) {
  74. this.$refs.contents.scrollTop = 0
  75. }
  76. }
  77. },
  78. render (h) {
  79. const tabs = this.$slots.default
  80. .map((slot, index) => {
  81. if (!slot.tag) return
  82. const classesTab = ['tab', 'button-default']
  83. const classesWrapper = ['tab-wrapper']
  84. if (this.activeIndex === index) {
  85. classesTab.push('active')
  86. classesWrapper.push('active')
  87. }
  88. if (slot.data.attrs.image) {
  89. return (
  90. <div class={classesWrapper.join(' ')}>
  91. <button
  92. disabled={slot.data.attrs.disabled}
  93. onClick={this.clickTab(index)}
  94. class={classesTab.join(' ')}
  95. type="button"
  96. >
  97. <img src={slot.data.attrs.image} title={slot.data.attrs['image-tooltip']}/>
  98. {slot.data.attrs.label ? '' : slot.data.attrs.label}
  99. </button>
  100. </div>
  101. )
  102. }
  103. return (
  104. <div class={classesWrapper.join(' ')}>
  105. <button
  106. disabled={slot.data.attrs.disabled}
  107. onClick={this.clickTab(index)}
  108. class={classesTab.join(' ')}
  109. type="button"
  110. >
  111. {!slot.data.attrs.icon ? '' : (<FAIcon class="tab-icon" size="2x" fixed-width icon={slot.data.attrs.icon}/>)}
  112. <span class="text">
  113. {slot.data.attrs.label}
  114. </span>
  115. </button>
  116. </div>
  117. )
  118. })
  119. const contents = this.$slots.default.map((slot, index) => {
  120. if (!slot.tag) return
  121. const active = this.activeIndex === index
  122. const classes = [ active ? 'active' : 'hidden' ]
  123. if (slot.data.attrs.fullHeight) {
  124. classes.push('full-height')
  125. }
  126. const renderSlot = (!this.renderOnlyFocused || active)
  127. ? slot
  128. : ''
  129. return (
  130. <div class={classes}>
  131. {
  132. this.sideTabBar
  133. ? <h1 class="mobile-label">{slot.data.attrs.label}</h1>
  134. : ''
  135. }
  136. {renderSlot}
  137. </div>
  138. )
  139. })
  140. return (
  141. <div class={'tab-switcher ' + (this.sideTabBar ? 'side-tabs' : 'top-tabs')}>
  142. <div class="tabs">
  143. {tabs}
  144. </div>
  145. <div ref="contents" class={'contents' + (this.scrollableTabs ? ' scrollable-tabs' : '')} v-body-scroll-lock={this.settingsModalVisible}>
  146. {contents}
  147. </div>
  148. </div>
  149. )
  150. }
  151. })