All files / atoms/ListGroup/mobile ListGroup.native.tsx

95% Statements 19/20
81.25% Branches 39/48
100% Functions 4/4
95% Lines 19/20

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116          4x                                   98x 98x   98x   98x       98x 271x 178x   93x     98x                           271x               271x       271x           271x                   271x 3x 3x     271x                                                   4x      
import React, { ReactNode } from 'react';
import { View, Pressable, Text, GestureResponderEvent } from 'react-native';
import { ListGroupNativeProps } from '../ListGroup.types';
import { cn } from '@sb/libs/utils';
 
const ListGroup = React.forwardRef<View, ListGroupNativeProps>(
  (
    {
      variant,
      stripedColors,
      direction = 'vertical',
      hover = false,
      activeIndex,
      items,
      itemTemplate,
      onSelect,
      onClick,
      className,
      style,
      accessibilityLabel = 'List group',
    },
    ref
  ) => {
    const isStriped = variant === 'striped';
    const isBordered = variant === 'bordered';
 
    const containerBorderClass = isBordered ? 'border border-gray-200 rounded' : '';
 
    Iif (items === undefined || items === null || items.length === 0) {
      return null;
    }
 
    const renderItem = (item: object | ReactNode, index?: number): ReactNode => {
      if (React.isValidElement(item)) {
        return item;
      }
      return itemTemplate ? itemTemplate(item as object, index) : <Text>{item as string}</Text>;
    };
 
    return (
      <View
        ref={ref}
        className={cn(
          'flex w-full',
          direction === 'horizontal' ? 'flex-row' : 'flex-col',
          containerBorderClass
        )}
        style={style}
        accessibilityRole="list"
        accessibilityLabel={accessibilityLabel}
      >
        {items.map((item, index) => {
          const itemAccessibilityLabel =
            !React.isValidElement(item) &&
            typeof item === 'object' &&
            item !== null &&
            'ariaLabel' in item
              ? (item as { ariaLabel: string }).ariaLabel
              : undefined;
 
          const isActive =
            Array.isArray(activeIndex) && activeIndex.includes(index)
              ? true
              : activeIndex === index;
 
          const stripeClass = isStriped
            ? index! % 2 !== 0
              ? stripedColors?.odd || 'bg-tertiary'
              : stripedColors?.even || 'bg-primary'
            : 'bg-transparent';
 
          const borderClass = isBordered
            ? direction === 'horizontal'
              ? index! < items.length - 1
                ? 'border-r border-gray-200'
                : ''
              : index! < items.length - 1
                ? 'border-b border-gray-200'
                : ''
            : '';
 
          const handlePress = (event: GestureResponderEvent) => {
            onSelect?.(index);
            onClick?.(event, index);
          };
 
          return (
            <Pressable
              key={index}
              className={cn(
                'p-3',
                direction === 'horizontal' ? 'flex-1' : '',
                hover && 'opacity-80',
                stripeClass,
                borderClass,
                isActive && 'bg-accent text-text-main',
                className
              )}
              onPress={handlePress}
              accessibilityRole="button"
              accessibilityLabel={itemAccessibilityLabel}
              accessibilityState={{ selected: isActive }}
            >
              {renderItem(item, index)}
            </Pressable>
          );
        })}
      </View>
    );
  }
);
 
ListGroup.displayName = 'ListGroup';
 
export { ListGroup };