ttk-app-core
Version:
@ttk/recat enterprise develop framework
164 lines (157 loc) • 6.28 kB
JSX
import React, { useState, useEffect, useCallback, useRef } from 'react'
import { Icon, Radio, Button, Menu, Dropdown } from 'antd';
import { useDispatch } from 'react-redux'
import { useData, useCommit, useActions } from '@ttk/app-loader'
import { useHistory } from '@ttk/router'
import { removeAllTabAction, removeOtherTabsAction, removeLeftTabsAction, removeRightTabsAction, openTabAction } from '@/apps/portal/app-root/action'
// export default React.memo(TTKTabs)
export default function TTKTabBar(props) {
const commit = useCommit()
const dispatch = useDispatch()
const history = useHistory()
const tags = useData('app-root/tags/list')
let currentTag = useData('app-root/tags/currentTag')//.toJS()
const actions = useActions(props)
currentTag = currentTag.toJS()
const [translateX, setTranslateX] = useState(0)
const [activeTab, setActiveTab] = useState()
const [navWrap, setNavWrap] = useState()
// const [tabsWrap, setTabsWrap] = useState()
const [gutter, setGutter] = useState(400)
// const tabsRef = useCallback((node, a) => {
// if(node != null){
// console.log('=====>>: ', node)
// setTabsWrap({scrollW: parseInt(node.scrollWidth), left: parseInt(node.getBoundingClientRect().left)})
// }
// }, [tags])
const activeTabRef = useCallback((node, a) => {
if (node !== null) {
const scrollW = node.scrollWidth
const left = node.getBoundingClientRect().left
// console.log('activeTabRef:: ', scrollW, node.getBoundingClientRect())
setActiveTab({ scrollW: parseInt(scrollW), left: parseInt(left) })
}
}, [])
const navWrapRef = useCallback((node) => {
if (node !== null) {
const scrollW = node.scrollWidth
const offsetW = node.offsetWidth
const left = node.getBoundingClientRect().left
// console.log('navWrapRef==<:: ', node.getBoundingClientRect(), node)
setNavWrap({ scrollW: parseInt(scrollW), offsetW: parseInt(offsetW), left: parseInt(left) })
}
}, [activeTab])
const onClickLeft = useCallback(() => {
if (translateX + gutter > 0)
setTranslateX(0)
else
setTranslateX(translateX + gutter)
}, [translateX])
function onClickRight() {
if (!navWrap || !activeTab) return
if (translateX - gutter < navWrap.offsetW - navWrap.scrollW) {
setTranslateX(navWrap.offsetW - navWrap.scrollW-1)
} else {
setTranslateX(translateX - gutter)
}
}
const onClickOperation = useCallback((node) =>{
if (node.key === 'all') {
// 关闭全部
dispatch(removeAllTabAction())
history.replace('/') // 跳转到默认页
} else if (node.key === 'left') {
// 关闭其他
dispatch(removeLeftTabsAction(currentTag))
} else if (node.key === 'right') {
// 关闭其他
dispatch(removeRightTabsAction(currentTag))
} else if (node.key === 'other') {
// 关闭其他
dispatch(removeOtherTabsAction(currentTag))
} else {
// 关闭当前
actions.closeTab(currentTag)
}
})
function scrollToActiveTab() {
if (!navWrap || !activeTab) return
const wrapL = navWrap.left
const wrapW = navWrap.offsetW
const activeTabL = activeTab.left
const activeTabScrollW = activeTab.scrollW
let translate
if (wrapL > activeTabL) {
translate = wrapL - activeTabL
// console.log('-', translate, translateX, translateX + translate)
setTranslateX(translateX + translate)
} else if (wrapL + wrapW < activeTabL + activeTabScrollW) {
translate = (activeTabL + activeTabScrollW) - (wrapL + wrapW)
// console.log('-==:: ', translate, translateX -translate, '----',
// `${activeTabL} + ${activeTabScrollW} = ${activeTabL + activeTabScrollW}`,
// `${wrapL} + ${wrapW} = ${wrapL + wrapW}`)
setTranslateX(translateX - translate-1)
}
}
useEffect(() => {
scrollToActiveTab()
}, [activeTab])
const tabsDropdown = (
<Menu onClick={onClickOperation}>
<Menu.Item key="current">关闭当前</Menu.Item>
{ tags.size > 1 && <Menu.Item key="left">关闭左侧</Menu.Item>}
{ tags.size > 1 && <Menu.Item key="right">关闭右侧</Menu.Item>}
{ tags.size > 1 && <Menu.Item key="other">关闭其他</Menu.Item>}
{ tags.size > 1 && <Menu.Item key="all">关闭所有</Menu.Item>}
</Menu>
)
return (
<div className="app-portal-tabs">
<span className="arrow left" onClick={onClickLeft}><Icon type="double-left" /></span>
<span className="arrow right" onClick={onClickRight}><Icon type="double-right" /></span>
<Dropdown overlay={tabsDropdown}>
<span className="arrow operation">
<Icon type="menu" onClick={() => console.log('onoperation')} />
</span>
</Dropdown>
<div ref={tags.size > 0 ? navWrapRef : null} className="tabs">
<Radio.Group value={currentTag.url} style={{ transform: `translateX(${translateX}px)`, transition: "transform 0.3s" }}>
{
tags && tags.map((item, index) => {
return <span
className="tab"
key={item.url + index}
ref={currentTag.url === item.url ? activeTabRef : null}
><Radio.Button
key={item.url + index}
size='small'
value={item.url}
onClick={(e) => {
commit('app-root/tags', { type: 'setCurrentTag', data: item })
history.push(`${item.url}`)
// history.replace(item.url)
e.preventDefault(true)
}}
>
{item.name}
<Icon
key={item.url + index}
onClick={(e) => {
// console.log('j333333', actions)
actions.closeTab(item)
// history.push(`${item.url}`)
// commit('app-root/tags', { type: 'removeTag', data: item })
// history.goBack()
e.preventDefault(true)
}}
type="close"
/>
</Radio.Button>
</span>
})
}
</Radio.Group>
</div>
</div>
)
}