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