rn-rich-text-editor 1.2.2 → 1.3.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.
- package/package.json +1 -1
- package/src/Toolbar.js +52 -10
- package/src/actions.js +1 -0
- package/src/editor/createHTML.js +14 -1
- package/src/index.d.ts +2 -0
package/package.json
CHANGED
package/src/Toolbar.js
CHANGED
|
@@ -169,19 +169,21 @@ export default class Toolbar extends Component {
|
|
|
169
169
|
};
|
|
170
170
|
|
|
171
171
|
static getDerivedStateFromProps(nextProps, prevState) {
|
|
172
|
-
const { actions } = nextProps;
|
|
173
|
-
if (
|
|
172
|
+
const { actions: actionsList } = nextProps;
|
|
173
|
+
if (actionsList !== prevState.actions) {
|
|
174
174
|
const items = prevState.items || [];
|
|
175
175
|
const isItemSelected = (action) =>
|
|
176
176
|
items.includes(action) || items.some(item => item && item.type === action);
|
|
177
177
|
return {
|
|
178
|
-
actions,
|
|
179
|
-
data:
|
|
178
|
+
actions: actionsList,
|
|
179
|
+
data: actionsList.map(action => ({
|
|
180
180
|
action,
|
|
181
181
|
selected:
|
|
182
|
-
action === actions.
|
|
183
|
-
?
|
|
184
|
-
:
|
|
182
|
+
action === actions.separator
|
|
183
|
+
? false // Separators are never selected
|
|
184
|
+
: action === actions.align
|
|
185
|
+
? ALIGN_ACTIONS.some(a => isItemSelected(a))
|
|
186
|
+
: isItemSelected(action),
|
|
185
187
|
})),
|
|
186
188
|
};
|
|
187
189
|
}
|
|
@@ -224,6 +226,9 @@ export default class Toolbar extends Component {
|
|
|
224
226
|
items,
|
|
225
227
|
selectedAlign,
|
|
226
228
|
data: this.state.actions.map(action => {
|
|
229
|
+
if (action === actions.separator) {
|
|
230
|
+
return { action, selected: false };
|
|
231
|
+
}
|
|
227
232
|
const isAlignAction = action === actions.align;
|
|
228
233
|
const selected = isAlignAction
|
|
229
234
|
? !!selectedAlign
|
|
@@ -277,6 +282,11 @@ export default class Toolbar extends Component {
|
|
|
277
282
|
return;
|
|
278
283
|
}
|
|
279
284
|
|
|
285
|
+
// Separators are not clickable
|
|
286
|
+
if (action === actions.separator) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
|
|
280
290
|
if (action === actions.align) {
|
|
281
291
|
const { selectedAlign } = this.state;
|
|
282
292
|
// Cycle through alignments: Left -> Center -> Right -> Justify -> Left
|
|
@@ -448,7 +458,33 @@ export default class Toolbar extends Component {
|
|
|
448
458
|
);
|
|
449
459
|
}
|
|
450
460
|
|
|
461
|
+
_renderSeparator() {
|
|
462
|
+
const { style, separatorStyle, iconGap = 16 } = this.props;
|
|
463
|
+
const separatorStylesFromStyle = style && typeof style === 'object' && !Array.isArray(style) && style.separator
|
|
464
|
+
? style.separator
|
|
465
|
+
: null;
|
|
466
|
+
return (
|
|
467
|
+
<View
|
|
468
|
+
key="separator"
|
|
469
|
+
pointerEvents="none"
|
|
470
|
+
style={[
|
|
471
|
+
{
|
|
472
|
+
width: 1,
|
|
473
|
+
height: 24,
|
|
474
|
+
backgroundColor: '#E2E2E4', // Fallback color
|
|
475
|
+
marginHorizontal: iconGap / 2,
|
|
476
|
+
},
|
|
477
|
+
separatorStylesFromStyle, // From style.separator
|
|
478
|
+
separatorStyle, // From separatorStyle prop (for backward compatibility)
|
|
479
|
+
]}
|
|
480
|
+
/>
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
|
|
451
484
|
_renderAction(action, selected) {
|
|
485
|
+
if (action === actions.separator) {
|
|
486
|
+
return this._renderSeparator();
|
|
487
|
+
}
|
|
452
488
|
if (action === actions.align) {
|
|
453
489
|
return this._renderAlignButton(action, selected);
|
|
454
490
|
}
|
|
@@ -463,8 +499,14 @@ export default class Toolbar extends Component {
|
|
|
463
499
|
return null;
|
|
464
500
|
}
|
|
465
501
|
const disabledStyle = disabled ? { backgroundColor: '#C9CED7' } : {};
|
|
466
|
-
|
|
467
|
-
|
|
502
|
+
// Extract separator styles from style prop if present, keep rest for container
|
|
503
|
+
let containerStyle = style;
|
|
504
|
+
if (style && typeof style === 'object' && !Array.isArray(style) && style.separator) {
|
|
505
|
+
const { separator, ...rest } = style;
|
|
506
|
+
containerStyle = rest;
|
|
507
|
+
}
|
|
508
|
+
const vStyle = [styles.barContainer, disabledStyle, containerStyle, disabled && this._getButtonDisabledStyle()];
|
|
509
|
+
const barBg = (containerStyle && typeof containerStyle === 'object' && !Array.isArray(containerStyle) && containerStyle.backgroundColor) || (disabled && '#C9CED7') || TOOLBAR_BG;
|
|
468
510
|
const showFades = horizontal && !disabled;
|
|
469
511
|
return (
|
|
470
512
|
<View style={vStyle}>
|
|
@@ -473,7 +515,7 @@ export default class Toolbar extends Component {
|
|
|
473
515
|
horizontal={horizontal}
|
|
474
516
|
style={[flatContainerStyle, showFades && styles.scrollList]}
|
|
475
517
|
keyboardShouldPersistTaps={'always'}
|
|
476
|
-
keyExtractor={(item, index) => item.action + '-' + index}
|
|
518
|
+
keyExtractor={(item, index) => (item.action === actions.separator ? 'separator' : item.action) + '-' + index}
|
|
477
519
|
data={this.state.data}
|
|
478
520
|
alwaysBounceHorizontal={false}
|
|
479
521
|
showsHorizontalScrollIndicator={false}
|
package/src/actions.js
CHANGED
|
@@ -44,6 +44,7 @@ export const actions = {
|
|
|
44
44
|
hiliteColor: 'hiliteColor',
|
|
45
45
|
blockquote: 'quote',
|
|
46
46
|
keyboard: 'keyboard',
|
|
47
|
+
separator: 'separator', // Visual separator for toolbar
|
|
47
48
|
setTitlePlaceholder: 'SET_TITLE_PLACEHOLDER',
|
|
48
49
|
setContentPlaceholder: 'SET_CONTENT_PLACEHOLDER',
|
|
49
50
|
setTitleFocusHandler: 'SET_TITLE_FOCUS_HANDLER',
|
package/src/editor/createHTML.js
CHANGED
|
@@ -801,11 +801,22 @@ function createReadOnlyHTML(options = {}) {
|
|
|
801
801
|
${useDefaultFont ? 'font-family: Arial, Helvetica, sans-serif; font-size: 1em;' : ''}
|
|
802
802
|
color: ${color};
|
|
803
803
|
padding: 0;
|
|
804
|
+
margin: 0;
|
|
804
805
|
height: auto !important;
|
|
805
806
|
min-height: 0 !important;
|
|
806
807
|
width: 100%;
|
|
807
808
|
${contentCSSText}
|
|
808
809
|
}
|
|
810
|
+
.readonly-container > *:first-child {
|
|
811
|
+
margin-top: 0 !important;
|
|
812
|
+
}
|
|
813
|
+
.readonly-container p {
|
|
814
|
+
margin-top: 0;
|
|
815
|
+
margin-bottom: 0.5em;
|
|
816
|
+
}
|
|
817
|
+
.readonly-container p:last-child {
|
|
818
|
+
margin-bottom: 0;
|
|
819
|
+
}
|
|
809
820
|
</style>
|
|
810
821
|
${getContentCSS()}
|
|
811
822
|
<style>${cssText}</style>
|
|
@@ -820,7 +831,9 @@ function createReadOnlyHTML(options = {}) {
|
|
|
820
831
|
el.innerHTML = content;
|
|
821
832
|
var lastH = 0;
|
|
822
833
|
var sendHeight = function() {
|
|
823
|
-
var
|
|
834
|
+
var scrollH = el.scrollHeight;
|
|
835
|
+
var offsetH = el.offsetHeight;
|
|
836
|
+
var h = Math.ceil(Math.max(scrollH, offsetH)) + 16;
|
|
824
837
|
if (h !== lastH && window.ReactNativeWebView) {
|
|
825
838
|
lastH = h;
|
|
826
839
|
window.ReactNativeWebView.postMessage(JSON.stringify({type: 'OFFSET_HEIGHT', data: h}));
|
package/src/index.d.ts
CHANGED
|
@@ -81,6 +81,7 @@ export interface ToolbarProps {
|
|
|
81
81
|
selectedButtonStyle?: object;
|
|
82
82
|
unselectedButtonStyle?: object;
|
|
83
83
|
disabledButtonStyle?: object;
|
|
84
|
+
separatorStyle?: object;
|
|
84
85
|
iconMap?: Record<string, unknown>;
|
|
85
86
|
renderAction?: (action: string, selected: boolean) => React.ReactElement;
|
|
86
87
|
onPressAddImage?: () => void;
|
|
@@ -139,6 +140,7 @@ export const actions: {
|
|
|
139
140
|
hiliteColor: string;
|
|
140
141
|
blockquote: string;
|
|
141
142
|
keyboard: string;
|
|
143
|
+
separator: string;
|
|
142
144
|
[key: string]: string;
|
|
143
145
|
};
|
|
144
146
|
|