/** * Copyright (c) Paymium. * * This source code is licensed under the MIT license found in the * LICENSE file in the root of this projects source tree. */ import { Pressable, PressableProps, View, type ViewProps } from 'react-native'; import { composeStyles, createStyles, type CrossedMethods, } from '@crossed/styled'; import { forwardRef, PropsWithChildren, useCallback, useMemo } from 'react'; import { baseStyle } from '../styles/base'; import { gapStyles } from '../styles/gap'; import { justifyContentStyle } from '../styles/justifyContent'; import { alignItemsStyle, alignSelfStyle } from '../styles/alignItems'; const styleBox = createStyles( () => ({ root: { base: { display: 'flex' }, web: { base: { boxSizing: 'border-box' } }, }, center: { base: { alignItems: 'center', justifyContent: 'center' }, }, }) as const ); type Base = { /** * extends style */ style?: CrossedMethods; /** * Gap between children * if null, disable gap */ space?: null | keyof typeof gapStyles; /** * Center content * @default false */ center?: boolean; /** * Set justify-content style */ justifyContent?: keyof typeof justifyContentStyle; /** * Set align-items style */ alignItems?: keyof typeof alignItemsStyle; /** * Set align-self style */ alignSelf?: keyof typeof alignSelfStyle; }; export type BoxPressableProps = PropsWithChildren<{ pressable: true; }> & Base & Omit & React.RefAttributes; export type BoxViewProps = { pressable?: never | false; } & Base & Omit & React.RefAttributes; /** * Represents the properties for a Box component. */ export type BoxProps = BoxViewProps | BoxPressableProps; type BoxComponent = React.ForwardRefExoticComponent< BoxViewProps | BoxPressableProps >; export const Box: BoxComponent = forwardRef( ( { style, space, center, justifyContent, alignItems, alignSelf, pressable, ...props }, ref ) => { const styles = useMemo(() => { return composeStyles( baseStyle.view, styleBox.root, justifyContentStyle[justifyContent], alignItemsStyle[alignItems], alignSelfStyle[alignSelf], center === true && styleBox.center, gapStyles[space], style ); }, [center, style, alignSelf, alignItems, justifyContent, space]); const handleStyles = useCallback( ({ pressed, hovered, focused }) => { return styles.rnw({ active: pressed, hover: hovered, focus: focused, }).style; }, [styles] ); const Comp = useMemo(() => { return pressable ? Pressable : View; }, [pressable]); return ( ); } );