react-native-simple-rich-text-editor 0.1.0-beta.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.
Files changed (122) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +69 -0
  3. package/lib/commonjs/index.js +166 -0
  4. package/lib/commonjs/index.js.map +1 -0
  5. package/lib/commonjs/internal/rendering/components/Bold.js +23 -0
  6. package/lib/commonjs/internal/rendering/components/Bold.js.map +1 -0
  7. package/lib/commonjs/internal/rendering/components/BulletPoint.js +30 -0
  8. package/lib/commonjs/internal/rendering/components/BulletPoint.js.map +1 -0
  9. package/lib/commonjs/internal/rendering/components/Headline.js +37 -0
  10. package/lib/commonjs/internal/rendering/components/Headline.js.map +1 -0
  11. package/lib/commonjs/internal/rendering/components/Italic.js +23 -0
  12. package/lib/commonjs/internal/rendering/components/Italic.js.map +1 -0
  13. package/lib/commonjs/internal/rendering/components/Render.js +99 -0
  14. package/lib/commonjs/internal/rendering/components/Render.js.map +1 -0
  15. package/lib/commonjs/internal/rendering/utils.js +19 -0
  16. package/lib/commonjs/internal/rendering/utils.js.map +1 -0
  17. package/lib/commonjs/internal/text-formats/conversions.js +47 -0
  18. package/lib/commonjs/internal/text-formats/conversions.js.map +1 -0
  19. package/lib/commonjs/internal/text-formats/markdown-format.js +2 -0
  20. package/lib/commonjs/internal/text-formats/markdown-format.js.map +1 -0
  21. package/lib/commonjs/internal/text-formats/unicode-markers-format/constants.js +48 -0
  22. package/lib/commonjs/internal/text-formats/unicode-markers-format/constants.js.map +1 -0
  23. package/lib/commonjs/internal/text-formats/unicode-markers-format/encode-decode.js +65 -0
  24. package/lib/commonjs/internal/text-formats/unicode-markers-format/encode-decode.js.map +1 -0
  25. package/lib/commonjs/internal/text-formats/unicode-markers-format/markers.js +19 -0
  26. package/lib/commonjs/internal/text-formats/unicode-markers-format/markers.js.map +1 -0
  27. package/lib/commonjs/internal/text-formats/unicode-markers-format/text-manipulation.js +124 -0
  28. package/lib/commonjs/internal/text-formats/unicode-markers-format/text-manipulation.js.map +1 -0
  29. package/lib/module/index.js +162 -0
  30. package/lib/module/index.js.map +1 -0
  31. package/lib/module/internal/rendering/components/Bold.js +18 -0
  32. package/lib/module/internal/rendering/components/Bold.js.map +1 -0
  33. package/lib/module/internal/rendering/components/BulletPoint.js +25 -0
  34. package/lib/module/internal/rendering/components/BulletPoint.js.map +1 -0
  35. package/lib/module/internal/rendering/components/Headline.js +32 -0
  36. package/lib/module/internal/rendering/components/Headline.js.map +1 -0
  37. package/lib/module/internal/rendering/components/Italic.js +18 -0
  38. package/lib/module/internal/rendering/components/Italic.js.map +1 -0
  39. package/lib/module/internal/rendering/components/Render.js +94 -0
  40. package/lib/module/internal/rendering/components/Render.js.map +1 -0
  41. package/lib/module/internal/rendering/utils.js +16 -0
  42. package/lib/module/internal/rendering/utils.js.map +1 -0
  43. package/lib/module/internal/text-formats/conversions.js +43 -0
  44. package/lib/module/internal/text-formats/conversions.js.map +1 -0
  45. package/lib/module/internal/text-formats/markdown-format.js +2 -0
  46. package/lib/module/internal/text-formats/markdown-format.js.map +1 -0
  47. package/lib/module/internal/text-formats/unicode-markers-format/constants.js +45 -0
  48. package/lib/module/internal/text-formats/unicode-markers-format/constants.js.map +1 -0
  49. package/lib/module/internal/text-formats/unicode-markers-format/encode-decode.js +61 -0
  50. package/lib/module/internal/text-formats/unicode-markers-format/encode-decode.js.map +1 -0
  51. package/lib/module/internal/text-formats/unicode-markers-format/markers.js +15 -0
  52. package/lib/module/internal/text-formats/unicode-markers-format/markers.js.map +1 -0
  53. package/lib/module/internal/text-formats/unicode-markers-format/text-manipulation.js +117 -0
  54. package/lib/module/internal/text-formats/unicode-markers-format/text-manipulation.js.map +1 -0
  55. package/lib/typescript/commonjs/package.json +1 -0
  56. package/lib/typescript/commonjs/src/index.d.ts +38 -0
  57. package/lib/typescript/commonjs/src/index.d.ts.map +1 -0
  58. package/lib/typescript/commonjs/src/internal/rendering/components/Bold.d.ts +3 -0
  59. package/lib/typescript/commonjs/src/internal/rendering/components/Bold.d.ts.map +1 -0
  60. package/lib/typescript/commonjs/src/internal/rendering/components/BulletPoint.d.ts +3 -0
  61. package/lib/typescript/commonjs/src/internal/rendering/components/BulletPoint.d.ts.map +1 -0
  62. package/lib/typescript/commonjs/src/internal/rendering/components/Headline.d.ts +24 -0
  63. package/lib/typescript/commonjs/src/internal/rendering/components/Headline.d.ts.map +1 -0
  64. package/lib/typescript/commonjs/src/internal/rendering/components/Italic.d.ts +3 -0
  65. package/lib/typescript/commonjs/src/internal/rendering/components/Italic.d.ts.map +1 -0
  66. package/lib/typescript/commonjs/src/internal/rendering/components/Render.d.ts +4 -0
  67. package/lib/typescript/commonjs/src/internal/rendering/components/Render.d.ts.map +1 -0
  68. package/lib/typescript/commonjs/src/internal/rendering/utils.d.ts +3 -0
  69. package/lib/typescript/commonjs/src/internal/rendering/utils.d.ts.map +1 -0
  70. package/lib/typescript/commonjs/src/internal/text-formats/conversions.d.ts +9 -0
  71. package/lib/typescript/commonjs/src/internal/text-formats/conversions.d.ts.map +1 -0
  72. package/lib/typescript/commonjs/src/internal/text-formats/markdown-format.d.ts +1 -0
  73. package/lib/typescript/commonjs/src/internal/text-formats/markdown-format.d.ts.map +1 -0
  74. package/lib/typescript/commonjs/src/internal/text-formats/unicode-markers-format/constants.d.ts +26 -0
  75. package/lib/typescript/commonjs/src/internal/text-formats/unicode-markers-format/constants.d.ts.map +1 -0
  76. package/lib/typescript/commonjs/src/internal/text-formats/unicode-markers-format/encode-decode.d.ts +15 -0
  77. package/lib/typescript/commonjs/src/internal/text-formats/unicode-markers-format/encode-decode.d.ts.map +1 -0
  78. package/lib/typescript/commonjs/src/internal/text-formats/unicode-markers-format/markers.d.ts +11 -0
  79. package/lib/typescript/commonjs/src/internal/text-formats/unicode-markers-format/markers.d.ts.map +1 -0
  80. package/lib/typescript/commonjs/src/internal/text-formats/unicode-markers-format/text-manipulation.d.ts +52 -0
  81. package/lib/typescript/commonjs/src/internal/text-formats/unicode-markers-format/text-manipulation.d.ts.map +1 -0
  82. package/lib/typescript/module/package.json +1 -0
  83. package/lib/typescript/module/src/index.d.ts +38 -0
  84. package/lib/typescript/module/src/index.d.ts.map +1 -0
  85. package/lib/typescript/module/src/internal/rendering/components/Bold.d.ts +3 -0
  86. package/lib/typescript/module/src/internal/rendering/components/Bold.d.ts.map +1 -0
  87. package/lib/typescript/module/src/internal/rendering/components/BulletPoint.d.ts +3 -0
  88. package/lib/typescript/module/src/internal/rendering/components/BulletPoint.d.ts.map +1 -0
  89. package/lib/typescript/module/src/internal/rendering/components/Headline.d.ts +24 -0
  90. package/lib/typescript/module/src/internal/rendering/components/Headline.d.ts.map +1 -0
  91. package/lib/typescript/module/src/internal/rendering/components/Italic.d.ts +3 -0
  92. package/lib/typescript/module/src/internal/rendering/components/Italic.d.ts.map +1 -0
  93. package/lib/typescript/module/src/internal/rendering/components/Render.d.ts +4 -0
  94. package/lib/typescript/module/src/internal/rendering/components/Render.d.ts.map +1 -0
  95. package/lib/typescript/module/src/internal/rendering/utils.d.ts +3 -0
  96. package/lib/typescript/module/src/internal/rendering/utils.d.ts.map +1 -0
  97. package/lib/typescript/module/src/internal/text-formats/conversions.d.ts +9 -0
  98. package/lib/typescript/module/src/internal/text-formats/conversions.d.ts.map +1 -0
  99. package/lib/typescript/module/src/internal/text-formats/markdown-format.d.ts +1 -0
  100. package/lib/typescript/module/src/internal/text-formats/markdown-format.d.ts.map +1 -0
  101. package/lib/typescript/module/src/internal/text-formats/unicode-markers-format/constants.d.ts +26 -0
  102. package/lib/typescript/module/src/internal/text-formats/unicode-markers-format/constants.d.ts.map +1 -0
  103. package/lib/typescript/module/src/internal/text-formats/unicode-markers-format/encode-decode.d.ts +15 -0
  104. package/lib/typescript/module/src/internal/text-formats/unicode-markers-format/encode-decode.d.ts.map +1 -0
  105. package/lib/typescript/module/src/internal/text-formats/unicode-markers-format/markers.d.ts +11 -0
  106. package/lib/typescript/module/src/internal/text-formats/unicode-markers-format/markers.d.ts.map +1 -0
  107. package/lib/typescript/module/src/internal/text-formats/unicode-markers-format/text-manipulation.d.ts +52 -0
  108. package/lib/typescript/module/src/internal/text-formats/unicode-markers-format/text-manipulation.d.ts.map +1 -0
  109. package/package.json +194 -0
  110. package/src/index.tsx +178 -0
  111. package/src/internal/rendering/components/Bold.tsx +12 -0
  112. package/src/internal/rendering/components/BulletPoint.tsx +19 -0
  113. package/src/internal/rendering/components/Headline.tsx +32 -0
  114. package/src/internal/rendering/components/Italic.tsx +12 -0
  115. package/src/internal/rendering/components/Render.tsx +105 -0
  116. package/src/internal/rendering/utils.ts +15 -0
  117. package/src/internal/text-formats/conversions.ts +62 -0
  118. package/src/internal/text-formats/markdown-format.ts +0 -0
  119. package/src/internal/text-formats/unicode-markers-format/constants.ts +64 -0
  120. package/src/internal/text-formats/unicode-markers-format/encode-decode.ts +60 -0
  121. package/src/internal/text-formats/unicode-markers-format/markers.ts +19 -0
  122. package/src/internal/text-formats/unicode-markers-format/text-manipulation.ts +135 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAoBtD,QAAA,MAAM,cAAc,GAAI,uBAGrB;IACD,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;CAC9C,4CAwFA,CAAC;AAgCF,eAAe,cAAc,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PropsWithChildren } from 'react';
2
+ export declare const Bold: ({ children }: PropsWithChildren) => import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=Bold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Bold.d.ts","sourceRoot":"","sources":["../../../../../../../src/internal/rendering/components/Bold.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAG/C,eAAO,MAAM,IAAI,GAAI,cAAc,iBAAiB,4CAEnD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type PropsWithChildren } from 'react';
2
+ export declare const BulletPoint: ({ children }: PropsWithChildren) => import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=BulletPoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BulletPoint.d.ts","sourceRoot":"","sources":["../../../../../../../src/internal/rendering/components/BulletPoint.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAY,MAAM,OAAO,CAAC;AAIzD,eAAO,MAAM,WAAW,GAAI,cAAc,iBAAiB,4CAO1D,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { type PropsWithChildren } from 'react';
2
+ import { Markers } from '../../text-formats/unicode-markers-format/markers.ts';
3
+ export declare const Headline: ({ level, children, }: PropsWithChildren<{
4
+ level: keyof typeof styles;
5
+ }>) => import("react/jsx-runtime").JSX.Element;
6
+ declare const styles: {
7
+ [Markers.H1]: {
8
+ fontSize: number;
9
+ fontWeight: "bold";
10
+ marginVertical: number;
11
+ };
12
+ [Markers.H2]: {
13
+ fontSize: number;
14
+ fontWeight: "bold";
15
+ marginVertical: number;
16
+ };
17
+ [Markers.H3]: {
18
+ fontSize: number;
19
+ fontWeight: "bold";
20
+ marginVertical: number;
21
+ };
22
+ };
23
+ export {};
24
+ //# sourceMappingURL=Headline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Headline.d.ts","sourceRoot":"","sources":["../../../../../../../src/internal/rendering/components/Headline.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE/C,OAAO,EAAE,OAAO,EAAE,MAAM,sDAAsD,CAAC;AAE/E,eAAO,MAAM,QAAQ,GAAI,sBAGtB,iBAAiB,CAAC;IACnB,KAAK,EAAE,MAAM,OAAO,MAAM,CAAC;CAC5B,CAAC,4CAID,CAAC;AAEF,QAAA,MAAM,MAAM;IACV,CAAC,OAAO,CAAC,EAAE,CAAC;;;;MAIX;IACD,CAAC,OAAO,CAAC,EAAE,CAAC;;;;MAIX;IACD,CAAC,OAAO,CAAC,EAAE,CAAC;;;;MAIX;CACD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PropsWithChildren } from 'react';
2
+ export declare const Italic: ({ children }: PropsWithChildren) => import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=Italic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Italic.d.ts","sourceRoot":"","sources":["../../../../../../../src/internal/rendering/components/Italic.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAG/C,eAAO,MAAM,MAAM,GAAI,cAAc,iBAAiB,4CAErD,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare const Render: ({ encodedText }: {
2
+ encodedText: string;
3
+ }) => (import("react/jsx-runtime").JSX.Element | "")[];
4
+ //# sourceMappingURL=Render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Render.d.ts","sourceRoot":"","sources":["../../../../../../../src/internal/rendering/components/Render.tsx"],"names":[],"mappings":"AAcA,eAAO,MAAM,MAAM,GAAI,iBAAiB;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,qDAwE9D,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare function intersperse<T>(arr: T[], separator: T | string): (T | string)[];
2
+ export { intersperse };
3
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../../src/internal/rendering/utils.ts"],"names":[],"mappings":"AACA,iBAAS,WAAW,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,EAAE,CAWvE;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,9 @@
1
+ type MarkdownString = string;
2
+ /**
3
+ * convertInternalFormatToMarkdown converts text from the internal format to Markdown
4
+ * @param internalText rich text in the internal format
5
+ * @returns markdown formatted text
6
+ */
7
+ declare const convertInternalFormatToMarkdown: (internalText: string) => MarkdownString;
8
+ export { convertInternalFormatToMarkdown };
9
+ //# sourceMappingURL=conversions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversions.d.ts","sourceRoot":"","sources":["../../../../../../src/internal/text-formats/conversions.ts"],"names":[],"mappings":"AAcA,KAAK,cAAc,GAAG,MAAM,CAAC;AAE7B;;;;GAIG;AACH,QAAA,MAAM,+BAA+B,GACnC,cAAc,MAAM,KACnB,cAsBF,CAAC;AAgBF,OAAO,EAAE,+BAA+B,EAAE,CAAC"}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=markdown-format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-format.d.ts","sourceRoot":"","sources":["../../../../../../src/internal/text-formats/markdown-format.ts"],"names":[],"mappings":""}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Constants for rich text markers.
3
+ */
4
+ declare const ZWS = "\u200B";
5
+ declare const MARKER_BYTE_LENGTH = 6;
6
+ declare const MARKER_STRING_LENGTH: number;
7
+ declare const HEADLINE_MARKER_TYPE = 16;
8
+ declare const HEADLINE_LEVELS: {
9
+ readonly H1: 1;
10
+ readonly H2: 2;
11
+ readonly H3: 3;
12
+ };
13
+ declare const HEADLINE_MARKERS: Record<keyof typeof HEADLINE_LEVELS, Uint8Array>;
14
+ declare const BOLD_MARKER_TYPE = 32;
15
+ declare const BOLD_MARKERS: {
16
+ readonly START: Uint8Array<ArrayBuffer>;
17
+ readonly END: Uint8Array<ArrayBuffer>;
18
+ };
19
+ declare const ITALIC_MARKERS: {
20
+ readonly START: Uint8Array<ArrayBuffer>;
21
+ readonly END: Uint8Array<ArrayBuffer>;
22
+ };
23
+ declare const BULLET_POINT_UL_MARKER: Uint8Array<ArrayBuffer>;
24
+ declare const BULLET_POINT_STRING_REPRESENTATION = "\u2022 ";
25
+ export { ZWS, MARKER_STRING_LENGTH, MARKER_BYTE_LENGTH, HEADLINE_MARKER_TYPE, HEADLINE_LEVELS, HEADLINE_MARKERS, BOLD_MARKER_TYPE, BOLD_MARKERS, ITALIC_MARKERS, BULLET_POINT_UL_MARKER, BULLET_POINT_STRING_REPRESENTATION, };
26
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../../../../src/internal/text-formats/unicode-markers-format/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,QAAA,MAAM,GAAG,WAAW,CAAC;AACrB,QAAA,MAAM,kBAAkB,IAAI,CAAC;AAC7B,QAAA,MAAM,oBAAoB,QAAyB,CAAC;AACpD,QAAA,MAAM,oBAAoB,KAAO,CAAC;AAElC,QAAA,MAAM,eAAe;;;;CAIX,CAAC;AACX,QAAA,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,OAAO,eAAe,EAAE,UAAU,CAI7D,CAAC;AAEX,QAAA,MAAM,gBAAgB,KAAO,CAAC;AAI9B,QAAA,MAAM,YAAY;;;CAGR,CAAC;AAMX,QAAA,MAAM,cAAc;;;CAGV,CAAC;AAIX,QAAA,MAAM,sBAAsB,yBAG1B,CAAC;AACH,QAAA,MAAM,kCAAkC,YAAO,CAAC;AAQhD,OAAO,EACL,GAAG,EACH,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,sBAAsB,EACtB,kCAAkC,GACnC,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The encode function leverages a concept from the Unicode spec - Variant Selectors - which enables arbitrary bytes to be appended invisibly to a unicode char.
3
+ * @param base string, usually a single char, to which bytes are appended. These bytes remain invisible when base is rendered
4
+ * @param bytes to added to the base string/char.
5
+ * @returns string
6
+ */
7
+ declare function encode(base: string, bytes: Uint8Array): string;
8
+ /**
9
+ * The decode function extracts data hidden inside a string masquerading as variation selectors.
10
+ * @param variationSelectors string that may contain bytes hidden as variation selectors
11
+ * @returns a list of numbers/bytes
12
+ */
13
+ declare function decode(variationSelectors: string): number[];
14
+ export { encode, decode };
15
+ //# sourceMappingURL=encode-decode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encode-decode.d.ts","sourceRoot":"","sources":["../../../../../../../src/internal/text-formats/unicode-markers-format/encode-decode.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,iBAAS,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM,CAMvD;AAED;;;;GAIG;AACH,iBAAS,MAAM,CAAC,kBAAkB,EAAE,MAAM,GAAG,MAAM,EAAE,CAepD;AAyBD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC"}
@@ -0,0 +1,11 @@
1
+ export declare const Markers: {
2
+ readonly H1: string;
3
+ readonly H2: string;
4
+ readonly H3: string;
5
+ readonly BOLD_START: string;
6
+ readonly BOLD_END: string;
7
+ readonly ITALIC_START: string;
8
+ readonly ITALIC_END: string;
9
+ readonly UL: string;
10
+ };
11
+ //# sourceMappingURL=markers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markers.d.ts","sourceRoot":"","sources":["../../../../../../../src/internal/text-formats/unicode-markers-format/markers.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,OAAO;;;;;;;;;CASV,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Adds a bullet point marker to the text at the current cursor position.
3
+ * If the cursor is not at the beginning of a line, a newline is added before the marker.
4
+ * If the cursor is at the beginning of a line, the marker is added directly.
5
+ */
6
+ declare const addBulletPointMarker: (text: string, selection: {
7
+ start: number;
8
+ end: number;
9
+ }) => string;
10
+ /**
11
+ * Inserts a headline start marker into the text at the current cursor position.
12
+ * The marker encodes two bytes:
13
+ * - Byte 0: marker type (0x10 for headline)
14
+ * - Byte 1: headline level (here: 1)
15
+ *
16
+ * The marker is inserted so that it starts on a new line.
17
+ */
18
+ declare const addHeadlineMarker: (marker: string, // marker already contains the headline level encoded
19
+ text: string, selection: {
20
+ start: number;
21
+ end: number;
22
+ }) => string;
23
+ declare const addFontStyleEndMarker: (text: string, selection: {
24
+ start: number;
25
+ end: number;
26
+ }, style: "bold" | "italic") => {
27
+ text: string;
28
+ selection: {
29
+ start: number;
30
+ end: number;
31
+ };
32
+ };
33
+ declare const addFontStyleMarkers: (text: string, selection: {
34
+ start: number;
35
+ end: number;
36
+ }, style: "bold" | "italic") => {
37
+ text: string;
38
+ selection: {
39
+ start: number;
40
+ end: number;
41
+ };
42
+ };
43
+ declare function splitBySelection(text: string, selection: {
44
+ start: number;
45
+ end: number;
46
+ }): {
47
+ before: string;
48
+ selected: string;
49
+ after: string;
50
+ };
51
+ export { addBulletPointMarker, addHeadlineMarker, addFontStyleMarkers, addFontStyleEndMarker, splitBySelection, };
52
+ //# sourceMappingURL=text-manipulation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-manipulation.d.ts","sourceRoot":"","sources":["../../../../../../../src/internal/text-formats/unicode-markers-format/text-manipulation.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,QAAA,MAAM,oBAAoB,GACxB,MAAM,MAAM,EACZ,WAAW;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,WAkB1C,CAAC;AAEF;;;;;;;GAOG;AACH,QAAA,MAAM,iBAAiB,GACrB,QAAQ,MAAM,EAAE,qDAAqD;AACrE,MAAM,MAAM,EACZ,WAAW;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,WAqB1C,CAAC;AAaF,QAAA,MAAM,qBAAqB,GACzB,MAAM,MAAM,EACZ,WAAW;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EACzC,OAAO,MAAM,GAAG,QAAQ;;;eADJ,MAAM;aAAO,MAAM;;CAQxC,CAAC;AAEF,QAAA,MAAM,mBAAmB,GACvB,MAAM,MAAM,EACZ,WAAW;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EACzC,OAAO,MAAM,GAAG,QAAQ;;;eADJ,MAAM;aAAO,MAAM;;CA2BxC,CAAC;AAEF,iBAAS,gBAAgB,CACvB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAMrD;AAED,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,GACjB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,194 @@
1
+ {
2
+ "name": "react-native-simple-rich-text-editor",
3
+ "version": "0.1.0-beta.0",
4
+ "description": "A lean Rich Text Editor for React Native built upon TextInput outputting Markdown",
5
+ "source": "./src/index.tsx",
6
+ "main": "./lib/commonjs/index.js",
7
+ "module": "./lib/module/index.js",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./lib/typescript/module/src/index.d.ts",
12
+ "default": "./lib/module/index.js"
13
+ },
14
+ "require": {
15
+ "types": "./lib/typescript/commonjs/src/index.d.ts",
16
+ "default": "./lib/commonjs/index.js"
17
+ }
18
+ }
19
+ },
20
+ "types": "./lib/typescript/module/src/index.d.ts",
21
+ "files": [
22
+ "src",
23
+ "lib",
24
+ "android",
25
+ "ios",
26
+ "cpp",
27
+ "*.podspec",
28
+ "react-native.config.js",
29
+ "!ios/build",
30
+ "!android/build",
31
+ "!android/gradle",
32
+ "!android/gradlew",
33
+ "!android/gradlew.bat",
34
+ "!android/local.properties",
35
+ "!**/__tests__",
36
+ "!**/__fixtures__",
37
+ "!**/__mocks__",
38
+ "!**/.*"
39
+ ],
40
+ "scripts": {
41
+ "example": "yarn workspace react-native-simple-rich-text-editor-example",
42
+ "test": "jest",
43
+ "typecheck": "tsc",
44
+ "lint": "eslint \"**/*.{js,ts,tsx}\"",
45
+ "lint:fix": "eslint \"**/*.{ts,tsx}\" --fix",
46
+ "format": "prettier \"**/*.{ts,tsx,json}\" --write",
47
+ "clean": "del-cli lib",
48
+ "prepare": "bob build",
49
+ "release": "release-it"
50
+ },
51
+ "keywords": [
52
+ "react-native",
53
+ "ios",
54
+ "android"
55
+ ],
56
+ "repository": {
57
+ "type": "git",
58
+ "url": "git+https://github.com/christiankozalla/react-native-simple-rich-text-editor.git"
59
+ },
60
+ "author": "Christian Kozalla <christian.kozalla@gmail.com> (https://christiankozalla.com)",
61
+ "license": "MIT",
62
+ "bugs": {
63
+ "url": "https://github.com/christiankozalla/react-native-simple-rich-text-editor/issues"
64
+ },
65
+ "homepage": "https://github.com/christiankozalla/react-native-simple-rich-text-editor#readme",
66
+ "publishConfig": {
67
+ "registry": "https://registry.npmjs.org/"
68
+ },
69
+ "devDependencies": {
70
+ "@commitlint/config-conventional": "^17.0.2",
71
+ "@evilmartians/lefthook": "^1.5.0",
72
+ "@react-native/eslint-config": "^0.73.1",
73
+ "@release-it/conventional-changelog": "^9.0.4",
74
+ "@types/jest": "^29.5.5",
75
+ "@types/react": "^18.2.44",
76
+ "commitlint": "^17.0.2",
77
+ "conventional-changelog-angular": "^8.0.0",
78
+ "del-cli": "^5.1.0",
79
+ "eslint": "^8.51.0",
80
+ "eslint-config-prettier": "^9.0.0",
81
+ "eslint-plugin-prettier": "^5.0.1",
82
+ "jest": "^29.7.0",
83
+ "prettier": "^3.0.3",
84
+ "react": "18.3.1",
85
+ "react-native": "0.76.7",
86
+ "react-native-builder-bob": "^0.37.0",
87
+ "release-it": "^17.10.0",
88
+ "typescript": "^5.2.2"
89
+ },
90
+ "resolutions": {
91
+ "@types/react": "^18.2.44"
92
+ },
93
+ "peerDependencies": {
94
+ "react": "*",
95
+ "react-native": "*"
96
+ },
97
+ "workspaces": [
98
+ "example"
99
+ ],
100
+ "packageManager": "yarn@3.6.1",
101
+ "jest": {
102
+ "preset": "react-native",
103
+ "testMatch": [
104
+ "**/__tests__/**/*.test.ts"
105
+ ],
106
+ "modulePathIgnorePatterns": [
107
+ "<rootDir>/example/node_modules",
108
+ "<rootDir>/lib/"
109
+ ]
110
+ },
111
+ "commitlint": {
112
+ "extends": [
113
+ "@commitlint/config-conventional"
114
+ ]
115
+ },
116
+ "release-it": {
117
+ "git": {
118
+ "commitMessage": "chore: release ${version}",
119
+ "tagName": "v${version}"
120
+ },
121
+ "npm": {
122
+ "publish": true
123
+ },
124
+ "github": {
125
+ "release": false
126
+ },
127
+ "plugins": {
128
+ "@release-it/conventional-changelog": {
129
+ "preset": "angular"
130
+ }
131
+ }
132
+ },
133
+ "eslintConfig": {
134
+ "root": true,
135
+ "extends": [
136
+ "@react-native",
137
+ "prettier"
138
+ ],
139
+ "rules": {
140
+ "react/react-in-jsx-scope": "off",
141
+ "prettier/prettier": [
142
+ "error",
143
+ {
144
+ "quoteProps": "consistent",
145
+ "singleQuote": true,
146
+ "tabWidth": 2,
147
+ "trailingComma": "es5",
148
+ "useTabs": false
149
+ }
150
+ ]
151
+ }
152
+ },
153
+ "eslintIgnore": [
154
+ "node_modules/",
155
+ "lib/"
156
+ ],
157
+ "prettier": {
158
+ "quoteProps": "consistent",
159
+ "singleQuote": true,
160
+ "tabWidth": 2,
161
+ "trailingComma": "es5",
162
+ "useTabs": false
163
+ },
164
+ "react-native-builder-bob": {
165
+ "source": "src",
166
+ "output": "lib",
167
+ "targets": [
168
+ [
169
+ "commonjs",
170
+ {
171
+ "esm": true
172
+ }
173
+ ],
174
+ [
175
+ "module",
176
+ {
177
+ "esm": true
178
+ }
179
+ ],
180
+ [
181
+ "typescript",
182
+ {
183
+ "project": "tsconfig.build.json",
184
+ "esm": true
185
+ }
186
+ ]
187
+ ]
188
+ },
189
+ "create-react-native-library": {
190
+ "languages": "js",
191
+ "type": "library",
192
+ "version": "0.48.3"
193
+ }
194
+ }
package/src/index.tsx ADDED
@@ -0,0 +1,178 @@
1
+ /**
2
+ * React Native Simple Rich Text Editor
3
+ *
4
+ * Documentation of the public API:
5
+ * - SimpleRichTextEditor Component
6
+ * -> let user specifiy when to emit (e.g. on keyboard dismiss)
7
+ * -> let user pass custom H1, H2, Bold, Italic, List buttons
8
+ *
9
+ * Internals:
10
+ * - RichTextEditor is a controlled component. The user provides `state` and `setState` to receive markdown output.
11
+ * - Only a subset of markdown will be supported. Unsupported markdown like images will be rendered as plain markdown text.
12
+ * - Receive text prop -> convert markdown to internal representation -> render
13
+ * - onEmitText: convert internal representation to markdown -> setState(markdown)
14
+ *
15
+ * Usage Example:
16
+ *
17
+ * ```typescript
18
+ * import RichTextEditor from "react-native-simple-rich-text-editor";
19
+ * import { useState } from "react";
20
+ *
21
+ *
22
+ * const Screen = () => {
23
+ * const [markdownText, setMarkdownText] = useState("# Hello World\nA paragraph."); // or with backticks ``
24
+ *
25
+ * return (
26
+ * <RichTextEditor text={markdownText} onEmitText={setMarkdownText} style={styles.editor} />
27
+ * );
28
+ * };
29
+ * ```
30
+ */
31
+ import type { Dispatch, SetStateAction } from 'react';
32
+ import { useState } from 'react';
33
+ import {
34
+ StyleSheet,
35
+ TextInput,
36
+ TouchableOpacity,
37
+ View,
38
+ Text,
39
+ type NativeSyntheticEvent,
40
+ type TextInputSelectionChangeEventData,
41
+ } from 'react-native';
42
+ import { Render } from './internal/rendering/components/Render.tsx';
43
+ import {
44
+ addFontStyleMarkers,
45
+ addFontStyleEndMarker,
46
+ addHeadlineMarker,
47
+ addBulletPointMarker,
48
+ } from './internal/text-formats/unicode-markers-format/text-manipulation.ts';
49
+ import { Markers } from './internal/text-formats/unicode-markers-format/markers.ts';
50
+
51
+ const RichTextEditor = ({
52
+ text,
53
+ onEmitText,
54
+ }: {
55
+ text: string;
56
+ onEmitText: Dispatch<SetStateAction<string>>;
57
+ }) => {
58
+ // Track the current selection (cursor position) in the TextInput.
59
+ const [selection, setSelection] = useState<{ start: number; end: number }>({
60
+ start: 0,
61
+ end: 0,
62
+ });
63
+ const [needsBoldEndMarker, setNeedsBoldEndMarker] = useState(false); // we must count the BOLD_START and BOLD_END markers in text prop => inital state
64
+ const [needsItalicEndMarker, setNeedsItalicEndMarker] = useState(false);
65
+
66
+ const handleFontStyleMarkerInsertion = (style: 'bold' | 'italic') => () => {
67
+ const isBold = style === 'bold';
68
+ if (isBold ? needsBoldEndMarker : needsItalicEndMarker) {
69
+ const { text: newText } = addFontStyleEndMarker(text, selection, style);
70
+ isBold ? setNeedsBoldEndMarker(false) : setNeedsItalicEndMarker(false);
71
+ onEmitText(newText);
72
+ } else {
73
+ const { text: newText } = addFontStyleMarkers(text, selection, style);
74
+ // this is a reaction to an implementation detail of addBoldMarkers - TODO: solve it cleanly
75
+ if (selection.start - selection.end === 0)
76
+ isBold ? setNeedsBoldEndMarker(true) : setNeedsItalicEndMarker(true);
77
+ onEmitText(newText);
78
+ }
79
+ };
80
+
81
+ return (
82
+ <View style={styles.container}>
83
+ <View style={styles.row}>
84
+ <TouchableOpacity
85
+ style={styles.button}
86
+ onPress={() =>
87
+ onEmitText(addHeadlineMarker(Markers.H1, text, selection))
88
+ }
89
+ >
90
+ <Text style={styles.buttonText}>H1</Text>
91
+ </TouchableOpacity>
92
+ <TouchableOpacity
93
+ style={styles.button}
94
+ onPress={() =>
95
+ onEmitText(addHeadlineMarker(Markers.H2, text, selection))
96
+ }
97
+ >
98
+ <Text style={styles.buttonText}>H2</Text>
99
+ </TouchableOpacity>
100
+ <TouchableOpacity
101
+ style={styles.button}
102
+ onPress={() =>
103
+ onEmitText(addHeadlineMarker(Markers.H3, text, selection))
104
+ }
105
+ >
106
+ <Text style={styles.buttonText}>H3</Text>
107
+ </TouchableOpacity>
108
+ <TouchableOpacity
109
+ style={styles.button}
110
+ onPress={() => onEmitText(addBulletPointMarker(text, selection))}
111
+ >
112
+ <Text style={styles.buttonText}>List</Text>
113
+ </TouchableOpacity>
114
+ <TouchableOpacity
115
+ style={[styles.button, styles.fixedWidth]}
116
+ onPress={handleFontStyleMarkerInsertion('bold')}
117
+ >
118
+ <Text style={styles.buttonText}>
119
+ {needsBoldEndMarker ? 'Bold ✖' : 'Bold'}
120
+ </Text>
121
+ </TouchableOpacity>
122
+ <TouchableOpacity
123
+ style={[styles.button, styles.fixedWidth]}
124
+ onPress={handleFontStyleMarkerInsertion('italic')}
125
+ >
126
+ <Text style={styles.buttonText}>
127
+ {needsItalicEndMarker ? 'Italic ✖' : 'Italic'}
128
+ </Text>
129
+ </TouchableOpacity>
130
+ </View>
131
+ <TextInput
132
+ multiline
133
+ autoFocus
134
+ autoCorrect={false}
135
+ style={styles.input}
136
+ onSelectionChange={(
137
+ e: NativeSyntheticEvent<TextInputSelectionChangeEventData>
138
+ ) => setSelection(e.nativeEvent.selection)}
139
+ onChangeText={onEmitText}
140
+ >
141
+ <Render encodedText={text} />
142
+ </TextInput>
143
+ </View>
144
+ );
145
+ };
146
+
147
+ const electricBlueHex = '#009DDC';
148
+ const styles = StyleSheet.create({
149
+ container: {
150
+ flex: 1,
151
+ },
152
+ row: {
153
+ margin: 8,
154
+ flexDirection: 'row',
155
+ justifyContent: 'space-between',
156
+ flexWrap: 'nowrap',
157
+ },
158
+ input: { flex: 1, textAlignVertical: 'top' },
159
+ button: {
160
+ paddingVertical: 6,
161
+ paddingHorizontal: 8,
162
+ borderRadius: 4,
163
+ borderWidth: 1,
164
+ borderColor: electricBlueHex,
165
+ backgroundColor: 'white',
166
+ flexShrink: 1,
167
+ },
168
+ buttonText: {
169
+ textAlign: 'center',
170
+ color: electricBlueHex,
171
+ },
172
+ fixedWidth: {
173
+ width: 70,
174
+ },
175
+ });
176
+
177
+ export default RichTextEditor;
178
+ export { RichTextEditor };
@@ -0,0 +1,12 @@
1
+ import type { PropsWithChildren } from 'react';
2
+ import { Text, StyleSheet } from 'react-native';
3
+
4
+ export const Bold = ({ children }: PropsWithChildren) => {
5
+ return <Text style={styles.bold}>{children}</Text>;
6
+ };
7
+
8
+ const styles = StyleSheet.create({
9
+ bold: {
10
+ fontWeight: 700,
11
+ },
12
+ });
@@ -0,0 +1,19 @@
1
+ import { type PropsWithChildren, Fragment } from 'react';
2
+ import { Text, StyleSheet } from 'react-native';
3
+ import { BULLET_POINT_STRING_REPRESENTATION } from '../../text-formats/unicode-markers-format/constants';
4
+
5
+ export const BulletPoint = ({ children }: PropsWithChildren) => {
6
+ return (
7
+ <Fragment>
8
+ <Text style={styles.bullet}>{BULLET_POINT_STRING_REPRESENTATION}</Text>
9
+ <Text>{children}</Text>
10
+ </Fragment>
11
+ );
12
+ };
13
+
14
+ const styles = StyleSheet.create({
15
+ bullet: {
16
+ marginRight: 8,
17
+ fontSize: 16,
18
+ },
19
+ });
@@ -0,0 +1,32 @@
1
+ import { type PropsWithChildren } from 'react';
2
+ import { type TextStyle, Text, StyleSheet } from 'react-native';
3
+ import { Markers } from '../../text-formats/unicode-markers-format/markers.ts';
4
+
5
+ export const Headline = ({
6
+ level,
7
+ children,
8
+ }: PropsWithChildren<{
9
+ level: keyof typeof styles;
10
+ }>) => {
11
+ return (
12
+ <Text style={(styles[level] as TextStyle) ?? styles[3]}>{children}</Text>
13
+ );
14
+ };
15
+
16
+ const styles = StyleSheet.create({
17
+ [Markers.H1]: {
18
+ fontSize: 32,
19
+ fontWeight: 'bold',
20
+ marginVertical: 4,
21
+ },
22
+ [Markers.H2]: {
23
+ fontSize: 24,
24
+ fontWeight: 'bold',
25
+ marginVertical: 4,
26
+ },
27
+ [Markers.H3]: {
28
+ fontSize: 18,
29
+ fontWeight: 'bold',
30
+ marginVertical: 4,
31
+ },
32
+ });