@campxdev/react-native-blueprint 0.1.23 → 0.1.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/global.css +3 -3
- package/lib/global.css +1 -1
- package/lib/module/assets/icons/Image.png +0 -0
- package/lib/module/components/DataDisplay/Avatar/Avatar.js +1 -1
- package/lib/module/components/DataDisplay/Avatar/Avatar.js.map +1 -1
- package/lib/module/components/DataDisplay/Banner/Banner.figma.js +17 -3
- package/lib/module/components/DataDisplay/Banner/Banner.figma.js.map +1 -1
- package/lib/module/components/DataDisplay/Banner/Banner.js +138 -34
- package/lib/module/components/DataDisplay/Banner/Banner.js.map +1 -1
- package/lib/module/components/DataDisplay/CalendarItem/CalendarItem.js +2 -2
- package/lib/module/components/DataDisplay/CalendarItem/CalendarItem.js.map +1 -1
- package/lib/module/components/DataDisplay/Card/Card.figma.js +11 -4
- package/lib/module/components/DataDisplay/Card/Card.figma.js.map +1 -1
- package/lib/module/components/DataDisplay/Card/Card.js +119 -65
- package/lib/module/components/DataDisplay/Card/Card.js.map +1 -1
- package/lib/module/components/DataDisplay/ChatBubble/ChatBubble.figma.js +54 -0
- package/lib/module/components/DataDisplay/ChatBubble/ChatBubble.figma.js.map +1 -0
- package/lib/module/components/DataDisplay/ChatBubble/ChatBubble.js +318 -0
- package/lib/module/components/DataDisplay/ChatBubble/ChatBubble.js.map +1 -0
- package/lib/module/components/DataDisplay/ChatBubble/index.js +4 -0
- package/lib/module/components/DataDisplay/ChatBubble/index.js.map +1 -0
- package/lib/module/components/DataDisplay/FeedCard/AttachmentDetails.js +69 -0
- package/lib/module/components/DataDisplay/FeedCard/AttachmentDetails.js.map +1 -0
- package/lib/module/components/DataDisplay/FeedCard/FeedCard.figma.js +19 -17
- package/lib/module/components/DataDisplay/FeedCard/FeedCard.figma.js.map +1 -1
- package/lib/module/components/DataDisplay/FeedCard/FeedCard.js +30 -19
- package/lib/module/components/DataDisplay/FeedCard/FeedCard.js.map +1 -1
- package/lib/module/components/DataDisplay/Greeting/Greeting.figma.js +5 -5
- package/lib/module/components/DataDisplay/Greeting/Greeting.figma.js.map +1 -1
- package/lib/module/components/DataDisplay/Greeting/Greeting.js +46 -70
- package/lib/module/components/DataDisplay/Greeting/Greeting.js.map +1 -1
- package/lib/module/components/DataDisplay/ProfileCard/ProfileCard.figma.js +16 -0
- package/lib/module/components/DataDisplay/ProfileCard/ProfileCard.figma.js.map +1 -0
- package/lib/module/components/DataDisplay/ProfileCard/ProfileCard.js +111 -0
- package/lib/module/components/DataDisplay/ProfileCard/ProfileCard.js.map +1 -0
- package/lib/module/components/DataDisplay/ProfileCard/index.js +4 -0
- package/lib/module/components/DataDisplay/ProfileCard/index.js.map +1 -0
- package/lib/module/components/Input/Button/Button.js +77 -129
- package/lib/module/components/Input/Button/Button.js.map +1 -1
- package/lib/module/components/Navigation/Appbar/AppBar.figma.js +18 -6
- package/lib/module/components/Navigation/Appbar/AppBar.figma.js.map +1 -1
- package/lib/module/components/Navigation/Appbar/AppBar.js +36 -9
- package/lib/module/components/Navigation/Appbar/AppBar.js.map +1 -1
- package/lib/module/components/Navigation/Popover/Popover.js +1 -1
- package/lib/module/components/Navigation/Popover/Popover.js.map +1 -1
- package/lib/module/components/ui/index.js +2 -0
- package/lib/module/components/ui/index.js.map +1 -1
- package/lib/module/lib/theme.js +2 -2
- package/lib/module/patterns/pattern-components/AccountPattern/AccountPattern.figma.js +196 -0
- package/lib/module/patterns/pattern-components/AccountPattern/AccountPattern.figma.js.map +1 -0
- package/lib/module/patterns/pattern-components/AccountPattern/AccountPattern.js +255 -0
- package/lib/module/patterns/pattern-components/AccountPattern/AccountPattern.js.map +1 -0
- package/lib/module/patterns/pattern-components/AccountPattern/index.js +4 -0
- package/lib/module/patterns/pattern-components/AccountPattern/index.js.map +1 -0
- package/lib/module/patterns/pattern-components/CalendarPattern/CalendarPattern.figma.js +1 -1
- package/lib/module/patterns/pattern-components/CardListPattern/CardListPattern.js +2 -4
- package/lib/module/patterns/pattern-components/CardListPattern/CardListPattern.js.map +1 -1
- package/lib/module/patterns/pattern-components/FeedPattern/FeedPattern.figma.js +144 -0
- package/lib/module/patterns/pattern-components/FeedPattern/FeedPattern.figma.js.map +1 -0
- package/lib/module/patterns/pattern-components/FeedPattern/FeedPattern.js +213 -0
- package/lib/module/patterns/pattern-components/FeedPattern/FeedPattern.js.map +1 -0
- package/lib/module/patterns/pattern-components/FeedPattern/index.js +4 -0
- package/lib/module/patterns/pattern-components/FeedPattern/index.js.map +1 -0
- package/lib/module/patterns/pattern-components/HomeFacultyPattern/HomeFacultyPattern.figma.js +70 -0
- package/lib/module/patterns/pattern-components/HomeFacultyPattern/HomeFacultyPattern.figma.js.map +1 -0
- package/lib/module/patterns/pattern-components/HomeFacultyPattern/HomeFacultyPattern.js +260 -0
- package/lib/module/patterns/pattern-components/HomeFacultyPattern/HomeFacultyPattern.js.map +1 -0
- package/lib/module/patterns/pattern-components/HomeFacultyPattern/index.js +4 -0
- package/lib/module/patterns/pattern-components/HomeFacultyPattern/index.js.map +1 -0
- package/lib/module/patterns/pattern-components/HomeParentPattern/HomeParentPattern.figma.js +82 -0
- package/lib/module/patterns/pattern-components/HomeParentPattern/HomeParentPattern.figma.js.map +1 -0
- package/lib/module/patterns/pattern-components/HomeParentPattern/HomeParentPattern.js +256 -0
- package/lib/module/patterns/pattern-components/HomeParentPattern/HomeParentPattern.js.map +1 -0
- package/lib/module/patterns/pattern-components/HomeParentPattern/index.js +4 -0
- package/lib/module/patterns/pattern-components/HomeParentPattern/index.js.map +1 -0
- package/lib/module/patterns/pattern-components/HomeStudentPattern/HomeStudentPattern.figma.js +73 -0
- package/lib/module/patterns/pattern-components/HomeStudentPattern/HomeStudentPattern.figma.js.map +1 -0
- package/lib/module/patterns/pattern-components/HomeStudentPattern/HomeStudentPattern.js +283 -0
- package/lib/module/patterns/pattern-components/HomeStudentPattern/HomeStudentPattern.js.map +1 -0
- package/lib/module/patterns/pattern-components/HomeStudentPattern/index.js +4 -0
- package/lib/module/patterns/pattern-components/HomeStudentPattern/index.js.map +1 -0
- package/lib/module/patterns/pattern-components/index.js +5 -0
- package/lib/module/patterns/pattern-components/index.js.map +1 -1
- package/package.json +27 -1
- package/src/assets/icons/Image.png +0 -0
- package/src/components/DataDisplay/Avatar/Avatar.tsx +24 -21
- package/src/components/DataDisplay/Banner/Banner.figma.tsx +18 -3
- package/src/components/DataDisplay/Banner/Banner.tsx +153 -26
- package/src/components/DataDisplay/CalendarItem/CalendarItem.tsx +2 -2
- package/src/components/DataDisplay/Card/Card.figma.tsx +7 -3
- package/src/components/DataDisplay/Card/Card.tsx +152 -101
- package/src/components/DataDisplay/ChatBubble/ChatBubble.figma.tsx +54 -0
- package/src/components/DataDisplay/ChatBubble/ChatBubble.tsx +404 -0
- package/src/components/DataDisplay/ChatBubble/index.ts +8 -0
- package/src/components/DataDisplay/FeedCard/AttachmentDetails.tsx +96 -0
- package/src/components/DataDisplay/FeedCard/FeedCard.figma.tsx +17 -15
- package/src/components/DataDisplay/FeedCard/FeedCard.tsx +66 -35
- package/src/components/DataDisplay/Greeting/Greeting.figma.tsx +5 -5
- package/src/components/DataDisplay/Greeting/Greeting.tsx +58 -96
- package/src/components/DataDisplay/ProfileCard/ProfileCard.figma.tsx +17 -0
- package/src/components/DataDisplay/ProfileCard/ProfileCard.tsx +173 -0
- package/src/components/DataDisplay/ProfileCard/index.ts +1 -0
- package/src/components/Input/Button/Button.tsx +71 -157
- package/src/components/Navigation/Appbar/AppBar.figma.tsx +18 -6
- package/src/components/Navigation/Appbar/AppBar.tsx +58 -13
- package/src/components/Navigation/Popover/Popover.tsx +3 -3
- package/src/components/ui/index.ts +2 -0
- package/src/lib/theme.ts +2 -2
- package/src/patterns/pattern-components/AccountPattern/AccountPattern.figma.tsx +193 -0
- package/src/patterns/pattern-components/AccountPattern/AccountPattern.tsx +301 -0
- package/src/patterns/pattern-components/AccountPattern/index.ts +1 -0
- package/src/patterns/pattern-components/CalendarPattern/CalendarPattern.figma.tsx +1 -1
- package/src/patterns/pattern-components/CardListPattern/CardListPattern.tsx +4 -9
- package/src/patterns/pattern-components/FeedPattern/FeedPattern.figma.tsx +146 -0
- package/src/patterns/pattern-components/FeedPattern/FeedPattern.tsx +264 -0
- package/src/patterns/pattern-components/FeedPattern/index.ts +2 -0
- package/src/patterns/pattern-components/HomeFacultyPattern/HomeFacultyPattern.figma.tsx +66 -0
- package/src/patterns/pattern-components/HomeFacultyPattern/HomeFacultyPattern.tsx +326 -0
- package/src/patterns/pattern-components/HomeFacultyPattern/index.ts +2 -0
- package/src/patterns/pattern-components/HomeParentPattern/HomeParentPattern.figma.tsx +75 -0
- package/src/patterns/pattern-components/HomeParentPattern/HomeParentPattern.tsx +328 -0
- package/src/patterns/pattern-components/HomeParentPattern/index.ts +2 -0
- package/src/patterns/pattern-components/HomeStudentPattern/HomeStudentPattern.figma.tsx +66 -0
- package/src/patterns/pattern-components/HomeStudentPattern/HomeStudentPattern.tsx +355 -0
- package/src/patterns/pattern-components/HomeStudentPattern/index.ts +2 -0
- package/src/patterns/pattern-components/index.ts +5 -0
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import {
|
|
4
|
+
View,
|
|
5
|
+
Text as RNText,
|
|
6
|
+
Image as RNImage,
|
|
7
|
+
Pressable,
|
|
8
|
+
type StyleProp,
|
|
9
|
+
type ViewStyle,
|
|
10
|
+
type ImageSourcePropType,
|
|
11
|
+
} from 'react-native';
|
|
12
|
+
import { cssInterop } from 'nativewind';
|
|
13
|
+
|
|
14
|
+
import { Avatar } from '../Avatar/Avatar';
|
|
15
|
+
import { Badge } from '../Badge/Badge';
|
|
16
|
+
|
|
17
|
+
cssInterop(View, { className: 'style' });
|
|
18
|
+
cssInterop(RNText, { className: 'style' });
|
|
19
|
+
cssInterop(RNImage, { className: 'style' });
|
|
20
|
+
cssInterop(Pressable, { className: 'style' });
|
|
21
|
+
|
|
22
|
+
const View_ = View as any;
|
|
23
|
+
const Text = RNText as any;
|
|
24
|
+
const Image = RNImage as any;
|
|
25
|
+
|
|
26
|
+
/* ============================================================================
|
|
27
|
+
* Types
|
|
28
|
+
* ============================================================================ */
|
|
29
|
+
|
|
30
|
+
export type ChatBubbleType = 'incoming' | 'outgoing';
|
|
31
|
+
export type ChatBubbleVariant = 'default' | 'ai';
|
|
32
|
+
|
|
33
|
+
export interface ChatBubbleQuotedMessage {
|
|
34
|
+
author: string;
|
|
35
|
+
text: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ChatBubbleAttachment {
|
|
39
|
+
type: 'image' | 'link';
|
|
40
|
+
uri?: string;
|
|
41
|
+
title?: string;
|
|
42
|
+
description?: string;
|
|
43
|
+
url?: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface ChatBubbleProps {
|
|
47
|
+
type?: ChatBubbleType;
|
|
48
|
+
variant?: ChatBubbleVariant;
|
|
49
|
+
message?: string;
|
|
50
|
+
userName?: string;
|
|
51
|
+
userAvatar?: ImageSourcePropType;
|
|
52
|
+
timestamp?: string;
|
|
53
|
+
showUser?: boolean;
|
|
54
|
+
showMessage?: boolean;
|
|
55
|
+
showEditedIndication?: boolean;
|
|
56
|
+
showQuotedReply?: boolean;
|
|
57
|
+
quotedMessage?: ChatBubbleQuotedMessage;
|
|
58
|
+
showMessageAttachment?: boolean;
|
|
59
|
+
attachment?: ChatBubbleAttachment;
|
|
60
|
+
showReactions?: boolean;
|
|
61
|
+
reactions?: string[];
|
|
62
|
+
showActions?: boolean;
|
|
63
|
+
onCopy?: () => void;
|
|
64
|
+
onLike?: () => void;
|
|
65
|
+
onDislike?: () => void;
|
|
66
|
+
onRegenerate?: () => void;
|
|
67
|
+
style?: StyleProp<ViewStyle>;
|
|
68
|
+
testID?: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* ============================================================================
|
|
72
|
+
* Component
|
|
73
|
+
* ============================================================================ */
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* ChatBubble Component
|
|
77
|
+
*
|
|
78
|
+
* A comprehensive chat message bubble component for chat interfaces.
|
|
79
|
+
* Supports incoming/outgoing messages with default and AI variants.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```tsx
|
|
83
|
+
* <ChatBubble
|
|
84
|
+
* type="incoming"
|
|
85
|
+
* variant="default"
|
|
86
|
+
* message="Hello!"
|
|
87
|
+
* userName="John"
|
|
88
|
+
* timestamp="09:10 PM"
|
|
89
|
+
* />
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export function ChatBubble({
|
|
93
|
+
type = 'incoming',
|
|
94
|
+
variant = 'default',
|
|
95
|
+
message = 'This is the Message bubble content. This will have truncated content and we can fix the width as 300px.',
|
|
96
|
+
userName = 'User Name',
|
|
97
|
+
_userAvatar,
|
|
98
|
+
timestamp = '09:10 PM',
|
|
99
|
+
showUser = true,
|
|
100
|
+
showMessage = true,
|
|
101
|
+
showEditedIndication = true,
|
|
102
|
+
showQuotedReply = true,
|
|
103
|
+
quotedMessage = {
|
|
104
|
+
author: 'John Doe',
|
|
105
|
+
text: 'This is a quoted reply section',
|
|
106
|
+
},
|
|
107
|
+
showMessageAttachment = true,
|
|
108
|
+
attachment,
|
|
109
|
+
showReactions = true,
|
|
110
|
+
reactions = ['👍', '❤️'],
|
|
111
|
+
showActions = true,
|
|
112
|
+
onCopy,
|
|
113
|
+
onLike,
|
|
114
|
+
onDislike,
|
|
115
|
+
onRegenerate,
|
|
116
|
+
style,
|
|
117
|
+
testID,
|
|
118
|
+
}: ChatBubbleProps) {
|
|
119
|
+
const isIncoming = type === 'incoming';
|
|
120
|
+
const isOutgoing = type === 'outgoing';
|
|
121
|
+
const isAi = variant === 'ai';
|
|
122
|
+
const isDefault = variant === 'default';
|
|
123
|
+
|
|
124
|
+
if (isIncoming && isDefault) {
|
|
125
|
+
return (
|
|
126
|
+
<View_
|
|
127
|
+
testID={testID ?? 'chat-bubble'}
|
|
128
|
+
style={style}
|
|
129
|
+
className="flex-row gap-2 px-5 py-2 items-end"
|
|
130
|
+
>
|
|
131
|
+
{/* Avatar */}
|
|
132
|
+
{showUser && (
|
|
133
|
+
<Avatar
|
|
134
|
+
size="sm"
|
|
135
|
+
type="initials"
|
|
136
|
+
initials={userName?.slice(0, 2).toUpperCase() ?? 'AK'}
|
|
137
|
+
showRing={true}
|
|
138
|
+
/>
|
|
139
|
+
)}
|
|
140
|
+
|
|
141
|
+
{/* Content */}
|
|
142
|
+
<View_ className="flex-1 gap-1">
|
|
143
|
+
{/* Meta */}
|
|
144
|
+
<View_ className="flex-row items-center justify-between px-4">
|
|
145
|
+
<Text className="text-xs font-medium text-text-secondary">
|
|
146
|
+
{userName}
|
|
147
|
+
</Text>
|
|
148
|
+
<View_ className="flex-row items-center gap-1">
|
|
149
|
+
{showEditedIndication && (
|
|
150
|
+
<>
|
|
151
|
+
<Text className="text-xs font-medium text-text-secondary">
|
|
152
|
+
Edited
|
|
153
|
+
</Text>
|
|
154
|
+
<View_ className="w-0.5 h-0.5 rounded-full bg-text-secondary" />
|
|
155
|
+
</>
|
|
156
|
+
)}
|
|
157
|
+
<Text className="text-xs font-medium text-text-secondary">
|
|
158
|
+
{timestamp}
|
|
159
|
+
</Text>
|
|
160
|
+
</View_>
|
|
161
|
+
</View_>
|
|
162
|
+
|
|
163
|
+
{/* Bubble */}
|
|
164
|
+
<View_ className="rounded-3xl rounded-bl-none bg-white px-4 py-3 gap-3">
|
|
165
|
+
{/* Quoted Reply */}
|
|
166
|
+
{showQuotedReply && quotedMessage && (
|
|
167
|
+
<View_ className="bg-white rounded-xl border-l-4 border-l-highlight-purple px-3 py-2 gap-0.5">
|
|
168
|
+
<Text className="text-xs font-semibold text-text-primary">
|
|
169
|
+
{quotedMessage.author}
|
|
170
|
+
</Text>
|
|
171
|
+
<Text className="text-xs font-medium text-text-secondary">
|
|
172
|
+
{quotedMessage.text}
|
|
173
|
+
</Text>
|
|
174
|
+
</View_>
|
|
175
|
+
)}
|
|
176
|
+
|
|
177
|
+
{/* Message */}
|
|
178
|
+
{showMessage && (
|
|
179
|
+
<Text className="text-sm font-medium text-text-primary leading-5">
|
|
180
|
+
{message}
|
|
181
|
+
</Text>
|
|
182
|
+
)}
|
|
183
|
+
|
|
184
|
+
{/* Image */}
|
|
185
|
+
{showMessageAttachment &&
|
|
186
|
+
attachment?.type === 'image' &&
|
|
187
|
+
attachment.uri && (
|
|
188
|
+
<Image
|
|
189
|
+
source={{ uri: attachment.uri }}
|
|
190
|
+
style={{
|
|
191
|
+
width: '100%',
|
|
192
|
+
height: 160,
|
|
193
|
+
borderRadius: 16,
|
|
194
|
+
}}
|
|
195
|
+
resizeMode="cover"
|
|
196
|
+
/>
|
|
197
|
+
)}
|
|
198
|
+
</View_>
|
|
199
|
+
|
|
200
|
+
{/* Reactions */}
|
|
201
|
+
{showReactions && reactions && reactions.length > 0 && (
|
|
202
|
+
<View_ className="flex-row gap-1 px-4 pt-1">
|
|
203
|
+
{reactions.map((reaction, idx) => (
|
|
204
|
+
<Badge
|
|
205
|
+
key={idx}
|
|
206
|
+
variant="default"
|
|
207
|
+
size="sm"
|
|
208
|
+
className="rounded-full"
|
|
209
|
+
>
|
|
210
|
+
<Text className="text-sm">{reaction}</Text>
|
|
211
|
+
</Badge>
|
|
212
|
+
))}
|
|
213
|
+
</View_>
|
|
214
|
+
)}
|
|
215
|
+
</View_>
|
|
216
|
+
</View_>
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (isOutgoing && isDefault) {
|
|
221
|
+
return (
|
|
222
|
+
<View_
|
|
223
|
+
testID={testID ?? 'chat-bubble'}
|
|
224
|
+
style={style}
|
|
225
|
+
className="flex-row-reverse gap-2 px-5 py-2 items-end"
|
|
226
|
+
>
|
|
227
|
+
{/* Avatar */}
|
|
228
|
+
{showUser && (
|
|
229
|
+
<Avatar
|
|
230
|
+
size="sm"
|
|
231
|
+
type="image"
|
|
232
|
+
initials={userName?.slice(0, 2).toUpperCase() ?? 'AK'}
|
|
233
|
+
showRing={true}
|
|
234
|
+
/>
|
|
235
|
+
)}
|
|
236
|
+
|
|
237
|
+
{/* Content */}
|
|
238
|
+
<View_ className="flex-1 gap-1">
|
|
239
|
+
{/* Meta */}
|
|
240
|
+
<View_ className="flex-row items-center justify-between px-4">
|
|
241
|
+
<View_ className="flex-row items-center gap-1">
|
|
242
|
+
<Text className="text-xs font-medium text-text-secondary">
|
|
243
|
+
{timestamp}
|
|
244
|
+
</Text>
|
|
245
|
+
{showEditedIndication && (
|
|
246
|
+
<>
|
|
247
|
+
<View_ className="w-0.5 h-0.5 rounded-full bg-text-secondary" />
|
|
248
|
+
<Text className="text-xs font-medium text-text-secondary">
|
|
249
|
+
Edited
|
|
250
|
+
</Text>
|
|
251
|
+
</>
|
|
252
|
+
)}
|
|
253
|
+
</View_>
|
|
254
|
+
<Text className="text-xs font-medium text-text-secondary">You</Text>
|
|
255
|
+
</View_>
|
|
256
|
+
|
|
257
|
+
{/* Bubble */}
|
|
258
|
+
<View_ className="rounded-3xl rounded-br-none bg-surface-subtle px-4 py-3 gap-3">
|
|
259
|
+
{/* Quoted Reply */}
|
|
260
|
+
{showQuotedReply && quotedMessage && (
|
|
261
|
+
<View_ className="bg-surface-default rounded-xl border-l-4 border-l-white px-3 py-2 gap-0.5">
|
|
262
|
+
<Text className="text-xs font-semibold text-text-primary">
|
|
263
|
+
{quotedMessage.author}
|
|
264
|
+
</Text>
|
|
265
|
+
<Text className="text-xs font-medium text-text-secondary">
|
|
266
|
+
{quotedMessage.text}
|
|
267
|
+
</Text>
|
|
268
|
+
</View_>
|
|
269
|
+
)}
|
|
270
|
+
|
|
271
|
+
{/* Message */}
|
|
272
|
+
{showMessage && (
|
|
273
|
+
<Text className="text-sm font-medium text-text-primary leading-5">
|
|
274
|
+
{message}
|
|
275
|
+
</Text>
|
|
276
|
+
)}
|
|
277
|
+
|
|
278
|
+
{/* Link Attachment */}
|
|
279
|
+
{showMessageAttachment && attachment?.type === 'link' && (
|
|
280
|
+
<View_ className="gap-2">
|
|
281
|
+
<View_ className="bg-white rounded-2xl px-3 py-2 gap-1">
|
|
282
|
+
<Text className="text-xs font-semibold text-text-primary">
|
|
283
|
+
{attachment.title}
|
|
284
|
+
</Text>
|
|
285
|
+
<Text className="text-xs font-medium text-text-muted">
|
|
286
|
+
{attachment.description}
|
|
287
|
+
</Text>
|
|
288
|
+
<Text className="text-xs font-medium text-text-secondary">
|
|
289
|
+
{attachment.url}
|
|
290
|
+
</Text>
|
|
291
|
+
</View_>
|
|
292
|
+
<Pressable>
|
|
293
|
+
<Text className="text-xs font-medium text-highlight-purple underline">
|
|
294
|
+
{attachment.url && `https://${attachment.url}/home`}
|
|
295
|
+
</Text>
|
|
296
|
+
</Pressable>
|
|
297
|
+
</View_>
|
|
298
|
+
)}
|
|
299
|
+
</View_>
|
|
300
|
+
|
|
301
|
+
{/* Footer */}
|
|
302
|
+
<View_ className="flex-row items-center justify-between px-4 pt-1">
|
|
303
|
+
{showReactions && reactions && reactions.length > 0 && (
|
|
304
|
+
<View_ className="flex-row gap-1">
|
|
305
|
+
{reactions.map((reaction, idx) => (
|
|
306
|
+
<Badge
|
|
307
|
+
key={idx}
|
|
308
|
+
variant="default"
|
|
309
|
+
size="sm"
|
|
310
|
+
className="rounded-full"
|
|
311
|
+
>
|
|
312
|
+
<Text className="text-sm">{reaction}</Text>
|
|
313
|
+
</Badge>
|
|
314
|
+
))}
|
|
315
|
+
</View_>
|
|
316
|
+
)}
|
|
317
|
+
|
|
318
|
+
<View_ className="flex-row items-center gap-1">
|
|
319
|
+
<View_ className="w-3 h-3 rounded-full bg-text-muted" />
|
|
320
|
+
<Text className="text-xs font-medium text-text-muted">Sent</Text>
|
|
321
|
+
</View_>
|
|
322
|
+
</View_>
|
|
323
|
+
</View_>
|
|
324
|
+
</View_>
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (isIncoming && isAi) {
|
|
329
|
+
return (
|
|
330
|
+
<View_
|
|
331
|
+
testID={testID ?? 'chat-bubble'}
|
|
332
|
+
style={style}
|
|
333
|
+
className="flex-row gap-2 px-5 py-2 items-end"
|
|
334
|
+
>
|
|
335
|
+
{/* Avatar */}
|
|
336
|
+
{showUser && (
|
|
337
|
+
<Avatar size="sm" type="icon" initials="AI" showRing={true} />
|
|
338
|
+
)}
|
|
339
|
+
|
|
340
|
+
{/* Content */}
|
|
341
|
+
<View_ className="flex-1 gap-1">
|
|
342
|
+
{/* Meta */}
|
|
343
|
+
<View_ className="flex-row items-center justify-between px-4">
|
|
344
|
+
<Text className="text-lg">✨</Text>
|
|
345
|
+
<Text className="text-xs font-medium text-text-secondary">
|
|
346
|
+
{timestamp}
|
|
347
|
+
</Text>
|
|
348
|
+
</View_>
|
|
349
|
+
|
|
350
|
+
{/* Bubble */}
|
|
351
|
+
<View_ className="rounded-3xl rounded-bl-none bg-white px-4 py-3 gap-3">
|
|
352
|
+
{/* Message */}
|
|
353
|
+
{showMessage && (
|
|
354
|
+
<Text className="text-sm font-medium text-text-primary leading-5">
|
|
355
|
+
{message}
|
|
356
|
+
</Text>
|
|
357
|
+
)}
|
|
358
|
+
|
|
359
|
+
{/* Image */}
|
|
360
|
+
{showMessageAttachment &&
|
|
361
|
+
attachment?.type === 'image' &&
|
|
362
|
+
attachment.uri && (
|
|
363
|
+
<Image
|
|
364
|
+
source={{ uri: attachment.uri }}
|
|
365
|
+
style={{
|
|
366
|
+
width: '100%',
|
|
367
|
+
height: 160,
|
|
368
|
+
borderRadius: 16,
|
|
369
|
+
}}
|
|
370
|
+
resizeMode="cover"
|
|
371
|
+
/>
|
|
372
|
+
)}
|
|
373
|
+
</View_>
|
|
374
|
+
|
|
375
|
+
{/* Actions */}
|
|
376
|
+
<View_ className="flex-row items-center gap-5 px-4 pt-2">
|
|
377
|
+
{showActions && (
|
|
378
|
+
<>
|
|
379
|
+
<Pressable onPress={onCopy}>
|
|
380
|
+
<Text className="text-base">📋</Text>
|
|
381
|
+
</Pressable>
|
|
382
|
+
<Pressable onPress={onLike}>
|
|
383
|
+
<Text className="text-base">👍</Text>
|
|
384
|
+
</Pressable>
|
|
385
|
+
<Pressable onPress={onDislike}>
|
|
386
|
+
<Text className="text-base">👎</Text>
|
|
387
|
+
</Pressable>
|
|
388
|
+
<Pressable onPress={onRegenerate}>
|
|
389
|
+
<Text className="text-base">🔄</Text>
|
|
390
|
+
</Pressable>
|
|
391
|
+
</>
|
|
392
|
+
)}
|
|
393
|
+
</View_>
|
|
394
|
+
</View_>
|
|
395
|
+
</View_>
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
return null;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
ChatBubble.displayName = 'ChatBubble';
|
|
403
|
+
|
|
404
|
+
export type { ChatBubbleProps };
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import {
|
|
3
|
+
View as RNView,
|
|
4
|
+
Text as RNTextBase,
|
|
5
|
+
type StyleProp,
|
|
6
|
+
type ViewStyle,
|
|
7
|
+
} from 'react-native';
|
|
8
|
+
import { cssInterop } from 'nativewind';
|
|
9
|
+
|
|
10
|
+
// NativeWind interop (className -> style)
|
|
11
|
+
const View = cssInterop(RNView, { className: 'style' });
|
|
12
|
+
const RNText = cssInterop(RNTextBase, { className: 'style' });
|
|
13
|
+
|
|
14
|
+
export type AttachmentDetailsProps = {
|
|
15
|
+
/** File name */
|
|
16
|
+
fileName?: string;
|
|
17
|
+
|
|
18
|
+
/** Number of pages */
|
|
19
|
+
pages?: number;
|
|
20
|
+
|
|
21
|
+
/** File size in MB */
|
|
22
|
+
sizeMB?: number;
|
|
23
|
+
|
|
24
|
+
/** File type (e.g., PDF, DOC) */
|
|
25
|
+
fileType?: string;
|
|
26
|
+
|
|
27
|
+
/** Styling */
|
|
28
|
+
style?: StyleProp<ViewStyle>;
|
|
29
|
+
testID?: string;
|
|
30
|
+
className?: never;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* AttachmentDetails - Displays file attachment metadata
|
|
35
|
+
*
|
|
36
|
+
* Shows file name, pages, size, and file type in a compact card format
|
|
37
|
+
*
|
|
38
|
+
* @component
|
|
39
|
+
* @example
|
|
40
|
+
* ```tsx
|
|
41
|
+
* <AttachmentDetails
|
|
42
|
+
* fileName="Document"
|
|
43
|
+
* pages={27}
|
|
44
|
+
* sizeMB={3}
|
|
45
|
+
* fileType="PDF"
|
|
46
|
+
* />
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export function AttachmentDetails({
|
|
50
|
+
fileName = 'File Name',
|
|
51
|
+
pages = 27,
|
|
52
|
+
sizeMB = 3,
|
|
53
|
+
fileType = 'Pdf',
|
|
54
|
+
style,
|
|
55
|
+
testID,
|
|
56
|
+
}: AttachmentDetailsProps) {
|
|
57
|
+
return (
|
|
58
|
+
<View
|
|
59
|
+
testID={testID ?? 'attachment-details'}
|
|
60
|
+
className="bg-surface-subtle rounded-lg px-4 py-3 flex-col gap-1 w-full"
|
|
61
|
+
style={style}
|
|
62
|
+
>
|
|
63
|
+
{/* File Name */}
|
|
64
|
+
<RNText
|
|
65
|
+
testID="attachment-file-name"
|
|
66
|
+
numberOfLines={1}
|
|
67
|
+
className="text-sm font-semibold text-text-primary"
|
|
68
|
+
>
|
|
69
|
+
{fileName}
|
|
70
|
+
</RNText>
|
|
71
|
+
|
|
72
|
+
{/* Meta Information */}
|
|
73
|
+
<View testID="attachment-meta" className="flex-row items-center gap-2">
|
|
74
|
+
<RNText className="text-xs font-medium text-text-secondary">
|
|
75
|
+
{pages} Pages
|
|
76
|
+
</RNText>
|
|
77
|
+
|
|
78
|
+
{/* Divider dot */}
|
|
79
|
+
<View className="w-1 h-1 rounded-full bg-text-secondary" />
|
|
80
|
+
|
|
81
|
+
<RNText className="text-xs font-medium text-text-secondary">
|
|
82
|
+
{sizeMB} MB
|
|
83
|
+
</RNText>
|
|
84
|
+
|
|
85
|
+
{/* Divider dot */}
|
|
86
|
+
<View className="w-1 h-1 rounded-full bg-text-secondary" />
|
|
87
|
+
|
|
88
|
+
<RNText className="text-xs font-medium text-text-secondary">
|
|
89
|
+
{fileType}
|
|
90
|
+
</RNText>
|
|
91
|
+
</View>
|
|
92
|
+
</View>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
AttachmentDetails.displayName = 'AttachmentDetails';
|
|
@@ -10,34 +10,36 @@ figma.connect(FeedCard, FIGMA_URL, {
|
|
|
10
10
|
post: 'post',
|
|
11
11
|
announcement: 'announcement',
|
|
12
12
|
}),
|
|
13
|
-
authorName: figma.string('authorName'),
|
|
14
|
-
postTitle: figma.string('postTitle'),
|
|
15
|
-
subtitle: figma.string('subtitle'),
|
|
16
|
-
postContent: figma.string('postContent'),
|
|
17
|
-
showHeader: figma.boolean('Show Header'),
|
|
18
|
-
showLeading: figma.boolean('Show Leading'),
|
|
19
13
|
showMedia: figma.boolean('Show Media'),
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
showHeader: figma.boolean('Show Header'),
|
|
15
|
+
showPostContent: figma.boolean('Show Post Content'),
|
|
16
|
+
showBody: figma.boolean('Show Body'),
|
|
22
17
|
showBadges: figma.boolean('Show Badges'),
|
|
23
18
|
showFooterActions: figma.boolean('Show FooterActions'),
|
|
19
|
+
showLeading: figma.boolean('Show Leading'),
|
|
20
|
+
showSubtitle: figma.boolean('Show Subtitle'),
|
|
24
21
|
showSecondaryButton: figma.boolean('Show SecondaryButton'),
|
|
22
|
+
authorName: figma.string('Author Name'),
|
|
23
|
+
postTitle: figma.string('Post Title'),
|
|
24
|
+
subtitle: figma.string('Subtitle'),
|
|
25
|
+
postContent: figma.string('Post Content'),
|
|
25
26
|
},
|
|
26
27
|
example: (props) => (
|
|
27
28
|
<FeedCard
|
|
28
29
|
type={props.type}
|
|
29
|
-
authorName={props.authorName}
|
|
30
|
-
postTitle={props.postTitle}
|
|
31
|
-
subtitle={props.subtitle}
|
|
32
|
-
postContent={props.postContent}
|
|
33
|
-
showHeader={props.showHeader}
|
|
34
|
-
showLeading={props.showLeading}
|
|
35
30
|
showMedia={props.showMedia}
|
|
31
|
+
showHeader={props.showHeader}
|
|
36
32
|
showPostContent={props.showPostContent}
|
|
37
|
-
|
|
33
|
+
showBody={props.showBody}
|
|
38
34
|
showBadges={props.showBadges}
|
|
39
35
|
showFooterActions={props.showFooterActions}
|
|
36
|
+
showLeading={props.showLeading}
|
|
37
|
+
showSubtitle={props.showSubtitle}
|
|
40
38
|
showSecondaryButton={props.showSecondaryButton}
|
|
39
|
+
authorName={props.authorName}
|
|
40
|
+
postTitle={props.postTitle}
|
|
41
|
+
subtitle={props.subtitle}
|
|
42
|
+
postContent={props.postContent}
|
|
41
43
|
/>
|
|
42
44
|
),
|
|
43
45
|
});
|