parent
f78b3f2c16
commit
256b222d69
@ -0,0 +1,19 @@ |
||||
import React from 'react'; |
||||
import { View, ViewProps } from 'react-native'; |
||||
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils'; |
||||
import { boxStyle } from './styles'; |
||||
|
||||
type IBoxProps = ViewProps & |
||||
VariantProps<typeof boxStyle> & { className?: string }; |
||||
|
||||
const Box = React.forwardRef<React.ComponentRef<typeof View>, IBoxProps>( |
||||
function Box({ className, ...props }, ref) { |
||||
return ( |
||||
<View ref={ref} {...props} className={boxStyle({ class: className })} /> |
||||
); |
||||
} |
||||
); |
||||
|
||||
Box.displayName = 'Box'; |
||||
export { Box }; |
@ -0,0 +1,19 @@ |
||||
import React from 'react'; |
||||
import { boxStyle } from './styles'; |
||||
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils'; |
||||
|
||||
type IBoxProps = React.ComponentPropsWithoutRef<'div'> & |
||||
VariantProps<typeof boxStyle> & { className?: string }; |
||||
|
||||
const Box = React.forwardRef<HTMLDivElement, IBoxProps>(function Box( |
||||
{ className, ...props }, |
||||
ref |
||||
) { |
||||
return ( |
||||
<div ref={ref} className={boxStyle({ class: className })} {...props} /> |
||||
); |
||||
}); |
||||
|
||||
Box.displayName = 'Box'; |
||||
export { Box }; |
@ -0,0 +1,10 @@ |
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils'; |
||||
import { isWeb } from '@gluestack-ui/utils/nativewind-utils'; |
||||
|
||||
const baseStyle = isWeb |
||||
? 'flex flex-col relative z-0 box-border border-0 list-none min-w-0 min-h-0 bg-transparent items-stretch m-0 p-0 text-decoration-none' |
||||
: ''; |
||||
|
||||
export const boxStyle = tva({ |
||||
base: baseStyle, |
||||
}); |
@ -0,0 +1,39 @@ |
||||
'use client'; |
||||
import React from 'react'; |
||||
import { createPressable } from '@gluestack-ui/core/pressable/creator'; |
||||
import { Pressable as RNPressable } from 'react-native'; |
||||
|
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils'; |
||||
import { withStyleContext } from '@gluestack-ui/utils/nativewind-utils'; |
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils'; |
||||
|
||||
const UIPressable = createPressable({ |
||||
Root: withStyleContext(RNPressable), |
||||
}); |
||||
|
||||
const pressableStyle = tva({ |
||||
base: 'data-[focus-visible=true]:outline-none data-[focus-visible=true]:ring-indicator-info data-[focus-visible=true]:ring-2 data-[disabled=true]:opacity-40', |
||||
}); |
||||
|
||||
type IPressableProps = Omit< |
||||
React.ComponentProps<typeof UIPressable>, |
||||
'context' |
||||
> & |
||||
VariantProps<typeof pressableStyle>; |
||||
const Pressable = React.forwardRef< |
||||
React.ComponentRef<typeof UIPressable>, |
||||
IPressableProps |
||||
>(function Pressable({ className, ...props }, ref) { |
||||
return ( |
||||
<UIPressable |
||||
{...props} |
||||
ref={ref} |
||||
className={pressableStyle({ |
||||
class: className, |
||||
})} |
||||
/> |
||||
); |
||||
}); |
||||
|
||||
Pressable.displayName = 'Pressable'; |
||||
export { Pressable }; |
@ -0,0 +1,240 @@ |
||||
'use client'; |
||||
import React from 'react'; |
||||
import { createToastHook } from '@gluestack-ui/core/toast/creator'; |
||||
import { AccessibilityInfo, Text, View, ViewStyle } from 'react-native'; |
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils'; |
||||
import { cssInterop } from 'nativewind'; |
||||
import { |
||||
Motion, |
||||
AnimatePresence, |
||||
MotionComponentProps, |
||||
} from '@legendapp/motion'; |
||||
import { |
||||
withStyleContext, |
||||
useStyleContext, |
||||
} from '@gluestack-ui/utils/nativewind-utils'; |
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils'; |
||||
|
||||
type IMotionViewProps = React.ComponentProps<typeof View> & |
||||
MotionComponentProps<typeof View, ViewStyle, unknown, unknown, unknown>; |
||||
|
||||
const MotionView = Motion.View as React.ComponentType<IMotionViewProps>; |
||||
|
||||
const useToast = createToastHook(MotionView, AnimatePresence); |
||||
const SCOPE = 'TOAST'; |
||||
|
||||
cssInterop(MotionView, { className: 'style' }); |
||||
|
||||
const toastStyle = tva({ |
||||
base: 'p-4 m-1 rounded-md gap-1 web:pointer-events-auto shadow-hard-5 border-outline-100', |
||||
variants: { |
||||
action: { |
||||
error: 'bg-error-800', |
||||
warning: 'bg-warning-700', |
||||
success: 'bg-success-700', |
||||
info: 'bg-info-700', |
||||
muted: 'bg-background-800', |
||||
}, |
||||
|
||||
variant: { |
||||
solid: '', |
||||
outline: 'border bg-background-0', |
||||
}, |
||||
}, |
||||
}); |
||||
|
||||
const toastTitleStyle = tva({ |
||||
base: 'text-typography-0 font-medium font-body tracking-md text-left', |
||||
variants: { |
||||
isTruncated: { |
||||
true: '', |
||||
}, |
||||
bold: { |
||||
true: 'font-bold', |
||||
}, |
||||
underline: { |
||||
true: 'underline', |
||||
}, |
||||
strikeThrough: { |
||||
true: 'line-through', |
||||
}, |
||||
size: { |
||||
'2xs': 'text-2xs', |
||||
'xs': 'text-xs', |
||||
'sm': 'text-sm', |
||||
'md': 'text-base', |
||||
'lg': 'text-lg', |
||||
'xl': 'text-xl', |
||||
'2xl': 'text-2xl', |
||||
'3xl': 'text-3xl', |
||||
'4xl': 'text-4xl', |
||||
'5xl': 'text-5xl', |
||||
'6xl': 'text-6xl', |
||||
}, |
||||
}, |
||||
parentVariants: { |
||||
variant: { |
||||
solid: '', |
||||
outline: '', |
||||
}, |
||||
action: { |
||||
error: '', |
||||
warning: '', |
||||
success: '', |
||||
info: '', |
||||
muted: '', |
||||
}, |
||||
}, |
||||
parentCompoundVariants: [ |
||||
{ |
||||
variant: 'outline', |
||||
action: 'error', |
||||
class: 'text-error-800', |
||||
}, |
||||
{ |
||||
variant: 'outline', |
||||
action: 'warning', |
||||
class: 'text-warning-800', |
||||
}, |
||||
{ |
||||
variant: 'outline', |
||||
action: 'success', |
||||
class: 'text-success-800', |
||||
}, |
||||
{ |
||||
variant: 'outline', |
||||
action: 'info', |
||||
class: 'text-info-800', |
||||
}, |
||||
{ |
||||
variant: 'outline', |
||||
action: 'muted', |
||||
class: 'text-background-800', |
||||
}, |
||||
], |
||||
}); |
||||
|
||||
const toastDescriptionStyle = tva({ |
||||
base: 'font-normal font-body tracking-md text-left', |
||||
variants: { |
||||
isTruncated: { |
||||
true: '', |
||||
}, |
||||
bold: { |
||||
true: 'font-bold', |
||||
}, |
||||
underline: { |
||||
true: 'underline', |
||||
}, |
||||
strikeThrough: { |
||||
true: 'line-through', |
||||
}, |
||||
size: { |
||||
'2xs': 'text-2xs', |
||||
'xs': 'text-xs', |
||||
'sm': 'text-sm', |
||||
'md': 'text-base', |
||||
'lg': 'text-lg', |
||||
'xl': 'text-xl', |
||||
'2xl': 'text-2xl', |
||||
'3xl': 'text-3xl', |
||||
'4xl': 'text-4xl', |
||||
'5xl': 'text-5xl', |
||||
'6xl': 'text-6xl', |
||||
}, |
||||
}, |
||||
parentVariants: { |
||||
variant: { |
||||
solid: 'text-typography-50', |
||||
outline: 'text-typography-900', |
||||
}, |
||||
}, |
||||
}); |
||||
|
||||
const Root = withStyleContext(View, SCOPE); |
||||
type IToastProps = React.ComponentProps<typeof Root> & { |
||||
className?: string; |
||||
} & VariantProps<typeof toastStyle>; |
||||
|
||||
const Toast = React.forwardRef<React.ComponentRef<typeof Root>, IToastProps>( |
||||
function Toast( |
||||
{ className, variant = 'solid', action = 'muted', ...props }, |
||||
ref |
||||
) { |
||||
return ( |
||||
<Root |
||||
ref={ref} |
||||
className={toastStyle({ variant, action, class: className })} |
||||
context={{ variant, action }} |
||||
{...props} |
||||
/> |
||||
); |
||||
} |
||||
); |
||||
|
||||
type IToastTitleProps = React.ComponentProps<typeof Text> & { |
||||
className?: string; |
||||
} & VariantProps<typeof toastTitleStyle>; |
||||
|
||||
const ToastTitle = React.forwardRef< |
||||
React.ComponentRef<typeof Text>, |
||||
IToastTitleProps |
||||
>(function ToastTitle({ className, size = 'md', children, ...props }, ref) { |
||||
const { variant: parentVariant, action: parentAction } = |
||||
useStyleContext(SCOPE); |
||||
React.useEffect(() => { |
||||
// Issue from react-native side
|
||||
// Hack for now, will fix this later
|
||||
AccessibilityInfo.announceForAccessibility(children as string); |
||||
}, [children]); |
||||
|
||||
return ( |
||||
<Text |
||||
{...props} |
||||
ref={ref} |
||||
aria-live="assertive" |
||||
aria-atomic="true" |
||||
role="alert" |
||||
className={toastTitleStyle({ |
||||
size, |
||||
class: className, |
||||
parentVariants: { |
||||
variant: parentVariant, |
||||
action: parentAction, |
||||
}, |
||||
})} |
||||
> |
||||
{children} |
||||
</Text> |
||||
); |
||||
}); |
||||
|
||||
type IToastDescriptionProps = React.ComponentProps<typeof Text> & { |
||||
className?: string; |
||||
} & VariantProps<typeof toastDescriptionStyle>; |
||||
|
||||
const ToastDescription = React.forwardRef< |
||||
React.ComponentRef<typeof Text>, |
||||
IToastDescriptionProps |
||||
>(function ToastDescription({ className, size = 'md', ...props }, ref) { |
||||
const { variant: parentVariant } = useStyleContext(SCOPE); |
||||
return ( |
||||
<Text |
||||
ref={ref} |
||||
{...props} |
||||
className={toastDescriptionStyle({ |
||||
size, |
||||
class: className, |
||||
parentVariants: { |
||||
variant: parentVariant, |
||||
}, |
||||
})} |
||||
/> |
||||
); |
||||
}); |
||||
|
||||
Toast.displayName = 'Toast'; |
||||
ToastTitle.displayName = 'ToastTitle'; |
||||
ToastDescription.displayName = 'ToastDescription'; |
||||
|
||||
export { useToast, Toast, ToastTitle, ToastDescription }; |
Loading…
Reference in new issue