浏览代码

✨ feat(components): add switch component and use in address edit page

- add new Switch component with configurable size, color and disabled state
- implement toggle functionality with smooth transitions
- support small, medium and large size variants
- replace native switch with new Switch component in address edit page
yourname 3 月之前
父节点
当前提交
db912e34fb
共有 2 个文件被更改,包括 78 次插入1 次删除
  1. 76 0
      mini/src/components/ui/switch.tsx
  2. 2 1
      mini/src/pages/address-edit/index.tsx

+ 76 - 0
mini/src/components/ui/switch.tsx

@@ -0,0 +1,76 @@
+import { useState } from 'react'
+import { View } from '@tarojs/components'
+import { cn } from '@/utils/cn'
+
+interface SwitchProps {
+  checked?: boolean
+  onChange?: (checked: boolean) => void
+  disabled?: boolean
+  color?: string
+  size?: 'sm' | 'md' | 'lg'
+  className?: string
+}
+
+export function Switch({
+  checked = false,
+  onChange,
+  disabled = false,
+  color = '#1976D2',
+  size = 'md',
+  className,
+}: SwitchProps) {
+  const [isChecked, setIsChecked] = useState(checked)
+
+  const handleToggle = () => {
+    if (disabled) return
+    
+    const newValue = !isChecked
+    setIsChecked(newValue)
+    onChange?.(newValue)
+  }
+
+  const sizes = {
+    sm: {
+      track: 'w-10 h-5',
+      thumb: 'w-4 h-4',
+      translate: 'translate-x-5',
+    },
+    md: {
+      track: 'w-12 h-6',
+      thumb: 'w-5 h-5',
+      translate: 'translate-x-6',
+    },
+    lg: {
+      track: 'w-14 h-7',
+      thumb: 'w-6 h-6',
+      translate: 'translate-x-7',
+    },
+  }
+
+  const currentSize = sizes[size]
+
+  return (
+    <View
+      className={cn(
+        'relative inline-flex items-center rounded-full cursor-pointer transition-colors duration-200 ease-in-out',
+        currentSize.track,
+        isChecked ? '' : 'bg-gray-300',
+        disabled && 'opacity-50 cursor-not-allowed',
+        className,
+      )}
+      style={{
+        backgroundColor: isChecked ? color : undefined,
+      }}
+      onClick={handleToggle}
+      hoverClass={disabled ? '' : 'opacity-80'}
+    >
+      <View
+        className={cn(
+          'absolute left-1 bg-white rounded-full shadow-lg transition-transform duration-200 ease-in-out',
+          currentSize.thumb,
+          isChecked ? currentSize.translate : '',
+        )}
+      />
+    </View>
+  )
+}

+ 2 - 1
mini/src/pages/address-edit/index.tsx

@@ -12,6 +12,7 @@ import { Card } from '@/components/ui/card'
 import { Button } from '@/components/ui/button'
 import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from '@/components/ui/form'
 import { Input } from '@/components/ui/input'
+import { Switch } from '@/components/ui/switch'
 import { useAuth } from '@/utils/auth'
 import { CitySelector } from '@/components/ui/city-selector'
 
@@ -221,7 +222,7 @@ export default function AddressEditPage() {
                         <View className="flex items-center justify-between">
                           <FormLabel>设为默认地址</FormLabel>
                           <FormControl>
-                            <switch
+                            <Switch
                               checked={field.value}
                               onChange={field.onChange}
                               color="#1976D2"