@kesha-antonov/react-native-chat 4.4.0 → 5.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.
Files changed (49) hide show
  1. package/README.md +365 -211
  2. package/lib/Bubble/index.d.ts +13 -0
  3. package/lib/Bubble/index.d.ts.map +1 -1
  4. package/lib/Bubble/index.js +84 -67
  5. package/lib/Bubble/index.js.map +1 -1
  6. package/lib/Chat/index.d.ts.map +1 -1
  7. package/lib/Chat/index.js +36 -15
  8. package/lib/Chat/index.js.map +1 -1
  9. package/lib/Chat/types.d.ts +12 -11
  10. package/lib/Chat/types.d.ts.map +1 -1
  11. package/lib/InputToolbar.d.ts.map +1 -1
  12. package/lib/InputToolbar.js +3 -0
  13. package/lib/InputToolbar.js.map +1 -1
  14. package/lib/MessageImage.d.ts.map +1 -1
  15. package/lib/MessageImage.js +13 -8
  16. package/lib/MessageImage.js.map +1 -1
  17. package/lib/MessagesContainer/components/DayAnimated/debug.d.ts +1 -1
  18. package/lib/MessagesContainer/components/DayAnimated/debug.d.ts.map +1 -1
  19. package/lib/MessagesContainer/components/DayAnimated/debug.js +2 -2
  20. package/lib/MessagesContainer/components/DayAnimated/debug.js.map +1 -1
  21. package/lib/MessagesContainer/components/DayAnimated/index.d.ts.map +1 -1
  22. package/lib/MessagesContainer/components/DayAnimated/index.js +5 -5
  23. package/lib/MessagesContainer/components/DayAnimated/index.js.map +1 -1
  24. package/lib/MessagesContainer/components/DayAnimated/useScrollGatedOpacity.d.ts.map +1 -1
  25. package/lib/MessagesContainer/components/DayAnimated/useScrollGatedOpacity.js +1 -1
  26. package/lib/MessagesContainer/components/DayAnimated/useScrollGatedOpacity.js.map +1 -1
  27. package/lib/MessagesContainer/components/Item/index.d.ts.map +1 -1
  28. package/lib/MessagesContainer/components/Item/index.js +42 -19
  29. package/lib/MessagesContainer/components/Item/index.js.map +1 -1
  30. package/lib/MessagesContainer/index.d.ts.map +1 -1
  31. package/lib/MessagesContainer/index.js +71 -42
  32. package/lib/MessagesContainer/index.js.map +1 -1
  33. package/lib/MessagesContainer/types.d.ts +1 -0
  34. package/lib/MessagesContainer/types.d.ts.map +1 -1
  35. package/lib/TypingIndicator/index.d.ts.map +1 -1
  36. package/lib/TypingIndicator/index.js +11 -5
  37. package/lib/TypingIndicator/index.js.map +1 -1
  38. package/lib/components/TouchableOpacity.d.ts.map +1 -1
  39. package/lib/components/TouchableOpacity.js +15 -4
  40. package/lib/components/TouchableOpacity.js.map +1 -1
  41. package/lib/hooks/useUpdateLayoutEffect.d.ts.map +1 -1
  42. package/lib/hooks/useUpdateLayoutEffect.js +3 -0
  43. package/lib/hooks/useUpdateLayoutEffect.js.map +1 -1
  44. package/lib/linkParser.d.ts +16 -1
  45. package/lib/linkParser.d.ts.map +1 -1
  46. package/lib/linkParser.js +109 -35
  47. package/lib/linkParser.js.map +1 -1
  48. package/llms.txt +175 -0
  49. package/package.json +21 -22
package/lib/linkParser.js CHANGED
@@ -1,9 +1,13 @@
1
- import React from 'react';
1
+ import React, { useMemo } from 'react';
2
2
  import { Text, Linking } from 'react-native';
3
3
  const DEFAULT_MATCHERS = [
4
4
  {
5
5
  type: 'url',
6
- pattern: /(?:https?:\/\/(?:www\.)?|www\.)[^\s]+|(?<![A-Za-z0-9_.@])(?![A-Za-z0-9._%+-]*@)[a-zA-Z0-9][a-zA-Z0-9-]*\.(?!@)[a-zA-Z]{2,}(?![A-Za-z0-9._%+-]*@)(?:\/[^\s]*)?/gi,
6
+ // The bare-domain alternative is captured so `notPrecededBy` applies to it
7
+ // alone, leaving scheme/www links matchable anywhere.
8
+ pattern: /(?:https?:\/\/(?:www\.)?|www\.)[^\s]+|((?![A-Za-z0-9._%+-]*@)[a-zA-Z0-9][a-zA-Z0-9-]*\.(?!@)[a-zA-Z]{2,}(?![A-Za-z0-9._%+-]*@)(?:\/[^\s]*)?)/gi,
9
+ notPrecededBy: /[A-Za-z0-9_.@]/,
10
+ notPrecededByGroup: 1,
7
11
  getLinkUrl: (text) => {
8
12
  if (!/^https?:\/\//i.test(text))
9
13
  return `http://${text}`;
@@ -12,12 +16,14 @@ const DEFAULT_MATCHERS = [
12
16
  },
13
17
  {
14
18
  type: 'email',
15
- pattern: /(?<![A-Za-z0-9])([a-zA-Z0-9][a-zA-Z0-9._%+-]*@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/gi,
19
+ pattern: /([a-zA-Z0-9][a-zA-Z0-9._%+-]*@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/gi,
20
+ notPrecededBy: /[A-Za-z0-9]/,
16
21
  getLinkUrl: (text) => `mailto:${text}`,
17
22
  },
18
23
  {
19
24
  type: 'phone',
20
- pattern: /(?<![A-Za-z0-9_])(?:\+?\d{1,3}[\s.\-]?)?\(?\d{1,4}\)?[\s.\-]?\d{1,4}[\s.\-]?\d{1,9}(?![A-Za-z0-9_]|\.[a-z]{2,4})/gi,
25
+ pattern: /(?:\+?\d{1,3}[\s.\-]?)?\(?\d{1,4}\)?[\s.\-]?\d{1,4}[\s.\-]?\d{1,9}(?![A-Za-z0-9_]|\.[a-z]{2,4})/gi,
26
+ notPrecededBy: /[A-Za-z0-9_]/,
21
27
  getLinkUrl: (text) => {
22
28
  const cleaned = text.replace(/[\s.()\-]/g, '');
23
29
  return `tel:${cleaned}`;
@@ -31,15 +37,73 @@ const DEFAULT_MATCHERS = [
31
37
  },
32
38
  {
33
39
  type: 'mention',
34
- pattern: /(?<![a-zA-Z0-9._%+-])@[\w-]+/g,
40
+ pattern: /@[\w-]+/g,
41
+ notPrecededBy: /[a-zA-Z0-9._%+-]/,
35
42
  getLinkUrl: (text) => text,
36
43
  baseUrl: undefined,
37
44
  },
38
45
  ];
46
+ /**
47
+ * Runs `matcher.pattern` over `text`, honouring `matcher.notPrecededBy`.
48
+ *
49
+ * The pattern is cloned so a matcher shared between renders never carries
50
+ * `lastIndex` state around, which is what `String.prototype.matchAll` does too.
51
+ * When the preceding character is rejected the scan restarts at
52
+ * `match.index + 1` rather than after the match, so a start position ruled out
53
+ * here can still be part of a match found one character later - the same
54
+ * behaviour a lookbehind assertion gives.
55
+ */
56
+ // Compiling a RegExp is the expensive half of parsing, and every pattern here is a
57
+ // constant - only `lastIndex` varies per call, and that is reset on checkout. Without
58
+ // this, each message re-compiled the whole matcher set on every render of its text.
59
+ // Keyed on the source RegExp object so custom matchers benefit too, as long as the
60
+ // consumer keeps their pattern stable.
61
+ const globalPatternCache = new WeakMap();
62
+ const boundaryPatternCache = new WeakMap();
63
+ function globalPattern(pattern) {
64
+ let compiled = globalPatternCache.get(pattern);
65
+ if (!compiled) {
66
+ const flags = pattern.flags.includes('g') ? pattern.flags : `${pattern.flags}g`;
67
+ compiled = new RegExp(pattern.source, flags);
68
+ globalPatternCache.set(pattern, compiled);
69
+ }
70
+ // Reused across calls, so the cursor has to be rewound rather than assumed at 0.
71
+ compiled.lastIndex = 0;
72
+ return compiled;
73
+ }
74
+ function boundaryPattern(notPrecededBy) {
75
+ let compiled = boundaryPatternCache.get(notPrecededBy);
76
+ if (!compiled) {
77
+ // Dropped `g` here as well: `test` on a global regex advances lastIndex and
78
+ // would skip every other rejection.
79
+ compiled = new RegExp(notPrecededBy.source, notPrecededBy.flags.replace(/[gy]/g, ''));
80
+ boundaryPatternCache.set(notPrecededBy, compiled);
81
+ }
82
+ return compiled;
83
+ }
84
+ function execMatches(text, matcher) {
85
+ const { pattern, notPrecededBy, notPrecededByGroup } = matcher;
86
+ const regex = globalPattern(pattern);
87
+ const boundary = notPrecededBy ? boundaryPattern(notPrecededBy) : undefined;
88
+ const matches = [];
89
+ let match;
90
+ while ((match = regex.exec(text)) !== null) {
91
+ const guarded = notPrecededByGroup === undefined || match[notPrecededByGroup] !== undefined;
92
+ if (boundary && guarded && match.index > 0 && boundary.test(text[match.index - 1])) {
93
+ regex.lastIndex = match.index + 1;
94
+ continue;
95
+ }
96
+ matches.push(match);
97
+ // Zero-length matches would otherwise spin forever.
98
+ if (match[0].length === 0)
99
+ regex.lastIndex += 1;
100
+ }
101
+ return matches;
102
+ }
39
103
  function parseLinks(text, matchers) {
40
104
  const links = [];
41
105
  matchers.forEach(matcher => {
42
- const matches = text.matchAll(matcher.pattern);
106
+ const matches = execMatches(text, matcher);
43
107
  for (const match of matches)
44
108
  if (match.index !== undefined) {
45
109
  const matchText = match[0];
@@ -76,37 +140,42 @@ function removeOverlaps(links) {
76
140
  }
77
141
  return filtered;
78
142
  }
79
- export function LinkParser({ text, matchers: customMatchers, email = true, phone = true, url = true, hashtag = false, mention = false, hashtagUrl, mentionUrl, linkStyle, onPress, stripPrefix = true, textStyle, TextComponent = Text, }) {
80
- const activeMatchers = [];
81
- // Add custom matchers first (they take precedence)
82
- if (customMatchers)
83
- activeMatchers.push(...customMatchers);
84
- // Add default matchers based on flags
85
- if (url && !customMatchers?.some(m => m.type === 'url'))
86
- activeMatchers.push(DEFAULT_MATCHERS.find(m => m.type === 'url'));
87
- if (email && !customMatchers?.some(m => m.type === 'email'))
88
- activeMatchers.push(DEFAULT_MATCHERS.find(m => m.type === 'email'));
89
- if (phone && !customMatchers?.some(m => m.type === 'phone'))
90
- activeMatchers.push(DEFAULT_MATCHERS.find(m => m.type === 'phone'));
91
- if (hashtag && !customMatchers?.some(m => m.type === 'hashtag')) {
92
- const hashtagMatcher = { ...DEFAULT_MATCHERS.find(m => m.type === 'hashtag') };
93
- if (hashtagUrl) {
94
- hashtagMatcher.baseUrl = hashtagUrl;
95
- const baseUrl = hashtagUrl.endsWith('/') ? hashtagUrl : `${hashtagUrl}/`;
96
- hashtagMatcher.getLinkUrl = (text) => `${baseUrl}${text.substring(1)}`;
143
+ function LinkParserComponent({ text, matchers: customMatchers, email = true, phone = true, url = true, hashtag = false, mention = false, hashtagUrl, mentionUrl, linkStyle, onPress, stripPrefix = true, textStyle, TextComponent = Text, }) {
144
+ // Parsing is the expensive part of rendering a message body - matcher assembly plus a
145
+ // scan per matcher - and it depends only on the text and the matcher configuration.
146
+ // Left in the render body it re-ran on every render of every message.
147
+ const { links, activeMatchers } = useMemo(() => {
148
+ const activeMatchers = [];
149
+ // Add custom matchers first (they take precedence)
150
+ if (customMatchers)
151
+ activeMatchers.push(...customMatchers);
152
+ // Add default matchers based on flags
153
+ if (url && !customMatchers?.some(m => m.type === 'url'))
154
+ activeMatchers.push(DEFAULT_MATCHERS.find(m => m.type === 'url'));
155
+ if (email && !customMatchers?.some(m => m.type === 'email'))
156
+ activeMatchers.push(DEFAULT_MATCHERS.find(m => m.type === 'email'));
157
+ if (phone && !customMatchers?.some(m => m.type === 'phone'))
158
+ activeMatchers.push(DEFAULT_MATCHERS.find(m => m.type === 'phone'));
159
+ if (hashtag && !customMatchers?.some(m => m.type === 'hashtag')) {
160
+ const hashtagMatcher = { ...DEFAULT_MATCHERS.find(m => m.type === 'hashtag') };
161
+ if (hashtagUrl) {
162
+ hashtagMatcher.baseUrl = hashtagUrl;
163
+ const baseUrl = hashtagUrl.endsWith('/') ? hashtagUrl : `${hashtagUrl}/`;
164
+ hashtagMatcher.getLinkUrl = (text) => `${baseUrl}${text.substring(1)}`;
165
+ }
166
+ activeMatchers.push(hashtagMatcher);
97
167
  }
98
- activeMatchers.push(hashtagMatcher);
99
- }
100
- if (mention && !customMatchers?.some(m => m.type === 'mention')) {
101
- const mentionMatcher = { ...DEFAULT_MATCHERS.find(m => m.type === 'mention') };
102
- if (mentionUrl) {
103
- mentionMatcher.baseUrl = mentionUrl;
104
- const baseUrl = mentionUrl.endsWith('/') ? mentionUrl : `${mentionUrl}/`;
105
- mentionMatcher.getLinkUrl = (text) => `${baseUrl}${text.substring(1)}`;
168
+ if (mention && !customMatchers?.some(m => m.type === 'mention')) {
169
+ const mentionMatcher = { ...DEFAULT_MATCHERS.find(m => m.type === 'mention') };
170
+ if (mentionUrl) {
171
+ mentionMatcher.baseUrl = mentionUrl;
172
+ const baseUrl = mentionUrl.endsWith('/') ? mentionUrl : `${mentionUrl}/`;
173
+ mentionMatcher.getLinkUrl = (text) => `${baseUrl}${text.substring(1)}`;
174
+ }
175
+ activeMatchers.push(mentionMatcher);
106
176
  }
107
- activeMatchers.push(mentionMatcher);
108
- }
109
- const links = removeOverlaps(parseLinks(text, activeMatchers));
177
+ return { activeMatchers, links: removeOverlaps(parseLinks(text, activeMatchers)) };
178
+ }, [text, customMatchers, url, email, phone, hashtag, mention, hashtagUrl, mentionUrl]);
110
179
  if (links.length === 0)
111
180
  return <TextComponent style={textStyle}>{text}</TextComponent>;
112
181
  const elements = [];
@@ -151,4 +220,9 @@ export function LinkParser({ text, matchers: customMatchers, email = true, phone
151
220
  </TextComponent>);
152
221
  return <TextComponent style={textStyle}>{elements}</TextComponent>;
153
222
  }
223
+ // Rendered once per message body, and rebuilding its element list is the second most expensive
224
+ // thing a message row does after the row itself. The parse is already memoised, but the component
225
+ // still re-ran whenever its parent did - which, in a list, is on every commit that touches the
226
+ // row. Memoising the component lets an unchanged body skip the work entirely.
227
+ export const LinkParser = React.memo(LinkParserComponent);
154
228
  //# sourceMappingURL=linkParser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"linkParser.js","sourceRoot":"","sources":["../src/linkParser.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"linkParser.js","sourceRoot":"","sources":["../src/linkParser.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAAE,IAAI,EAAwB,OAAO,EAAE,MAAM,cAAc,CAAA;AAsDlE,MAAM,gBAAgB,GAAkB;IACtC;QACE,IAAI,EAAE,KAAK;QACX,2EAA2E;QAC3E,sDAAsD;QACtD,OAAO,EAAE,gJAAgJ;QACzJ,aAAa,EAAE,gBAAgB;QAC/B,kBAAkB,EAAE,CAAC;QACrB,UAAU,EAAE,CAAC,IAAY,EAAE,EAAE;YAC3B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC7B,OAAO,UAAU,IAAI,EAAE,CAAA;YAEzB,OAAO,IAAI,CAAA;QACb,CAAC;KACF;IACD;QACE,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,+DAA+D;QACxE,aAAa,EAAE,aAAa;QAC5B,UAAU,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,UAAU,IAAI,EAAE;KAC/C;IACD;QACE,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,mGAAmG;QAC5G,aAAa,EAAE,cAAc;QAC7B,UAAU,EAAE,CAAC,IAAY,EAAE,EAAE;YAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;YAC9C,OAAO,OAAO,OAAO,EAAE,CAAA;QACzB,CAAC;KACF;IACD;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,SAAS;QAClB,UAAU,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI;QAClC,OAAO,EAAE,SAAS;KACnB;IACD;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,UAAU;QACnB,aAAa,EAAE,kBAAkB;QACjC,UAAU,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI;QAClC,OAAO,EAAE,SAAS;KACnB;CACF,CAAA;AAED;;;;;;;;;GASG;AACH,mFAAmF;AACnF,sFAAsF;AACtF,oFAAoF;AACpF,mFAAmF;AACnF,uCAAuC;AACvC,MAAM,kBAAkB,GAAG,IAAI,OAAO,EAAkB,CAAA;AACxD,MAAM,oBAAoB,GAAG,IAAI,OAAO,EAAkB,CAAA;AAE1D,SAAS,aAAa,CAAC,OAAe;IACpC,IAAI,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAE9C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,GAAG,CAAA;QAC/E,QAAQ,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;QAC5C,kBAAkB,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;IAC3C,CAAC;IAED,iFAAiF;IACjF,QAAQ,CAAC,SAAS,GAAG,CAAC,CAAA;IACtB,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,SAAS,eAAe,CAAC,aAAqB;IAC5C,IAAI,QAAQ,GAAG,oBAAoB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;IAEtD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,4EAA4E;QAC5E,oCAAoC;QACpC,QAAQ,GAAG,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;QACrF,oBAAoB,CAAC,GAAG,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAA;IACnD,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,OAAoB;IACrD,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAA;IAC9D,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;IACpC,MAAM,QAAQ,GAAG,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC3E,MAAM,OAAO,GAAsB,EAAE,CAAA;IAErC,IAAI,KAA6B,CAAA;IACjC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,kBAAkB,KAAK,SAAS,IAAI,KAAK,CAAC,kBAAkB,CAAC,KAAK,SAAS,CAAA;QAE3F,IAAI,QAAQ,IAAI,OAAO,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACnF,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAA;YACjC,SAAQ;QACV,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAEnB,oDAAoD;QACpD,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC;YACvB,KAAK,CAAC,SAAS,IAAI,CAAC,CAAA;IAExB,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,IAAY,EAAE,QAAuB;IACvD,MAAM,KAAK,GAAiB,EAAE,CAAA;IAE9B,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;QACzB,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAC1C,KAAK,MAAM,KAAK,IAAI,OAAO;YACzB,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC9B,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;gBAC1B,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU;oBAC5B,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC;oBAC/B,CAAC,CAAC,SAAS,CAAA;gBACb,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW;oBAClC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC;oBAChC,CAAC,CAAC,SAAS,CAAA;gBAEb,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,IAAI,EAAE,QAAQ;oBACd,GAAG;oBACH,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,MAAM,EAAE,SAAS,CAAC,MAAM;iBACzB,CAAC,CAAA;YACJ,CAAC;IAEL,CAAC,CAAC,CAAA;IAEF,kCAAkC;IAClC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAA;AAChD,CAAC;AAED,SAAS,cAAc,CAAC,KAAmB;IACzC,MAAM,QAAQ,GAAiB,EAAE,CAAA;IAEjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;YAC1C,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAA;YACpD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAA;YAExC,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC;gBAC1D,CAAC,OAAO,GAAG,QAAQ,CAAC,KAAK,IAAI,OAAO,IAAI,WAAW,CAAC;gBACpD,CAAC,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,IAAI,OAAO,IAAI,WAAW,CAAC,CACzD,CAAA;QACH,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,UAAU;YACb,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAEvB,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,SAAS,mBAAmB,CAAC,EAC3B,IAAI,EACJ,QAAQ,EAAE,cAAc,EACxB,KAAK,GAAG,IAAI,EACZ,KAAK,GAAG,IAAI,EACZ,GAAG,GAAG,IAAI,EACV,OAAO,GAAG,KAAK,EACf,OAAO,GAAG,KAAK,EACf,UAAU,EACV,UAAU,EACV,SAAS,EACT,OAAO,EACP,WAAW,GAAG,IAAI,EAClB,SAAS,EACT,aAAa,GAAG,IAAI,GACJ;IAChB,sFAAsF;IACtF,oFAAoF;IACpF,sEAAsE;IACtE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE;QAC7C,MAAM,cAAc,GAAkB,EAAE,CAAA;QAExC,mDAAmD;QACnD,IAAI,cAAc;YAChB,cAAc,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAA;QAGxC,sCAAsC;QACtC,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC;YACrD,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAE,CAAC,CAAA;QAEpE,IAAI,KAAK,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC;YACzD,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAE,CAAC,CAAA;QAEtE,IAAI,KAAK,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC;YACzD,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAE,CAAC,CAAA;QAEtE,IAAI,OAAO,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,EAAE,CAAC;YAChE,MAAM,cAAc,GAAG,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAE,EAAE,CAAA;YAC/E,IAAI,UAAU,EAAE,CAAC;gBACf,cAAc,CAAC,OAAO,GAAG,UAAU,CAAA;gBACnC,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,GAAG,CAAA;gBACxE,cAAc,CAAC,UAAU,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAA;YAChF,CAAC;YACD,cAAc,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QACrC,CAAC;QAED,IAAI,OAAO,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,EAAE,CAAC;YAChE,MAAM,cAAc,GAAG,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAE,EAAE,CAAA;YAC/E,IAAI,UAAU,EAAE,CAAC;gBACf,cAAc,CAAC,OAAO,GAAG,UAAU,CAAA;gBACnC,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,GAAG,CAAA;gBACxE,cAAc,CAAC,UAAU,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAA;YAChF,CAAC;YACD,cAAc,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QACrC,CAAC;QAGD,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,CAAC,UAAU,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,EAAE,CAAA;IACpF,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAA;IAEvF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QACpB,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,CAAA;IAGhE,MAAM,QAAQ,GAAsB,EAAE,CAAA;IACtC,IAAI,SAAS,GAAG,CAAC,CAAA;IAEjB,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC5B,uBAAuB;QACvB,IAAI,IAAI,CAAC,KAAK,GAAG,SAAS;YACxB,QAAQ,CAAC,IAAI,CACX,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CACpD;UAAA,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CACxC;QAAA,EAAE,aAAa,CAAC,CACjB,CAAA;QAGH,iCAAiC;QACjC,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAA;QAE9D,wBAAwB;QACxB,IAAI,OAAO,EAAE,UAAU,EAAE,CAAC;YACxB,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QAC1E,CAAC;aAAM,CAAC;YACN,MAAM,WAAW,GAAG,GAAG,EAAE;gBACvB,IAAI,OAAO,EAAE,OAAO;oBAClB,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;qBACjC,IAAI,OAAO;oBACd,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;;oBAE5B,mBAAmB;oBACnB,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;wBACpC,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAA;oBAC1C,CAAC,CAAC,CAAA;YAEN,CAAC,CAAA;YAED,IAAI,WAAW,GAAG,IAAI,CAAC,IAAI,CAAA;YAC3B,IAAI,WAAW,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK;gBACpC,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAA;YAGxD,QAAQ,CAAC,IAAI,CACX,CAAC,aAAa,CACZ,GAAG,CAAC,CAAC,QAAQ,KAAK,EAAE,CAAC,CACrB,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CACnC,OAAO,CAAC,CAAC,WAAW,CAAC,CAErB;UAAA,CAAC,WAAW,CACd;QAAA,EAAE,aAAa,CAAC,CACjB,CAAA;QACH,CAAC;QAED,SAAS,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAA;IACtC,CAAC,CAAC,CAAA;IAEF,qBAAqB;IACrB,IAAI,SAAS,GAAG,IAAI,CAAC,MAAM;QACzB,QAAQ,CAAC,IAAI,CACX,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAC7C;QAAA,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAC5B;MAAA,EAAE,aAAa,CAAC,CACjB,CAAA;IAGH,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC,CAAA;AACpE,CAAC;AAED,+FAA+F;AAC/F,kGAAkG;AAClG,+FAA+F;AAC/F,8EAA8E;AAC9E,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA"}
package/llms.txt ADDED
@@ -0,0 +1,175 @@
1
+ # @kesha-antonov/react-native-chat
2
+
3
+ > Chat UI for React Native, Expo and Web. A maintained continuation of
4
+ > `react-native-gifted-chat` with the same `IMessage` model and prop names, plus dark mode
5
+ > and theming, streaming (AI) messages, emoji reactions, swipe-to-reply, and inline
6
+ > video/audio/location messages. TypeScript-first; no native code of its own.
7
+
8
+ This file is a condensed integration guide for AI agents. Full docs: [README](https://github.com/kesha-antonov/react-native-chat#readme).
9
+
10
+ ## Install
11
+
12
+ Required peers - all four must be installed and configured:
13
+
14
+ ```bash
15
+ npx expo install @kesha-antonov/react-native-chat react-native-reanimated react-native-gesture-handler react-native-safe-area-context react-native-keyboard-controller
16
+ ```
17
+
18
+ Bare React Native: use `yarn add` / `npm install --save` with the same list, then
19
+ `npx pod-install`, then add Reanimated's Babel plugin to `babel.config.js`
20
+ (`plugins: ['react-native-worklets/plugin']` for Reanimated 4, `'react-native-reanimated/plugin'` for 3).
21
+
22
+ Requires React Native >= 0.70, iOS >= 13.4, Android API 21+, Expo SDK 50+.
23
+
24
+ ## Minimal working example
25
+
26
+ ```tsx
27
+ import { useCallback, useState } from 'react'
28
+ import { Chat, IMessage } from '@kesha-antonov/react-native-chat'
29
+
30
+ export function ChatScreen () {
31
+ const [messages, setMessages] = useState<IMessage[]>([
32
+ {
33
+ _id: 1,
34
+ text: 'Hello developer',
35
+ createdAt: new Date(),
36
+ user: { _id: 2, name: 'John Doe' },
37
+ },
38
+ ])
39
+
40
+ const onSend = useCallback((newMessages: IMessage[] = []) => {
41
+ setMessages(previous => Chat.append(previous, newMessages))
42
+ }, [])
43
+
44
+ return <Chat messages={messages} onSend={onSend} user={{ _id: 1 }} />
45
+ }
46
+ ```
47
+
48
+ `Chat` fills its parent, so give it a `flex: 1` container. It mounts its own
49
+ `GestureHandlerRootView` and `KeyboardProvider` unless the app already provides them.
50
+
51
+ ## Data model
52
+
53
+ ```ts
54
+ interface IMessage {
55
+ _id: string | number
56
+ text: string
57
+ createdAt: Date | number
58
+ user: { _id: string | number, name?: string, avatar?: string | number | (() => React.ReactNode) }
59
+ image?: string
60
+ video?: string
61
+ audio?: string
62
+ system?: boolean // renders as a centered system notice
63
+ sent?: boolean // ✓
64
+ received?: boolean // ✓✓
65
+ pending?: boolean // 🕓
66
+ streaming?: boolean // shows a typing caret while tokens arrive
67
+ quickReplies?: { type: 'radio' | 'checkbox', values: { title: string, value: string }[], keepIt?: boolean }
68
+ replyMessage?: { _id: string | number, text: string, user: User, image?: string, audio?: string }
69
+ reactions?: { emoji: string, userIds: (string | number)[] }[]
70
+ location?: { latitude: number, longitude: number }
71
+ }
72
+ ```
73
+
74
+ Messages are newest-first by default (`isInverted` defaults to `true`). `Chat.append(previous, newMessages)`
75
+ prepends correctly for that ordering.
76
+
77
+ ## Props you will reach for first
78
+
79
+ - `messages`, `user`, `onSend` - required
80
+ - `text` + `textInputProps.onChangeText` - only if you control the composer text externally
81
+ - `theme` / `darkTheme` - deep-merged token overrides (`colors`, `radii`, `spacing`, `typography`, …)
82
+ - `colorScheme` - `'light' | 'dark'` to force a scheme; omit to follow the system
83
+ - `locale` + `labels` - 15 built-in translations (es, fr, de, ru, zh, ar, pt, ja, ko, it, tr, hi, nl, pl, id; English is the default, `pt-BR` falls back to `pt`) and per-string overrides
84
+ - `renderBubble`, `renderMessageText`, `renderAvatar`, `renderInputToolbar`, … - override any component
85
+ - `isTyping` - typing indicator
86
+ - `loadEarlierMessagesProps` - `{ isAvailable, onPress, isLoading, isInfiniteScrollEnabled }`
87
+ - `isScrollToBottomEnabled`, `listProps`, `isFlashListEnabled`
88
+
89
+ ## Optional features and the peers they need
90
+
91
+ Each is inert until you install its peer and turn it on - nothing is forced on the user.
92
+
93
+ | Feature | Enable with | Extra peer dependency |
94
+ | --- | --- | --- |
95
+ | Inline video playback | `IMessage.video` | `expo-video` |
96
+ | Inline audio playback | `IMessage.audio` | `expo-audio` |
97
+ | Voice notes (hold to record) | `audioRecording={{ isEnabled: true }}` | `expo-audio`, plus `react-native-audio-api` for the waveform |
98
+ | Video messages (camera notes) | `videoRecording={{ isEnabled: true }}` | `react-native-vision-camera`, or `expo-image-picker` |
99
+ | Location messages | `IMessage.location` | none |
100
+ | Emoji reactions | `reactions={{ isEnabled: true, onReactionPress }}` | none |
101
+ | Long-press action menu | `messageActions={[{ label, onPress }]}` | none |
102
+ | Rich markdown for AI replies | `messageTextProps={{ markdown: true }}` | none (built-in), `react-native-streamdown` upgrades it |
103
+ | Recycling list for huge histories | `isFlashListEnabled` | `@shopify/flash-list` |
104
+ | Custom icons | `icons={{ send: … }}` | `react-native-svg` for the built-in Lucide glyphs |
105
+
106
+ ## Streaming (AI) replies
107
+
108
+ ```tsx
109
+ import { Chat, IMessage, useStreamingMessages } from '@kesha-antonov/react-native-chat'
110
+
111
+ const { messages, append, startStream, isStreaming, stop } = useStreamingMessages<IMessage>()
112
+
113
+ const onSend = useCallback((newMessages: IMessage[] = []) => {
114
+ append(newMessages[0])
115
+ const stream = startStream({ user: { _id: 2, name: 'Assistant' } })
116
+
117
+ runModel(newMessages[0].text, {
118
+ signal: stream.signal, // aborts when stop() is called
119
+ onToken: token => stream.push(token), // batched, one render per frame
120
+ onDone: () => stream.done(),
121
+ })
122
+ }, [append, startStream])
123
+ ```
124
+
125
+ Tokens are batched with `requestAnimationFrame`, and only the streaming bubble re-renders.
126
+ The send button becomes a Stop control while `isStreaming`.
127
+
128
+ ## Emoji reactions
129
+
130
+ Reaction state is owned by the app, so it works with any backend. `onReactionPress` fires for
131
+ both the picker and a pill tap; you implement the toggle:
132
+
133
+ ```tsx
134
+ <Chat
135
+ reactions={{
136
+ isEnabled: true,
137
+ onReactionPress: (message, emoji) => toggleReaction(message._id, emoji),
138
+ }}
139
+ {...props}
140
+ />
141
+ ```
142
+
143
+ ## Coming from react-native-gifted-chat
144
+
145
+ Same props, same `IMessage`. Swap the package and rename: `GiftedChat` → `Chat`,
146
+ `GiftedAvatar` → `ChatAvatar`, `GiftedChatContext` → `ChatContext`. Everything else -
147
+ `IMessage`, `User`, `useChatContext` - is unchanged. A codemod is in
148
+ [docs/MIGRATION.md](https://github.com/kesha-antonov/react-native-chat/blob/main/docs/MIGRATION.md).
149
+
150
+ ## Common mistakes
151
+
152
+ - **Unstable render props.** Each row is `React.memo`'d with a comparator that
153
+ reference-compares every prop except the message. An inline `renderBubble={props => …}` or
154
+ `reactions={{ … }}` re-renders every row on every parent render - wrap them in `useCallback` /
155
+ `useMemo`.
156
+ - **Mutating messages in place.** The comparator detects updates by value, so always build new
157
+ arrays and objects.
158
+ - **Setting `keyboardVerticalOffset` by hand.** Chat measures its own position on screen; a
159
+ manual value replaces the measured one and usually leaves the toolbar floating. Pass one only
160
+ to add deliberate extra space.
161
+ - **Nesting a second `GestureHandlerRootView`.** If the app already mounts one (directly or via
162
+ a bottom-sheet library), set `enableGestureHandlerRootView={false}` - it cannot be
163
+ auto-detected. An existing `KeyboardProvider` *is* detected and reused automatically.
164
+ - **Expecting `actionSheet()` to work out of the box.** The bundled
165
+ `@expo/react-native-action-sheet` dependency was removed; prefer `messageActions`, or supply
166
+ your own `actionSheet` implementation.
167
+ - **Forgetting the container.** `<Chat>` needs a parent with `flex: 1`.
168
+
169
+ ## Links
170
+
171
+ - [README](https://github.com/kesha-antonov/react-native-chat#readme) - full props reference and guides
172
+ - [Migration guide](https://github.com/kesha-antonov/react-native-chat/blob/main/docs/MIGRATION.md)
173
+ - [Streaming guide](https://github.com/kesha-antonov/react-native-chat/blob/main/docs/STREAMING.md)
174
+ - [Example app](https://github.com/kesha-antonov/react-native-chat/tree/main/example)
175
+ - [Expo Snack playground](https://snack.expo.dev/@kesha-antonov/react-native-chat-playground)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kesha-antonov/react-native-chat",
3
- "version": "4.4.0",
3
+ "version": "5.0.1",
4
4
  "description": "The most complete chat UI for React Native & Web - streaming AI messages, emoji reactions, replies, quick replies, and full customization. TypeScript-first, Expo-ready. A maintained react-native-gifted-chat successor.",
5
5
  "keywords": [
6
6
  "react-native",
@@ -45,7 +45,8 @@
45
45
  "access": "public"
46
46
  },
47
47
  "files": [
48
- "lib"
48
+ "lib",
49
+ "llms.txt"
49
50
  ],
50
51
  "scripts": {
51
52
  "typecheck": "yarn tsc --noEmit",
@@ -69,9 +70,9 @@
69
70
  },
70
71
  "dependencies": {
71
72
  "@types/lodash.isequal": "^4.5.8",
72
- "dayjs": "^1.11.21",
73
+ "dayjs": "^1.11.23",
73
74
  "lodash.isequal": "^4.5.0",
74
- "react-native-zoom-reanimated": "^1.5.4"
75
+ "react-native-zoom-reanimated": "^1.5.6"
75
76
  },
76
77
  "devDependencies": {
77
78
  "@babel/core": "^7.28.5",
@@ -84,28 +85,26 @@
84
85
  "@react-native-community/cli": "20.2.0",
85
86
  "@react-native-community/cli-platform-android": "20.2.0",
86
87
  "@react-native-community/cli-platform-ios": "20.2.0",
87
- "@react-native/babel-preset": "0.86.2",
88
- "@react-native/eslint-config": "0.86.2",
89
- "@react-native/jest-preset": "0.86.2",
90
- "@react-native/metro-config": "0.86.2",
91
- "@react-native/typescript-config": "0.86.2",
88
+ "@react-native/babel-preset": "0.86.3",
89
+ "@react-native/eslint-config": "0.86.3",
90
+ "@react-native/jest-preset": "0.86.3",
91
+ "@react-native/metro-config": "0.86.3",
92
+ "@react-native/typescript-config": "0.86.3",
92
93
  "@shopify/flash-list": "^2.3.2",
93
94
  "@stylistic/eslint-plugin": "^5.10.0",
94
95
  "@testing-library/dom": "^10.4.1",
95
96
  "@testing-library/react": "^16.3.2",
96
- "@testing-library/react-native": "^13.3.3",
97
+ "@testing-library/react-native": "^14.0.1",
97
98
  "@types/jest": "^29.5.14",
98
99
  "@types/react": "^19.2.18",
99
- "@types/react-dom": "^19.2.4",
100
- "@types/react-native": "^0.73.0",
101
- "@types/react-test-renderer": "^19.1.0",
102
- "@typescript-eslint/eslint-plugin": "^8.66.0",
103
- "@typescript-eslint/parser": "^8.66.0",
100
+ "@types/react-dom": "^19.2.5",
101
+ "@typescript-eslint/eslint-plugin": "^8.68.0",
102
+ "@typescript-eslint/parser": "^8.68.0",
104
103
  "babel-jest": "^29.7.0",
105
- "eslint": "^10.8.0",
104
+ "eslint": "^10.9.1",
106
105
  "eslint-import-resolver-typescript": "^4.4.5",
107
106
  "eslint-plugin-import": "^2.32.0",
108
- "eslint-plugin-jest": "^29.16.0",
107
+ "eslint-plugin-jest": "^29.16.2",
109
108
  "eslint-plugin-perfectionist": "^5.10.1",
110
109
  "eslint-plugin-react": "^7.37.5",
111
110
  "eslint-plugin-react-hooks": "^7.1.1",
@@ -115,13 +114,13 @@
115
114
  "lint-staged": "^17.3.0",
116
115
  "react": "19.2.3",
117
116
  "react-dom": "19.2.3",
118
- "react-native": "0.86.2",
117
+ "react-native": "0.86.3",
119
118
  "react-native-gesture-handler": "~2.32.0",
120
- "react-native-keyboard-controller": "^1.21.14",
121
- "react-native-reanimated": "~4.5.3",
119
+ "react-native-keyboard-controller": "^1.22.4",
120
+ "react-native-reanimated": "~4.6.0",
122
121
  "react-native-safe-area-context": "~5.7.0",
123
- "react-native-worklets": "~0.10.3",
124
- "react-test-renderer": "19.2.3",
122
+ "react-native-worklets": "~0.12.1",
123
+ "test-renderer": "^1.2.0",
125
124
  "typescript": "^6.0.3"
126
125
  },
127
126
  "peerDependencies": {