MessageBubble CC 19 -> below 10. The fence and indented code block rules were identical and are now one CodeBlock component; the Markdown style map lives in markdownStyles.ts. Adds characterization tests for the bubble (roles, actions visibility, edited badge, copy feedback).
74 lines
2.1 KiB
TypeScript
74 lines
2.1 KiB
TypeScript
import { Check, Copy } from 'lucide-react-native';
|
|
import React from 'react';
|
|
import { ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
|
|
|
interface CodeBlockProps {
|
|
language: string;
|
|
content: string;
|
|
copied: boolean;
|
|
onCopy: (text: string) => void;
|
|
}
|
|
|
|
export function CodeBlock({ language, content, copied, onCopy }: CodeBlockProps) {
|
|
const CopyIcon = copied ? Check : Copy;
|
|
|
|
return (
|
|
<View style={styles.codeBlockWrapper}>
|
|
<View style={styles.codeBlockHeader}>
|
|
<Text style={styles.codeBlockLanguage}>{language}</Text>
|
|
<TouchableOpacity onPress={() => onCopy(content)} style={styles.copyButton}>
|
|
<CopyIcon size={14} color="#A0A0A0" />
|
|
<Text style={styles.copyText}>{copied ? 'Copied!' : 'Copy'}</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
<ScrollView horizontal style={styles.codeScrollView} showsHorizontalScrollIndicator={false}>
|
|
<Text style={styles.codeText}>{content}</Text>
|
|
</ScrollView>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
codeBlockWrapper: {
|
|
backgroundColor: '#1E1E1E',
|
|
borderRadius: 8,
|
|
marginVertical: 8,
|
|
overflow: 'hidden',
|
|
width: '100%',
|
|
},
|
|
codeBlockHeader: {
|
|
flexDirection: 'row',
|
|
justifyContent: 'space-between',
|
|
alignItems: 'center',
|
|
backgroundColor: '#2D2D2D',
|
|
paddingHorizontal: 12,
|
|
paddingVertical: 8,
|
|
borderBottomWidth: 1,
|
|
borderBottomColor: '#404040',
|
|
},
|
|
codeBlockLanguage: {
|
|
color: '#A0A0A0',
|
|
fontSize: 12,
|
|
fontFamily: 'monospace',
|
|
textTransform: 'lowercase',
|
|
},
|
|
copyButton: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
gap: 4,
|
|
padding: 4,
|
|
},
|
|
copyText: {
|
|
color: '#A0A0A0',
|
|
fontSize: 12,
|
|
},
|
|
codeScrollView: {
|
|
padding: 12,
|
|
},
|
|
codeText: {
|
|
color: '#D4D4D4',
|
|
fontSize: 13,
|
|
fontFamily: 'monospace',
|
|
},
|
|
});
|