react-native-enriched-markdown-scaffold 1.0.2-scaffold.4 → 1.0.2-scaffold.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.
Files changed (68) hide show
  1. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +12 -0
  2. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +2 -0
  3. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +12 -0
  4. package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +2 -0
  5. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +74 -0
  6. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +68 -0
  7. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +10 -0
  8. package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +2 -0
  9. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt +107 -0
  10. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +19 -0
  11. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +14 -0
  12. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +48 -0
  13. package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +14 -0
  14. package/android/src/main/java/com/swmansion/enriched/markdown/events/SelectionChangeEvent.kt +42 -0
  15. package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +14 -0
  16. package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionChangeReporter.kt +230 -0
  17. package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +11 -1
  18. package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +8 -1
  19. package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +8 -1
  20. package/docs/API_REFERENCE.md +58 -0
  21. package/ios/EnrichedMarkdown.mm +174 -2
  22. package/ios/EnrichedMarkdownText.mm +103 -1
  23. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +74 -0
  24. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +68 -0
  25. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +10 -0
  26. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +2 -0
  27. package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +50 -2
  28. package/ios/utils/ENRMLinkChip.m +14 -14
  29. package/ios/utils/ENRMLinkLayout.m +12 -12
  30. package/ios/utils/ENRMSelectionChange.h +96 -0
  31. package/ios/utils/ENRMSelectionChange.m +204 -0
  32. package/ios/utils/EditMenuUtils+macOS.m +1 -1
  33. package/ios/utils/MarkdownAccessibilityElementBuilder.m +1 -2
  34. package/ios/views/ENRMCodeBlockContainerView.h +3 -0
  35. package/ios/views/ENRMCodeBlockContainerView.m +3 -0
  36. package/ios/views/ENRMMathContainerView.h +3 -0
  37. package/ios/views/ENRMMathContainerView.m +3 -0
  38. package/ios/views/TableContainerView.h +3 -0
  39. package/ios/views/TableContainerView.m +4 -1
  40. package/lib/module/EnrichedMarkdownNativeComponent.ts +60 -1
  41. package/lib/module/EnrichedMarkdownTextNativeComponent.ts +60 -1
  42. package/lib/module/index.js.map +1 -1
  43. package/lib/module/jest/index.js +13 -0
  44. package/lib/module/jest/index.js.map +1 -1
  45. package/lib/module/native/EnrichedMarkdownText.js +44 -4
  46. package/lib/module/native/EnrichedMarkdownText.js.map +1 -1
  47. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +53 -2
  48. package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
  49. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +53 -2
  50. package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
  51. package/lib/typescript/src/index.d.ts +2 -2
  52. package/lib/typescript/src/index.d.ts.map +1 -1
  53. package/lib/typescript/src/jest/index.d.ts +1 -1
  54. package/lib/typescript/src/jest/index.d.ts.map +1 -1
  55. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts +5 -5
  56. package/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +1 -1
  57. package/lib/typescript/src/types/MarkdownTextProps.d.ts +36 -3
  58. package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -1
  59. package/lib/typescript/src/types/events.d.ts +36 -0
  60. package/lib/typescript/src/types/events.d.ts.map +1 -1
  61. package/package.json +1 -1
  62. package/src/EnrichedMarkdownNativeComponent.ts +60 -1
  63. package/src/EnrichedMarkdownTextNativeComponent.ts +60 -1
  64. package/src/index.tsx +3 -0
  65. package/src/jest/index.tsx +21 -1
  66. package/src/native/EnrichedMarkdownText.tsx +85 -9
  67. package/src/types/MarkdownTextProps.ts +43 -2
  68. package/src/types/events.ts +38 -0
@@ -2,5 +2,5 @@ import type { EnrichedMarkdownTextInputProps } from '../EnrichedMarkdownTextInpu
2
2
  import type { EnrichedMarkdownTextProps } from '../native/EnrichedMarkdownText';
3
3
  export { DEFAULT_ACCESSIBILITY_LABELS, resolveAccessibilityLabels, } from '../accessibilityLabelDefaults';
4
4
  export declare const 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, }: EnrichedMarkdownTextInputProps) => import("react/jsx-runtime").JSX.Element;
5
- export declare const EnrichedMarkdownText: ({ markdown, containerStyle, testID, accessible, accessibilityLabel, accessibilityHint, accessibilityRole, accessibilityState, nativeID, markdownStyle: _markdownStyle, 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, contextMenuItems: _contextMenuItems, imageRequestHeaders: _imageRequestHeaders, selectionMenuConfig: _selectionMenuConfig, accessibilityLabels: _accessibilityLabels, selectionColor: _selectionColor, selectionHandleColor: _selectionHandleColor, textBreakStrategy: _textBreakStrategy, lineBreakStrategyIOS: _lineBreakStrategyIOS, writingDirection: _writingDirection, }: EnrichedMarkdownTextProps) => import("react/jsx-runtime").JSX.Element;
5
+ export declare const EnrichedMarkdownText: ({ ref, markdown, containerStyle, testID, accessible, accessibilityLabel, accessibilityHint, accessibilityRole, accessibilityState, nativeID, markdownStyle: _markdownStyle, onLinkPress: _onLinkPress, onLinkLongPress: _onLinkLongPress, onTaskListItemPress: _onTaskListItemPress, onSelectionChange: _onSelectionChange, enableLinkPreview: _enableLinkPreview, selectable: _selectable, md4cFlags: _md4cFlags, allowFontScaling: _allowFontScaling, maxFontSizeMultiplier: _maxFontSizeMultiplier, allowTrailingMargin: _allowTrailingMargin, flavor: _flavor, streamingAnimation: _streamingAnimation, streamingConfig: _streamingConfig, spoilerOverlay: _spoilerOverlay, contextMenuItems: _contextMenuItems, imageRequestHeaders: _imageRequestHeaders, selectionMenuConfig: _selectionMenuConfig, accessibilityLabels: _accessibilityLabels, selectionColor: _selectionColor, selectionHandleColor: _selectionHandleColor, textBreakStrategy: _textBreakStrategy, lineBreakStrategyIOS: _lineBreakStrategyIOS, writingDirection: _writingDirection, }: EnrichedMarkdownTextProps) => import("react/jsx-runtime").JSX.Element;
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/jest/index.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAGV,8BAA8B,EAE/B,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAEhF,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,+BAA+B,CAAC;AASvC,eAAO,MAAM,yBAAyB,GAAI,02BAuCvC,8BAA8B,4CAmFhC,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,o9BAiClC,yBAAyB,4CAe3B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/jest/index.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAGV,8BAA8B,EAE/B,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAEV,yBAAyB,EAC1B,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,+BAA+B,CAAC;AASvC,eAAO,MAAM,yBAAyB,GAAI,02BAuCvC,8BAA8B,4CAmFhC,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,ggCAmClC,yBAAyB,4CA8B3B,CAAC"}
@@ -1,9 +1,9 @@
1
1
  import type { MarkdownStyle, Md4cFlags } from '../types/MarkdownStyle';
2
- import type { EnrichedMarkdownTextProps, StreamingConfig, ContextMenuItem, SelectionMenuConfig, SelectionMenuPluralLabels, LinkDecorationInfo, LinkRect } from '../types/MarkdownTextProps';
3
- import type { LinkPressEvent, LinkLongPressEvent, TaskListItemPressEvent, CopyPressEvent, CopyEvent } from '../types/events';
2
+ import type { EnrichedMarkdownTextProps, EnrichedMarkdownTextInstance, StreamingConfig, ContextMenuItem, SelectionMenuConfig, SelectionMenuPluralLabels, LinkDecorationInfo, LinkRect } from '../types/MarkdownTextProps';
3
+ import type { LinkPressEvent, LinkLongPressEvent, TaskListItemPressEvent, CopyPressEvent, CopyEvent, SelectionChangeEvent, SelectionRect } from '../types/events';
4
4
  export type { MarkdownStyle, Md4cFlags };
5
- export type { EnrichedMarkdownTextProps, StreamingConfig, ContextMenuItem, SelectionMenuConfig, SelectionMenuPluralLabels, LinkDecorationInfo, LinkRect, };
6
- export type { LinkPressEvent, LinkLongPressEvent, TaskListItemPressEvent, CopyPressEvent, CopyEvent, };
7
- export declare const EnrichedMarkdownText: ({ markdown, markdownStyle, containerStyle, onLinkPress, onLinkLongPress, onTaskListItemPress, enableTaskListItemToggle, onCopyPress, onCopy, enableLinkPreview, selectable, md4cFlags, allowFontScaling, maxFontSizeMultiplier, allowTrailingMargin, flavor, streamingAnimation, streamingConfig, spoilerOverlay, contextMenuItems, imageRequestHeaders, contextMenuHidden, selectionMenuConfig, accessibilityLabels, selectionColor, selectionHandleColor, textBreakStrategy, lineBreakStrategyIOS, writingDirection, renderLinkDecoration, onLayout, ...rest }: EnrichedMarkdownTextProps) => import("react/jsx-runtime").JSX.Element;
5
+ export type { EnrichedMarkdownTextProps, EnrichedMarkdownTextInstance, StreamingConfig, ContextMenuItem, SelectionMenuConfig, SelectionMenuPluralLabels, LinkDecorationInfo, LinkRect, };
6
+ export type { LinkPressEvent, LinkLongPressEvent, TaskListItemPressEvent, CopyPressEvent, CopyEvent, SelectionChangeEvent, SelectionRect, };
7
+ export declare const EnrichedMarkdownText: ({ ref, markdown, markdownStyle, containerStyle, onLinkPress, onLinkLongPress, onTaskListItemPress, enableTaskListItemToggle, onCopyPress, onCopy, onSelectionChange, enableLinkPreview, selectable, md4cFlags, allowFontScaling, maxFontSizeMultiplier, allowTrailingMargin, flavor, streamingAnimation, streamingConfig, spoilerOverlay, contextMenuItems, imageRequestHeaders, contextMenuHidden, selectionMenuConfig, accessibilityLabels, selectionColor, selectionHandleColor, textBreakStrategy, lineBreakStrategyIOS, writingDirection, renderLinkDecoration, onLayout, ...rest }: EnrichedMarkdownTextProps) => import("react/jsx-runtime").JSX.Element;
8
8
  export default EnrichedMarkdownText;
9
9
  //# sourceMappingURL=EnrichedMarkdownText.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EnrichedMarkdownText.d.ts","sourceRoot":"","sources":["../../../../src/native/EnrichedMarkdownText.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,KAAK,EACV,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,EAClB,QAAQ,EACT,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,cAAc,EACd,SAAS,EAEV,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AACzC,YAAY,EACV,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,EAClB,QAAQ,GACT,CAAC;AACF,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,cAAc,EACd,SAAS,GACV,CAAC;AAoGF,eAAO,MAAM,oBAAoB,GAAI,kiBAiClC,yBAAyB,4CA0R3B,CAAC;AAMF,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"EnrichedMarkdownText.d.ts","sourceRoot":"","sources":["../../../../src/native/EnrichedMarkdownText.tsx"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,KAAK,EACV,yBAAyB,EACzB,4BAA4B,EAC5B,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,EAClB,QAAQ,EACT,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,cAAc,EACd,SAAS,EAET,oBAAoB,EACpB,aAAa,EACd,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AACzC,YAAY,EACV,yBAAyB,EACzB,4BAA4B,EAC5B,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,EAClB,QAAQ,GACT,CAAC;AACF,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,cAAc,EACd,SAAS,EACT,oBAAoB,EACpB,aAAa,GACd,CAAC;AAoGF,eAAO,MAAM,oBAAoB,GAAI,0jBAmClC,yBAAyB,4CA8U3B,CAAC;AAMF,eAAe,oBAAoB,CAAC"}
@@ -1,8 +1,20 @@
1
- import type { ReactNode } from 'react';
2
- import type { ColorValue, ViewProps, ViewStyle, TextStyle } from 'react-native';
1
+ import type { ReactNode, RefObject } from 'react';
2
+ import type { ColorValue, HostInstance, ViewProps, ViewStyle, TextStyle } from 'react-native';
3
3
  import type { MarkdownStyle, Md4cFlags } from './MarkdownStyle';
4
4
  import type { AccessibilityLabels } from './AccessibilityLabels';
5
- import type { LinkPressEvent, LinkLongPressEvent, TaskListItemPressEvent, CopyPressEvent, CopyEvent } from './events';
5
+ import type { LinkPressEvent, LinkLongPressEvent, TaskListItemPressEvent, CopyPressEvent, CopyEvent, SelectionChangeEvent } from './events';
6
+ /** Imperative handle of `EnrichedMarkdownText`, reached through its `ref`. */
7
+ export interface EnrichedMarkdownTextInstance {
8
+ /**
9
+ * Clears the text selection (and any long-pressed block) and fires
10
+ * `onSelectionChange` with `active: false`.
11
+ * @platform ios, android
12
+ */
13
+ clearSelection: () => void;
14
+ measure: HostInstance['measure'];
15
+ measureInWindow: HostInstance['measureInWindow'];
16
+ measureLayout: HostInstance['measureLayout'];
17
+ }
6
18
  /**
7
19
  * A rect in dp, relative to the component's content box (inside any
8
20
  * `containerStyle` padding).
@@ -168,6 +180,11 @@ export interface StreamingConfig {
168
180
  codeBlockMode?: 'hidden' | 'progressive';
169
181
  }
170
182
  export interface EnrichedMarkdownTextProps extends Omit<ViewProps, 'style'> {
183
+ /**
184
+ * Imperative handle: `clearSelection()` plus the host `measure*` methods.
185
+ * @platform ios, android
186
+ */
187
+ ref?: RefObject<EnrichedMarkdownTextInstance | null>;
171
188
  /**
172
189
  * Markdown content to render.
173
190
  * @platform ios, android, web
@@ -268,6 +285,22 @@ export interface EnrichedMarkdownTextProps extends Omit<ViewProps, 'style'> {
268
285
  * @platform ios, android
269
286
  */
270
287
  onCopy?: (event: CopyEvent) => void;
288
+ /**
289
+ * Reports the text selection so the app can draw its own menu (pair it with
290
+ * `contextMenuHidden`). Fires at most once per frame while the selection
291
+ * changes, and with `active: false` once it is gone. With
292
+ * `contextMenuHidden`, a long press on a table / math / code block fires it
293
+ * too (`source` is the block kind, `whole: true`), since those blocks have no
294
+ * text selection of their own. Only one part of a component holds a
295
+ * selection at a time; clearing the selection of *other* components is up to
296
+ * the app (`ref.current.clearSelection()`).
297
+ *
298
+ * Rects are relative to the view that `ref.current.measureInWindow`
299
+ * measures — add that origin to position UI on screen. There is no
300
+ * "dragging" flag: debounce before showing a menu.
301
+ * @platform ios, android
302
+ */
303
+ onSelectionChange?: (event: SelectionChangeEvent) => void;
271
304
  /**
272
305
  * Controls whether the system link preview is shown on long press (iOS only).
273
306
  *
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownTextProps.d.ts","sourceRoot":"","sources":["../../../../src/types/MarkdownTextProps.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MarkdownTextProps.d.ts","sourceRoot":"","sources":["../../../../src/types/MarkdownTextProps.ts"],"names":[],"mappings":"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"}
@@ -35,6 +35,42 @@ export interface CopyEvent {
35
35
  */
36
36
  whole: boolean;
37
37
  }
38
+ /**
39
+ * A rect in dp, relative to the component's native view: add the origin from
40
+ * the component ref's `measureInWindow` to get window coordinates.
41
+ */
42
+ export interface SelectionRect {
43
+ x: number;
44
+ y: number;
45
+ width: number;
46
+ height: number;
47
+ }
48
+ /**
49
+ * Payload of `onSelectionChange`: the current text selection, or a table /
50
+ * math / code block long-pressed while `contextMenuHidden` is on. Content
51
+ * fields carry what `onCopy` would receive for the same selection.
52
+ */
53
+ export interface SelectionChangeEvent {
54
+ /** `false` once the selection is gone; every other field is then empty / zero. */
55
+ active: boolean;
56
+ /** `'selection'` for text; the block kind for a long-pressed block. */
57
+ source: CopyEvent['source'];
58
+ /** Rendered text of the selection, or the block's raw content. */
59
+ text: string;
60
+ /** Same as `CopyEvent.markdown` for this selection. */
61
+ markdown: string;
62
+ /** Same as `CopyEvent.whole`. Always `true` for blocks. */
63
+ whole: boolean;
64
+ /**
65
+ * Bounding box of the selection (full content width when it spans several
66
+ * lines); the block's frame for blocks.
67
+ */
68
+ rect: SelectionRect;
69
+ /** Selected part of the first line (block: same as `rect`). */
70
+ startRect: SelectionRect;
71
+ /** Selected part of the last line (block: same as `rect`). */
72
+ endRect: SelectionRect;
73
+ }
38
74
  /**
39
75
  * Native-level context menu item config sent to the native component.
40
76
  * Does not include the `onPress` callback — callbacks are managed on the JS side.
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../../src/types/events.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,2CAA2C;IAC3C,MAAM,EAAE,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAChD;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../../src/types/events.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,2CAA2C;IAC3C,MAAM,EAAE,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAChD;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,kFAAkF;IAClF,MAAM,EAAE,OAAO,CAAC;IAChB,uEAAuE;IACvE,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC5B,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,KAAK,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,IAAI,EAAE,aAAa,CAAC;IACpB,+DAA+D;IAC/D,SAAS,EAAE,aAAa,CAAC;IACzB,8DAA8D;IAC9D,OAAO,EAAE,aAAa,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-enriched-markdown-scaffold",
3
- "version": "1.0.2-scaffold.4",
3
+ "version": "1.0.2-scaffold.5",
4
4
  "description": "Markdown-based Rich Text solution for React Native",
5
5
  "main": "./lib/module/index",
6
6
  "module": "./lib/module/index",
@@ -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.
@@ -594,6 +642,17 @@ export interface NativeProps extends ViewProps {
594
642
  writingDirection?: CodegenTypes.WithDefault<string, 'first-strong'>;
595
643
  }
596
644
 
645
+ type ComponentType = HostComponent<NativeProps>;
646
+
647
+ interface NativeCommands {
648
+ /** Clears the text selection (and any active block) and fires `onSelectionChange` with `active: false`. */
649
+ clearSelection: (viewRef: React.ElementRef<ComponentType>) => void;
650
+ }
651
+
652
+ export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
653
+ supportedCommands: ['clearSelection'],
654
+ });
655
+
597
656
  export default codegenNativeComponent<NativeProps>('EnrichedMarkdown', {
598
657
  interfaceOnly: true,
599
- });
658
+ }) 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.
@@ -594,6 +642,17 @@ export interface NativeProps extends ViewProps {
594
642
  writingDirection?: CodegenTypes.WithDefault<string, 'first-strong'>;
595
643
  }
596
644
 
645
+ type ComponentType = HostComponent<NativeProps>;
646
+
647
+ interface NativeCommands {
648
+ /** Clears the text selection (and any active block) and fires `onSelectionChange` with `active: false`. */
649
+ clearSelection: (viewRef: React.ElementRef<ComponentType>) => void;
650
+ }
651
+
652
+ export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
653
+ supportedCommands: ['clearSelection'],
654
+ });
655
+
597
656
  export default codegenNativeComponent<NativeProps>('EnrichedMarkdownText', {
598
657
  interfaceOnly: true,
599
- });
658
+ }) as HostComponent<NativeProps>;
package/src/index.tsx CHANGED
@@ -1,6 +1,7 @@
1
1
  export { default as EnrichedMarkdownText } from './native/EnrichedMarkdownText';
2
2
  export type {
3
3
  EnrichedMarkdownTextProps,
4
+ EnrichedMarkdownTextInstance,
4
5
  StreamingConfig,
5
6
  MarkdownStyle,
6
7
  Md4cFlags,
@@ -17,6 +18,8 @@ export type {
17
18
  CopyPressEvent,
18
19
  CopyEvent,
19
20
  OnPasteEvent,
21
+ SelectionChangeEvent,
22
+ SelectionRect,
20
23
  } from './types/events';
21
24
  export type {
22
25
  AccessibilityLabels,
@@ -26,7 +26,10 @@ import type {
26
26
  EnrichedMarkdownTextInputProps,
27
27
  InsertMathOptions,
28
28
  } from '../EnrichedMarkdownTextInput';
29
- import type { EnrichedMarkdownTextProps } from '../native/EnrichedMarkdownText';
29
+ import type {
30
+ EnrichedMarkdownTextInstance,
31
+ EnrichedMarkdownTextProps,
32
+ } from '../native/EnrichedMarkdownText';
30
33
 
31
34
  export {
32
35
  DEFAULT_ACCESSIBILITY_LABELS,
@@ -165,6 +168,7 @@ export const EnrichedMarkdownTextInput = ({
165
168
  };
166
169
 
167
170
  export const EnrichedMarkdownText = ({
171
+ ref,
168
172
  markdown,
169
173
  containerStyle,
170
174
  testID,
@@ -178,6 +182,7 @@ export const EnrichedMarkdownText = ({
178
182
  onLinkPress: _onLinkPress,
179
183
  onLinkLongPress: _onLinkLongPress,
180
184
  onTaskListItemPress: _onTaskListItemPress,
185
+ onSelectionChange: _onSelectionChange,
181
186
  enableLinkPreview: _enableLinkPreview,
182
187
  selectable: _selectable,
183
188
  md4cFlags: _md4cFlags,
@@ -198,6 +203,21 @@ export const EnrichedMarkdownText = ({
198
203
  lineBreakStrategyIOS: _lineBreakStrategyIOS,
199
204
  writingDirection: _writingDirection,
200
205
  }: EnrichedMarkdownTextProps) => {
206
+ const instanceRef = useRef<EnrichedMarkdownTextInstance | null>(null);
207
+ if (instanceRef.current === null) {
208
+ instanceRef.current = {
209
+ // No native selection under Jest; the mock records the call.
210
+ clearSelection: spy(() => {}),
211
+ measure: spy((callback) => callback(0, 0, 0, 0, 0, 0)),
212
+ measureInWindow: spy((callback) => callback(0, 0, 0, 0)),
213
+ measureLayout: spy((_relativeToNativeNode, onSuccess) =>
214
+ onSuccess(0, 0, 0, 0)
215
+ ),
216
+ };
217
+ }
218
+
219
+ useImperativeHandle(ref, () => instanceRef.current!);
220
+
201
221
  return (
202
222
  <Text
203
223
  style={containerStyle}
@@ -1,10 +1,22 @@
1
- import { useMemo, useCallback, useRef, useEffect, useState } from 'react';
2
- import EnrichedMarkdownTextNativeComponent from '../EnrichedMarkdownTextNativeComponent';
1
+ import {
2
+ useMemo,
3
+ useCallback,
4
+ useRef,
5
+ useEffect,
6
+ useState,
7
+ useImperativeHandle,
8
+ } from 'react';
9
+ import EnrichedMarkdownTextNativeComponent, {
10
+ Commands as TextCommands,
11
+ } from '../EnrichedMarkdownTextNativeComponent';
3
12
  import type {
4
13
  LinkLayoutEvent,
5
14
  MarkdownStyleInternal,
15
+ SelectionChangeEvent as NativeSelectionChangeEvent,
6
16
  } from '../EnrichedMarkdownTextNativeComponent';
7
- import EnrichedMarkdownNativeComponent from '../EnrichedMarkdownNativeComponent';
17
+ import EnrichedMarkdownNativeComponent, {
18
+ Commands as MarkdownCommands,
19
+ } from '../EnrichedMarkdownNativeComponent';
8
20
  import { normalizeMarkdownStyle } from '../normalizeMarkdownStyle';
9
21
  import { resolveAccessibilityLabels } from '../accessibilityLabelDefaults';
10
22
  import {
@@ -12,10 +24,15 @@ import {
12
24
  normalizeLegacyBooleanMenuItem,
13
25
  } from '../normalizeMenuItem';
14
26
  import { StyleSheet, View } from 'react-native';
15
- import type { LayoutChangeEvent, NativeSyntheticEvent } from 'react-native';
27
+ import type {
28
+ HostInstance,
29
+ LayoutChangeEvent,
30
+ NativeSyntheticEvent,
31
+ } from 'react-native';
16
32
  import type { MarkdownStyle, Md4cFlags } from '../types/MarkdownStyle';
17
33
  import type {
18
34
  EnrichedMarkdownTextProps,
35
+ EnrichedMarkdownTextInstance,
19
36
  StreamingConfig,
20
37
  ContextMenuItem,
21
38
  SelectionMenuConfig,
@@ -30,11 +47,14 @@ import type {
30
47
  CopyPressEvent,
31
48
  CopyEvent,
32
49
  OnContextMenuItemPressEvent,
50
+ SelectionChangeEvent,
51
+ SelectionRect,
33
52
  } from '../types/events';
34
53
 
35
54
  export type { MarkdownStyle, Md4cFlags };
36
55
  export type {
37
56
  EnrichedMarkdownTextProps,
57
+ EnrichedMarkdownTextInstance,
38
58
  StreamingConfig,
39
59
  ContextMenuItem,
40
60
  SelectionMenuConfig,
@@ -48,6 +68,8 @@ export type {
48
68
  TaskListItemPressEvent,
49
69
  CopyPressEvent,
50
70
  CopyEvent,
71
+ SelectionChangeEvent,
72
+ SelectionRect,
51
73
  };
52
74
 
53
75
  // Default English labels for the built-in selection menu actions. Defaults are
@@ -149,6 +171,7 @@ const defaultMd4cFlags: Md4cFlags = {
149
171
  };
150
172
 
151
173
  export const EnrichedMarkdownText = ({
174
+ ref,
152
175
  markdown,
153
176
  markdownStyle = {},
154
177
  containerStyle,
@@ -158,6 +181,7 @@ export const EnrichedMarkdownText = ({
158
181
  enableTaskListItemToggle = true,
159
182
  onCopyPress,
160
183
  onCopy,
184
+ onSelectionChange,
161
185
  enableLinkPreview,
162
186
  selectable = true,
163
187
  md4cFlags = defaultMd4cFlags,
@@ -315,6 +339,54 @@ export const EnrichedMarkdownText = ({
315
339
  setNativeOffset((prev) => (prev.x === x && prev.y === y ? prev : { x, y }));
316
340
  }, []);
317
341
 
342
+ // Rects stay relative to the native view — the view the ref's
343
+ // `measureInWindow` measures — even when decorations wrap it.
344
+ const handleSelectionChange = useCallback(
345
+ // Codegen types `source` as a plain string; native only sends the four
346
+ // values of SelectionChangeEvent['source'].
347
+ (e: NativeSyntheticEvent<NativeSelectionChangeEvent>) => {
348
+ const { source, ...payload } = e.nativeEvent;
349
+ onSelectionChange?.({
350
+ ...payload,
351
+ source: source as SelectionChangeEvent['source'],
352
+ });
353
+ },
354
+ [onSelectionChange]
355
+ );
356
+
357
+ const nativeRef = useRef<HostInstance | null>(null);
358
+ const isGithubFlavor = flavor === 'github';
359
+ useImperativeHandle(
360
+ ref,
361
+ () => ({
362
+ clearSelection: () => {
363
+ const node = nativeRef.current;
364
+ if (node == null) return;
365
+ // Codegen's ViewRef resolves to `never` with RN 0.84's function-based
366
+ // HostComponent type — the cast is safe at runtime.
367
+ if (isGithubFlavor) {
368
+ MarkdownCommands.clearSelection(
369
+ node as Parameters<(typeof MarkdownCommands)['clearSelection']>[0]
370
+ );
371
+ } else {
372
+ TextCommands.clearSelection(
373
+ node as Parameters<(typeof TextCommands)['clearSelection']>[0]
374
+ );
375
+ }
376
+ },
377
+ measure: (callback) => nativeRef.current?.measure(callback),
378
+ measureInWindow: (callback) =>
379
+ nativeRef.current?.measureInWindow(callback),
380
+ measureLayout: (relativeToNativeNode, onSuccess, onFail) =>
381
+ nativeRef.current?.measureLayout(
382
+ relativeToNativeNode,
383
+ onSuccess,
384
+ onFail
385
+ ),
386
+ }),
387
+ [isGithubFlavor]
388
+ );
389
+
318
390
  const tableMode = streamingConfig?.tableMode ?? 'progressive';
319
391
  const codeBlockMode = streamingConfig?.codeBlockMode ?? 'progressive';
320
392
  const normalizedStreamingConfig = useMemo(
@@ -396,6 +468,8 @@ export const EnrichedMarkdownText = ({
396
468
  enableTaskListItemToggle,
397
469
  onCopyPress: handleCopyPress,
398
470
  onCopyRequest: handleCopyRequest,
471
+ emitSelectionChange: onSelectionChange != null,
472
+ onSelectionChange: handleSelectionChange,
399
473
  enableLinkPreview: onLinkLongPress == null && (enableLinkPreview ?? true),
400
474
  selectable,
401
475
  md4cFlags: normalizedMd4cFlags,
@@ -420,21 +494,23 @@ export const EnrichedMarkdownText = ({
420
494
  ...rest,
421
495
  };
422
496
 
423
- const NativeComponent =
424
- flavor === 'github'
425
- ? EnrichedMarkdownNativeComponent
426
- : EnrichedMarkdownTextNativeComponent;
497
+ const NativeComponent = isGithubFlavor
498
+ ? EnrichedMarkdownNativeComponent
499
+ : EnrichedMarkdownTextNativeComponent;
427
500
 
428
501
  // Without decorations the native view is returned as-is (no wrapper, no
429
502
  // layout events) so existing layouts are untouched.
430
503
  if (!decorated) {
431
- return <NativeComponent {...sharedProps} onLayout={onLayout} />;
504
+ return (
505
+ <NativeComponent {...sharedProps} ref={nativeRef} onLayout={onLayout} />
506
+ );
432
507
  }
433
508
 
434
509
  return (
435
510
  <View style={containerStyle} onLayout={onLayout}>
436
511
  <NativeComponent
437
512
  {...sharedProps}
513
+ ref={nativeRef}
438
514
  style={undefined}
439
515
  emitLinkLayout
440
516
  onLinkLayout={handleLinkLayout}