eletrotupi / tcc/ commit / 41f25ec

frontend: add filter pills component

Pedro Lucas Porcellis porcellis@eletrotupi.com · 5 months ago 41f25ece6046650157c93068eda9b67ae26c8aaf Browse files
Parents 27c3a09
Changed files
1
Additions
+111
Deletions
0
/dev/null → frontend/components/ui/FilterPills.tsx
1 +
import { useRef } from 'react';
2 +
import {
3 +
  ScrollView,
4 +
  TouchableOpacity,
5 +
  Text,
6 +
  View,
7 +
  StyleSheet,
8 +
  Platform,
9 +
} from 'react-native';
10 +
import { LinearGradient } from 'expo-linear-gradient';
11 +
import type { HistoryCategory } from '@/lib/history/types';
12 +
import { Colors } from '@/constants/theme';
13 +

14 +
export type FilterOption = {
15 +
  label: string
16 +
  value: HistoryCategory | 'all'
17 +
};
18 +

19 +
export const HISTORY_FILTERS: FilterOption[] = [
20 +
  { label: 'Tudo',         value: 'all'          },
21 +
  { label: 'Humor',        value: 'mood'         },
22 +
  { label: 'Sono',         value: 'sleep'        }
23 +
];
24 +

25 +
type Props = {
26 +
  active: HistoryCategory | 'all'
27 +
  onChange: (value: HistoryCategory | 'all') => void
28 +
};
29 +

30 +
export function FilterPills({ active, onChange }: Props) {
31 +
  const scrollRef = useRef<ScrollView>(null);
32 +

33 +
  return (
34 +
    <View style={styles.wrapper}>
35 +
      <ScrollView
36 +
        ref={scrollRef}
37 +
        horizontal
38 +
        showsHorizontalScrollIndicator={false}
39 +
        contentContainerStyle={styles.scrollContent}
40 +
      >
41 +
        {HISTORY_FILTERS.map((filter) => {
42 +
          const isActive = filter.value === active
43 +
          return (
44 +
            <TouchableOpacity
45 +
              key={filter.value}
46 +
              onPress={() => onChange(filter.value)}
47 +
              activeOpacity={0.7}
48 +
              style={[styles.pill, isActive && styles.pillActive]}
49 +
            >
50 +
              <Text style={[styles.label, isActive && styles.labelActive]}>
51 +
                {filter.label}
52 +
              </Text>
53 +
            </TouchableOpacity>
54 +
          )
55 +
        })}
56 +
      </ScrollView>
57 +

58 +
      {/*
59 +
        TODO: needs a new build, probably
60 +
        <LinearGradient
61 +
          colors={['transparent', 'rgba(255,255,255,0.95)']}
62 +
          start={{ x: 0, y: 0 }}
63 +
          end={{ x: 1, y: 0 }}
64 +
          style={styles.fadeRight}
65 +
          pointerEvents="none"
66 +
        />
67 +
      */}
68 +
    </View>
69 +
  )
70 +
}
71 +

72 +
const styles = StyleSheet.create({
73 +
  wrapper: {
74 +
    position: 'relative',
75 +
  },
76 +
  scrollContent: {
77 +
    paddingHorizontal: 16,
78 +
    paddingVertical: 12,
79 +
    gap: 8,
80 +
    flexDirection: 'row',
81 +
  },
82 +
  pill: {
83 +
    paddingHorizontal: 16,
84 +
    paddingVertical: 7,
85 +
    borderRadius: 999,
86 +
    backgroundColor: '#F2F2F7',
87 +
    borderWidth: 1,
88 +
    borderColor: 'transparent',
89 +
    elevation: 1
90 +
  },
91 +
  pillActive: {
92 +
    backgroundColor: Colors.light.tint,
93 +
    borderColor: Colors.light.tint,
94 +
  },
95 +
  label: {
96 +
    fontSize: 14,
97 +
    fontWeight: '500',
98 +
    color: '#3C3C43',
99 +
    letterSpacing: -0.1,
100 +
  },
101 +
  labelActive: {
102 +
    color: Colors.light.text
103 +
  },
104 +
  fadeRight: {
105 +
    position: 'absolute',
106 +
    right: 0,
107 +
    top: 0,
108 +
    bottom: 0,
109 +
    width: 48,
110 +
  },
111 +
});