react-native-richify 1.0.0

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 (172) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +231 -0
  3. package/lib/commonjs/components/OverlayText.d.js +6 -0
  4. package/lib/commonjs/components/OverlayText.d.js.map +1 -0
  5. package/lib/commonjs/components/OverlayText.js +45 -0
  6. package/lib/commonjs/components/OverlayText.js.map +1 -0
  7. package/lib/commonjs/components/RichTextInput.d.js +6 -0
  8. package/lib/commonjs/components/RichTextInput.d.js.map +1 -0
  9. package/lib/commonjs/components/RichTextInput.js +160 -0
  10. package/lib/commonjs/components/RichTextInput.js.map +1 -0
  11. package/lib/commonjs/components/Toolbar.d.js +6 -0
  12. package/lib/commonjs/components/Toolbar.d.js.map +1 -0
  13. package/lib/commonjs/components/Toolbar.js +99 -0
  14. package/lib/commonjs/components/Toolbar.js.map +1 -0
  15. package/lib/commonjs/components/ToolbarButton.d.js +6 -0
  16. package/lib/commonjs/components/ToolbarButton.d.js.map +1 -0
  17. package/lib/commonjs/components/ToolbarButton.js +63 -0
  18. package/lib/commonjs/components/ToolbarButton.js.map +1 -0
  19. package/lib/commonjs/constants/defaultStyles.d.js +6 -0
  20. package/lib/commonjs/constants/defaultStyles.d.js.map +1 -0
  21. package/lib/commonjs/constants/defaultStyles.js +172 -0
  22. package/lib/commonjs/constants/defaultStyles.js.map +1 -0
  23. package/lib/commonjs/context/RichTextContext.d.js +6 -0
  24. package/lib/commonjs/context/RichTextContext.d.js.map +1 -0
  25. package/lib/commonjs/context/RichTextContext.js +61 -0
  26. package/lib/commonjs/context/RichTextContext.js.map +1 -0
  27. package/lib/commonjs/hooks/useFormatting.d.js +6 -0
  28. package/lib/commonjs/hooks/useFormatting.d.js.map +1 -0
  29. package/lib/commonjs/hooks/useFormatting.js +82 -0
  30. package/lib/commonjs/hooks/useFormatting.js.map +1 -0
  31. package/lib/commonjs/hooks/useRichText.d.js +6 -0
  32. package/lib/commonjs/hooks/useRichText.d.js.map +1 -0
  33. package/lib/commonjs/hooks/useRichText.js +136 -0
  34. package/lib/commonjs/hooks/useRichText.js.map +1 -0
  35. package/lib/commonjs/hooks/useSelection.d.js +6 -0
  36. package/lib/commonjs/hooks/useSelection.d.js.map +1 -0
  37. package/lib/commonjs/hooks/useSelection.js +39 -0
  38. package/lib/commonjs/hooks/useSelection.js.map +1 -0
  39. package/lib/commonjs/index.d.js +186 -0
  40. package/lib/commonjs/index.d.js.map +1 -0
  41. package/lib/commonjs/index.js +186 -0
  42. package/lib/commonjs/index.js.map +1 -0
  43. package/lib/commonjs/package.json +1 -0
  44. package/lib/commonjs/types/index.d.js +6 -0
  45. package/lib/commonjs/types/index.d.js.map +1 -0
  46. package/lib/commonjs/types/index.js +6 -0
  47. package/lib/commonjs/types/index.js.map +1 -0
  48. package/lib/commonjs/utils/formatter.d.js +13 -0
  49. package/lib/commonjs/utils/formatter.d.js.map +1 -0
  50. package/lib/commonjs/utils/formatter.js +229 -0
  51. package/lib/commonjs/utils/formatter.js.map +1 -0
  52. package/lib/commonjs/utils/parser.d.js +6 -0
  53. package/lib/commonjs/utils/parser.d.js.map +1 -0
  54. package/lib/commonjs/utils/parser.js +221 -0
  55. package/lib/commonjs/utils/parser.js.map +1 -0
  56. package/lib/commonjs/utils/styleMapper.d.js +6 -0
  57. package/lib/commonjs/utils/styleMapper.d.js.map +1 -0
  58. package/lib/commonjs/utils/styleMapper.js +87 -0
  59. package/lib/commonjs/utils/styleMapper.js.map +1 -0
  60. package/lib/module/components/OverlayText.d.js +4 -0
  61. package/lib/module/components/OverlayText.d.js.map +1 -0
  62. package/lib/module/components/OverlayText.js +41 -0
  63. package/lib/module/components/OverlayText.js.map +1 -0
  64. package/lib/module/components/RichTextInput.d.js +4 -0
  65. package/lib/module/components/RichTextInput.d.js.map +1 -0
  66. package/lib/module/components/RichTextInput.js +155 -0
  67. package/lib/module/components/RichTextInput.js.map +1 -0
  68. package/lib/module/components/Toolbar.d.js +4 -0
  69. package/lib/module/components/Toolbar.d.js.map +1 -0
  70. package/lib/module/components/Toolbar.js +95 -0
  71. package/lib/module/components/Toolbar.js.map +1 -0
  72. package/lib/module/components/ToolbarButton.d.js +4 -0
  73. package/lib/module/components/ToolbarButton.d.js.map +1 -0
  74. package/lib/module/components/ToolbarButton.js +59 -0
  75. package/lib/module/components/ToolbarButton.js.map +1 -0
  76. package/lib/module/constants/defaultStyles.d.js +4 -0
  77. package/lib/module/constants/defaultStyles.d.js.map +1 -0
  78. package/lib/module/constants/defaultStyles.js +168 -0
  79. package/lib/module/constants/defaultStyles.js.map +1 -0
  80. package/lib/module/context/RichTextContext.d.js +4 -0
  81. package/lib/module/context/RichTextContext.d.js.map +1 -0
  82. package/lib/module/context/RichTextContext.js +55 -0
  83. package/lib/module/context/RichTextContext.js.map +1 -0
  84. package/lib/module/hooks/useFormatting.d.js +11 -0
  85. package/lib/module/hooks/useFormatting.d.js.map +1 -0
  86. package/lib/module/hooks/useFormatting.js +78 -0
  87. package/lib/module/hooks/useFormatting.js.map +1 -0
  88. package/lib/module/hooks/useRichText.d.js +4 -0
  89. package/lib/module/hooks/useRichText.d.js.map +1 -0
  90. package/lib/module/hooks/useRichText.js +132 -0
  91. package/lib/module/hooks/useRichText.js.map +1 -0
  92. package/lib/module/hooks/useSelection.d.js +4 -0
  93. package/lib/module/hooks/useSelection.d.js.map +1 -0
  94. package/lib/module/hooks/useSelection.js +35 -0
  95. package/lib/module/hooks/useSelection.js.map +1 -0
  96. package/lib/module/index.d.js +15 -0
  97. package/lib/module/index.d.js.map +1 -0
  98. package/lib/module/index.js +25 -0
  99. package/lib/module/index.js.map +1 -0
  100. package/lib/module/types/index.d.js +4 -0
  101. package/lib/module/types/index.d.js.map +1 -0
  102. package/lib/module/types/index.js +4 -0
  103. package/lib/module/types/index.js.map +1 -0
  104. package/lib/module/utils/formatter.d.js +30 -0
  105. package/lib/module/utils/formatter.d.js.map +1 -0
  106. package/lib/module/utils/formatter.js +217 -0
  107. package/lib/module/utils/formatter.js.map +1 -0
  108. package/lib/module/utils/parser.d.js +4 -0
  109. package/lib/module/utils/parser.d.js.map +1 -0
  110. package/lib/module/utils/parser.js +211 -0
  111. package/lib/module/utils/parser.js.map +1 -0
  112. package/lib/module/utils/styleMapper.d.js +4 -0
  113. package/lib/module/utils/styleMapper.d.js.map +1 -0
  114. package/lib/module/utils/styleMapper.js +82 -0
  115. package/lib/module/utils/styleMapper.js.map +1 -0
  116. package/lib/typescript/src/components/OverlayText.d.ts +11 -0
  117. package/lib/typescript/src/components/OverlayText.d.ts.map +1 -0
  118. package/lib/typescript/src/components/RichTextInput.d.ts +21 -0
  119. package/lib/typescript/src/components/RichTextInput.d.ts.map +1 -0
  120. package/lib/typescript/src/components/Toolbar.d.ts +13 -0
  121. package/lib/typescript/src/components/Toolbar.d.ts.map +1 -0
  122. package/lib/typescript/src/components/ToolbarButton.d.ts +8 -0
  123. package/lib/typescript/src/components/ToolbarButton.d.ts.map +1 -0
  124. package/lib/typescript/src/constants/defaultStyles.d.ts +46 -0
  125. package/lib/typescript/src/constants/defaultStyles.d.ts.map +1 -0
  126. package/lib/typescript/src/context/RichTextContext.d.ts +31 -0
  127. package/lib/typescript/src/context/RichTextContext.d.ts.map +1 -0
  128. package/lib/typescript/src/hooks/useFormatting.d.ts +26 -0
  129. package/lib/typescript/src/hooks/useFormatting.d.ts.map +1 -0
  130. package/lib/typescript/src/hooks/useRichText.d.ts +17 -0
  131. package/lib/typescript/src/hooks/useRichText.d.ts.map +1 -0
  132. package/lib/typescript/src/hooks/useSelection.d.ts +14 -0
  133. package/lib/typescript/src/hooks/useSelection.d.ts.map +1 -0
  134. package/lib/typescript/src/index.d.ts +16 -0
  135. package/lib/typescript/src/index.d.ts.map +1 -0
  136. package/lib/typescript/src/types/index.d.ts +245 -0
  137. package/lib/typescript/src/types/index.d.ts.map +1 -0
  138. package/lib/typescript/src/utils/formatter.d.ts +29 -0
  139. package/lib/typescript/src/utils/formatter.d.ts.map +1 -0
  140. package/lib/typescript/src/utils/parser.d.ts +46 -0
  141. package/lib/typescript/src/utils/parser.d.ts.map +1 -0
  142. package/lib/typescript/src/utils/styleMapper.d.ts +16 -0
  143. package/lib/typescript/src/utils/styleMapper.d.ts.map +1 -0
  144. package/package.json +83 -0
  145. package/src/components/OverlayText.d.ts +10 -0
  146. package/src/components/OverlayText.tsx +46 -0
  147. package/src/components/RichTextInput.d.ts +20 -0
  148. package/src/components/RichTextInput.tsx +174 -0
  149. package/src/components/Toolbar.d.ts +12 -0
  150. package/src/components/Toolbar.tsx +100 -0
  151. package/src/components/ToolbarButton.d.ts +7 -0
  152. package/src/components/ToolbarButton.tsx +65 -0
  153. package/src/constants/defaultStyles.d.ts +45 -0
  154. package/src/constants/defaultStyles.ts +144 -0
  155. package/src/context/RichTextContext.d.ts +30 -0
  156. package/src/context/RichTextContext.tsx +63 -0
  157. package/src/hooks/useFormatting.d.ts +25 -0
  158. package/src/hooks/useFormatting.ts +135 -0
  159. package/src/hooks/useRichText.d.ts +16 -0
  160. package/src/hooks/useRichText.ts +171 -0
  161. package/src/hooks/useSelection.d.ts +13 -0
  162. package/src/hooks/useSelection.ts +40 -0
  163. package/src/index.d.ts +15 -0
  164. package/src/index.ts +68 -0
  165. package/src/types/index.d.ts +244 -0
  166. package/src/types/index.ts +295 -0
  167. package/src/utils/formatter.d.ts +28 -0
  168. package/src/utils/formatter.ts +276 -0
  169. package/src/utils/parser.d.ts +45 -0
  170. package/src/utils/parser.ts +252 -0
  171. package/src/utils/styleMapper.d.ts +15 -0
  172. package/src/utils/styleMapper.ts +92 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 react-native-richify contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,231 @@
1
+ # react-native-richify
2
+
3
+ A production-grade, fully customizable React Native Rich Text Input using the **Overlay Technique** — no WebView required.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/react-native-richify.svg)](https://www.npmjs.com/package/react-native-richify)
6
+ [![license](https://img.shields.io/npm/l/react-native-richify.svg)](https://github.com/soumya-99/react-native-richify/blob/main/LICENSE)
7
+
8
+ ## Features
9
+
10
+ - 🚀 **No WebView** — Pure React Native components (TextInput + Text overlay)
11
+ - 📝 **Rich Formatting** — Bold, italic, underline, strikethrough, code
12
+ - 🎨 **Text & Background Colors** — Full color customization
13
+ - 📐 **Font Sizes & Headings** — H1, H2, H3 presets + custom sizes
14
+ - 🔧 **Fully Customizable Toolbar** — Default toolbar + render props for full control
15
+ - 🎭 **Theming** — Complete theme system with plug-and-play defaults
16
+ - 💾 **Serialization** — Export/import as JSON
17
+ - 📦 **TypeScript First** — Full type definitions out of the box
18
+ - 🪝 **Headless Hook** — `useRichText` for building custom UIs
19
+ - 🌐 **Context API** — `RichTextProvider` for nested component access
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ npm install react-native-richify
25
+ # or
26
+ yarn add react-native-richify
27
+ ```
28
+
29
+ No native dependencies required. Works with Expo and bare React Native.
30
+
31
+ ## Quick Start
32
+
33
+ ```tsx
34
+ import React from 'react';
35
+ import { View } from 'react-native';
36
+ import { RichTextInput } from 'react-native-richify';
37
+
38
+ export default function App() {
39
+ return (
40
+ <View style={{ flex: 1, padding: 16 }}>
41
+ <RichTextInput
42
+ placeholder="Start typing..."
43
+ showToolbar
44
+ onChangeText={(text) => console.log('Plain text:', text)}
45
+ onChangeSegments={(segments) => console.log('Segments:', segments)}
46
+ />
47
+ </View>
48
+ );
49
+ }
50
+ ```
51
+
52
+ That's it! You get a fully functional rich text editor with default styling.
53
+
54
+ ## API Reference
55
+
56
+ ### `<RichTextInput />`
57
+
58
+ The main component. Drop it in and it works.
59
+
60
+ | Prop | Type | Default | Description |
61
+ |------|------|---------|-------------|
62
+ | `initialSegments` | `StyledSegment[]` | `[]` | Initial content |
63
+ | `onChangeSegments` | `(segments: StyledSegment[]) => void` | — | Called when content changes |
64
+ | `onChangeText` | `(text: string) => void` | — | Called with plain text |
65
+ | `placeholder` | `string` | `"Start typing..."` | Placeholder text |
66
+ | `editable` | `boolean` | `true` | Whether input is editable |
67
+ | `maxLength` | `number` | — | Max character length |
68
+ | `showToolbar` | `boolean` | `true` | Show formatting toolbar |
69
+ | `toolbarPosition` | `'top' \| 'bottom'` | `'top'` | Toolbar position |
70
+ | `toolbarItems` | `ToolbarItem[]` | Default items | Custom toolbar items |
71
+ | `theme` | `RichTextTheme` | Default theme | Theme overrides |
72
+ | `multiline` | `boolean` | `true` | Enable multiline |
73
+ | `minHeight` | `number` | `120` | Minimum editor height |
74
+ | `maxHeight` | `number` | — | Maximum editor height |
75
+ | `autoFocus` | `boolean` | `false` | Auto-focus on mount |
76
+ | `renderToolbar` | `(props) => ReactElement` | — | Custom toolbar renderer |
77
+ | `onReady` | `(actions: RichTextActions) => void` | — | Called with action methods |
78
+
79
+ ### `useRichText(options?)`
80
+
81
+ Headless hook for building custom UIs.
82
+
83
+ ```tsx
84
+ import { useRichText } from 'react-native-richify';
85
+
86
+ function MyEditor() {
87
+ const { state, actions } = useRichText({
88
+ onChangeText: (text) => console.log(text),
89
+ });
90
+
91
+ return (
92
+ <>
93
+ <Button title="Bold" onPress={() => actions.toggleFormat('bold')} />
94
+ <TextInput
95
+ value={actions.getPlainText()}
96
+ onChangeText={actions.handleTextChange}
97
+ onSelectionChange={(e) =>
98
+ actions.handleSelectionChange(e.nativeEvent.selection)
99
+ }
100
+ />
101
+ </>
102
+ );
103
+ }
104
+ ```
105
+
106
+ ### `<RichTextProvider>` & `useRichTextContext()`
107
+
108
+ Share state across the component tree:
109
+
110
+ ```tsx
111
+ import { RichTextProvider, useRichTextContext } from 'react-native-richify';
112
+
113
+ function CustomToolbar() {
114
+ const { state, actions } = useRichTextContext();
115
+ return <Button title="B" onPress={() => actions.toggleFormat('bold')} />;
116
+ }
117
+
118
+ function App() {
119
+ return (
120
+ <RichTextProvider onChangeText={console.log}>
121
+ <CustomToolbar />
122
+ <RichTextInput showToolbar={false} />
123
+ </RichTextProvider>
124
+ );
125
+ }
126
+ ```
127
+
128
+ ### Actions
129
+
130
+ | Method | Description |
131
+ |--------|-------------|
132
+ | `toggleFormat(format)` | Toggle bold/italic/underline/strikethrough/code |
133
+ | `setColor(color)` | Set text color |
134
+ | `setBackgroundColor(color)` | Set highlight color |
135
+ | `setFontSize(size)` | Set font size |
136
+ | `setHeading(level)` | Set heading (h1/h2/h3/none) |
137
+ | `handleTextChange(text)` | Process text input changes |
138
+ | `handleSelectionChange(sel)` | Process selection changes |
139
+ | `getPlainText()` | Get plain text content |
140
+ | `exportJSON()` | Export segments as JSON |
141
+ | `importJSON(segments)` | Import segments from JSON |
142
+ | `clear()` | Clear all content |
143
+
144
+ ## Theming
145
+
146
+ Customize every aspect of the editor:
147
+
148
+ ```tsx
149
+ <RichTextInput
150
+ theme={{
151
+ colors: {
152
+ primary: '#8B5CF6',
153
+ background: '#1F2937',
154
+ text: '#F9FAFB',
155
+ placeholder: '#6B7280',
156
+ toolbarBackground: '#374151',
157
+ toolbarBorder: '#4B5563',
158
+ cursor: '#8B5CF6',
159
+ },
160
+ containerStyle: {
161
+ borderRadius: 16,
162
+ borderWidth: 2,
163
+ borderColor: '#4B5563',
164
+ },
165
+ toolbarButtonActiveStyle: {
166
+ backgroundColor: '#4C1D95',
167
+ },
168
+ }}
169
+ />
170
+ ```
171
+
172
+ ## Custom Toolbar
173
+
174
+ ```tsx
175
+ <RichTextInput
176
+ toolbarItems={[
177
+ { id: 'bold', label: 'B', format: 'bold' },
178
+ { id: 'italic', label: 'I', format: 'italic' },
179
+ {
180
+ id: 'custom',
181
+ label: '🎨',
182
+ onPress: () => showColorPicker(),
183
+ },
184
+ {
185
+ id: 'render',
186
+ label: 'Custom',
187
+ renderButton: ({ active, onPress }) => (
188
+ <MyCustomButton active={active} onPress={onPress} />
189
+ ),
190
+ },
191
+ ]}
192
+ />
193
+ ```
194
+
195
+ ## Data Model
196
+
197
+ Content is stored as an array of `StyledSegment` objects:
198
+
199
+ ```typescript
200
+ interface StyledSegment {
201
+ text: string;
202
+ styles: {
203
+ bold?: boolean;
204
+ italic?: boolean;
205
+ underline?: boolean;
206
+ strikethrough?: boolean;
207
+ code?: boolean;
208
+ color?: string;
209
+ backgroundColor?: string;
210
+ fontSize?: number;
211
+ heading?: 'h1' | 'h2' | 'h3' | 'none';
212
+ };
213
+ }
214
+ ```
215
+
216
+ ## How It Works
217
+
218
+ The **Overlay Technique** layers two components:
219
+
220
+ 1. **Bottom**: A `<Text>` component renders the styled/formatted text
221
+ 2. **Top**: A transparent `<TextInput>` captures user input and selection
222
+
223
+ Both layers use identical font metrics so text aligns perfectly. The user sees the formatted text from the bottom layer while typing into the invisible top layer.
224
+
225
+ ## Contributing
226
+
227
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
228
+
229
+ ## License
230
+
231
+ MIT © react-native-richify contributors
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ //# sourceMappingURL=OverlayText.d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"..\\..\\..\\src","sources":["components/OverlayText.d.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.OverlayText = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _styleMapper = require("@/utils/styleMapper");
10
+ var _defaultStyles = require("@/constants/defaultStyles");
11
+ var _jsxRuntime = require("react/jsx-runtime");
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ /**
14
+ * OverlayText renders the styled text segments as a `<Text>` component tree.
15
+ *
16
+ * This component is positioned behind the transparent TextInput to create
17
+ * the overlay effect — the user types into the TextInput while seeing
18
+ * the formatted rendering from this component.
19
+ */
20
+ const OverlayText = exports.OverlayText = /*#__PURE__*/_react.default.memo(({
21
+ segments,
22
+ baseTextStyle,
23
+ theme
24
+ }) => {
25
+ const resolvedTheme = theme ?? _defaultStyles.DEFAULT_THEME;
26
+ const overlayStyle = resolvedTheme.overlayContainerStyle ?? _defaultStyles.DEFAULT_THEME.overlayContainerStyle;
27
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
28
+ style: overlayStyle,
29
+ pointerEvents: "none",
30
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
31
+ children: segments.map((segment, index) => {
32
+ if (segment.text.length === 0 && segments.length > 1) {
33
+ return null;
34
+ }
35
+ const textStyle = (0, _styleMapper.segmentToTextStyle)(segment, resolvedTheme);
36
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
37
+ style: [baseTextStyle, textStyle],
38
+ children: segment.text
39
+ }, `${index}-${segment.text.slice(0, 8)}`);
40
+ })
41
+ })
42
+ });
43
+ });
44
+ OverlayText.displayName = 'OverlayText';
45
+ //# sourceMappingURL=OverlayText.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","_interopRequireDefault","require","_reactNative","_styleMapper","_defaultStyles","_jsxRuntime","e","__esModule","default","OverlayText","exports","React","memo","segments","baseTextStyle","theme","resolvedTheme","DEFAULT_THEME","overlayStyle","overlayContainerStyle","jsx","View","style","pointerEvents","children","Text","map","segment","index","text","length","textStyle","segmentToTextStyle","slice","displayName"],"sourceRoot":"..\\..\\..\\src","sources":["components/OverlayText.tsx"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AAEA,IAAAE,YAAA,GAAAF,OAAA;AACA,IAAAG,cAAA,GAAAH,OAAA;AAA0D,IAAAI,WAAA,GAAAJ,OAAA;AAAA,SAAAD,uBAAAM,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAE1D;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMG,WAAuC,GAAAC,OAAA,CAAAD,WAAA,gBAAGE,cAAK,CAACC,IAAI,CAC/D,CAAC;EAAEC,QAAQ;EAAEC,aAAa;EAAEC;AAAM,CAAC,KAAK;EACtC,MAAMC,aAAa,GAAGD,KAAK,IAAIE,4BAAa;EAC5C,MAAMC,YAAY,GAChBF,aAAa,CAACG,qBAAqB,IACnCF,4BAAa,CAACE,qBAAqB;EAErC,oBACE,IAAAd,WAAA,CAAAe,GAAA,EAAClB,YAAA,CAAAmB,IAAI;IAACC,KAAK,EAAEJ,YAAa;IAACK,aAAa,EAAC,MAAM;IAAAC,QAAA,eAC7C,IAAAnB,WAAA,CAAAe,GAAA,EAAClB,YAAA,CAAAuB,IAAI;MAAAD,QAAA,EACFX,QAAQ,CAACa,GAAG,CAAC,CAACC,OAAO,EAAEC,KAAK,KAAK;QAChC,IAAID,OAAO,CAACE,IAAI,CAACC,MAAM,KAAK,CAAC,IAAIjB,QAAQ,CAACiB,MAAM,GAAG,CAAC,EAAE;UACpD,OAAO,IAAI;QACb;QAEA,MAAMC,SAAS,GAAG,IAAAC,+BAAkB,EAACL,OAAO,EAAEX,aAAa,CAAC;QAE5D,oBACE,IAAAX,WAAA,CAAAe,GAAA,EAAClB,YAAA,CAAAuB,IAAI;UAEHH,KAAK,EAAE,CAACR,aAAa,EAAEiB,SAAS,CAAE;UAAAP,QAAA,EAEjCG,OAAO,CAACE;QAAI,GAHR,GAAGD,KAAK,IAAID,OAAO,CAACE,IAAI,CAACI,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAIrC,CAAC;MAEX,CAAC;IAAC,CACE;EAAC,CACH,CAAC;AAEX,CACF,CAAC;AAEDxB,WAAW,CAACyB,WAAW,GAAG,aAAa","ignoreList":[]}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ //# sourceMappingURL=RichTextInput.d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"..\\..\\..\\src","sources":["components/RichTextInput.d.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.RichTextInput = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _defaultStyles = require("@/constants/defaultStyles");
10
+ var _parser = require("@/utils/parser");
11
+ var _useRichText = require("@/hooks/useRichText");
12
+ var _OverlayText = require("@/components/OverlayText");
13
+ var _Toolbar = require("@/components/Toolbar");
14
+ var _jsxRuntime = require("react/jsx-runtime");
15
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
16
+ /**
17
+ * RichTextInput — The main rich text editor component.
18
+ *
19
+ * Uses the Overlay Technique:
20
+ * - A transparent `TextInput` on top captures user input and selection
21
+ * - A styled `<Text>` layer behind it renders the formatted content
22
+ * - Both share identical font metrics for pixel-perfect alignment
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * <RichTextInput
27
+ * placeholder="Start typing..."
28
+ * showToolbar
29
+ * onChangeSegments={(segments) => console.log(segments)}
30
+ * />
31
+ * ```
32
+ */
33
+ const RichTextInput = ({
34
+ initialSegments,
35
+ onChangeSegments,
36
+ onChangeText,
37
+ placeholder = 'Start typing...',
38
+ editable = true,
39
+ maxLength,
40
+ showToolbar = true,
41
+ toolbarPosition = 'top',
42
+ toolbarItems,
43
+ theme,
44
+ multiline = true,
45
+ minHeight = 120,
46
+ maxHeight,
47
+ autoFocus = false,
48
+ textInputProps,
49
+ renderToolbar,
50
+ onReady
51
+ }) => {
52
+ const resolvedTheme = theme ?? _defaultStyles.DEFAULT_THEME;
53
+ const {
54
+ state,
55
+ actions
56
+ } = (0, _useRichText.useRichText)({
57
+ initialSegments,
58
+ onChangeSegments,
59
+ onChangeText
60
+ });
61
+
62
+ // Expose actions via onReady callback
63
+ (0, _react.useEffect)(() => {
64
+ onReady?.(actions);
65
+ }, [onReady, actions]);
66
+
67
+ // Build plain text for the TextInput value
68
+ const plainText = (0, _parser.segmentsToPlainText)(state.segments);
69
+
70
+ // Handle selection change from TextInput
71
+ const onSelectionChange = (0, _react.useCallback)(e => {
72
+ const {
73
+ start,
74
+ end
75
+ } = e.nativeEvent.selection;
76
+ actions.handleSelectionChange({
77
+ start,
78
+ end
79
+ });
80
+ }, [actions]);
81
+
82
+ // Container style
83
+ const containerStyle = [resolvedTheme.containerStyle ?? _defaultStyles.DEFAULT_THEME.containerStyle];
84
+
85
+ // Input area style
86
+ const inputAreaStyle = [styles.inputArea, {
87
+ minHeight
88
+ }, maxHeight ? {
89
+ maxHeight
90
+ } : undefined];
91
+
92
+ // Input style
93
+ const inputStyle = [styles.textInput, resolvedTheme.inputStyle ?? _defaultStyles.DEFAULT_THEME.inputStyle];
94
+
95
+ // Toolbar component
96
+ const toolbarComponent = showToolbar ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Toolbar.Toolbar, {
97
+ actions: actions,
98
+ state: state,
99
+ items: toolbarItems,
100
+ theme: resolvedTheme,
101
+ renderToolbar: renderToolbar
102
+ }) : null;
103
+
104
+ // Toolbar border
105
+ const toolbarBorderStyle = toolbarPosition === 'top' ? {
106
+ borderBottomWidth: 1,
107
+ borderBottomColor: resolvedTheme.colors?.toolbarBorder ?? _defaultStyles.DEFAULT_THEME.colors?.toolbarBorder
108
+ } : {
109
+ borderTopWidth: 1,
110
+ borderTopColor: resolvedTheme.colors?.toolbarBorder ?? _defaultStyles.DEFAULT_THEME.colors?.toolbarBorder
111
+ };
112
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
113
+ style: containerStyle,
114
+ children: [toolbarPosition === 'top' && toolbarComponent && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
115
+ style: toolbarBorderStyle,
116
+ children: toolbarComponent
117
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
118
+ style: inputAreaStyle,
119
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_OverlayText.OverlayText, {
120
+ segments: state.segments,
121
+ baseTextStyle: resolvedTheme.baseTextStyle,
122
+ theme: resolvedTheme
123
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
124
+ ...textInputProps,
125
+ style: inputStyle,
126
+ value: plainText,
127
+ onChangeText: actions.handleTextChange,
128
+ onSelectionChange: onSelectionChange,
129
+ multiline: multiline,
130
+ placeholder: placeholder,
131
+ placeholderTextColor: resolvedTheme.colors?.placeholder ?? _defaultStyles.DEFAULT_THEME.colors?.placeholder,
132
+ editable: editable,
133
+ maxLength: maxLength,
134
+ autoFocus: autoFocus,
135
+ selectionColor: resolvedTheme.colors?.cursor ?? _defaultStyles.DEFAULT_THEME.colors?.cursor,
136
+ textAlignVertical: "top",
137
+ scrollEnabled: true
138
+ })]
139
+ }), toolbarPosition === 'bottom' && toolbarComponent && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
140
+ style: toolbarBorderStyle,
141
+ children: toolbarComponent
142
+ })]
143
+ });
144
+ };
145
+ exports.RichTextInput = RichTextInput;
146
+ RichTextInput.displayName = 'RichTextInput';
147
+ const styles = _reactNative.StyleSheet.create({
148
+ inputArea: {
149
+ position: 'relative'
150
+ },
151
+ textInput: {
152
+ // The TextInput must be transparent so the overlay text shows through.
153
+ // Only the caret/cursor and selection highlight are visible.
154
+ color: 'transparent',
155
+ // Ensure it matches the overlay text positioning exactly.
156
+ position: 'relative',
157
+ zIndex: 1
158
+ }
159
+ });
160
+ //# sourceMappingURL=RichTextInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_defaultStyles","_parser","_useRichText","_OverlayText","_Toolbar","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","RichTextInput","initialSegments","onChangeSegments","onChangeText","placeholder","editable","maxLength","showToolbar","toolbarPosition","toolbarItems","theme","multiline","minHeight","maxHeight","autoFocus","textInputProps","renderToolbar","onReady","resolvedTheme","DEFAULT_THEME","state","actions","useRichText","useEffect","plainText","segmentsToPlainText","segments","onSelectionChange","useCallback","start","end","nativeEvent","selection","handleSelectionChange","containerStyle","inputAreaStyle","styles","inputArea","undefined","inputStyle","textInput","toolbarComponent","jsx","Toolbar","items","toolbarBorderStyle","borderBottomWidth","borderBottomColor","colors","toolbarBorder","borderTopWidth","borderTopColor","jsxs","View","style","children","OverlayText","baseTextStyle","TextInput","value","handleTextChange","placeholderTextColor","selectionColor","cursor","textAlignVertical","scrollEnabled","exports","displayName","StyleSheet","create","position","color","zIndex"],"sourceRoot":"..\\..\\..\\src","sources":["components/RichTextInput.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ //# sourceMappingURL=Toolbar.d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"..\\..\\..\\src","sources":["components/Toolbar.d.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Toolbar = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _defaultStyles = require("@/constants/defaultStyles");
10
+ var _ToolbarButton = require("@/components/ToolbarButton");
11
+ var _jsxRuntime = require("react/jsx-runtime");
12
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
13
+ /**
14
+ * Formatting toolbar for the rich text editor.
15
+ *
16
+ * Supports:
17
+ * - Default toolbar items (bold, italic, underline, etc.)
18
+ * - Custom toolbar items via the `items` prop
19
+ * - Fully custom rendering via `renderToolbar`
20
+ * - Horizontal scrolling for overflow
21
+ */
22
+ const Toolbar = exports.Toolbar = /*#__PURE__*/_react.default.memo(({
23
+ actions,
24
+ state,
25
+ items,
26
+ theme,
27
+ visible = true,
28
+ renderToolbar
29
+ }) => {
30
+ const resolvedTheme = theme ?? _defaultStyles.DEFAULT_THEME;
31
+ const toolbarItems = items ?? _defaultStyles.DEFAULT_TOOLBAR_ITEMS;
32
+
33
+ // Compute active state for each item
34
+ const enrichedItems = (0, _react.useMemo)(() => {
35
+ return toolbarItems.map(item => {
36
+ let isActive = false;
37
+ if (item.format) {
38
+ // Check if the format is currently active
39
+ const {
40
+ activeStyles
41
+ } = state;
42
+ isActive = !!activeStyles[item.format];
43
+ }
44
+ if (item.heading) {
45
+ isActive = state.activeStyles.heading === item.heading;
46
+ }
47
+ return {
48
+ ...item,
49
+ active: item.active ?? isActive
50
+ };
51
+ });
52
+ }, [toolbarItems, state]);
53
+
54
+ // Custom render
55
+ if (renderToolbar) {
56
+ return renderToolbar({
57
+ items: enrichedItems,
58
+ state,
59
+ actions
60
+ });
61
+ }
62
+ if (!visible) {
63
+ return null;
64
+ }
65
+ const toolbarStyle = [resolvedTheme.toolbarStyle ?? _defaultStyles.DEFAULT_THEME.toolbarStyle];
66
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
67
+ style: toolbarStyle,
68
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
69
+ horizontal: true,
70
+ showsHorizontalScrollIndicator: false,
71
+ keyboardShouldPersistTaps: "always",
72
+ contentContainerStyle: styles.scrollContent,
73
+ children: enrichedItems.map(item => /*#__PURE__*/(0, _jsxRuntime.jsx)(_ToolbarButton.ToolbarButton, {
74
+ label: item.label,
75
+ active: !!item.active,
76
+ theme: resolvedTheme,
77
+ renderButton: item.renderButton,
78
+ onPress: () => {
79
+ if (item.onPress) {
80
+ item.onPress();
81
+ } else if (item.format) {
82
+ actions.toggleFormat(item.format);
83
+ } else if (item.heading) {
84
+ actions.setHeading(item.heading);
85
+ }
86
+ }
87
+ }, item.id))
88
+ })
89
+ });
90
+ });
91
+ Toolbar.displayName = 'Toolbar';
92
+ const styles = _reactNative.StyleSheet.create({
93
+ scrollContent: {
94
+ flexDirection: 'row',
95
+ alignItems: 'center',
96
+ gap: 2
97
+ }
98
+ });
99
+ //# sourceMappingURL=Toolbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_defaultStyles","_ToolbarButton","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","Toolbar","exports","React","memo","actions","state","items","theme","visible","renderToolbar","resolvedTheme","DEFAULT_THEME","toolbarItems","DEFAULT_TOOLBAR_ITEMS","enrichedItems","useMemo","map","item","isActive","format","activeStyles","heading","active","toolbarStyle","jsx","View","style","children","ScrollView","horizontal","showsHorizontalScrollIndicator","keyboardShouldPersistTaps","contentContainerStyle","styles","scrollContent","ToolbarButton","label","renderButton","onPress","toggleFormat","setHeading","id","displayName","StyleSheet","create","flexDirection","alignItems","gap"],"sourceRoot":"..\\..\\..\\src","sources":["components/Toolbar.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ //# sourceMappingURL=ToolbarButton.d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"..\\..\\..\\src","sources":["components/ToolbarButton.d.ts"],"mappings":"","ignoreList":[]}