aboutsummaryrefslogtreecommitdiff
path: root/src/components/tab_switcher/tab_switcher.jsx
diff options
context:
space:
mode:
authorHenry Jameson <me@hjkos.com>2021-04-18 14:58:02 +0300
committerHenry Jameson <me@hjkos.com>2021-04-18 14:58:02 +0300
commit433ea02a18c0328b8079a40657220633c09e363a (patch)
treefdc3de3ebd5dd69ecbd81dc83416a8797cdddece /src/components/tab_switcher/tab_switcher.jsx
parent8b96ea93776fd1eb462a7c54822d4f8ad6a9e776 (diff)
Changed some of TabSwitcher's internals for easier Vue3 migration
Diffstat (limited to 'src/components/tab_switcher/tab_switcher.jsx')
-rw-r--r--src/components/tab_switcher/tab_switcher.jsx171
1 files changed, 171 insertions, 0 deletions
diff --git a/src/components/tab_switcher/tab_switcher.jsx b/src/components/tab_switcher/tab_switcher.jsx
new file mode 100644
index 00000000..68eee122
--- /dev/null
+++ b/src/components/tab_switcher/tab_switcher.jsx
@@ -0,0 +1,171 @@
+import { mapState } from 'vuex'
+import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome'
+
+import './tab_switcher.scss'
+
+// TODO VUE3: change data to props
+const findFirstUsable = (slots) => slots.findIndex(_ => _.data && _.data.attrs)
+
+export default {
+ name: 'TabSwitcher',
+ props: {
+ renderOnlyFocused: {
+ required: false,
+ type: Boolean,
+ default: false
+ },
+ onSwitch: {
+ required: false,
+ type: Function,
+ default: undefined
+ },
+ activeTab: {
+ required: false,
+ type: String,
+ default: undefined
+ },
+ scrollableTabs: {
+ required: false,
+ type: Boolean,
+ default: false
+ },
+ sideTabBar: {
+ required: false,
+ type: Boolean,
+ default: false
+ }
+ },
+ data () {
+ console.log(this.$slots.default)
+ return {
+ // TODO VUE3: add () after 'default'
+ active: findFirstUsable(this.$slots.default)
+ }
+ },
+ computed: {
+ slots () {
+ // TODO VUE3: add () at the end
+ return this.$slots.default
+ },
+ activeIndex () {
+ // In case of controlled component
+ if (this.activeTab) {
+ return this.$slots.default.findIndex(slot => this.activeTab === slot.key)
+ } else {
+ return this.active
+ }
+ },
+ settingsModalVisible () {
+ return this.settingsModalState === 'visible'
+ },
+ ...mapState({
+ settingsModalState: state => state.interface.settingsModalState
+ })
+ },
+ beforeUpdate () {
+ console.log(this.slots, this.active)
+ const currentSlot = this.slots[this.active]
+ // TODO VUE3: change data to props
+ if (!currentSlot.data) {
+ this.active = findFirstUsable(this.slots)
+ }
+ },
+ methods: {
+ clickTab (index) {
+ return (e) => {
+ e.preventDefault()
+ this.setTab(index)
+ }
+ },
+ setTab (index) {
+ if (typeof this.onSwitch === 'function') {
+ this.onSwitch.call(null, this.slots[index].key)
+ }
+ this.active = index
+ if (this.scrollableTabs) {
+ this.$refs.contents.scrollTop = 0
+ }
+ }
+ },
+ // TODO VUE3: remove 'h' here
+ render (h) {
+ const tabs = this.slots
+ .map((slot, index) => {
+ // TODO VUE3 change to slot.props
+ const props = slot.data && slot.data.attrs
+ if (!props) return
+ const classesTab = ['tab', 'button-default']
+ const classesWrapper = ['tab-wrapper']
+ if (this.activeIndex === index) {
+ classesTab.push('active')
+ classesWrapper.push('active')
+ }
+ if (props.image) {
+ return (
+ <div class={classesWrapper.join(' ')}>
+ <button
+ disabled={props.disabled}
+ onClick={this.clickTab(index)}
+ class={classesTab.join(' ')}
+ type="button"
+ >
+ <img src={props.image} title={props['image-tooltip']}/>
+ {props.label ? '' : props.label}
+ </button>
+ </div>
+ )
+ }
+ return (
+ <div class={classesWrapper.join(' ')}>
+ <button
+ disabled={props.disabled}
+ onClick={this.clickTab(index)}
+ class={classesTab.join(' ')}
+ type="button"
+ >
+ {!props.icon ? '' : (<FAIcon class="tab-icon" size="2x" fixed-width icon={props.icon}/>)}
+ <span class="text">
+ {props.label}
+ </span>
+ </button>
+ </div>
+ )
+ })
+
+ const contents = this.slots.map((slot, index) => {
+ // TODO VUE3 change to slot.props
+ const props = slot.data && slot.data.attrs
+ if (!props) return
+ const active = this.activeIndex === index
+ const classes = [ active ? 'active' : 'hidden' ]
+ if (props.fullHeight) {
+ classes.push('full-height')
+ }
+ const renderSlot = (!this.renderOnlyFocused || active)
+ ? slot
+ : ''
+
+ return (
+ <div class={classes}>
+ {
+ this.sideTabBar
+ ? <h1 class="mobile-label">{props.label}</h1>
+ : ''
+ }
+ {renderSlot}
+ </div>
+ )
+ })
+
+ return (
+ <div class={'tab-switcher ' + (this.sideTabBar ? 'side-tabs' : 'top-tabs')}>
+ <div class="tabs">
+ {tabs}
+ </div>
+ <div ref="contents" class={'contents' + (this.scrollableTabs ? ' scrollable-tabs' : '')} v-body-scroll-lock={this.settingsModalVisible}>
+ {contents}
+ </div>
+ </div>
+ )
+ }
+}