| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- import React from 'react'
- import { View, Text } from '@tarojs/components'
- import { useRouter } from '@tarojs/taro'
- import clsx from 'clsx'
- export interface TabBarItem {
- key: string
- title: string
- icon?: string
- selectedIcon?: string
- badge?: number | string
- dot?: boolean
- }
- export interface TabBarProps {
- items: TabBarItem[]
- activeKey?: string
- onChange?: (key: string) => void
- className?: string
- style?: React.CSSProperties
- fixed?: boolean
- safeArea?: boolean
- color?: string
- selectedColor?: string
- backgroundColor?: string
- }
- const TabBar = React.forwardRef<HTMLDivElement, TabBarProps>(({
- items,
- activeKey,
- onChange,
- className,
- style,
- fixed = true,
- safeArea = true,
- color = '#7f7f7f',
- selectedColor = '#1890ff',
- backgroundColor = '#ffffff',
- }, ref) => {
- const router = useRouter()
-
- const currentActiveKey = activeKey || items[0]?.key
- const handleTabChange = (key: string) => {
- if (key !== currentActiveKey) {
- onChange?.(key)
- }
- }
- return (
- <View
- ref={ref}
- className={clsx(
- 'tab-bar',
- fixed && 'fixed bottom-0 left-0 right-0',
- safeArea && 'pb-safe',
- 'z-50',
- className
- )}
- style={{
- backgroundColor,
- ...style,
- }}
- >
- <View className="flex h-16 border-t border-gray-200">
- {items.map((item) => {
- const isActive = item.key === currentActiveKey
-
- return (
- <View
- key={item.key}
- className={clsx(
- 'flex-1 flex flex-col items-center justify-center',
- 'px-2 py-1',
- 'cursor-pointer',
- 'transition-colors duration-200',
- 'hover:opacity-80'
- )}
- onClick={() => handleTabChange(item.key)}
- >
- <View className="relative">
- {item.icon && (
- <View
- className={clsx(
- 'text-2xl',
- 'mb-1',
- isActive ? 'text-blue-500' : 'text-gray-500'
- )}
- style={{
- color: isActive ? selectedColor : color,
- }}
- >
- {isActive && item.selectedIcon ? item.selectedIcon : item.icon}
- </View>
- )}
-
- {item.badge && (
- <View
- className={clsx(
- 'absolute -top-1 -right-2',
- 'bg-red-500 text-white text-xs',
- 'rounded-full px-1.5 py-0.5',
- 'min-w-4 h-4 flex items-center justify-center'
- )}
- >
- {typeof item.badge === 'number' && item.badge > 99 ? '99+' : item.badge}
- </View>
- )}
-
- {item.dot && (
- <View
- className={clsx(
- 'absolute -top-1 -right-1',
- 'w-2 h-2 bg-red-500 rounded-full'
- )}
- />
- )}
- </View>
-
- <Text
- className={clsx(
- 'text-xs',
- 'leading-tight',
- isActive ? 'font-medium' : 'font-normal'
- )}
- style={{
- color: isActive ? selectedColor : color,
- }}
- numberOfLines={1}
- >
- {item.title}
- </Text>
- </View>
- )
- })}
- </View>
- </View>
- )
- })
- TabBar.displayName = 'TabBar'
- export { TabBar }
|