@cryterion/expo-chat-ui 1.0.0 → 1.0.1

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/README.md CHANGED
@@ -1,11 +1,11 @@
1
- # @tovia/chat-ui
1
+ # @cryterion/expo-chat-ui
2
2
 
3
3
  A reusable chat UI component for Expo + React Native applications.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- bun add @tovia/chat-ui
8
+ bun add @cryterion/expo-chat-ui
9
9
  ```
10
10
 
11
11
  ## Usage
@@ -13,7 +13,7 @@ bun add @tovia/chat-ui
13
13
  ### Basic Usage
14
14
 
15
15
  ```tsx
16
- import { Chat, ChatMessage } from '@tovia/chat-ui';
16
+ import { Chat, ChatMessage } from '@cryterion/expo-chat-ui';
17
17
 
18
18
  function ChatScreen() {
19
19
  const [messages, setMessages] = useState<ChatMessage[]>([]);
@@ -45,7 +45,7 @@ function ChatScreen() {
45
45
  ### With Custom Theme
46
46
 
47
47
  ```tsx
48
- import { Chat, ChatTheme } from '@tovia/chat-ui';
48
+ import { Chat, ChatTheme } from '@cryterion/expo-chat-ui';
49
49
 
50
50
  const customTheme: Partial<ChatTheme> = {
51
51
  colors: {
@@ -73,7 +73,7 @@ function ChatScreen() {
73
73
  You can also use the individual building blocks:
74
74
 
75
75
  ```tsx
76
- import { MessageList, ChatInput, MessageBubble } from '@tovia/chat-ui';
76
+ import { MessageList, ChatInput, MessageBubble } from '@cryterion/expo-chat-ui';
77
77
 
78
78
  function CustomChat() {
79
79
  return (
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cryterion/expo-chat-ui",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "A reusable chat UI component for Expo + React Native applications",
5
5
  "author": "cryterion",
6
6
  "license": "MIT",
@@ -61,4 +61,4 @@
61
61
  "react-native": "0.73.6",
62
62
  "typescript": "~5.9.3"
63
63
  }
64
- }
64
+ }
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { StyleSheet, View } from 'react-native';
2
+ import { KeyboardAvoidingView, Platform, StyleSheet, View } from 'react-native';
3
3
  import { mergeTheme } from '../theme/defaultTheme';
4
4
  import { ChatProps } from '../types';
5
5
  import { ChatInput } from './ChatInput';
@@ -29,27 +29,34 @@ export function Chat({
29
29
  placeholder,
30
30
  emptyStateTitle,
31
31
  emptyStateSubtitle,
32
+ keyboardVerticalOffset = 0,
32
33
  }: ChatProps) {
33
34
  const theme = mergeTheme(themeProp);
34
35
 
35
36
  return (
36
- <View style={[styles.container, { backgroundColor: theme.colors.background }]}>
37
- <MessageList
38
- messages={messages}
39
- isLoading={isLoading}
40
- theme={theme}
41
- renderEmptyState={renderEmptyState}
42
- onCopyMessage={onCopyMessage}
43
- emptyStateTitle={emptyStateTitle}
44
- emptyStateSubtitle={emptyStateSubtitle}
45
- />
46
- <ChatInput
47
- onSend={onSend}
48
- disabled={disabled || isLoading}
49
- theme={theme}
50
- placeholder={placeholder}
51
- />
52
- </View>
37
+ <KeyboardAvoidingView
38
+ style={{ flex: 1 }}
39
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
40
+ keyboardVerticalOffset={keyboardVerticalOffset}
41
+ >
42
+ <View style={[styles.container, { backgroundColor: theme.colors.background }]}>
43
+ <MessageList
44
+ messages={messages}
45
+ isLoading={isLoading}
46
+ theme={theme}
47
+ renderEmptyState={renderEmptyState}
48
+ onCopyMessage={onCopyMessage}
49
+ emptyStateTitle={emptyStateTitle}
50
+ emptyStateSubtitle={emptyStateSubtitle}
51
+ />
52
+ <ChatInput
53
+ onSend={onSend}
54
+ disabled={disabled || isLoading}
55
+ theme={theme}
56
+ placeholder={placeholder}
57
+ />
58
+ </View>
59
+ </KeyboardAvoidingView>
53
60
  );
54
61
  }
55
62
 
@@ -1,8 +1,6 @@
1
1
  import { Ionicons } from '@expo/vector-icons';
2
2
  import React, { useState } from 'react';
3
3
  import {
4
- KeyboardAvoidingView,
5
- Platform,
6
4
  StyleSheet,
7
5
  TextInput,
8
6
  TouchableOpacity,
@@ -30,55 +28,50 @@ export function ChatInput({
30
28
  const canSend = text.trim().length > 0 && !disabled;
31
29
 
32
30
  return (
33
- <KeyboardAvoidingView
34
- behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
35
- keyboardVerticalOffset={Platform.OS === 'ios' ? 0 : 0}
31
+ <View
32
+ style={[
33
+ styles.container,
34
+ {
35
+ backgroundColor: colors.background,
36
+ borderTopColor: colors.border,
37
+ },
38
+ ]}
36
39
  >
37
40
  <View
38
41
  style={[
39
- styles.container,
40
- {
41
- backgroundColor: colors.background,
42
- borderTopColor: colors.border,
43
- },
42
+ styles.inputContainer,
43
+ { backgroundColor: colors.inputBackground },
44
44
  ]}
45
45
  >
46
- <View
46
+ <TextInput
47
+ style={[styles.input, { color: colors.text }]}
48
+ placeholder={placeholder}
49
+ placeholderTextColor={colors.placeholder}
50
+ value={text}
51
+ onChangeText={setText}
52
+ multiline
53
+ maxLength={2000}
54
+ editable={!disabled}
55
+ onSubmitEditing={handleSend}
56
+ blurOnSubmit={false}
57
+ />
58
+ <TouchableOpacity
47
59
  style={[
48
- styles.inputContainer,
49
- { backgroundColor: colors.inputBackground },
60
+ styles.sendButton,
61
+ {
62
+ backgroundColor: canSend
63
+ ? colors.primary
64
+ : colors.sendButtonDisabled,
65
+ },
50
66
  ]}
67
+ onPress={handleSend}
68
+ disabled={!canSend}
69
+ activeOpacity={0.7}
51
70
  >
52
- <TextInput
53
- style={[styles.input, { color: colors.text }]}
54
- placeholder={placeholder}
55
- placeholderTextColor={colors.placeholder}
56
- value={text}
57
- onChangeText={setText}
58
- multiline
59
- maxLength={2000}
60
- editable={!disabled}
61
- onSubmitEditing={handleSend}
62
- blurOnSubmit={false}
63
- />
64
- <TouchableOpacity
65
- style={[
66
- styles.sendButton,
67
- {
68
- backgroundColor: canSend
69
- ? colors.primary
70
- : colors.sendButtonDisabled,
71
- },
72
- ]}
73
- onPress={handleSend}
74
- disabled={!canSend}
75
- activeOpacity={0.7}
76
- >
77
- <Ionicons name="send" size={18} color="#FFFFFF" />
78
- </TouchableOpacity>
79
- </View>
71
+ <Ionicons name="send" size={18} color="#FFFFFF" />
72
+ </TouchableOpacity>
80
73
  </View>
81
- </KeyboardAvoidingView>
74
+ </View>
82
75
  );
83
76
  }
84
77
 
package/src/types.ts CHANGED
@@ -88,6 +88,8 @@ export interface ChatProps {
88
88
  emptyStateTitle?: string;
89
89
  /** Empty state subtitle */
90
90
  emptyStateSubtitle?: string;
91
+ /** Keyboard vertical offset for KeyboardAvoidingView (defaults to 0) */
92
+ keyboardVerticalOffset?: number;
91
93
  }
92
94
 
93
95
  /**