This commit is contained in:
oneao committed 2026-02-27 17:29:28 +08:00
1 parent 1903861354
commit 1b1a54f7dd
35 files changed
+1185 -535

No files matched your search

@@ -39,14 +39,9 @@ const Button: React.FC<CustomButtonProps> = ({
const isDisabled = disabled || loading
const hasChildren = !!children
const renderIcon = (
icon?: IconProp,
position: 'left' | 'right' = 'left',
) => {
if (!icon)
return null
if (loading && position === 'left') {
const renderLeftIcon = () => {
// 左侧 loading
if (loading) {
const spinnerColor = variant === 'outline'
? 'rgba(0,0,0,0.6)'
: 'rgba(255,255,255,0.9)'
@@ -57,17 +52,25 @@ const Button: React.FC<CustomButtonProps> = ({
)
}
const node = typeof icon === 'function'
? icon()
: icon
// 左侧 icon
if (!leftIcon)
return null
const node = typeof leftIcon === 'function' ? leftIcon() : leftIcon
return (
<View className={hasChildren
? position === 'left'
? 'mr-2'
: 'ml-2'
: undefined}
>
<View className={hasChildren ? 'mr-1' : undefined}>
{node}
</View>
)
}
const renderRightIcon = () => {
if (!rightIcon)
return null
const node = typeof rightIcon === 'function' ? rightIcon() : rightIcon
return (
<View className={hasChildren ? 'ml-1' : undefined}>
{node}
</View>
)
@@ -83,9 +86,9 @@ const Button: React.FC<CustomButtonProps> = ({
variant={variant}
size={size}
>
{renderIcon(leftIcon, 'left')}
{renderLeftIcon()}
{children && <ButtonText>{children}</ButtonText>}
{renderIcon(rightIcon, 'right')}
{renderRightIcon()}
</NativeButton>
)
}
@@ -1,7 +1,8 @@
import type { ViewStyle } from 'react-native'
import { useState } from 'react'
import { Text } from 'react-native'
import { Heading } from '@/components/ui/heading'
import { CloseIcon, Icon } from '@/components/ui/icon'
import {
Modal,
ModalBackdrop,
@@ -19,7 +20,7 @@ interface AModalProps {
body?: string | React.ReactNode
footer?: React.ReactNode
onClose?: () => void
onConfirm?: () => void
onConfirm?: () => Promise<void> | void
onCancel?: () => void
showBackdrop?: boolean
showCloseIcon?: boolean
@@ -41,6 +42,29 @@ export default function AModal({
className,
style,
}: AModalProps) {
const [innerLoading, setInnerLoading] = useState(false)
const handleConfirm = () => {
if (!onConfirm || innerLoading)
return
try {
const result = onConfirm()
// 只有当返回的是 Promise 才开启 loading
if (result && typeof (result as Promise<void>).then === 'function') {
setInnerLoading(true)
result.finally(() => {
setInnerLoading(false)
})
}
}
catch (error) {
console.error(error)
}
}
return (
<Modal
isOpen={isOpen}
@@ -55,7 +79,7 @@ export default function AModal({
}}
>
<ModalHeader>
{title && (typeof title === 'string' ? <Text>{title}</Text> : title)}
{title && (typeof title === 'string' ? <Heading>{title}</Heading> : title)}
{
showCloseIcon && (
<ModalCloseButton>
@@ -76,11 +100,14 @@ export default function AModal({
action="secondary"
className="mr-3"
onPress={onClose}
size="sm"
>
取消
</AButton>
<AButton
onPress={onConfirm}
onPress={handleConfirm}
size="sm"
loading={innerLoading}
>
确认
</AButton>
@@ -1,26 +1,28 @@
import React, { useEffect } from 'react';
import { config } from './config';
import { View, ViewProps } from 'react-native';
import { OverlayProvider } from '@gluestack-ui/core/overlay/creator';
import { ToastProvider } from '@gluestack-ui/core/toast/creator';
import { useColorScheme } from 'nativewind';
import type { ViewProps } from 'react-native'
import { OverlayProvider } from '@gluestack-ui/core/overlay/creator'
import { ToastProvider } from '@gluestack-ui/core/toast/creator'
import { useColorScheme } from 'nativewind'
import React, { useEffect } from 'react'
import { View } from 'react-native'
import { Toaster } from 'sonner-native'
import { config } from './config'
export type ModeType = 'light' | 'dark' | 'system';
export type ModeType = 'light' | 'dark' | 'system'
export function GluestackUIProvider({
mode = 'light',
...props
}: {
mode?: ModeType;
children?: React.ReactNode;
style?: ViewProps['style'];
mode?: ModeType
children?: React.ReactNode
style?: ViewProps['style']
}) {
const { colorScheme, setColorScheme } = useColorScheme();
const { colorScheme, setColorScheme } = useColorScheme()
useEffect(() => {
setColorScheme(mode);
setColorScheme(mode)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [mode]);
}, [mode])
return (
<View
@@ -34,5 +36,5 @@ export function GluestackUIProvider({
<ToastProvider>{props.children}</ToastProvider>
</OverlayProvider>
</View>
);
)
}