Procházet zdrojové kódy

✨ feat(ui): add navbar component

- 创建可定制的导航栏组件,支持标题、左右按钮和图标
- 实现自动计算状态栏和导航栏高度,适配不同设备
- 提供默认、深色、透明和主色调四种预设样式
- 支持固定定位、边框显示和占位元素等功能
- 添加点击事件处理和默认返回上一页行为
yourname před 4 měsíci
rodič
revize
52fc7e1bc5
1 změnil soubory, kde provedl 185 přidání a 0 odebrání
  1. 185 0
      mini/src/components/ui/navbar.tsx

+ 185 - 0
mini/src/components/ui/navbar.tsx

@@ -0,0 +1,185 @@
+import React from 'react'
+import { View, Text } from '@tarojs/components'
+import { cn } from '@/utils/cn'
+import Taro from '@tarojs/taro'
+
+export interface NavbarProps {
+  title?: string
+  leftText?: string
+  leftIcon?: string
+  rightText?: string
+  rightIcon?: string
+  backgroundColor?: string
+  textColor?: string
+  border?: boolean
+  fixed?: boolean
+  placeholder?: boolean
+  onClickLeft?: () => void
+  onClickRight?: () => void
+  children?: React.ReactNode
+  className?: string
+}
+
+const systemInfo = Taro.getSystemInfoSync()
+const menuButtonInfo = Taro.getMenuButtonBoundingClientRect()
+
+// 计算导航栏高度
+const NAVBAR_HEIGHT = 44
+const STATUS_BAR_HEIGHT = systemInfo.statusBarHeight || 0
+const TOTAL_HEIGHT = STATUS_BAR_HEIGHT + NAVBAR_HEIGHT
+
+export const Navbar: React.FC<NavbarProps> = ({
+  title,
+  leftText,
+  leftIcon = 'i-heroicons-chevron-left-20-solid',
+  rightText,
+  rightIcon,
+  backgroundColor = 'bg-white',
+  textColor = 'text-gray-900',
+  border = true,
+  fixed = true,
+  placeholder = true,
+  onClickLeft,
+  onClickRight,
+  children,
+  className,
+}) => {
+  // 处理左侧点击
+  const handleLeftClick = () => {
+    if (onClickLeft) {
+      onClickLeft()
+    } else {
+      // 默认返回上一页
+      Taro.navigateBack()
+    }
+  }
+
+  // 渲染左侧内容
+  const renderLeft = () => {
+    if (children) return null
+    
+    return (
+      <View 
+        className="absolute left-3 top-0 bottom-0 flex items-center z-10"
+        style={{ height: NAVBAR_HEIGHT }}
+        onClick={handleLeftClick}
+      >
+        <View className="flex items-center">
+          {leftIcon && (
+            <View className={cn(leftIcon, 'w-5 h-5', textColor)} />
+          )}
+          {leftText && (
+            <Text className={cn('ml-1 text-sm', textColor)}>{leftText}</Text>
+          )}
+        </View>
+      </View>
+    )
+  }
+
+  // 渲染右侧内容
+  const renderRight = () => {
+    if (!rightText && !rightIcon) return null
+    
+    return (
+      <View 
+        className="absolute right-3 top-0 bottom-0 flex items-center z-10"
+        style={{ height: NAVBAR_HEIGHT }}
+        onClick={onClickRight}
+      >
+        <View className="flex items-center">
+          {rightText && (
+            <Text className={cn('mr-1 text-sm', textColor)}>{rightText}</Text>
+          )}
+          {rightIcon && (
+            <View className={cn(rightIcon, 'w-5 h-5', textColor)} />
+          )}
+        </View>
+      </View>
+    )
+  }
+
+  // 渲染标题
+  const renderTitle = () => {
+    if (children) return children
+    
+    return (
+      <Text className={cn('text-base font-semibold', textColor)}>
+        {title}
+      </Text>
+    )
+  }
+
+  // 导航栏样式
+  const navbarStyle = {
+    height: TOTAL_HEIGHT,
+    paddingTop: STATUS_BAR_HEIGHT,
+  }
+
+  return (
+    <>
+      <View
+        className={cn(
+          'relative w-full',
+          backgroundColor,
+          border && 'border-b border-gray-200',
+          fixed && 'fixed top-0 left-0 right-0 z-50',
+          className
+        )}
+        style={navbarStyle}
+      >
+        {/* 导航栏内容 */}
+        <View 
+          className="relative flex items-center justify-center"
+          style={{ height: NAVBAR_HEIGHT }}
+        >
+          {renderLeft()}
+          {renderTitle()}
+          {renderRight()}
+        </View>
+      </View>
+      
+      {/* 占位元素 */}
+      {fixed && placeholder && (
+        <View style={{ height: TOTAL_HEIGHT }} />
+      )}
+    </>
+  )
+}
+
+// 预设样式
+export const NavbarPresets = {
+  // 默认白色导航栏
+  default: {
+    backgroundColor: 'bg-white',
+    textColor: 'text-gray-900',
+    border: true,
+  },
+  
+  // 深色导航栏
+  dark: {
+    backgroundColor: 'bg-gray-900',
+    textColor: 'text-white',
+    border: true,
+  },
+  
+  // 透明导航栏
+  transparent: {
+    backgroundColor: 'bg-transparent',
+    textColor: 'text-white',
+    border: false,
+  },
+  
+  // 主色调导航栏
+  primary: {
+    backgroundColor: 'bg-blue-500',
+    textColor: 'text-white',
+    border: false,
+  },
+}
+
+// 快捷创建函数
+export const createNavbar = (preset: keyof typeof NavbarPresets) => {
+  return NavbarPresets[preset]
+}
+
+export default Navbar