/* eslint-disable react-native/no-inline-styles */ import React, { ComponentProps, memo, ReactNode } from 'react'; import { Stack, useSpacing } from '@mobily/stacks'; import { ViewStyle, StyleProp, View, AccessibilityProps } from 'react-native'; import { TouchableRipple } from 'react-native-paper'; import BoxNucleon, { BoxNucleonProps } from './nucleons/BoxNucleon'; import TextRoleNucleon from './nucleons/TextRoleNucleon'; import contentWidthContextNucleon from './nucleons/contentWidthContextNucleon'; import { useNuclearContentWidth } from './nucleons/useContentWidthContext'; import IconNucleon, { IconName, IconNucleonProps } from './nucleons/IconNucleon'; import GestureHandlerAdapterNucleon from './nucleons/GestureHandlerAdapterNucleon'; import { useColorRoles } from '../theme/colorSystem'; export interface UITideAtomProps extends AccessibilityProps { style?: StyleProp; title: string; align?: 'left' | 'right'; leftIconName?: IconName; rightIconName?: IconName; active?: boolean; right?: ReactNode | (({ width }: { width: number }) => ReactNode); bottom?: ReactNode | (() => ReactNode); onPress?: ComponentProps['onPress']; } const ICON_SIZE = 25; const RIGHT_WIDTH = 60; const COMPONENT_PADDING = 2; const INLINE_SPACING = 2; function ConditionalTouchable({ children, onPress, ...other }: any) { const { pressable } = useColorRoles(); return onPress ? ( {children} ) : ( <>{children} ); } function LefIcon({ color, name, ...nucProps }: Pick & BoxNucleonProps) { return ( ); } function Right({ right, rightIconName, color, ...nucProps }: Pick & BoxNucleonProps & { color: string }) { return ( {typeof right === 'function' ? right({ width: RIGHT_WIDTH }) : right || (rightIconName ? ( ) : null)} ); } function Title({ title, color }: { color: string; title: string }) { return ( {title} ); } function CenterBottom({ availableWidth, bottom }: { availableWidth: number; bottom: UITideAtomProps['bottom']; }) { return ( {typeof bottom === 'function' ? bottom() : bottom} ); } const UITideAtom = memo(function UITideAtom({ style, title, leftIconName, right, bottom, onPress, rightIconName, active, align = 'left', ...accessibilityProps }: UITideAtomProps) { const isSelectable = typeof active === 'boolean'; const { pressable, selectable, softIconColor } = useColorRoles(); const displayRight = !!(right || rightIconName); const displayBottom = !!bottom; const displayLeft = !!leftIconName; const inlineSpaces = Number(displayRight) + Number(displayLeft); const hzSpace = useSpacing( (COMPONENT_PADDING + INLINE_SPACING * inlineSpaces) * 2 ); const backgroundColor = isSelectable ? active && onPress ? selectable.activeBackground : selectable.inactiveBackground : pressable.background; const contentColor = isSelectable ? active ? selectable.activeTint : selectable.inactiveTint : pressable.tint; const iconColor = isSelectable && active ? selectable.activeTint : softIconColor; const middleWidth = useNuclearContentWidth() - ICON_SIZE * Number(displayLeft) - hzSpace - Number(displayRight) * RIGHT_WIDTH; return ( {displayLeft && ( )} {displayBottom && ( <CenterBottom availableWidth={middleWidth} bottom={bottom} /> )} </Stack> {displayRight && ( <Right marginLeft={INLINE_SPACING} right={right} rightIconName={rightIconName} color={iconColor} /> )} </View> </ConditionalTouchable> </View> ); }); UITideAtom.displayName = 'MemoizedUITideAtom'; export default UITideAtom;