enriched-text-input 1.0.3 → 1.0.5

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.
@@ -0,0 +1,119 @@
1
+ # API Reference
2
+
3
+ ## Props
4
+
5
+ ### `ref`
6
+
7
+ A React ref that lets you call any ref methods on the input.
8
+
9
+ ### `patterns`
10
+
11
+ An array of style patterns for the input. Use this prop to define which styles should be available for the input to use.
12
+
13
+ ```jsx
14
+ interface Pattern {
15
+ name: string;
16
+ render: React.Component;
17
+ opening: string | null;
18
+ closing: string | null;
19
+ }
20
+ ```
21
+
22
+ A pattern can have either both opening and closing enclosures defined or just the opening enclosure, but cannot have only the closing enclosure defined.
23
+
24
+ ### `defaultValue`
25
+
26
+ Provides an initial value for the input. Can be a string or an array of tokens. If it’s a string and it matches any style defined in the `patterns` prop, proper styles will be applied.
27
+
28
+ ### `onSelectionChange`
29
+
30
+ Callback that is called when the text input selection is changed.
31
+
32
+ ### `onValueChange`
33
+
34
+ Callback that is called when the text input's value changes. You can use this callback to call ref methods such as `.getRawValue()`, `.getRichTextValue()` or `.getTokenizedValue()` to get the text input’s value in your preferred
35
+
36
+ ### `onDebounceValueChange`
37
+
38
+ Same as `onValueChange` but with an applied debouncing effect.
39
+
40
+ ## Ref methods
41
+
42
+ ### `.setValue()`
43
+
44
+ ```jsx
45
+ setValue: (value: string | Tokens[]) => void;
46
+ ```
47
+
48
+ Sets the value of the input.
49
+
50
+ - `value: string | Tokens[]` - the value to set the input. If it’s a valid rich text string, the corresponding styling will be applied.
51
+
52
+ ### `.setSelection()`
53
+
54
+ ```jsx
55
+ setSelection: (start: number, end: number) => void;
56
+ ```
57
+
58
+ Sets the selection of the input.
59
+
60
+ - `start: number` - the start index of the input’s selection.
61
+ - `end: number` - the end index of the input’s selection.
62
+
63
+ ### `.focus()`
64
+
65
+ ```jsx
66
+ focus: () => void;
67
+ ```
68
+
69
+ Focuses the input;
70
+
71
+ ### `.blur()`
72
+
73
+ ```jsx
74
+ blur: () => void;
75
+ ```
76
+
77
+ Blurs the input.
78
+
79
+ ### `.toggleStyle()`
80
+
81
+ ```jsx
82
+ toggleStyle: (style: string) => void;
83
+ ```
84
+
85
+ Toggles a style at the cursor’s position.
86
+
87
+ - `style: string` - the name of a pattern to toggle.
88
+
89
+ ### `.getActiveStyle()`
90
+
91
+ ```jsx
92
+ getActiveStyle: () => string[] | [];
93
+ ```
94
+
95
+ Returns the active styles for the current selection.
96
+
97
+ ### `.getRawValue()`
98
+
99
+ ```jsx
100
+ getRawValue: () => string;
101
+ ```
102
+
103
+ Returns the input’s value as a raw string without rich text enclosures.
104
+
105
+ ### `.getRichTextValue()`
106
+
107
+ ```jsx
108
+ getRichTextValue: () => string;
109
+ ```
110
+
111
+ Returns the text input’s value as a rich text string matching the patterns for each style defined in the patterns prop. If a style does not define an opening and closing char, it is ignored.
112
+
113
+ ### `.getTokenizedValue()`
114
+
115
+ ```jsx
116
+ getTokenizedValue: () => Tokens[];
117
+ ```
118
+
119
+ Returns the text input's value as an array of tokens.
@@ -0,0 +1,33 @@
1
+ # Contributing
2
+
3
+ ## Clone this repo
4
+
5
+ 1. Fork and clone your Github froked repo:
6
+ ```
7
+ git clone https://github.com/<github_username>/enriched-text-input.git
8
+ ```
9
+
10
+ 2. Go to cloned repo directory:
11
+ ```
12
+ cd enriched-text-input
13
+ ```
14
+
15
+ ## Install dependencies
16
+
17
+ 1. Install the dependencies in the root of the repo:
18
+ ```
19
+ npm install
20
+ ```
21
+
22
+ 2. Go to the example project and install dependencies:
23
+ ```
24
+ cd example && npm install
25
+ ```
26
+
27
+ 3. After that you can start the project with:
28
+ ```
29
+ cd example && npm start
30
+ ```
31
+
32
+ ## Create a pull request
33
+ After making any changes, open a pull request. Once you submit your pull request, it will get reviewed.
package/README.md CHANGED
@@ -1,52 +1,36 @@
1
- [![plastic](https://dcbadge.limes.pink/api/server/https://discord.gg/DRmNp34bFE?bot=true&style=plastic)](https://discord.gg/DRmNp34bFE)
2
-
3
1
  # enriched-text-input
4
2
 
5
3
  > [!Note]
6
- > This library is still a work in progress. Expect breaking changes.
4
+ This library is still a work in progress. Expect breaking changes.
5
+ >
7
6
 
8
- Proof of concept for a JavaScript only rich-text TextInput component for React Native.
9
- The main idea is to render `<Text>` views as children of `<TextInput>`.
10
- It will only support text styling since it's not possible to render images inside `Text` views in React Native. [Try it on Expo Snack](https://snack.expo.dev/@patosala/enriched-text-input).
7
+ Proof of concept for a JavaScript only rich-text TextInput component for React Native. The main idea is to render `<Text>` views as children of `<TextInput>`. It will only support text styling since it's not possible to render images inside `Text` views in React Native. [Try it on Expo Snack](https://snack.expo.dev/@patosala/enriched-text-input).
11
8
 
12
9
  ## Motivation
13
- The field for rich-text in react native is still a bit green. Current libraries that add support for rich-text in react native applications are either WebViews wrapping libraries for the web, limiting customization, or require native code which drops support for Expo Go and react-native-web.
14
-
15
- In theory, by only using JavaScript we are able to provide better cross-platform compatibility and the possibility to style elements however you want as long as they follow react-native's `Text` supported styles.
16
-
17
- ## Features
18
10
 
19
- - [x] Basic text formatting (__bold__, _italic_, underline, ~~strikethrough~~ and `codeblocks`).
20
- - [x] Rich text format parsing.
21
- - [ ] Links and mentions.
22
- - [ ] Custom styling.
23
- - [ ] Custom rich text patterns.
24
- - [ ] Exposed event handlers (onSubmit, onChange, onBlur, onFocus, etc).
25
- - [ ] Custom methods and event handlers (setValue, onStartMention, onStyleChange, etc).
26
- - [ ] Headings.
11
+ The field for rich-text in react native is still a bit green. Current libraries that add support for rich-text in react native applications are either WebViews wrapping libraries for the web, limiting customization, or require native code which drops support for Expo Go and react-native-web.
27
12
 
28
- ## Known limitations
29
- - Inline images.
30
- - Only `Text`component styles are supported.
13
+ In theory, by only using JavaScript we are able to provide better cross-platform compatibility and the possibility to style elements however you want as long as they follow react-native's `Text` supported styles.
31
14
 
32
15
  ## Installation
33
- ```
16
+
17
+ ```bash
34
18
  npm install enriched-text-input
35
19
  ```
36
20
 
37
21
  ## Usage
38
- ```js
22
+
23
+ ```jsx
39
24
  import { useRef } from 'react';
40
25
  import { StyleSheet, View } from 'react-native';
41
-
42
- import { RichTextInput, Toolbar } from 'enriched-text-input';
26
+ import { EnrichedTextInput, Toolbar } from 'enriched-text-input';
43
27
 
44
28
  export default function App() {
45
29
  const richTextInputRef = useRef(null);
46
30
 
47
31
  return (
48
32
  <View style={styles.container}>
49
- <RichTextInput ref={richTextInputRef}/>
33
+ <EnrichedTextInput ref={richTextInputRef}/>
50
34
  <Toolbar richTextInputRef={richTextInputRef}>
51
35
  <Toolbar.Bold />
52
36
  <Toolbar.Italic />
@@ -66,35 +50,61 @@ const styles = StyleSheet.create({
66
50
  paddingTop: 120
67
51
  },
68
52
  });
53
+ ```
69
54
 
55
+ ## Current state
70
56
 
71
- ```
57
+ At the moment [1/1/2026] `enriched-text-input` works great for things such as small rich-text inputs (Eg. an input for a messaging app with rich-text support) but not for creating whole rich-text editors. This is because inline styles that do not break line are working as expected (Eg. bold, italic or underline work great but styles such as headings break line so they are currently not yet supported).
72
58
 
73
- ## Contributing
59
+ Live parsing of rich text symbols (such as wrapping words in asterisks `*`) is still a work in progress an not working correctly but you can toggle styles through the ref api of the `EnrichedTextInput` (or use the provided `Toolbar`component as shown in the example usage).
74
60
 
75
- ### Clone this repo
61
+ ## Features
76
62
 
77
- 1. Fork and clone your Github froked repo:
78
- ```
79
- git clone https://github.com/<github_username>/react-native-rich-text.git
80
- ```
63
+ - [x] Inline markdown styles (**bold**, *italic*, underline, ~~strikethrough~~ and `inline code`).
64
+ - [ ] Paragraph styles (headings, lists, quotes, etc).
65
+ - [ ] Live rich-text parsing.
66
+ - [ ] Links and mentions.
67
+ - [x] Custom inline styles.
68
+ - [x] Custom methods and event handlers (setValue, onStartMention, onStyleChange, etc).
81
69
 
82
- 2. Go to cloned repo directory:
83
- ```
84
- cd react-native-rich-text
85
- ```
70
+ ## API Reference
86
71
 
87
- ### Install dependencies
72
+ [API Reference](https://github.com/PatoSala/enriched-text-input/blob/main/API_REFERENCE.md)
88
73
 
89
- 1. Install the dependencies in the root of the repo:
90
- ```
91
- npm install
92
- ```
74
+ ## Style patterns
93
75
 
94
- 3. After that you can start the project with:
95
- ```
96
- npm start
76
+ Style patterns are the styles that you provide the input with for it to know how it should display certain portions of the text. You can check their structure in the [API reference](https://github.com/PatoSala/enriched-text-input/blob/main/API_REFERENCE.md#stylePatterns).
77
+
78
+ By default `enriched-text-input` uses a set of markdown styles (such as **bold**, *italic*, underline, ~~strikethrough~~ and `inline code`) for you to use out of the box, but you can provide your own custom styles through the `stylePatterns` prop. Keep in mind that when using this prop `enriched-text-input` will ignore any default style patterns so that only the ones you provided will be valid.
79
+
80
+ If you want you can provide `enriched-text-input` with both default style patterns and any additional style patterns you define:
81
+
82
+ ```bash
83
+ import { EnrichedTextInput, markdownStyles } from "enriched-text-input";
84
+
85
+ const customStyles = [
86
+ {
87
+ name: "comment",
88
+ opening: null,
89
+ closing: null,
90
+ render: Comment
91
+ }
92
+ ];
93
+
94
+ <EnrichedTextInput
95
+ stylePattrns={[...markdownStyles, ...customStyles]}
96
+ />
97
97
  ```
98
98
 
99
- ## Create a pull request
100
- After making any changes, open a pull request. Once you submit your pull request, it will get reviewed.
99
+ ## Applying styles
100
+
101
+ To apply styles you can either toggle them using the `ref` method `.toggleStyle()` which accepts as a parameter the name of a style pattern, or you can use rich-text enclosures while typing. This enclosures are defined within the `stylePatterns` prop and corresponding styles will get applied when a matching pattern is found inside the input.
102
+
103
+ ## Known limitations
104
+
105
+ - Inline images.
106
+ - Only `Text` component styles are supported.
107
+
108
+ ## Contributing
109
+
110
+ [Contributing guide](https://github.com/PatoSala/enriched-text-input/blob/main/CONTRIBUTING.md)
package/example/App.tsx CHANGED
@@ -1,70 +1,73 @@
1
1
  import { useRef, useState } from 'react';
2
- import { StyleSheet, View, KeyboardAvoidingView, Text, TouchableOpacity, Button, TextInput } from 'react-native';
3
- import { FontAwesome6 } from '@expo/vector-icons';
4
- import { RichTextInput, Toolbar, PATTERNS } from 'enriched-text-input';
5
-
6
- function Comment({ children }) {
7
- return (
8
- <Text style={{
9
- backgroundColor: "rgba(255, 203, 0, .12)",
10
- textDecorationLine: "underline",
11
- textDecorationColor: "rgba(255, 203, 0, .35)",
12
- }}>
13
- {children}
14
- </Text>
15
- )
16
- }
2
+ import { StyleSheet, View, KeyboardAvoidingView, Text, Button, TextInput } from 'react-native';
3
+ import { EnrichedTextInput, Toolbar, markdownStyles } from 'enriched-text-input';
4
+ import * as Clipboard from 'expo-clipboard';
17
5
 
18
6
  export default function App() {
19
7
  const [rawValue, setRawValue] = useState("");
8
+ const [richTextStringValue, setRichTextStringValue] = useState("");
9
+ const [activeStyles, setActiveStyles] = useState([]);
10
+ console.log("ACTIVE STYLES:", activeStyles);
20
11
  const richTextInputRef = useRef(null);
21
12
 
22
- const customPatterns = [
23
- ...PATTERNS,
24
- { style: "comment", regex: null, render: Comment }
25
- ];
13
+ const handleGetRichText = () => {
14
+ const richText = richTextInputRef.current?.getRichTextValue();
26
15
 
27
- const handleComment = () => {
28
- richTextInputRef.current?.toggleStyle("comment");
16
+ setRichTextStringValue(richText);
29
17
  }
30
18
 
31
- const handleGetRichText = () => {
32
- const richText = richTextInputRef.current?.getRichText();
33
- console.log(richText);
19
+ const handleCopyToClipboard = async (text: string) => {
20
+ await Clipboard.setStringAsync(text);
34
21
  }
35
22
 
36
23
  return (
37
24
  <KeyboardAvoidingView style={styles.container} behavior="padding">
38
25
  <View style={{ flex: 1 }}>
39
- {/* <TextInput
26
+ <TextInput
27
+ multiline
40
28
  style={{ fontSize: 20, padding: 16 }}
41
29
  value={rawValue}
42
30
  onChangeText={(text) => setRawValue(text)}
31
+ placeholder='Raw text'
43
32
  />
44
33
  <Button
45
34
  title='Set rich text string'
46
35
  onPress={() => richTextInputRef.current?.setValue(rawValue)}
47
- /> */}
48
- <RichTextInput
36
+ />
37
+
38
+ <EnrichedTextInput
49
39
  ref={richTextInputRef}
50
- patterns={customPatterns}/>
40
+ placeholder="Rich text"
41
+ onValueChange={() => console.log("VALUE CHANGE", richTextInputRef.current?.getRichTextValue())}
42
+ multiline={true}
43
+ />
44
+ <Button
45
+ title='Get rich text string'
46
+ onPress={handleGetRichText}
47
+ />
48
+ <Text style={{ padding: 16, fontSize: 20, color: richTextStringValue ? "black" : "#b3b3b3" }}>{richTextStringValue ? richTextStringValue : "Get rich text output will appear here!"}</Text>
51
49
 
50
+ <View style={{ flexDirection: "row", justifyContent: "center"}}>
51
+ <Button
52
+ title='Clear'
53
+ onPress={() => setRichTextStringValue("")}
54
+ />
52
55
  <Button
53
- title='Get rich text string (check console)'
54
- onPress={handleGetRichText}
55
- />
56
+ title='Copy'
57
+ onPress={() => handleCopyToClipboard(richTextStringValue)}
58
+ />
59
+ </View>
56
60
  </View>
57
61
  <View style={{ alignSelf: "end"}}>
58
62
  <Toolbar richTextInputRef={richTextInputRef}>
59
- <Toolbar.Bold />
63
+ <Toolbar.Bold/>
60
64
  <Toolbar.Italic />
61
65
  <Toolbar.Underline />
62
66
  <Toolbar.Strikethrough />
63
67
  <Toolbar.Code />
64
- <TouchableOpacity style={styles.toolbarButton} onPress={handleComment}>
68
+ {/* <TouchableOpacity style={styles.toolbarButton} onPress={handleComment}>
65
69
  <FontAwesome6 name="comment-alt" size={16} color="black" />
66
- </TouchableOpacity>
67
-
70
+ </TouchableOpacity> */}
68
71
  <Toolbar.Keyboard />
69
72
  </Toolbar>
70
73
  </View>
@@ -10,11 +10,12 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@expo/vector-icons": "^15.0.3",
13
+ "enriched-text-input": "file:../",
13
14
  "expo": "~54.0.25",
15
+ "expo-clipboard": "~8.0.8",
14
16
  "expo-status-bar": "~3.0.8",
15
17
  "react": "19.1.0",
16
- "react-native": "0.81.5",
17
- "enriched-text-input": "file:../"
18
+ "react-native": "0.81.5"
18
19
  },
19
20
  "private": true,
20
21
  "devDependencies": {
package/index.ts CHANGED
@@ -1,4 +1,5 @@
1
- import RichTextInput, { PATTERNS } from "./src/RichTextInput";
1
+ import EnrichedTextInput from "./src/EnrichedTextInput";
2
+ import { markdownStyles } from "./src/markdownStyles";
2
3
  import Toolbar from "./src/Toolbar";
3
4
 
4
- export { RichTextInput, PATTERNS, Toolbar };
5
+ export { EnrichedTextInput, markdownStyles, Toolbar };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "enriched-text-input",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "JavaScript only rich text input component for React Native. Compatible with Expo Go.",
5
5
  "keywords": [
6
6
  "rich-text",