u
This commit is contained in:
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} />
|
||||
|
||||
@@ -1,24 +1,21 @@
|
||||
'use client';
|
||||
import React from 'react';
|
||||
import { createAvatar } from '@gluestack-ui/core/avatar/creator';
|
||||
'use client'
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils'
|
||||
import { createAvatar } from '@gluestack-ui/core/avatar/creator'
|
||||
|
||||
import { View, Text, Image, Platform } from 'react-native';
|
||||
import { tva, useStyleContext, withStyleContext } from '@gluestack-ui/utils/nativewind-utils'
|
||||
|
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import {
|
||||
withStyleContext,
|
||||
useStyleContext,
|
||||
} from '@gluestack-ui/utils/nativewind-utils';
|
||||
const SCOPE = 'AVATAR';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import React from 'react'
|
||||
import { Image, Platform, Text, View } from 'react-native'
|
||||
|
||||
const SCOPE = 'AVATAR'
|
||||
|
||||
const UIAvatar = createAvatar({
|
||||
Root: withStyleContext(View, SCOPE),
|
||||
Badge: View,
|
||||
Group: View,
|
||||
Image: Image,
|
||||
Image,
|
||||
FallbackText: Text,
|
||||
});
|
||||
})
|
||||
|
||||
const avatarStyle = tva({
|
||||
base: 'rounded-full justify-center items-center relative bg-primary-600 group-[.avatar-group]/avatar-group:-ml-2.5',
|
||||
@@ -32,7 +29,7 @@ const avatarStyle = tva({
|
||||
'2xl': 'w-32 h-32',
|
||||
},
|
||||
},
|
||||
});
|
||||
})
|
||||
|
||||
const avatarFallbackTextStyle = tva({
|
||||
base: 'text-typography-0 font-semibold overflow-hidden text-transform:uppercase web:cursor-default',
|
||||
@@ -47,11 +44,11 @@ const avatarFallbackTextStyle = tva({
|
||||
'2xl': 'text-5xl',
|
||||
},
|
||||
},
|
||||
});
|
||||
})
|
||||
|
||||
const avatarGroupStyle = tva({
|
||||
base: 'group/avatar-group flex-row-reverse relative avatar-group',
|
||||
});
|
||||
})
|
||||
|
||||
const avatarBadgeStyle = tva({
|
||||
base: 'w-5 h-5 bg-success-500 rounded-full absolute right-0 bottom-0 border-background-0 border-2',
|
||||
@@ -65,22 +62,22 @@ const avatarBadgeStyle = tva({
|
||||
'2xl': 'w-8 h-8',
|
||||
},
|
||||
},
|
||||
});
|
||||
})
|
||||
|
||||
const avatarImageStyle = tva({
|
||||
base: 'h-full w-full rounded-full absolute',
|
||||
});
|
||||
})
|
||||
|
||||
type IAvatarProps = Omit<
|
||||
React.ComponentPropsWithoutRef<typeof UIAvatar>,
|
||||
'context'
|
||||
> &
|
||||
VariantProps<typeof avatarStyle>;
|
||||
>
|
||||
& VariantProps<typeof avatarStyle>
|
||||
|
||||
const Avatar = React.forwardRef<
|
||||
React.ComponentRef<typeof UIAvatar>,
|
||||
IAvatarProps
|
||||
>(function Avatar({ className, size = 'md', ...props }, ref) {
|
||||
>(({ className, size = 'md', ...props }, ref) => {
|
||||
return (
|
||||
<UIAvatar
|
||||
ref={ref}
|
||||
@@ -88,17 +85,17 @@ const Avatar = React.forwardRef<
|
||||
className={avatarStyle({ size, class: className })}
|
||||
context={{ size }}
|
||||
/>
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
type IAvatarBadgeProps = React.ComponentPropsWithoutRef<typeof UIAvatar.Badge> &
|
||||
VariantProps<typeof avatarBadgeStyle>;
|
||||
type IAvatarBadgeProps = React.ComponentPropsWithoutRef<typeof UIAvatar.Badge>
|
||||
& VariantProps<typeof avatarBadgeStyle>
|
||||
|
||||
const AvatarBadge = React.forwardRef<
|
||||
React.ComponentRef<typeof UIAvatar.Badge>,
|
||||
IAvatarBadgeProps
|
||||
>(function AvatarBadge({ className, size, ...props }, ref) {
|
||||
const { size: parentSize } = useStyleContext(SCOPE);
|
||||
>(({ className, size, ...props }, ref) => {
|
||||
const { size: parentSize } = useStyleContext(SCOPE)
|
||||
|
||||
return (
|
||||
<UIAvatar.Badge
|
||||
@@ -112,18 +109,18 @@ const AvatarBadge = React.forwardRef<
|
||||
class: className,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
type IAvatarFallbackTextProps = React.ComponentPropsWithoutRef<
|
||||
typeof UIAvatar.FallbackText
|
||||
> &
|
||||
VariantProps<typeof avatarFallbackTextStyle>;
|
||||
>
|
||||
& VariantProps<typeof avatarFallbackTextStyle>
|
||||
const AvatarFallbackText = React.forwardRef<
|
||||
React.ComponentRef<typeof UIAvatar.FallbackText>,
|
||||
IAvatarFallbackTextProps
|
||||
>(function AvatarFallbackText({ className, size, ...props }, ref) {
|
||||
const { size: parentSize } = useStyleContext(SCOPE);
|
||||
>(({ className, size, ...props }, ref) => {
|
||||
const { size: parentSize } = useStyleContext(SCOPE)
|
||||
|
||||
return (
|
||||
<UIAvatar.FallbackText
|
||||
@@ -137,16 +134,16 @@ const AvatarFallbackText = React.forwardRef<
|
||||
class: className,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
type IAvatarImageProps = React.ComponentPropsWithoutRef<typeof UIAvatar.Image> &
|
||||
VariantProps<typeof avatarImageStyle>;
|
||||
type IAvatarImageProps = React.ComponentPropsWithoutRef<typeof UIAvatar.Image>
|
||||
& VariantProps<typeof avatarImageStyle>
|
||||
|
||||
const AvatarImage = React.forwardRef<
|
||||
React.ComponentRef<typeof UIAvatar.Image>,
|
||||
IAvatarImageProps
|
||||
>(function AvatarImage({ className, ...props }, ref) {
|
||||
>(({ className, ...props }, ref) => {
|
||||
return (
|
||||
<UIAvatar.Image
|
||||
ref={ref}
|
||||
@@ -161,16 +158,16 @@ const AvatarImage = React.forwardRef<
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
type IAvatarGroupProps = React.ComponentPropsWithoutRef<typeof UIAvatar.Group> &
|
||||
VariantProps<typeof avatarGroupStyle>;
|
||||
type IAvatarGroupProps = React.ComponentPropsWithoutRef<typeof UIAvatar.Group>
|
||||
& VariantProps<typeof avatarGroupStyle>
|
||||
|
||||
const AvatarGroup = React.forwardRef<
|
||||
React.ComponentRef<typeof UIAvatar.Group>,
|
||||
IAvatarGroupProps
|
||||
>(function AvatarGroup({ className, ...props }, ref) {
|
||||
>(({ className, ...props }, ref) => {
|
||||
return (
|
||||
<UIAvatar.Group
|
||||
ref={ref}
|
||||
@@ -179,7 +176,7 @@ const AvatarGroup = React.forwardRef<
|
||||
class: className,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
export { Avatar, AvatarBadge, AvatarFallbackText, AvatarImage, AvatarGroup };
|
||||
export { Avatar, AvatarBadge, AvatarFallbackText, AvatarGroup, AvatarImage }
|
||||
Reference in new issue
Block a user