Skip to content

Commit

Permalink
feat: 添加tabbar功能
Browse files Browse the repository at this point in the history
  • Loading branch information
三少 committed Sep 17, 2021
1 parent baac1a6 commit 745a5c1
Show file tree
Hide file tree
Showing 11 changed files with 305 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

yarn lint-staged
npm test
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ src/style/index.less
import { Button } from '@antmjs/vantui'
```

yarn
yarn && npx husky install

npx lerna bootstrap

Expand Down Expand Up @@ -124,16 +124,27 @@ TreeSelect
Area

三少

Button[完成]

Icon[完成]

Progress[完成]

Skeleton[完成]

CountDown[完成]

Tag[完成]

Sticky[完成]

Rate[完成]

Search[完成]

NavBar[完成]
Tab
TabBar

Tab[完成]

TabBar[完成]
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@
"release:lerna": "lerna version --exact --no-git-tag-version --force-publish",
"release:beta": "lerna publish --force-publish=* --exact --skip-temp-tag --preid=beta --npm-tag=beta",
"release": "npm run release:lerna && npm run changelog && node ./pullRequest.js",
"test": "npx lerna run test"
"test": "npx lerna run test",
"prepare": "husky install"
},
"dependencies": {
"@commitlint/cli": "^12.1.4",
Expand Down Expand Up @@ -136,6 +137,7 @@
"devDependencies": {
"@antmjs/babel-preset": "^1.12.0",
"@antmjs/eslint": "^1.12.0",
"@antmjs/stylelint": "^1.12.0"
"@antmjs/stylelint": "^1.12.0",
"husky": "^7.0.0"
}
}
16 changes: 16 additions & 0 deletions packages/vantui-demo/src/pages/index/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
Skeleton,
Tag,
CountDown,
Tabbar,
TabbarItem,
} from '@antmjs/vantui'

import './index.less'
Expand Down Expand Up @@ -179,6 +181,20 @@ export default function Index() {
<Loading type="circular" size={80}>
加载中...
</Loading>
<Tabbar active={1}>
<TabbarItem info={null} name={null} icon="home-o">
标签
</TabbarItem>
<TabbarItem info={null} name={null} icon="search" dot>
标签
</TabbarItem>
<TabbarItem name={null} icon="friends-o" info="5">
标签
</TabbarItem>
<TabbarItem name={null} icon="setting-o" info="20">
标签
</TabbarItem>
</Tabbar>
</View>
)
}
85 changes: 85 additions & 0 deletions packages/vantui/src/components/tabbar-item/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { View, Block } from '@tarojs/components'
import * as utils from '../wxs/utils'
import Icon from '../icon'
import Info from '../info'
import { TabbarItemProps } from '../../../types/tabbar-item'

export default function Index(
props: TabbarItemProps & {
index: number
active?: number
activeColor?: string
inactiveColor?: string
onChange?: (data?: string | number) => void
},
) {
const {
icon,
name,
iconPrefix = 'van-icon',
dot,
info = null,
renderIconactive,
renderIcon,
index,
active,
activeColor,
inactiveColor,
onChange,
children,
style,
className,
onClick,
...others
} = props

const _click = function () {
if (onChange) {
const _active = name || index
if (_active !== active) {
onChange(_active)
}
}

onClick?.(name || index)
}

return onChange ? (
<View
className={
utils.bem('tabbar-item', {
active: active === (name || index),
}) +
' custom-class' +
` ${className}`
}
style={utils.style([
{
color: active === (name || index) ? activeColor : inactiveColor,
},
style,
])}
{...others}
onClick={_click}
>
<View className="van-tabbar-item__icon">
{icon ? (
<Icon
info={null}
name={icon}
classPrefix={iconPrefix}
className="van-tabbar-item__icon__inner"
></Icon>
) : (
<Block>
{active === (name || index) ? renderIconactive : renderIcon}
</Block>
)}
<Info dot={dot} info={info} className="van-tabbar-item__info"></Info>
</View>
<View className="van-tabbar-item__text">{children}</View>
</View>
) : (
<></>
)
}
143 changes: 143 additions & 0 deletions packages/vantui/src/components/tabbar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import Taro from '@tarojs/taro'
import {
useState,
isValidElement,
cloneElement,
useEffect,
useCallback,
} from 'react'
import toArray from 'rc-util/lib/Children/toArray'
import { View, Block } from '@tarojs/components'
import * as utils from '../wxs/utils'
import { getRect } from '../common/utils'
import { TabbarProps } from '../../../types/tabbar'
import { TabbarItemProps } from '../../../types/tabbar-item'

function parseTabList(children: React.ReactNode): any[] {
return toArray(children)
.map((node: React.ReactElement<TabbarItemProps>) => {
if (isValidElement(node)) {
const key = node.key !== undefined ? String(node.key) : undefined
return {
key,
...node.props,
node,
}
}

return null
})
.filter((tab) => tab)
}

export default function Index(props: TabbarProps) {
const [state, setState]: any = useState({
height: 50,
current: 0,
})
const { height, current } = state

const {
active,
activeColor,
inactiveColor,
border = true,
fixed = true,
safeAreaInsetBottom = true,
zIndex = 1,
placeholder,
onChange,
style,
className,
children,
...others
} = props
const _change = useCallback(
function (data) {
setState((pre: any) => {
return {
...pre,
current: data,
}
})
onChange?.(data)
},
[onChange],
)
const tabs = parseTabList(children)
const newChildren: any = tabs.map((tab, index) => {
return cloneElement(tab.node, {
key: index,
index: index,
active: current,
activeColor: activeColor,
inactiveColor: inactiveColor,
onChange: _change,
})
})

useEffect(
function () {
setState((pre: any) => {
return {
...pre,
current: active,
}
})
},
[active],
)

useEffect(
function () {
if (!fixed || !placeholder) {
return
}
Taro.nextTick(() => {
getRect(null, '.van-tabbar').then((res: any) => {
setState((pre: any) => {
return {
...pre,
height: res.height,
}
})
})
})
},
[fixed, placeholder],
)
// useEffect(
// function () {
// if (!Array.isArray(children) || !children.length) {
// return
// }
// children.forEach((child) => child.updateFromParent())
// },
// // eslint-disable-next-line react-hooks/exhaustive-deps
// [active, activeColor, inactiveColor],
// )

return (
<Block>
<View
className={
(border ? 'van-hairline--top-bottom' : '') +
' ' +
utils.bem('tabbar', {
fixed,
safe: safeAreaInsetBottom,
}) +
' custom-class' +
` ${className}`
}
style={utils.style([zIndex ? 'z-index: ' + zIndex : '', style])}
{...others}
>
{newChildren}
</View>
{fixed && placeholder && (
<View style={'height: ' + height + 'px;'}></View>
)}
</Block>
)
}
2 changes: 2 additions & 0 deletions packages/vantui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ export { default as Search } from './components/search'
export { default as Skeleton } from './components/skeleton'
export { default as Tag } from './components/tag'
export { default as CountDown } from './components/count-down'
export { default as Tabbar } from './components/tabbar'
export { default as TabbarItem } from './components/tabbar-item'
1 change: 1 addition & 0 deletions packages/vantui/src/style/components/tabbar-item.less
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
flex-direction: column;
align-items: center;
justify-content: center;
flex: 1;
height: 100%;
.theme(color, '@tabbar-item-text-color');
.theme(font-size, '@tabbar-item-font-size');
Expand Down
2 changes: 2 additions & 0 deletions packages/vantui/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ export { Search } from './search.d'
export { Skeleton } from './skeleton.d'
export { CountDown } from './count-down.d'
export { Tag } from './tag.d'
export { Tabbar } from './tabbar.d'
export { TabbarItem } from './tabbar-item.d'
18 changes: 18 additions & 0 deletions packages/vantui/types/tabbar-item.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ComponentClass, ReactNode } from 'react'
import { StandardProps } from '@tarojs/components'

export interface TabbarItemProps extends Omit<StandardProps, 'onClick'> {
info: null | string
name: null | string | number
icon?: string
dot?: boolean
iconPrefix?: string
renderIconactive?: ReactNode
renderIcon?: ReactNode
children?: ReactNode
onClick?: (data: string | number) => void
}

declare const TabbarItem: ComponentClass<TabbarItemProps>

export { TabbarItem }
19 changes: 19 additions & 0 deletions packages/vantui/types/tabbar.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ComponentClass, ReactNode } from 'react'
import { StandardProps } from '@tarojs/components'

export interface TabbarProps extends StandardProps {
active?: number
activeColor?: string
inactiveColor?: string
fixed?: boolean
placeholder?: boolean
border?: boolean
zIndex?: number
safeAreaInsetBottom?: boolean
children?: ReactNode
onChange?: (data?: string | number) => void
}

declare const Tabbar: ComponentClass<TabbarProps>

export { Tabbar }

0 comments on commit 745a5c1

Please sign in to comment.