This commit is contained in:
oneao committed 2026-01-25 22:18:27 +08:00
1 parent 500fab7a80
commit 8f3f6982db
54 files changed
+2076 -1877

No files matched your search

@@ -1,15 +1,13 @@
import type { icons } from 'lucide-react-native'
import type { ViewStyle } from 'react-native'
import type { LucideIconProps } from './LucideIcon'
import React from 'react'
import { View } from 'react-native'
import {
ButtonSpinner,
ButtonText,
Button as NativeButton,
} from '@/components/ui/button'
import LucideIcon from './LucideIcon'
type IconProp = (LucideIconProps & { icon: keyof typeof icons }) | React.ReactNode
type IconProp = React.ReactNode | (() => React.ReactNode)
interface CustomButtonProps {
children?: React.ReactNode
@@ -21,7 +19,6 @@ interface CustomButtonProps {
action?: 'primary' | 'secondary' | 'positive' | 'negative' | 'default'
variant?: 'solid' | 'outline' | 'link'
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
leftIcon?: IconProp
rightIcon?: IconProp
}
@@ -41,31 +38,39 @@ const Button: React.FC<CustomButtonProps> = ({
}) => {
const isDisabled = disabled || loading
const hasChildren = !!children
const renderLeftIcon = () => {
if (loading)
return <ButtonSpinner color="#fff" className={hasChildren ? 'mr-2' : ''} />
if (!leftIcon)
const renderIcon = (
icon?: IconProp,
position: 'left' | 'right' = 'left',
) => {
if (!icon)
return null
if (React.isValidElement(leftIcon)) {
return <span className={hasChildren ? 'mr-2' : ''}>{leftIcon}</span>
if (loading && position === 'left') {
const spinnerColor = variant === 'outline'
? 'rgba(0,0,0,0.6)'
: 'rgba(255,255,255,0.9)'
return (
<View className={hasChildren ? 'mr-2' : undefined}>
<ButtonSpinner color={spinnerColor} />
</View>
)
}
const { icon, ...props } = leftIcon as LucideIconProps & { icon: keyof typeof icons }
return <LucideIcon icon={icon} className={hasChildren ? 'mr-2' : ''} {...props} />
}
const node = typeof icon === 'function'
? icon()
: icon
const renderRightIcon = () => {
if (!rightIcon)
return null
if (React.isValidElement(rightIcon)) {
return <span className={hasChildren ? 'ml-2' : ''}>{rightIcon}</span>
}
const { icon, ...props } = rightIcon as LucideIconProps & { icon: keyof typeof icons }
return <LucideIcon icon={icon} className={hasChildren ? 'ml-2' : ''} {...props} />
return (
<View className={hasChildren
? position === 'left'
? 'mr-2'
: 'ml-2'
: undefined}
>
{node}
</View>
)
}
return (
@@ -78,13 +83,9 @@ const Button: React.FC<CustomButtonProps> = ({
variant={variant}
size={size}
>
{renderLeftIcon()}
{
children && (
<ButtonText>{children}</ButtonText>
)
}
{renderRightIcon()}
{renderIcon(leftIcon, 'left')}
{children && <ButtonText>{children}</ButtonText>}
{renderIcon(rightIcon, 'right')}
</NativeButton>
)
}
@@ -11,33 +11,36 @@ import { CheckIcon } from '@/components/ui/icon'
interface CustomCheckboxProps {
value?: string
isChecked: boolean
onChange: (checked: boolean) => void
label: React.ReactNode
checked?: boolean
onChange?: (checked: boolean) => void
label?: React.ReactNode
className?: string
style?: ViewStyle
disabled?: boolean
icon?: React.ElementType
size?: 'sm' | 'md' | 'lg'
}
const Checkbox: React.FC<CustomCheckboxProps> = ({
value,
isChecked,
checked,
onChange,
label,
className,
style,
disabled,
icon,
size,
}) => {
return (
<NativeCheckbox
value={value ?? ''} // 避免 undefined
isChecked={isChecked}
value={value ?? ''}
isChecked={checked}
onChange={onChange}
className={className}
style={style}
isDisabled={disabled}
size={size}
>
<CheckboxIndicator>
<CheckboxIcon as={icon ?? CheckIcon} />