react-native-enriched-markdown-scaffold 1.0.2-scaffold.4 → 1.0.2-scaffold.6
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/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +15 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +3 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +15 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +3 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +74 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +68 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +20 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +4 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt +107 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +19 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +22 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +48 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +22 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/events/SelectionChangeEvent.kt +42 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +14 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionChangeReporter.kt +230 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +11 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +8 -1
- package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +8 -1
- package/docs/API_REFERENCE.md +68 -0
- package/docs/WEB.md +1 -0
- package/ios/EnrichedMarkdown.mm +188 -2
- package/ios/EnrichedMarkdownText.mm +117 -1
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +74 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +68 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +20 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +4 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +50 -2
- package/ios/utils/ENRMLinkChip.m +38 -20
- package/ios/utils/ENRMLinkLayout.m +12 -12
- package/ios/utils/ENRMSelectionChange.h +96 -0
- package/ios/utils/ENRMSelectionChange.m +204 -0
- package/ios/utils/EditMenuUtils+macOS.m +1 -1
- package/ios/utils/EditMenuUtils.h +3 -0
- package/ios/utils/EditMenuUtils.m +116 -0
- package/ios/utils/MarkdownAccessibilityElementBuilder.m +1 -2
- package/ios/views/ENRMCodeBlockContainerView.h +3 -0
- package/ios/views/ENRMCodeBlockContainerView.m +3 -0
- package/ios/views/ENRMMathContainerView.h +3 -0
- package/ios/views/ENRMMathContainerView.m +3 -0
- package/ios/views/TableContainerView.h +3 -0
- package/ios/views/TableContainerView.m +4 -1
- package/lib/module/EnrichedMarkdownNativeComponent.ts +70 -1
- package/lib/module/EnrichedMarkdownTextNativeComponent.ts +70 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/jest/index.js +14 -0
- package/lib/module/jest/index.js.map +1 -1
- package/lib/module/native/EnrichedMarkdownText.js +46 -4
- package/lib/module/native/EnrichedMarkdownText.js.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +63 -2
- package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +63 -2
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/jest/index.d.ts +1 -1
- package/lib/typescript/src/jest/index.d.ts.map +1 -1
- package/lib/typescript/src/native/EnrichedMarkdownText.d.ts +5 -5
- package/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownTextProps.d.ts +46 -3
- package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -1
- package/lib/typescript/src/types/events.d.ts +36 -0
- package/lib/typescript/src/types/events.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/EnrichedMarkdownNativeComponent.ts +70 -1
- package/src/EnrichedMarkdownTextNativeComponent.ts +70 -1
- package/src/index.tsx +3 -0
- package/src/jest/index.tsx +22 -1
- package/src/native/EnrichedMarkdownText.tsx +87 -9
- package/src/types/MarkdownTextProps.ts +53 -2
- package/src/types/events.ts +38 -0
|
@@ -180,4 +180,120 @@ UIMenu *buildEditMenuForSelection(NSAttributedString *attributedText, NSRange ra
|
|
|
180
180
|
return [UIMenu menuWithChildren:result];
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
+
#import <objc/runtime.h>
|
|
184
|
+
|
|
185
|
+
static const void *kSelectionEditMenuPresenterKey = &kSelectionEditMenuPresenterKey;
|
|
186
|
+
|
|
187
|
+
API_AVAILABLE(ios(16.0))
|
|
188
|
+
@interface ENRMSelectionEditMenuPresenter : NSObject <UIEditMenuInteractionDelegate>
|
|
189
|
+
@property (nonatomic, weak) UITextView *textView;
|
|
190
|
+
@property (nonatomic, strong) UIEditMenuInteraction *interaction;
|
|
191
|
+
@property (nonatomic, assign) NSRange range;
|
|
192
|
+
@end
|
|
193
|
+
|
|
194
|
+
@implementation ENRMSelectionEditMenuPresenter
|
|
195
|
+
|
|
196
|
+
- (UIMenu *)editMenuInteraction:(UIEditMenuInteraction *)interaction
|
|
197
|
+
menuForConfiguration:(UIEditMenuConfiguration *)configuration
|
|
198
|
+
suggestedActions:(NSArray<UIMenuElement *> *)suggestedActions
|
|
199
|
+
{
|
|
200
|
+
UITextView *textView = self.textView;
|
|
201
|
+
id<UITextViewDelegate> delegate = textView.delegate;
|
|
202
|
+
if (!textView || ![delegate respondsToSelector:@selector(textView:editMenuForTextInRange:suggestedActions:)]) {
|
|
203
|
+
return nil;
|
|
204
|
+
}
|
|
205
|
+
return [delegate textView:textView editMenuForTextInRange:textView.selectedRange suggestedActions:suggestedActions];
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
- (CGRect)editMenuInteraction:(UIEditMenuInteraction *)interaction
|
|
209
|
+
targetRectForConfiguration:(UIEditMenuConfiguration *)configuration
|
|
210
|
+
{
|
|
211
|
+
UITextView *textView = self.textView;
|
|
212
|
+
UITextRange *textRange = textView.selectedTextRange;
|
|
213
|
+
if (!textView || !textRange) {
|
|
214
|
+
return CGRectNull;
|
|
215
|
+
}
|
|
216
|
+
return [textView firstRectForRange:textRange];
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
@end
|
|
220
|
+
|
|
221
|
+
static BOOL selectionEditMenuTextViewHasActiveGesture(UITextView *textView)
|
|
222
|
+
{
|
|
223
|
+
for (UIGestureRecognizer *recognizer in textView.gestureRecognizers) {
|
|
224
|
+
if (recognizer.state == UIGestureRecognizerStateBegan || recognizer.state == UIGestureRecognizerStateChanged) {
|
|
225
|
+
return YES;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return NO;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
static void presentSelectionEditMenu(UITextView *textView)
|
|
232
|
+
{
|
|
233
|
+
UITextRange *textRange = textView.selectedTextRange;
|
|
234
|
+
if (!textRange || textRange.isEmpty) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
CGRect rect = [textView firstRectForRange:textRange];
|
|
238
|
+
if (CGRectIsNull(rect) || CGRectIsEmpty(rect)) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (@available(iOS 16.0, *)) {
|
|
242
|
+
ENRMSelectionEditMenuPresenter *presenter = objc_getAssociatedObject(textView, kSelectionEditMenuPresenterKey);
|
|
243
|
+
if (!presenter) {
|
|
244
|
+
presenter = [[ENRMSelectionEditMenuPresenter alloc] init];
|
|
245
|
+
presenter.textView = textView;
|
|
246
|
+
presenter.interaction = [[UIEditMenuInteraction alloc] initWithDelegate:presenter];
|
|
247
|
+
[textView addInteraction:presenter.interaction];
|
|
248
|
+
objc_setAssociatedObject(textView, kSelectionEditMenuPresenterKey, presenter, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
|
249
|
+
}
|
|
250
|
+
presenter.range = textView.selectedRange;
|
|
251
|
+
UIEditMenuConfiguration *configuration =
|
|
252
|
+
[UIEditMenuConfiguration configurationWithIdentifier:nil
|
|
253
|
+
sourcePoint:CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect))];
|
|
254
|
+
[presenter.interaction presentEditMenuWithConfiguration:configuration];
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
#pragma clang diagnostic push
|
|
258
|
+
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
259
|
+
[[UIMenuController sharedMenuController] showMenuFromView:textView rect:rect];
|
|
260
|
+
#pragma clang diagnostic pop
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
static void presentSelectionEditMenuWhenTouchEnds(UITextView *textView, NSRange range, NSUInteger attemptsLeft)
|
|
264
|
+
{
|
|
265
|
+
if (!NSEqualRanges(textView.selectedRange, range)) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (attemptsLeft > 0 && selectionEditMenuTextViewHasActiveGesture(textView)) {
|
|
269
|
+
__weak UITextView *weakTextView = textView;
|
|
270
|
+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(50 * NSEC_PER_MSEC)), dispatch_get_main_queue(), ^{
|
|
271
|
+
UITextView *strongTextView = weakTextView;
|
|
272
|
+
if (strongTextView) {
|
|
273
|
+
presentSelectionEditMenuWhenTouchEnds(strongTextView, range, attemptsLeft - 1);
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
presentSelectionEditMenu(textView);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
void ENRMSelectRangeAndPresentEditMenu(UITextView *textView, NSRange range)
|
|
282
|
+
{
|
|
283
|
+
[textView becomeFirstResponder];
|
|
284
|
+
textView.selectedRange = range;
|
|
285
|
+
presentSelectionEditMenuWhenTouchEnds(textView, range, 200);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
void ENRMDismissSelectionEditMenuIfMoved(UITextView *textView)
|
|
289
|
+
{
|
|
290
|
+
if (@available(iOS 16.0, *)) {
|
|
291
|
+
ENRMSelectionEditMenuPresenter *presenter = objc_getAssociatedObject(textView, kSelectionEditMenuPresenterKey);
|
|
292
|
+
if (presenter && !NSEqualRanges(textView.selectedRange, presenter.range)) {
|
|
293
|
+
presenter.range = NSMakeRange(NSNotFound, 0);
|
|
294
|
+
[presenter.interaction dismissMenu];
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
183
299
|
#endif
|
|
@@ -115,8 +115,7 @@ static const CGFloat kFocusRectPadding = 2.0;
|
|
|
115
115
|
|
|
116
116
|
BOOL isImg = item[@"altText"] != nil;
|
|
117
117
|
// Link chips pad their text with spacer characters; keep them out of the spoken label.
|
|
118
|
-
NSString *label = isImg ? item[@"altText"]
|
|
119
|
-
: ENRMPlainTextByRemovingLinkSpacers(textView.attributedText, itemRange);
|
|
118
|
+
NSString *label = isImg ? item[@"altText"] : ENRMPlainTextByRemovingLinkSpacers(textView.attributedText, itemRange);
|
|
120
119
|
[elements addObject:[self createElementForRange:itemRange
|
|
121
120
|
type:isImg ? ElementTypeImage : ElementTypeLink
|
|
122
121
|
text:label
|
|
@@ -45,6 +45,9 @@ typedef void (^ENRMCodeBlockCopyBlock)(NSString *code, NSString *language);
|
|
|
45
45
|
/// Set by the host; receives the Copy item's content when
|
|
46
46
|
/// `menuOptions.interceptCopy` is set.
|
|
47
47
|
@property (nonatomic, copy, nullable) ENRMBlockCopyRequestBlock onCopyRequest;
|
|
48
|
+
/// Called instead of the menu on long press while `contextMenuHidden` is on, so
|
|
49
|
+
/// the owner can report the block (`onSelectionChange`) and show its own UI.
|
|
50
|
+
@property (nonatomic, copy, nullable) ENRMBlockCopyRequestBlock onMenuSuppressed;
|
|
48
51
|
|
|
49
52
|
// Fired when the code is copied (header button, context-menu Copy, or the
|
|
50
53
|
// VoiceOver copy action); set by the host to bridge up to the JS onCopyPress
|
|
@@ -495,6 +495,9 @@ static BOOL ENRMColorIsDark(RCTUIColor *color)
|
|
|
495
495
|
{
|
|
496
496
|
// Returning nil is the UIKit-sanctioned way to suppress a context menu.
|
|
497
497
|
if (_pending || self.contextMenuHidden) {
|
|
498
|
+
if (!_pending && self.onMenuSuppressed) {
|
|
499
|
+
self.onMenuSuppressed([self fencedMarkdown], _cachedCode ?: @"");
|
|
500
|
+
}
|
|
498
501
|
return nil;
|
|
499
502
|
}
|
|
500
503
|
__weak __typeof(self) weakSelf = self;
|
|
@@ -42,6 +42,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
42
42
|
/// Set by the host; receives the Copy item's content when
|
|
43
43
|
/// `menuOptions.interceptCopy` is set.
|
|
44
44
|
@property (nonatomic, copy, nullable) ENRMBlockCopyRequestBlock onCopyRequest;
|
|
45
|
+
/// Called instead of the menu on long press while `contextMenuHidden` is on, so
|
|
46
|
+
/// the owner can report the block (`onSelectionChange`) and show its own UI.
|
|
47
|
+
@property (nonatomic, copy, nullable) ENRMBlockCopyRequestBlock onMenuSuppressed;
|
|
45
48
|
|
|
46
49
|
@end
|
|
47
50
|
|
|
@@ -128,6 +128,9 @@
|
|
|
128
128
|
{
|
|
129
129
|
// Returning nil is the UIKit-sanctioned way to suppress a context menu.
|
|
130
130
|
if (self.contextMenuHidden) {
|
|
131
|
+
if (self.onMenuSuppressed) {
|
|
132
|
+
self.onMenuSuppressed([NSString stringWithFormat:@"$$\n%@\n$$", _cachedLatex ?: @""], _cachedLatex ?: @"");
|
|
133
|
+
}
|
|
131
134
|
return nil;
|
|
132
135
|
}
|
|
133
136
|
__weak __typeof(self) weakSelf = self;
|
|
@@ -63,6 +63,9 @@ typedef void (^TableLinkPressBlock)(NSString *url);
|
|
|
63
63
|
/// Set by the host; receives the Copy item's content when
|
|
64
64
|
/// `menuOptions.interceptCopy` is set.
|
|
65
65
|
@property (nonatomic, copy, nullable) ENRMBlockCopyRequestBlock onCopyRequest;
|
|
66
|
+
/// Called instead of the menu on long press while `contextMenuHidden` is on, so
|
|
67
|
+
/// the owner can report the block (`onSelectionChange`) and show its own UI.
|
|
68
|
+
@property (nonatomic, copy, nullable) ENRMBlockCopyRequestBlock onMenuSuppressed;
|
|
66
69
|
|
|
67
70
|
@property (nonatomic, readonly) NSUInteger rowCount;
|
|
68
71
|
/// Number of links across all cells. Tables are not reported by `onLinkLayout`,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#import "TableContainerView.h"
|
|
2
|
-
#import "ENRMLinkChip.h"
|
|
3
2
|
#import "AttributedRenderer.h"
|
|
4
3
|
#import "ENRMAccessibilityLabels.h"
|
|
4
|
+
#import "ENRMLinkChip.h"
|
|
5
5
|
#import "HTMLGenerator.h"
|
|
6
6
|
#import "LinkTapUtils.h"
|
|
7
7
|
#import "MarkdownASTNode.h"
|
|
@@ -486,6 +486,9 @@ static void ENRMTableComputeLayout(NSArray<NSArray<TableCellData *> *> *rows, NS
|
|
|
486
486
|
{
|
|
487
487
|
// Returning nil is the UIKit-sanctioned way to suppress a context menu.
|
|
488
488
|
if (self.contextMenuHidden) {
|
|
489
|
+
if (self.onMenuSuppressed) {
|
|
490
|
+
self.onMenuSuppressed(_cachedMarkdown ?: @"", [self buildPlainTextFromRows] ?: @"");
|
|
491
|
+
}
|
|
489
492
|
return nil;
|
|
490
493
|
}
|
|
491
494
|
__weak __typeof(self) weakSelf = self;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
codegenNativeComponent,
|
|
3
|
+
codegenNativeCommands,
|
|
3
4
|
type ViewProps,
|
|
4
5
|
type CodegenTypes,
|
|
5
6
|
type ColorValue,
|
|
7
|
+
type HostComponent,
|
|
6
8
|
} from 'react-native';
|
|
9
|
+
import type React from 'react';
|
|
7
10
|
|
|
8
11
|
// All block styles extend this interface
|
|
9
12
|
interface BaseBlockStyleInternal {
|
|
@@ -274,6 +277,39 @@ export interface LinkLayoutEvent {
|
|
|
274
277
|
}[];
|
|
275
278
|
}
|
|
276
279
|
|
|
280
|
+
/**
|
|
281
|
+
* Current text selection, or a long-pressed table / math / code block while
|
|
282
|
+
* `contextMenuHidden` is on. `active: false` means the selection was cleared
|
|
283
|
+
* (every other field is then empty / zero). Rects are in dp / pt, relative to
|
|
284
|
+
* the native view's origin; rect objects are written inline because codegen
|
|
285
|
+
* only accepts inline object literals in event payloads.
|
|
286
|
+
*/
|
|
287
|
+
export interface SelectionChangeEvent {
|
|
288
|
+
active: boolean;
|
|
289
|
+
source: string;
|
|
290
|
+
text: string;
|
|
291
|
+
markdown: string;
|
|
292
|
+
whole: boolean;
|
|
293
|
+
rect: {
|
|
294
|
+
x: CodegenTypes.Double;
|
|
295
|
+
y: CodegenTypes.Double;
|
|
296
|
+
width: CodegenTypes.Double;
|
|
297
|
+
height: CodegenTypes.Double;
|
|
298
|
+
};
|
|
299
|
+
startRect: {
|
|
300
|
+
x: CodegenTypes.Double;
|
|
301
|
+
y: CodegenTypes.Double;
|
|
302
|
+
width: CodegenTypes.Double;
|
|
303
|
+
height: CodegenTypes.Double;
|
|
304
|
+
};
|
|
305
|
+
endRect: {
|
|
306
|
+
x: CodegenTypes.Double;
|
|
307
|
+
y: CodegenTypes.Double;
|
|
308
|
+
width: CodegenTypes.Double;
|
|
309
|
+
height: CodegenTypes.Double;
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
|
|
277
313
|
export interface TaskListItemPressEvent {
|
|
278
314
|
index: CodegenTypes.Int32;
|
|
279
315
|
checked: boolean;
|
|
@@ -441,6 +477,18 @@ export interface NativeProps extends ViewProps {
|
|
|
441
477
|
* Deduplicated: not re-fired when the payload is unchanged.
|
|
442
478
|
*/
|
|
443
479
|
onLinkLayout?: CodegenTypes.DirectEventHandler<LinkLayoutEvent>;
|
|
480
|
+
/**
|
|
481
|
+
* When true, the view reports selection changes (and, with
|
|
482
|
+
* `contextMenuHidden`, block long-presses) through `onSelectionChange`.
|
|
483
|
+
* Set by the JS wrapper only when `onSelectionChange` is provided.
|
|
484
|
+
* @default false
|
|
485
|
+
*/
|
|
486
|
+
emitSelectionChange?: CodegenTypes.WithDefault<boolean, false>;
|
|
487
|
+
/**
|
|
488
|
+
* Fired while `emitSelectionChange` is on: coalesced to one event per frame,
|
|
489
|
+
* deduplicated, and `active: false` once the selection is gone.
|
|
490
|
+
*/
|
|
491
|
+
onSelectionChange?: CodegenTypes.DirectEventHandler<SelectionChangeEvent>;
|
|
444
492
|
/**
|
|
445
493
|
* Callback fired when a task list checkbox is tapped.
|
|
446
494
|
* Receives the 0-based task index, current checked state, and the item's plain text.
|
|
@@ -480,6 +528,16 @@ export interface NativeProps extends ViewProps {
|
|
|
480
528
|
* @default true
|
|
481
529
|
*/
|
|
482
530
|
enableLinkPreview?: CodegenTypes.WithDefault<boolean, true>;
|
|
531
|
+
/**
|
|
532
|
+
* When `true`, long-pressing a link selects its label and shows the
|
|
533
|
+
* selection edit menu instead of the system link preview (iOS only).
|
|
534
|
+
* Takes precedence over `enableLinkPreview` and `onLinkLongPress`.
|
|
535
|
+
*
|
|
536
|
+
* Android: No-op.
|
|
537
|
+
*
|
|
538
|
+
* @default false
|
|
539
|
+
*/
|
|
540
|
+
linkLongPressSelects?: CodegenTypes.WithDefault<boolean, false>;
|
|
483
541
|
/**
|
|
484
542
|
* - iOS: Controls text selection and link previews on long press.
|
|
485
543
|
* - Android: Controls text selection.
|
|
@@ -594,6 +652,17 @@ export interface NativeProps extends ViewProps {
|
|
|
594
652
|
writingDirection?: CodegenTypes.WithDefault<string, 'first-strong'>;
|
|
595
653
|
}
|
|
596
654
|
|
|
655
|
+
type ComponentType = HostComponent<NativeProps>;
|
|
656
|
+
|
|
657
|
+
interface NativeCommands {
|
|
658
|
+
/** Clears the text selection (and any active block) and fires `onSelectionChange` with `active: false`. */
|
|
659
|
+
clearSelection: (viewRef: React.ElementRef<ComponentType>) => void;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
|
|
663
|
+
supportedCommands: ['clearSelection'],
|
|
664
|
+
});
|
|
665
|
+
|
|
597
666
|
export default codegenNativeComponent<NativeProps>('EnrichedMarkdown', {
|
|
598
667
|
interfaceOnly: true,
|
|
599
|
-
})
|
|
668
|
+
}) as HostComponent<NativeProps>;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
codegenNativeComponent,
|
|
3
|
+
codegenNativeCommands,
|
|
3
4
|
type ViewProps,
|
|
4
5
|
type CodegenTypes,
|
|
5
6
|
type ColorValue,
|
|
7
|
+
type HostComponent,
|
|
6
8
|
} from 'react-native';
|
|
9
|
+
import type React from 'react';
|
|
7
10
|
|
|
8
11
|
// All block styles extend this interface
|
|
9
12
|
interface BaseBlockStyleInternal {
|
|
@@ -275,6 +278,39 @@ export interface LinkLayoutEvent {
|
|
|
275
278
|
}[];
|
|
276
279
|
}
|
|
277
280
|
|
|
281
|
+
/**
|
|
282
|
+
* Current text selection, or a long-pressed table / math / code block while
|
|
283
|
+
* `contextMenuHidden` is on. `active: false` means the selection was cleared
|
|
284
|
+
* (every other field is then empty / zero). Rects are in dp / pt, relative to
|
|
285
|
+
* the native view's origin; rect objects are written inline because codegen
|
|
286
|
+
* only accepts inline object literals in event payloads.
|
|
287
|
+
*/
|
|
288
|
+
export interface SelectionChangeEvent {
|
|
289
|
+
active: boolean;
|
|
290
|
+
source: string;
|
|
291
|
+
text: string;
|
|
292
|
+
markdown: string;
|
|
293
|
+
whole: boolean;
|
|
294
|
+
rect: {
|
|
295
|
+
x: CodegenTypes.Double;
|
|
296
|
+
y: CodegenTypes.Double;
|
|
297
|
+
width: CodegenTypes.Double;
|
|
298
|
+
height: CodegenTypes.Double;
|
|
299
|
+
};
|
|
300
|
+
startRect: {
|
|
301
|
+
x: CodegenTypes.Double;
|
|
302
|
+
y: CodegenTypes.Double;
|
|
303
|
+
width: CodegenTypes.Double;
|
|
304
|
+
height: CodegenTypes.Double;
|
|
305
|
+
};
|
|
306
|
+
endRect: {
|
|
307
|
+
x: CodegenTypes.Double;
|
|
308
|
+
y: CodegenTypes.Double;
|
|
309
|
+
width: CodegenTypes.Double;
|
|
310
|
+
height: CodegenTypes.Double;
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
|
|
278
314
|
export interface TaskListItemPressEvent {
|
|
279
315
|
index: CodegenTypes.Int32;
|
|
280
316
|
checked: boolean;
|
|
@@ -442,6 +478,18 @@ export interface NativeProps extends ViewProps {
|
|
|
442
478
|
* Deduplicated: not re-fired when the payload is unchanged.
|
|
443
479
|
*/
|
|
444
480
|
onLinkLayout?: CodegenTypes.DirectEventHandler<LinkLayoutEvent>;
|
|
481
|
+
/**
|
|
482
|
+
* When true, the view reports selection changes (and, with
|
|
483
|
+
* `contextMenuHidden`, block long-presses) through `onSelectionChange`.
|
|
484
|
+
* Set by the JS wrapper only when `onSelectionChange` is provided.
|
|
485
|
+
* @default false
|
|
486
|
+
*/
|
|
487
|
+
emitSelectionChange?: CodegenTypes.WithDefault<boolean, false>;
|
|
488
|
+
/**
|
|
489
|
+
* Fired while `emitSelectionChange` is on: coalesced to one event per frame,
|
|
490
|
+
* deduplicated, and `active: false` once the selection is gone.
|
|
491
|
+
*/
|
|
492
|
+
onSelectionChange?: CodegenTypes.DirectEventHandler<SelectionChangeEvent>;
|
|
445
493
|
/**
|
|
446
494
|
* Callback fired when a task list checkbox is tapped.
|
|
447
495
|
* Receives the 0-based task index, current checked state, and the item's plain text.
|
|
@@ -481,6 +529,16 @@ export interface NativeProps extends ViewProps {
|
|
|
481
529
|
* @default true
|
|
482
530
|
*/
|
|
483
531
|
enableLinkPreview?: CodegenTypes.WithDefault<boolean, true>;
|
|
532
|
+
/**
|
|
533
|
+
* When `true`, long-pressing a link selects its label and shows the
|
|
534
|
+
* selection edit menu instead of the system link preview (iOS only).
|
|
535
|
+
* Takes precedence over `enableLinkPreview` and `onLinkLongPress`.
|
|
536
|
+
*
|
|
537
|
+
* Android: No-op.
|
|
538
|
+
*
|
|
539
|
+
* @default false
|
|
540
|
+
*/
|
|
541
|
+
linkLongPressSelects?: CodegenTypes.WithDefault<boolean, false>;
|
|
484
542
|
/**
|
|
485
543
|
* - iOS: Controls text selection and link previews on long press.
|
|
486
544
|
* - Android: Controls text selection.
|
|
@@ -594,6 +652,17 @@ export interface NativeProps extends ViewProps {
|
|
|
594
652
|
writingDirection?: CodegenTypes.WithDefault<string, 'first-strong'>;
|
|
595
653
|
}
|
|
596
654
|
|
|
655
|
+
type ComponentType = HostComponent<NativeProps>;
|
|
656
|
+
|
|
657
|
+
interface NativeCommands {
|
|
658
|
+
/** Clears the text selection (and any active block) and fires `onSelectionChange` with `active: false`. */
|
|
659
|
+
clearSelection: (viewRef: React.ElementRef<ComponentType>) => void;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
|
|
663
|
+
supportedCommands: ['clearSelection'],
|
|
664
|
+
});
|
|
665
|
+
|
|
597
666
|
export default codegenNativeComponent<NativeProps>('EnrichedMarkdownText', {
|
|
598
667
|
interfaceOnly: true,
|
|
599
|
-
})
|
|
668
|
+
}) as HostComponent<NativeProps>;
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["default","EnrichedMarkdownText","DEFAULT_ACCESSIBILITY_LABELS","resolveAccessibilityLabels","EnrichedMarkdownTextInput"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,OAAO,IAAIC,oBAAoB,QAAQ,kCAA+B;
|
|
1
|
+
{"version":3,"names":["default","EnrichedMarkdownText","DEFAULT_ACCESSIBILITY_LABELS","resolveAccessibilityLabels","EnrichedMarkdownTextInput"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,OAAO,IAAIC,oBAAoB,QAAQ,kCAA+B;AA2B/E,SACEC,4BAA4B,EAC5BC,0BAA0B,QACrB,iCAA8B;AAErC,SAASC,yBAAyB,QAAQ,gCAA6B","ignoreList":[]}
|
package/lib/module/jest/index.js
CHANGED
|
@@ -143,6 +143,7 @@ export const EnrichedMarkdownTextInput = ({
|
|
|
143
143
|
});
|
|
144
144
|
};
|
|
145
145
|
export const EnrichedMarkdownText = ({
|
|
146
|
+
ref,
|
|
146
147
|
markdown,
|
|
147
148
|
containerStyle,
|
|
148
149
|
testID,
|
|
@@ -156,7 +157,9 @@ export const EnrichedMarkdownText = ({
|
|
|
156
157
|
onLinkPress: _onLinkPress,
|
|
157
158
|
onLinkLongPress: _onLinkLongPress,
|
|
158
159
|
onTaskListItemPress: _onTaskListItemPress,
|
|
160
|
+
onSelectionChange: _onSelectionChange,
|
|
159
161
|
enableLinkPreview: _enableLinkPreview,
|
|
162
|
+
linkLongPressSelects: _linkLongPressSelects,
|
|
160
163
|
selectable: _selectable,
|
|
161
164
|
md4cFlags: _md4cFlags,
|
|
162
165
|
allowFontScaling: _allowFontScaling,
|
|
@@ -176,6 +179,17 @@ export const EnrichedMarkdownText = ({
|
|
|
176
179
|
lineBreakStrategyIOS: _lineBreakStrategyIOS,
|
|
177
180
|
writingDirection: _writingDirection
|
|
178
181
|
}) => {
|
|
182
|
+
const instanceRef = useRef(null);
|
|
183
|
+
if (instanceRef.current === null) {
|
|
184
|
+
instanceRef.current = {
|
|
185
|
+
// No native selection under Jest; the mock records the call.
|
|
186
|
+
clearSelection: spy(() => {}),
|
|
187
|
+
measure: spy(callback => callback(0, 0, 0, 0, 0, 0)),
|
|
188
|
+
measureInWindow: spy(callback => callback(0, 0, 0, 0)),
|
|
189
|
+
measureLayout: spy((_relativeToNativeNode, onSuccess) => onSuccess(0, 0, 0, 0))
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
useImperativeHandle(ref, () => instanceRef.current);
|
|
179
193
|
return /*#__PURE__*/_jsx(Text, {
|
|
180
194
|
style: containerStyle,
|
|
181
195
|
testID: testID,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useImperativeHandle","useRef","useState","Text","TextInput","jsx","_jsx","DEFAULT_ACCESSIBILITY_LABELS","resolveAccessibilityLabels","spy","impl","jest","fn","EMPTY_CARET_RECT","x","y","width","height","EnrichedMarkdownTextInput","ref","defaultValue","onChangeText","onChangeMarkdown","onFocus","onBlur","editable","placeholder","placeholderTextColor","autoFocus","multiline","scrollEnabled","style","testID","accessible","accessibilityLabel","accessibilityHint","accessibilityRole","accessibilityState","nativeID","markdownStyle","_markdownStyle","cursorColor","_cursorColor","selectionColor","_selectionColor","autoCapitalize","_autoCapitalize","onChangeSelection","_onChangeSelection","onChangeState","_onChangeState","onKeyPress","_onKeyPress","onCaretRectChange","_onCaretRectChange","onLinkDetected","_onLinkDetected","mentionIndicators","_mentionIndicators","onStartMention","_onStartMention","onChangeMention","_onChangeMention","onEndMention","_onEndMention","contextMenuItems","_contextMenuItems","selectionMenuConfig","_selectionMenuConfig","formatMenuConfig","_formatMenuConfig","linkRegex","_linkRegex","writingDirection","_writingDirection","text","setText","textRef","inputRef","applyText","next","current","handleChangeText","instanceRef","focus","blur","measure","callback","measureInWindow","measureLayout","_relativeToNativeNode","onSuccess","setValue","markdown","setSelection","_start","_end","toggleBold","toggleItalic","toggleUnderline","toggleStrikethrough","toggleSpoiler","toggleHeading","_level","toggleUnorderedList","toggleOrderedList","indentList","outdentList","setLink","_url","insertLink","_text","insertText","insertMention","_displayText","startMention","_indicator","removeLink","copyToClipboard","resolvePaste","_markdown","insertMath","_latex","_options","updateMath","removeMath","getMarkdown","Promise","resolve","getCaretRect","value","EnrichedMarkdownText","containerStyle","onLinkPress","_onLinkPress","onLinkLongPress","_onLinkLongPress","onTaskListItemPress","_onTaskListItemPress","enableLinkPreview","_enableLinkPreview","selectable","_selectable","md4cFlags","_md4cFlags","allowFontScaling","_allowFontScaling","maxFontSizeMultiplier","_maxFontSizeMultiplier","allowTrailingMargin","_allowTrailingMargin","flavor","_flavor","streamingAnimation","_streamingAnimation","streamingConfig","_streamingConfig","spoilerOverlay","_spoilerOverlay","imageRequestHeaders","_imageRequestHeaders","accessibilityLabels","_accessibilityLabels","selectionHandleColor","_selectionHandleColor","textBreakStrategy","_textBreakStrategy","lineBreakStrategyIOS","_lineBreakStrategyIOS","children"],"sourceRoot":"../../../src","sources":["jest/index.tsx"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASA,mBAAmB,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,OAAO;AAE7D,SAASC,IAAI,EAAEC,SAAS,QAAQ,cAAc;AAAC,SAAAC,GAAA,IAAAC,IAAA;
|
|
1
|
+
{"version":3,"names":["useImperativeHandle","useRef","useState","Text","TextInput","jsx","_jsx","DEFAULT_ACCESSIBILITY_LABELS","resolveAccessibilityLabels","spy","impl","jest","fn","EMPTY_CARET_RECT","x","y","width","height","EnrichedMarkdownTextInput","ref","defaultValue","onChangeText","onChangeMarkdown","onFocus","onBlur","editable","placeholder","placeholderTextColor","autoFocus","multiline","scrollEnabled","style","testID","accessible","accessibilityLabel","accessibilityHint","accessibilityRole","accessibilityState","nativeID","markdownStyle","_markdownStyle","cursorColor","_cursorColor","selectionColor","_selectionColor","autoCapitalize","_autoCapitalize","onChangeSelection","_onChangeSelection","onChangeState","_onChangeState","onKeyPress","_onKeyPress","onCaretRectChange","_onCaretRectChange","onLinkDetected","_onLinkDetected","mentionIndicators","_mentionIndicators","onStartMention","_onStartMention","onChangeMention","_onChangeMention","onEndMention","_onEndMention","contextMenuItems","_contextMenuItems","selectionMenuConfig","_selectionMenuConfig","formatMenuConfig","_formatMenuConfig","linkRegex","_linkRegex","writingDirection","_writingDirection","text","setText","textRef","inputRef","applyText","next","current","handleChangeText","instanceRef","focus","blur","measure","callback","measureInWindow","measureLayout","_relativeToNativeNode","onSuccess","setValue","markdown","setSelection","_start","_end","toggleBold","toggleItalic","toggleUnderline","toggleStrikethrough","toggleSpoiler","toggleHeading","_level","toggleUnorderedList","toggleOrderedList","indentList","outdentList","setLink","_url","insertLink","_text","insertText","insertMention","_displayText","startMention","_indicator","removeLink","copyToClipboard","resolvePaste","_markdown","insertMath","_latex","_options","updateMath","removeMath","getMarkdown","Promise","resolve","getCaretRect","value","EnrichedMarkdownText","containerStyle","onLinkPress","_onLinkPress","onLinkLongPress","_onLinkLongPress","onTaskListItemPress","_onTaskListItemPress","onSelectionChange","_onSelectionChange","enableLinkPreview","_enableLinkPreview","linkLongPressSelects","_linkLongPressSelects","selectable","_selectable","md4cFlags","_md4cFlags","allowFontScaling","_allowFontScaling","maxFontSizeMultiplier","_maxFontSizeMultiplier","allowTrailingMargin","_allowTrailingMargin","flavor","_flavor","streamingAnimation","_streamingAnimation","streamingConfig","_streamingConfig","spoilerOverlay","_spoilerOverlay","imageRequestHeaders","_imageRequestHeaders","accessibilityLabels","_accessibilityLabels","selectionHandleColor","_selectionHandleColor","textBreakStrategy","_textBreakStrategy","lineBreakStrategyIOS","_lineBreakStrategyIOS","clearSelection","children"],"sourceRoot":"../../../src","sources":["jest/index.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import { useMemo, useCallback, useRef, useEffect, useState } from 'react';
|
|
4
|
-
import EnrichedMarkdownTextNativeComponent from '../EnrichedMarkdownTextNativeComponent';
|
|
5
|
-
import EnrichedMarkdownNativeComponent from '../EnrichedMarkdownNativeComponent';
|
|
3
|
+
import { useMemo, useCallback, useRef, useEffect, useState, useImperativeHandle } from 'react';
|
|
4
|
+
import EnrichedMarkdownTextNativeComponent, { Commands as TextCommands } from '../EnrichedMarkdownTextNativeComponent';
|
|
5
|
+
import EnrichedMarkdownNativeComponent, { Commands as MarkdownCommands } from '../EnrichedMarkdownNativeComponent';
|
|
6
6
|
import { normalizeMarkdownStyle } from '../normalizeMarkdownStyle';
|
|
7
7
|
import { resolveAccessibilityLabels } from "../accessibilityLabelDefaults.js";
|
|
8
8
|
import { normalizeMenuItem, normalizeLegacyBooleanMenuItem } from "../normalizeMenuItem.js";
|
|
@@ -104,6 +104,7 @@ const defaultMd4cFlags = {
|
|
|
104
104
|
hardSoftBreaks: false
|
|
105
105
|
};
|
|
106
106
|
export const EnrichedMarkdownText = ({
|
|
107
|
+
ref,
|
|
107
108
|
markdown,
|
|
108
109
|
markdownStyle = {},
|
|
109
110
|
containerStyle,
|
|
@@ -113,7 +114,9 @@ export const EnrichedMarkdownText = ({
|
|
|
113
114
|
enableTaskListItemToggle = true,
|
|
114
115
|
onCopyPress,
|
|
115
116
|
onCopy,
|
|
117
|
+
onSelectionChange,
|
|
116
118
|
enableLinkPreview,
|
|
119
|
+
linkLongPressSelects = false,
|
|
117
120
|
selectable = true,
|
|
118
121
|
md4cFlags = defaultMd4cFlags,
|
|
119
122
|
allowFontScaling = true,
|
|
@@ -260,6 +263,40 @@ export const EnrichedMarkdownText = ({
|
|
|
260
263
|
y
|
|
261
264
|
});
|
|
262
265
|
}, []);
|
|
266
|
+
|
|
267
|
+
// Rects stay relative to the native view — the view the ref's
|
|
268
|
+
// `measureInWindow` measures — even when decorations wrap it.
|
|
269
|
+
const handleSelectionChange = useCallback(
|
|
270
|
+
// Codegen types `source` as a plain string; native only sends the four
|
|
271
|
+
// values of SelectionChangeEvent['source'].
|
|
272
|
+
e => {
|
|
273
|
+
const {
|
|
274
|
+
source,
|
|
275
|
+
...payload
|
|
276
|
+
} = e.nativeEvent;
|
|
277
|
+
onSelectionChange?.({
|
|
278
|
+
...payload,
|
|
279
|
+
source: source
|
|
280
|
+
});
|
|
281
|
+
}, [onSelectionChange]);
|
|
282
|
+
const nativeRef = useRef(null);
|
|
283
|
+
const isGithubFlavor = flavor === 'github';
|
|
284
|
+
useImperativeHandle(ref, () => ({
|
|
285
|
+
clearSelection: () => {
|
|
286
|
+
const node = nativeRef.current;
|
|
287
|
+
if (node == null) return;
|
|
288
|
+
// Codegen's ViewRef resolves to `never` with RN 0.84's function-based
|
|
289
|
+
// HostComponent type — the cast is safe at runtime.
|
|
290
|
+
if (isGithubFlavor) {
|
|
291
|
+
MarkdownCommands.clearSelection(node);
|
|
292
|
+
} else {
|
|
293
|
+
TextCommands.clearSelection(node);
|
|
294
|
+
}
|
|
295
|
+
},
|
|
296
|
+
measure: callback => nativeRef.current?.measure(callback),
|
|
297
|
+
measureInWindow: callback => nativeRef.current?.measureInWindow(callback),
|
|
298
|
+
measureLayout: (relativeToNativeNode, onSuccess, onFail) => nativeRef.current?.measureLayout(relativeToNativeNode, onSuccess, onFail)
|
|
299
|
+
}), [isGithubFlavor]);
|
|
263
300
|
const tableMode = streamingConfig?.tableMode ?? 'progressive';
|
|
264
301
|
const codeBlockMode = streamingConfig?.codeBlockMode ?? 'progressive';
|
|
265
302
|
const normalizedStreamingConfig = useMemo(() => ({
|
|
@@ -301,7 +338,10 @@ export const EnrichedMarkdownText = ({
|
|
|
301
338
|
enableTaskListItemToggle,
|
|
302
339
|
onCopyPress: handleCopyPress,
|
|
303
340
|
onCopyRequest: handleCopyRequest,
|
|
341
|
+
emitSelectionChange: onSelectionChange != null,
|
|
342
|
+
onSelectionChange: handleSelectionChange,
|
|
304
343
|
enableLinkPreview: onLinkLongPress == null && (enableLinkPreview ?? true),
|
|
344
|
+
linkLongPressSelects,
|
|
305
345
|
selectable,
|
|
306
346
|
md4cFlags: normalizedMd4cFlags,
|
|
307
347
|
allowFontScaling,
|
|
@@ -324,13 +364,14 @@ export const EnrichedMarkdownText = ({
|
|
|
324
364
|
writingDirection,
|
|
325
365
|
...rest
|
|
326
366
|
};
|
|
327
|
-
const NativeComponent =
|
|
367
|
+
const NativeComponent = isGithubFlavor ? EnrichedMarkdownNativeComponent : EnrichedMarkdownTextNativeComponent;
|
|
328
368
|
|
|
329
369
|
// Without decorations the native view is returned as-is (no wrapper, no
|
|
330
370
|
// layout events) so existing layouts are untouched.
|
|
331
371
|
if (!decorated) {
|
|
332
372
|
return /*#__PURE__*/_jsx(NativeComponent, {
|
|
333
373
|
...sharedProps,
|
|
374
|
+
ref: nativeRef,
|
|
334
375
|
onLayout: onLayout
|
|
335
376
|
});
|
|
336
377
|
}
|
|
@@ -339,6 +380,7 @@ export const EnrichedMarkdownText = ({
|
|
|
339
380
|
onLayout: onLayout,
|
|
340
381
|
children: [/*#__PURE__*/_jsx(NativeComponent, {
|
|
341
382
|
...sharedProps,
|
|
383
|
+
ref: nativeRef,
|
|
342
384
|
style: undefined,
|
|
343
385
|
emitLinkLayout: true,
|
|
344
386
|
onLinkLayout: handleLinkLayout,
|