managarten/apps-archived/mukke/apps/mobile/components/ListItem.tsx
Till JS 7a56699d45 feat(mukke): rename LightWrite to Mukke and add music library, player, playlists
Combines LightWrite (beat/lyrics editor) and Mukke (iOS music player) into
a single web-based music workspace app. Archives the old Mukke mobile app.

- Rename: @lightwrite/* → @mukke/*, all branding, configs, Dockerfiles
- New DB schemas: songs, playlists, playlist_songs + songId FK on projects
- New backend modules: SongModule, PlaylistModule, LibraryModule
- New web: app shell with sidebar, library (songs/albums/artists/genres),
  web player (queue/shuffle/repeat/MediaSession), playlists, search,
  upload, dashboard, album/artist/genre detail pages
- Auth: add forgot-password + reset-password pages, extend auth store
- Tests: 40 backend unit tests (song, playlist, library services)
- Config: env generation, MinIO bucket, docker-compose prod, cloudflare
- Docs: update CLAUDE.md, auth guidelines with SvelteKit checklist

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 09:55:56 +01:00

66 lines
1.4 KiB
TypeScript

import { Ionicons } from '@expo/vector-icons';
import { Pressable, View, Text } from 'react-native';
import { useTheme } from '~/utils/themeContext';
interface ListItemProps {
title: string;
subtitle?: string;
trailing?: string;
left?: React.ReactNode;
onPress?: () => void;
onLongPress?: () => void;
showChevron?: boolean;
}
export function ListItem({
title,
subtitle,
trailing,
left,
onPress,
onLongPress,
showChevron,
}: ListItemProps) {
const { colors } = useTheme();
return (
<Pressable
onPress={onPress}
onLongPress={onLongPress}
style={({ pressed }) => ({
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 10,
paddingHorizontal: 16,
backgroundColor: pressed ? colors.backgroundTertiary : 'transparent',
})}
>
{left && <View style={{ marginRight: 12 }}>{left}</View>}
<View style={{ flex: 1, minWidth: 0 }}>
<Text style={{ fontSize: 16, color: colors.text }} numberOfLines={1}>
{title}
</Text>
{subtitle && (
<Text
style={{ fontSize: 13, color: colors.textSecondary, marginTop: 2 }}
numberOfLines={1}
>
{subtitle}
</Text>
)}
</View>
{trailing && (
<Text style={{ fontSize: 13, color: colors.textTertiary, marginLeft: 8 }}>{trailing}</Text>
)}
{showChevron && (
<Ionicons
name="chevron-forward"
size={18}
color={colors.textTertiary}
style={{ marginLeft: 4 }}
/>
)}
</Pressable>
);
}