eletrotupi / tcc/ frontend/components/ui/Sections.tsx32f2f039f05dad64bc0e752c2b571e606c991d7e
2.6 KB | 112 lines Raw
1
import React from 'react';
2
import {
3
  View,
4
  StyleSheet,
5
  Pressable,
6
  ViewStyle,
7
} from 'react-native';
8
import { ThemedText } from '@/components/misc/themed-text'
9
import { Row, Between } from '@/components/ui/LayoutHelpers';
10

11
import { Colors, Typography, Spacing, BorderRadius } from '@/constants/theme';
12
import { useThemeColor } from '@/hooks/use-theme-color';
13

14
interface SectionProps {
15
  children: React.ReactNode;
16
  style?: ViewStyle;
17
}
18

19
export const Section: React.FC<SectionProps> = ({ children, style }) => {
20
  const styles = StyleSheet.create({
21
    section: {
22
      marginBottom: Spacing.sectionGap,
23
    },
24
  });
25
  return <View style={[styles.section, style]}>{children}</View>;
26
};
27

28
interface SectionHeaderProps {
29
  title: string;
30
  subtitle?: string;
31
  actionLabel?: string;
32
  onActionPress?: () => void;
33
  style?: ViewStyle;
34
}
35

36
// XXX: A Section must either have a label as a pill/informative thing
37
// or it should be a link
38
export const SectionHeader: React.FC<SectionHeaderProps> = ({
39
  title,
40
  subtitle,
41
  info,
42
  actionLabel,
43
  onActionPress,
44
  style,
45
}) => {
46
  const textColor = useThemeColor({}, 'text');
47
  const tintColor = useThemeColor({}, 'tint');
48
  const textSecondaryColor = useThemeColor({}, 'textSecondary')
49

50
  const styles = StyleSheet.create({
51
    headerContainer: {
52
      marginBottom: (Spacing.cardGap * 2),
53
    },
54
    title: {
55
      fontSize: Typography.headlineMd.fontSize,
56
      fontWeight: Typography.headlineMd.fontWeight,
57
      color: textColor,
58
    },
59
    subtitle: {
60
      fontSize: 14,
61
      color: textSecondaryColor,
62
      lineHeight: 20,
63
      marginTop: 4
64
    },
65
    actionButton: {
66
      padding: 4,
67
    },
68
    actionText: {
69
      fontSize: Typography.bodyMd.fontSize,
70
      fontWeight: '600',
71
      color: tintColor,
72
    },
73
  });
74

75
  // TODO: Rework these when we finally have chips/badges
76
  return (
77
    <View style={[styles.headerContainer, style]}>
78
      <Between>
79
        <ThemedText style={styles.title}>
80
          {title}
81
        </ThemedText>
82

83
        {info && !actionLabel && (
84
          <ThemedText>
85
            {info}
86
          </ThemedText>
87
        )}
88

89
        {actionLabel && !info && onActionPress && (
90
          <Pressable
91
            style={styles.actionButton}
92
            onPress={onActionPress}
93
            hitSlop={8}
94
          >
95
            <ThemedText style={styles.actionText}>
96
              {actionLabel}
97
            </ThemedText>
98
          </Pressable>
99
        )}
100
      </Between>
101

102
      {subtitle && (
103
        <Row>
104
          <ThemedText style={styles.subtitle}>
105
            {subtitle}
106
          </ThemedText>
107
        </Row>
108
      )}
109
    </View>
110
  );
111
};
112