feat : Badge et Chip

This commit is contained in:
Yaël Perret
2026-09-01 14:43:51 +02:00
parent 4c74a27f57
commit 5a865d5635
3 changed files with 457 additions and 1 deletions

View File

@@ -1,14 +1,22 @@
import { ArrowUp, ArrowUpRight, Plus } from 'lucide-react-native';
import { useCallback } from 'react';
import { useCallback, useMemo, useState } from 'react';
import { ScrollView, StyleSheet, Text, View } from 'react-native';
import { Badge } from '@/components/Badge';
import { Button } from '@/components/Button';
import { ThemeChip } from '@/components/ThemeChip';
import { useTheme } from '@/theme/useTheme';
import '../global.css';
export default function Index() {
const { colors, spacing, typography } = useTheme();
const [selectedThemes, setSelectedThemes] = useState<string[]>(['Soirée', 'Techno', 'Festival']);
const themeOptions = useMemo(
() => ['Soirée', 'Techno', 'Festival', 'Fête de jeunesse', 'Concert', 'Bal', 'Afterwork', 'Gratuit'],
[],
);
const simulateSubmit = useCallback(async () => {
await new Promise<void>((resolve) => {
@@ -16,6 +24,20 @@ export default function Index() {
});
}, []);
const handleThemeSelect = useCallback((value: string, nextSelected: boolean) => {
setSelectedThemes((prev) => {
if (nextSelected) {
if (prev.includes(value)) {
return prev;
}
return [...prev, value];
}
return prev.filter((theme) => theme !== value);
});
}, []);
return (
<View style={[styles.screen, { backgroundColor: colors.deepBackground }]}>
<ScrollView
@@ -102,6 +124,53 @@ export default function Index() {
<Text style={[styles.caption, typography.digits, { color: colors.textSecondary }]}>Icône / FAB</Text>
</View>
</View>
<View style={{ gap: spacing[12] }}>
<Text style={[typography.sectionLabel, { color: colors.textSecondary, letterSpacing: 1.1 }]}>BADGES</Text>
<View style={styles.badgeWrap}>
<Badge variant="verified" />
<Badge variant="free" />
<Badge variant="complete" />
<Badge variant="tonight" />
<Badge variant="pro" />
<Badge variant="draft" />
<Badge date={{ day: '04', month: 'sept' }} />
</View>
</View>
<View style={{ gap: spacing[12] }}>
<Text style={[typography.sectionLabel, { color: colors.textSecondary, letterSpacing: 1.1 }]}>CHIPS DE THÈME · CAPSULE 34 PX</Text>
<View style={styles.chipWrap}>
<ThemeChip label="Soirée" selected selectedVariant="gradient" showCross={false} />
<ThemeChip label="Festival" selected selectedVariant="accent" />
<ThemeChip label="Fête de jeunesse" />
<ThemeChip label="Concert" />
<ThemeChip label="Bal" />
<ThemeChip label="Techno" />
<ThemeChip label="Afterwork" />
<ThemeChip label="Gratuit" selected selectedVariant="accent" showRemoveIcon={false} />
</View>
</View>
<View style={{ gap: spacing[12] }}>
<Text style={[typography.sectionLabel, { color: colors.textSecondary, letterSpacing: 1.1 }]}>THÈMES · MULTI-SÉLECTION</Text>
<View style={styles.chipWrap}>
{themeOptions.map((theme) => {
const selected = selectedThemes.includes(theme);
return (
<ThemeChip
key={theme}
label={theme}
value={theme}
selected={selected}
selectedVariant={theme === 'Soirée' ? 'gradient' : 'accent'}
onSelect={handleThemeSelect}
/>
);
})}
</View>
</View>
</ScrollView>
</View>
);
@@ -134,4 +203,16 @@ const styles = StyleSheet.create({
alignSelf: 'center',
width: 140,
},
badgeWrap: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: 12,
alignItems: 'center',
},
chipWrap: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: 10,
alignItems: 'center',
},
});