Setting the file. One moment.
Gold Standard Card · Stitch::react Native · google-labs-code/stitch-skills · Skills Docs
ContentsBack to the top of the page (opens in a new tab)
examples/ gold-standard-card.tsx
TypeScript · 167 lines · 4 KB
15
*/
16
17 import React from 'react' ;
18 import { View, Text, Image, Pressable, StyleSheet, Platform } from 'react-native' ;
19 import { colors, shadows } from '../src/theme' ;
20
21 /**
22 * Gold Standard: ActivityCard
23 * This file is the definitive reference for the agent.
24 */
25 export interface ActivityCardProps {
26 readonly id : string ;
27 readonly username : string ;
28 readonly action : 'MERGED' | 'COMMIT' ;
29 readonly timestamp : string ;
30 readonly avatarUrl : string ;
31 readonly repoName : string ;
32 readonly onPress ?: () => void ;
33 }
34
35 export const ActivityCard : React . FC < ActivityCardProps > = ({
36 username,
37 action,
38 timestamp,
39 avatarUrl,
40 repoName,
41 onPress,
42 }) => {
43 const isMerged = action === 'MERGED' ;
44
45 return (
46 < Pressable
47 style ={ ({ pressed }) => [styles.container, pressed && styles.pressed] }
48 onPress ={ onPress }
49 accessibilityRole = "button"
50 accessibilityLabel ={ `${ username } ${ action . toLowerCase () } in ${ repoName }` }
51 >
52 < View style ={ styles.leftContent } >
53 < Image
54 source ={ { uri: avatarUrl } }
55 style ={ styles.avatar }
56 accessibilityLabel ={ `Avatar for ${ username }` }
57 />
58
59 < View style ={ styles.textContent } >
60 < Text style ={ styles.username } numberOfLines ={ 1 } >
61 { username }
62 </ Text >
63
64 < View
65 style ={ [
66 styles.badge,
67 isMerged ? styles.badgeMerged : styles.badgeCommit,
68 ] }
69 >
70 < Text
71 style ={ [
72 styles.badgeText,
73 isMerged ? styles.badgeTextMerged : styles.badgeTextCommit,
74 ] }
75 >
76 { action }
77 </ Text >
78 </ View >
79
80 < Text style ={ styles.separator } >in</ Text >
81
82 < Text style ={ styles.repoName } numberOfLines ={ 1 } >
83 { repoName }
84 </ Text >
85 </ View >
86 </ View >
87
88 < Text style ={ styles.timestamp } > { timestamp } </ Text >
89 </ Pressable >
90 );
91 };
92
93 const styles = StyleSheet. create ({
94 container: {
95 flexDirection: 'row' ,
96 alignItems: 'center' ,
97 justifyContent: 'space-between' ,
98 gap: 16 ,
99 borderRadius: 8 ,
100 padding: 16 ,
101 minHeight: 56 ,
102 ... shadows.card,
103 },
104 pressed: {
105 opacity: 0.7 ,
106 },
107 leftContent: {
108 flexDirection: 'row' ,
109 alignItems: 'center' ,
110 gap: 16 ,
111 flex: 1 ,
112 overflow: 'hidden' ,
113 },
114 avatar: {
115 width: 40 ,
116 height: 40 ,
117 borderRadius: 20 ,
118 },
119 textContent: {
120 flexDirection: 'row' ,
121 flexWrap: 'wrap' ,
122 alignItems: 'center' ,
123 columnGap: 8 ,
124 rowGap: 4 ,
125 flex: 1 ,
126 },
127 username: {
128 fontWeight: '600' ,
129 fontSize: 14 ,
130 },
131 badge: {
132 paddingHorizontal: 8 ,
133 paddingVertical: 2 ,
134 borderRadius: 12 ,
135 },
136 badgeMerged: {
137 backgroundColor: colors.badgeMergedBg,
138 },
139 badgeCommit: {
140 backgroundColor: colors.badgeCommitBg,
141 },
142 badgeText: {
143 fontSize: 12 ,
144 fontWeight: '600' ,
145 },
146 badgeTextMerged: {
147 color: colors.badgeMergedText,
148 },
149 badgeTextCommit: {
150 color: colors.badgeCommitText,
151 },
152 separator: {
153 fontSize: 14 ,
154 opacity: 0.6 ,
155 },
156 repoName: {
157 fontSize: 14 ,
158 },
159 timestamp: {
160 fontSize: 14 ,
161 fontWeight: '400' ,
162 opacity: 0.5 ,
163 flexShrink: 0 ,
164 },
165 });
166
167 export default ActivityCard;