@cryterion/expo-chat-ui 1.0.0 → 1.0.2

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.2",
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,40 @@ export function Chat({
29
29
  placeholder,
30
30
  emptyStateTitle,
31
31
  emptyStateSubtitle,
32
+ keyboardVerticalOffset = 0,
33
+ autoCorrect,
34
+ spellCheck,
35
+ keyboardType,
32
36
  }: ChatProps) {
33
37
  const theme = mergeTheme(themeProp);
34
38
 
35
39
  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>
40
+ <KeyboardAvoidingView
41
+ style={{ flex: 1 }}
42
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
43
+ keyboardVerticalOffset={keyboardVerticalOffset}
44
+ >
45
+ <View style={[styles.container, { backgroundColor: theme.colors.background }]}>
46
+ <MessageList
47
+ messages={messages}
48
+ isLoading={isLoading}
49
+ theme={theme}
50
+ renderEmptyState={renderEmptyState}
51
+ onCopyMessage={onCopyMessage}
52
+ emptyStateTitle={emptyStateTitle}
53
+ emptyStateSubtitle={emptyStateSubtitle}
54
+ />
55
+ <ChatInput
56
+ onSend={onSend}
57
+ disabled={disabled || isLoading}
58
+ theme={theme}
59
+ placeholder={placeholder}
60
+ autoCorrect={autoCorrect}
61
+ spellCheck={spellCheck}
62
+ keyboardType={keyboardType}
63
+ />
64
+ </View>
65
+ </KeyboardAvoidingView>
53
66
  );
54
67
  }
55
68
 
@@ -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,
@@ -15,6 +13,9 @@ export function ChatInput({
15
13
  disabled,
16
14
  theme,
17
15
  placeholder = 'Type a message...',
16
+ autoCorrect = true,
17
+ spellCheck = true,
18
+ keyboardType = 'default',
18
19
  }: ChatInputProps) {
19
20
  const [text, setText] = useState('');
20
21
  const { colors } = theme;
@@ -30,55 +31,53 @@ export function ChatInput({
30
31
  const canSend = text.trim().length > 0 && !disabled;
31
32
 
32
33
  return (
33
- <KeyboardAvoidingView
34
- behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
35
- keyboardVerticalOffset={Platform.OS === 'ios' ? 0 : 0}
34
+ <View
35
+ style={[
36
+ styles.container,
37
+ {
38
+ backgroundColor: colors.background,
39
+ borderTopColor: colors.border,
40
+ },
41
+ ]}
36
42
  >
37
43
  <View
38
44
  style={[
39
- styles.container,
40
- {
41
- backgroundColor: colors.background,
42
- borderTopColor: colors.border,
43
- },
45
+ styles.inputContainer,
46
+ { backgroundColor: colors.inputBackground },
44
47
  ]}
45
48
  >
46
- <View
49
+ <TextInput
50
+ style={[styles.input, { color: colors.text }]}
51
+ placeholder={placeholder}
52
+ placeholderTextColor={colors.placeholder}
53
+ value={text}
54
+ onChangeText={setText}
55
+ multiline
56
+ maxLength={2000}
57
+ editable={!disabled}
58
+ onSubmitEditing={handleSend}
59
+ blurOnSubmit={false}
60
+ autoCorrect={autoCorrect}
61
+ spellCheck={spellCheck}
62
+ keyboardType={keyboardType}
63
+ />
64
+ <TouchableOpacity
47
65
  style={[
48
- styles.inputContainer,
49
- { backgroundColor: colors.inputBackground },
66
+ styles.sendButton,
67
+ {
68
+ backgroundColor: canSend
69
+ ? colors.primary
70
+ : colors.sendButtonDisabled,
71
+ },
50
72
  ]}
73
+ onPress={handleSend}
74
+ disabled={!canSend}
75
+ activeOpacity={0.7}
51
76
  >
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>
77
+ <Ionicons name="send" size={18} color="#FFFFFF" />
78
+ </TouchableOpacity>
80
79
  </View>
81
- </KeyboardAvoidingView>
80
+ </View>
82
81
  );
83
82
  }
84
83
 
package/src/types.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
+ import { KeyboardTypeOptions } from 'react-native';
2
3
 
3
4
  /**
4
5
  * Represents a single chat message
@@ -88,6 +89,14 @@ export interface ChatProps {
88
89
  emptyStateTitle?: string;
89
90
  /** Empty state subtitle */
90
91
  emptyStateSubtitle?: string;
92
+ /** Keyboard vertical offset for KeyboardAvoidingView (defaults to 0) */
93
+ keyboardVerticalOffset?: number;
94
+ /** Enable/disable autocorrect (defaults to true) */
95
+ autoCorrect?: boolean;
96
+ /** Enable/disable spell check (defaults to true) */
97
+ spellCheck?: boolean;
98
+ /** Keyboard type (defaults to 'default') */
99
+ keyboardType?: KeyboardTypeOptions;
91
100
  }
92
101
 
93
102
  /**
@@ -134,4 +143,10 @@ export interface ChatInputProps {
134
143
  theme: ChatTheme;
135
144
  /** Placeholder text */
136
145
  placeholder?: string;
146
+ /** Enable/disable autocorrect (defaults to true) */
147
+ autoCorrect?: boolean;
148
+ /** Enable/disable spell check (defaults to true) */
149
+ spellCheck?: boolean;
150
+ /** Keyboard type (defaults to 'default') */
151
+ keyboardType?: KeyboardTypeOptions;
137
152
  }