From 745a5c16e7871b081a08cf23084dfc5c9c0992c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=B0=91?= Date: Fri, 17 Sep 2021 12:43:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0tabbar=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .husky/pre-commit | 2 +- README.md | 17 ++- package.json | 6 +- .../vantui-demo/src/pages/index/index.tsx | 16 ++ .../src/components/tabbar-item/index.tsx | 85 +++++++++++ .../vantui/src/components/tabbar/index.tsx | 143 ++++++++++++++++++ packages/vantui/src/index.ts | 2 + .../src/style/components/tabbar-item.less | 1 + packages/vantui/types/index.d.ts | 2 + packages/vantui/types/tabbar-item.d.ts | 18 +++ packages/vantui/types/tabbar.d.ts | 19 +++ 11 files changed, 305 insertions(+), 6 deletions(-) create mode 100644 packages/vantui/src/components/tabbar-item/index.tsx create mode 100644 packages/vantui/src/components/tabbar/index.tsx create mode 100644 packages/vantui/types/tabbar-item.d.ts create mode 100644 packages/vantui/types/tabbar.d.ts diff --git a/.husky/pre-commit b/.husky/pre-commit index d2ae35e84..449fcdee1 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" -yarn lint-staged +npm test diff --git a/README.md b/README.md index 85c17c959..ac3a8a390 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ src/style/index.less import { Button } from '@antmjs/vantui' ``` -yarn +yarn && npx husky install npx lerna bootstrap @@ -124,16 +124,27 @@ TreeSelect Area 三少 + Button[完成] + Icon[完成] Progress[完成] + Skeleton[完成] + CountDown[完成] + Tag[完成] + Sticky[完成] + Rate[完成] + Search[完成] + NavBar[完成] -Tab -TabBar \ No newline at end of file + +Tab[完成] + +TabBar[完成] \ No newline at end of file diff --git a/package.json b/package.json index 261a85614..8b3e16a3d 100644 --- a/package.json +++ b/package.json @@ -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", @@ -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" } } diff --git a/packages/vantui-demo/src/pages/index/index.tsx b/packages/vantui-demo/src/pages/index/index.tsx index 95efd7405..b687a2b4c 100644 --- a/packages/vantui-demo/src/pages/index/index.tsx +++ b/packages/vantui-demo/src/pages/index/index.tsx @@ -18,6 +18,8 @@ import { Skeleton, Tag, CountDown, + Tabbar, + TabbarItem, } from '@antmjs/vantui' import './index.less' @@ -179,6 +181,20 @@ export default function Index() { 加载中... + + + 标签 + + + 标签 + + + 标签 + + + 标签 + + ) } diff --git a/packages/vantui/src/components/tabbar-item/index.tsx b/packages/vantui/src/components/tabbar-item/index.tsx new file mode 100644 index 000000000..e5a7082fd --- /dev/null +++ b/packages/vantui/src/components/tabbar-item/index.tsx @@ -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 ? ( + + + {icon ? ( + + ) : ( + + {active === (name || index) ? renderIconactive : renderIcon} + + )} + + + {children} + + ) : ( + <> + ) +} diff --git a/packages/vantui/src/components/tabbar/index.tsx b/packages/vantui/src/components/tabbar/index.tsx new file mode 100644 index 000000000..c1b8ab2f3 --- /dev/null +++ b/packages/vantui/src/components/tabbar/index.tsx @@ -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) => { + 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 ( + + + {newChildren} + + {fixed && placeholder && ( + + )} + + ) +} diff --git a/packages/vantui/src/index.ts b/packages/vantui/src/index.ts index 6046db3de..6695a9a0c 100644 --- a/packages/vantui/src/index.ts +++ b/packages/vantui/src/index.ts @@ -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' diff --git a/packages/vantui/src/style/components/tabbar-item.less b/packages/vantui/src/style/components/tabbar-item.less index 6f0703dd5..a87a3d43d 100644 --- a/packages/vantui/src/style/components/tabbar-item.less +++ b/packages/vantui/src/style/components/tabbar-item.less @@ -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'); diff --git a/packages/vantui/types/index.d.ts b/packages/vantui/types/index.d.ts index e06329319..8007424ee 100644 --- a/packages/vantui/types/index.d.ts +++ b/packages/vantui/types/index.d.ts @@ -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' diff --git a/packages/vantui/types/tabbar-item.d.ts b/packages/vantui/types/tabbar-item.d.ts new file mode 100644 index 000000000..94efd46f1 --- /dev/null +++ b/packages/vantui/types/tabbar-item.d.ts @@ -0,0 +1,18 @@ +import { ComponentClass, ReactNode } from 'react' +import { StandardProps } from '@tarojs/components' + +export interface TabbarItemProps extends Omit { + 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 + +export { TabbarItem } diff --git a/packages/vantui/types/tabbar.d.ts b/packages/vantui/types/tabbar.d.ts new file mode 100644 index 000000000..9e578843d --- /dev/null +++ b/packages/vantui/types/tabbar.d.ts @@ -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 + +export { Tabbar }