rn-rich-text-editor 0.0.13 → 0.0.15
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/package.json +1 -1
- package/src/RichEditor.js +7 -3
- package/src/RichToolbar.js +102 -6
- package/src/actions.js +1 -0
- package/src/index.d.ts +2 -0
package/package.json
CHANGED
package/src/RichEditor.js
CHANGED
|
@@ -304,13 +304,17 @@ export default class RichTextEditor extends Component {
|
|
|
304
304
|
// useContainer is an optional prop with default value of true
|
|
305
305
|
// If set to true, it will use a View wrapper with styles and height.
|
|
306
306
|
// If set to false, it will not use a View wrapper
|
|
307
|
-
const { useContainer, style } = this.props;
|
|
307
|
+
const { useContainer, style, errorMessage } = this.props;
|
|
308
|
+
const errorStyle = errorMessage ? { borderWidth: 1, borderColor: '#d92d20' } : {};
|
|
309
|
+
|
|
308
310
|
return useContainer ? (
|
|
309
|
-
<View style={[style, { height }]} onLayout={this.onViewLayout}>
|
|
311
|
+
<View style={[style, { height }, errorStyle]} onLayout={this.onViewLayout}>
|
|
310
312
|
{this.renderWebView()}
|
|
311
313
|
</View>
|
|
312
314
|
) : (
|
|
313
|
-
|
|
315
|
+
<View style={errorStyle}>
|
|
316
|
+
{this.renderWebView()}
|
|
317
|
+
</View>
|
|
314
318
|
);
|
|
315
319
|
}
|
|
316
320
|
|
package/src/RichToolbar.js
CHANGED
|
@@ -2,6 +2,13 @@ import React, { Component } from 'react';
|
|
|
2
2
|
import { FlatList, Image, StyleSheet, TouchableOpacity, View } from 'react-native';
|
|
3
3
|
import { actions } from './actions';
|
|
4
4
|
|
|
5
|
+
const ALIGN_ACTIONS = [
|
|
6
|
+
actions.alignLeft,
|
|
7
|
+
actions.alignCenter,
|
|
8
|
+
actions.alignRight,
|
|
9
|
+
// actions.alignFull,
|
|
10
|
+
];
|
|
11
|
+
|
|
5
12
|
export const defaultActions = [
|
|
6
13
|
actions.keyboard,
|
|
7
14
|
actions.setBold,
|
|
@@ -43,6 +50,7 @@ function getDefaultIcon() {
|
|
|
43
50
|
texts[actions.alignCenter] = require('./img/justify_center.png');
|
|
44
51
|
texts[actions.alignRight] = require('./img/justify_right.png');
|
|
45
52
|
texts[actions.alignFull] = require('./img/justify_full.png');
|
|
53
|
+
texts[actions.align] = require('./img/justify_left.png');
|
|
46
54
|
texts[actions.blockquote] = require('./img/blockquote.png');
|
|
47
55
|
texts[actions.line] = require('./img/line.png');
|
|
48
56
|
texts[actions.fontSize] = require('./img/fontSize.png');
|
|
@@ -65,6 +73,7 @@ export default class RichToolbar extends Component {
|
|
|
65
73
|
this.editor = null;
|
|
66
74
|
this.state = {
|
|
67
75
|
items: [],
|
|
76
|
+
selectedAlign: null,
|
|
68
77
|
};
|
|
69
78
|
}
|
|
70
79
|
|
|
@@ -74,6 +83,7 @@ export default class RichToolbar extends Component {
|
|
|
74
83
|
nextState.items !== that.state.items ||
|
|
75
84
|
nextState.actions !== that.state.actions ||
|
|
76
85
|
nextState.data !== that.state.data ||
|
|
86
|
+
nextState.selectedAlign !== that.state.selectedAlign ||
|
|
77
87
|
nextProps.style !== that.props.style
|
|
78
88
|
);
|
|
79
89
|
}
|
|
@@ -81,10 +91,18 @@ export default class RichToolbar extends Component {
|
|
|
81
91
|
static getDerivedStateFromProps(nextProps, prevState) {
|
|
82
92
|
const { actions } = nextProps;
|
|
83
93
|
if (actions !== prevState.actions) {
|
|
84
|
-
|
|
94
|
+
const items = prevState.items || [];
|
|
95
|
+
const isItemSelected = (action) =>
|
|
96
|
+
items.includes(action) || items.some(item => item && item.type === action);
|
|
85
97
|
return {
|
|
86
98
|
actions,
|
|
87
|
-
data: actions.map(action => ({
|
|
99
|
+
data: actions.map(action => ({
|
|
100
|
+
action,
|
|
101
|
+
selected:
|
|
102
|
+
action === actions.align
|
|
103
|
+
? ALIGN_ACTIONS.some(a => isItemSelected(a))
|
|
104
|
+
: isItemSelected(action),
|
|
105
|
+
})),
|
|
88
106
|
};
|
|
89
107
|
}
|
|
90
108
|
return null;
|
|
@@ -112,15 +130,26 @@ export default class RichToolbar extends Component {
|
|
|
112
130
|
}
|
|
113
131
|
};
|
|
114
132
|
|
|
133
|
+
_isItemSelected(items, action) {
|
|
134
|
+
return (
|
|
135
|
+
items.includes(action) || items.some(item => item && item.type === action)
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
115
139
|
setSelectedItems(items) {
|
|
116
140
|
const { items: selectedItems } = this.state;
|
|
117
141
|
if (this.editor && items !== selectedItems) {
|
|
142
|
+
const selectedAlign = ALIGN_ACTIONS.find(a => this._isItemSelected(items, a)) || null;
|
|
118
143
|
this.setState({
|
|
119
144
|
items,
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
145
|
+
selectedAlign,
|
|
146
|
+
data: this.state.actions.map(action => {
|
|
147
|
+
const isAlignAction = action === actions.align;
|
|
148
|
+
const selected = isAlignAction
|
|
149
|
+
? !!selectedAlign
|
|
150
|
+
: this._isItemSelected(items, action);
|
|
151
|
+
return { action, selected };
|
|
152
|
+
}),
|
|
124
153
|
});
|
|
125
154
|
}
|
|
126
155
|
}
|
|
@@ -168,6 +197,23 @@ export default class RichToolbar extends Component {
|
|
|
168
197
|
return;
|
|
169
198
|
}
|
|
170
199
|
|
|
200
|
+
if (action === actions.align) {
|
|
201
|
+
const { selectedAlign } = this.state;
|
|
202
|
+
// Cycle through alignments: Left -> Center -> Right -> Justify -> Left
|
|
203
|
+
let nextAlignIndex = 0; // Default to Left
|
|
204
|
+
if (selectedAlign) {
|
|
205
|
+
const currentIndex = ALIGN_ACTIONS.indexOf(selectedAlign);
|
|
206
|
+
if (currentIndex >= 0) {
|
|
207
|
+
nextAlignIndex = (currentIndex + 1) % ALIGN_ACTIONS.length;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const nextAlign = ALIGN_ACTIONS[nextAlignIndex];
|
|
211
|
+
editor.showAndroidKeyboard();
|
|
212
|
+
editor.sendAction(nextAlign, 'result');
|
|
213
|
+
// The selectedAlign will be updated when setSelectedItems is called by the editor
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
|
|
171
217
|
switch (action) {
|
|
172
218
|
case actions.insertLink:
|
|
173
219
|
if (onInsertLink) return onInsertLink();
|
|
@@ -270,7 +316,57 @@ export default class RichToolbar extends Component {
|
|
|
270
316
|
);
|
|
271
317
|
}
|
|
272
318
|
|
|
319
|
+
_renderAlignButton(action, selected) {
|
|
320
|
+
const that = this;
|
|
321
|
+
const { iconSize, iconGap, disabled, itemStyle } = that.props;
|
|
322
|
+
const style = selected ? that._getButtonSelectedStyle() : that._getButtonUnselectedStyle();
|
|
323
|
+
const tintColor = disabled
|
|
324
|
+
? that.props.disabledIconTint
|
|
325
|
+
: selected
|
|
326
|
+
? that.props.selectedIconTint
|
|
327
|
+
: that.props.iconTint;
|
|
328
|
+
const { selectedAlign } = that.state;
|
|
329
|
+
|
|
330
|
+
// Use the icon for the current alignment, or default to alignLeft icon
|
|
331
|
+
const currentAlignAction = selectedAlign || actions.alignLeft;
|
|
332
|
+
const icon = that._getButtonIcon(currentAlignAction);
|
|
333
|
+
|
|
334
|
+
return (
|
|
335
|
+
<TouchableOpacity
|
|
336
|
+
key={action}
|
|
337
|
+
disabled={disabled}
|
|
338
|
+
style={[{ width: iconGap + iconSize }, styles.item, itemStyle, style]}
|
|
339
|
+
testID={'button_align'}
|
|
340
|
+
accessible={true}
|
|
341
|
+
onPress={() => that._onPress(action)}>
|
|
342
|
+
{icon ? (
|
|
343
|
+
typeof icon === 'function' ? (
|
|
344
|
+
icon({
|
|
345
|
+
selected,
|
|
346
|
+
disabled,
|
|
347
|
+
tintColor: tintColor,
|
|
348
|
+
iconSize,
|
|
349
|
+
iconGap,
|
|
350
|
+
})
|
|
351
|
+
) : (
|
|
352
|
+
<Image
|
|
353
|
+
source={icon}
|
|
354
|
+
style={{
|
|
355
|
+
tintColor,
|
|
356
|
+
height: iconSize,
|
|
357
|
+
width: iconSize,
|
|
358
|
+
}}
|
|
359
|
+
/>
|
|
360
|
+
)
|
|
361
|
+
) : null}
|
|
362
|
+
</TouchableOpacity>
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
|
|
273
366
|
_renderAction(action, selected) {
|
|
367
|
+
if (action === actions.align) {
|
|
368
|
+
return this._renderAlignButton(action, selected);
|
|
369
|
+
}
|
|
274
370
|
return this.props.renderAction
|
|
275
371
|
? this.props.renderAction(action, selected)
|
|
276
372
|
: this._defaultRenderAction(action, selected);
|
package/src/actions.js
CHANGED
|
@@ -17,6 +17,7 @@ export const actions = {
|
|
|
17
17
|
alignCenter: 'justifyCenter',
|
|
18
18
|
alignRight: 'justifyRight',
|
|
19
19
|
alignFull: 'justifyFull',
|
|
20
|
+
align: 'align', // Single icon with dropdown for all 4 align options
|
|
20
21
|
insertBulletsList: 'unorderedList',
|
|
21
22
|
insertOrderedList: 'orderedList',
|
|
22
23
|
checkboxList: 'checkboxList',
|
package/src/index.d.ts
CHANGED
|
@@ -59,6 +59,7 @@ export interface RichEditorProps {
|
|
|
59
59
|
onCursorPosition?: (offsetY: number) => void;
|
|
60
60
|
onLink?: (data: unknown) => void;
|
|
61
61
|
onHeightChange?: (height: number) => void;
|
|
62
|
+
errorMessage?: string;
|
|
62
63
|
[key: string]: unknown;
|
|
63
64
|
}
|
|
64
65
|
|
|
@@ -109,6 +110,7 @@ export const actions: {
|
|
|
109
110
|
alignCenter: string;
|
|
110
111
|
alignRight: string;
|
|
111
112
|
alignFull: string;
|
|
113
|
+
align: string;
|
|
112
114
|
insertBulletsList: string;
|
|
113
115
|
insertOrderedList: string;
|
|
114
116
|
checkboxList: string;
|