import React, { useState } from 'react'; import { View, Text, ScrollView, StyleSheet, TouchableOpacity } from 'react-native'; import { Ux4gChoiceChip, Ux4gFilterChip, Ux4gInputChip, Ux4gChipGroup, Ux4gInputChipField, Ux4gInputChipSize, } from '../components/chips/Chips'; import { useUx4gTheme } from '../theme/Ux4gThemeContext'; export const ChipsShowcase: React.FC = () => { const theme = useUx4gTheme(); const colors = theme.colors; // 1. Choice Chips state const [selectedChoice, setSelectedChoice] = useState('Flight'); const [selectedChoiceSmall, setSelectedChoiceSmall] = useState('Economy'); const [selectedPill, setSelectedPill] = useState('Standard Radius (8px)'); const [selectedStatusTab, setSelectedStatusTab] = useState('Under Review'); // 2. Filter Chips state const [filters, setFilters] = useState>({ 'Free Wi-Fi': true, 'Pool': false, 'Gym': true, 'Pet Friendly': false, 'Breakfast Included': true, }); const [smallFilters, setSmallFilters] = useState>({ '4+ Stars': true, 'Superhost': false, 'Instant Book': true, 'Self Check-in': false, }); // 3. Input Chips state const defaultInputChips = [ 'react-native', 'ux4g-design-system', 'typescript', 'figma-tokens', ]; const [inputChips, setInputChips] = useState(defaultInputChips); const defaultSizeComparison: Array<{ id: string; text: string; size: Ux4gInputChipSize }> = [ { id: 'xs', text: 'Size XS (20px)', size: 'xs' }, { id: 's', text: 'Size S (28px)', size: 's' }, { id: 'm', text: 'Size M (32px)', size: 'm' }, ]; const [sizeChips, setSizeChips] = useState(defaultSizeComparison); const handleDismissChip = (chipText: string) => { setInputChips((prev) => prev.filter((item) => item !== chipText)); }; const handleDismissSizeChip = (id: string) => { setSizeChips((prev) => prev.filter((item) => item.id !== id)); }; // 4. Chip Group Arrangements states const [selectedHorizontalTag, setSelectedHorizontalTag] = useState('Tag #3'); const [selectedWrapTag, setSelectedWrapTag] = useState('Tokens'); // 5. Input Chip Field state (free text) const [fieldValue, setFieldValue] = useState(''); const [fieldChips, setFieldChips] = useState(['flutter', 'react-native']); const handleAddFieldChip = (val: string) => { if (!fieldChips.includes(val)) { setFieldChips((prev) => [...prev, val]); } }; // 6. Input Chip Field state (dropdown) const [dropdownValue, setDropdownValue] = useState(''); const [dropdownChips, setDropdownChips] = useState(['Design Systems']); const handleAddDropdownChip = (val: string) => { if (!dropdownChips.includes(val)) { setDropdownChips((prev) => [...prev, val]); } }; const cardStyle = [ styles.card, { backgroundColor: theme.isDark ? '#1F1F1F' : '#FFFFFF', borderColor: theme.isDark ? '#333333' : '#E4E4E7', }, ]; const titleStyle = [ styles.sectionTitle, { color: theme.isDark ? '#F4F4F5' : '#18181B' }, ]; const subtitleStyle = [ styles.subText, { color: theme.isDark ? '#A1A1AA' : '#71717A' }, ]; const activeFiltersCount = Object.values(filters).filter(Boolean).length; const activeSmallFiltersCount = Object.values(smallFilters).filter(Boolean).length; const renderTrailingBadge = (count: number | string, isSelected: boolean) => ( {count} ); return ( 🍟 Chips Component Suite (`Ux4gChoiceChip`, `Ux4gFilterChip`, `Ux4gInputChip`) 100% complete interactive working functionality for all chip cases! Test single choice selections, multi-filter toggling, dynamic tag removal, custom radii, sizes (`xs`, `s`, `m`), and input fields. {/* 1. Choice Chips */} 1. Choice Chips (`Ux4gChoiceChip`) Allows single selection from a set of options. Supports `size = 'm'`, `size = 's'`, custom border radii, and leading/trailing icons. Choice Chips with Trailing Status Badges (`trailingContent`): { const isSel = selectedStatusTab === item.text; return ( setSelectedStatusTab(item.text)} size="m" trailingContent={renderTrailingBadge(item.count, isSel)} /> ); })} arrangement="wrap" /> Active Status Filter: {selectedStatusTab} Medium Size (`size = 'm'`, 32px height) with Leading Emojis: ( setSelectedChoice(item.text)} size="m" leadingContent={{item.icon}} /> ))} arrangement="wrap" /> Active Choice: {selectedChoice} Small Size (`size = 's'`, 28px height): ( setSelectedChoiceSmall(item)} size="s" /> ))} arrangement="wrap" /> Active Tier: {selectedChoiceSmall} Custom Border Radius (`borderRadius = 24` Full Pill vs Default): ( setSelectedPill(item)} size="m" borderRadius={idx === 1 ? 24 : undefined} /> ))} arrangement="wrap" /> Disabled State (`enabled = false`): {}} enabled={false} />, {}} enabled={false} />, ]} /> {/* 2. Filter Chips */} 2. Filter Chips (`Ux4gFilterChip`) Used to filter content by attributes. Selected chips highlight with primary background opacity (`0.08`) and primary border. Medium Filter Chips (`size = 'm'`) with Leading Checkmark Indicator: ( ✓ ) : undefined } onClick={() => setFilters((prev) => ({ ...prev, [name]: !prev[name] })) } /> ))} arrangement="wrap" /> Active Filters ({activeFiltersCount}):{' '} {Object.entries(filters) .filter(([_, sel]) => sel) .map(([k]) => k) .join(', ') || 'None'} Small Filter Chips (`size = 's'`) Independent State: ( setSmallFilters((prev) => ({ ...prev, [name]: !prev[name] })) } /> ))} arrangement="wrap" /> Small Active ({activeSmallFiltersCount}):{' '} {Object.entries(smallFilters) .filter(([_, sel]) => sel) .map(([k]) => k) .join(', ') || 'None'} {/* 3. Input Chips */} 3. Input Chips (`Ux4gInputChip`) {inputChips.length < defaultInputChips.length && ( setInputChips(defaultInputChips)} style={[styles.resetBtn, { backgroundColor: colors.primary }]} > ↺ Reset Tags )} Compact tags representing user input with trailing close/dismiss (`✕`) action. Try dismissing them! Interactive Dismissible Input Chips (`size = 'm'`): {inputChips.length === 0 ? ( All tags dismissed! Click "↺ Reset Tags" above to restore. ) : ( ( handleDismissChip(chipText)} /> ))} arrangement="wrap" /> )} All Sizes Comparison (`xs` 20px, `s` 28px, `m` 32px): {sizeChips.length < defaultSizeComparison.length && ( setSizeChips(defaultSizeComparison)} style={[styles.resetBtnSmall, { borderColor: colors.primary }]} > ↺ Restore Sizes )} {sizeChips.length === 0 ? ( All size comparison chips dismissed. ) : ( ( handleDismissSizeChip(item.id)} /> ))} /> )} {/* 4. Chip Group Arrangements */} 4. Chip Group Arrangements (`Ux4gChipGroup`) Arranges multiple chips inside either a horizontal touch/mouse drag `ScrollView` (`horizontal`) or wrapping multi-line grid (`wrap`). Arrangement: `horizontal` (Scroll horizontally across 10 tags): `Tag #${i + 1}`).map((t) => ( setSelectedHorizontalTag(t)} /> ))} /> Selected Horizontal: {selectedHorizontalTag} Arrangement: `wrap` (Multi-line grid with `spacing = 10`, `runSpacing = 10`): ( setSelectedWrapTag(t)} /> ))} /> Selected Wrap Filter: {selectedWrapTag} {/* 5. Input Chip Field (Free Text Entry) */} 5. Input Chip Field (`Ux4gInputChipField` - Free Text Mode) Type text inside the field below and tap the `+` icon (or press Return on keyboard) to dynamically append a new chip tag below! ( setFieldChips((prev) => prev.filter((i) => i !== t))} /> ))} /> Field Tags Count: {fieldChips.length} ({fieldChips.join(', ') || 'None'}) {/* 6. Input Chip Field (Dropdown Mode) */} 6. Input Chip Field (`Ux4gInputChipField` - Dropdown Mode) When `isDropdown = true`, tapping the trigger box pops open a selectable dropdown options menu. Selecting an item adds it to the active chips below. ( setDropdownChips((prev) => prev.filter((i) => i !== t))} /> ))} /> Dropdown Tags Count: {dropdownChips.length} ({dropdownChips.join(', ') || 'None'}) {/* 7. Status Tabs / Choice Chips with Trailing Badges */} 7. Choice Chips with Trailing Status Badges (`trailingContent`) Replicates status filter tabs with circular/pill count badges (`All 62`, `Pending 3`, `Under Review 12`, `Approved 41`, `Rejected 6`). { const isSel = selectedStatusTab === item.text; return ( setSelectedStatusTab(item.text)} size="m" trailingContent={renderTrailingBadge(item.count, isSel)} /> ); })} arrangement="wrap" /> ); }; const styles = StyleSheet.create({ container: { flex: 1, }, contentContainer: { padding: 16, paddingBottom: 64, }, header: { marginBottom: 20, }, title: { fontSize: 22, fontWeight: '700', marginBottom: 6, }, subText: { fontSize: 14, lineHeight: 20, }, card: { borderWidth: 1, borderRadius: 12, padding: 16, marginBottom: 16, }, sectionTitle: { fontSize: 16, fontWeight: '600', }, titleRow: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6, }, resetBtn: { paddingHorizontal: 10, paddingVertical: 5, borderRadius: 6, }, resetBtnText: { color: '#FFFFFF', fontSize: 12, fontWeight: '600', }, resetBtnSmall: { borderWidth: 1, paddingHorizontal: 8, paddingVertical: 3, borderRadius: 4, }, label: { fontSize: 13, fontWeight: '600', marginBottom: 8, }, rowSpacing: { marginTop: 14, }, stateMonitorText: { fontSize: 13, marginTop: 10, fontStyle: 'italic', }, emptyAlertBox: { padding: 12, borderWidth: 1, borderColor: 'rgba(239, 68, 68, 0.3)', borderRadius: 8, backgroundColor: 'rgba(239, 68, 68, 0.05)', }, badgeBox: { paddingHorizontal: 7, paddingVertical: 2, borderRadius: 12, marginLeft: 6, justifyContent: 'center', alignItems: 'center', minWidth: 22, }, badgeText: { fontSize: 11, fontWeight: '700', color: '#FFFFFF', textAlign: 'center', }, });