react-native-markdown-native 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/MarkdownNative.podspec +19 -0
- package/README.md +109 -0
- package/android/.gradle/8.9/checksums/checksums.lock +0 -0
- package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.9/executionHistory/executionHistory.lock +0 -0
- package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.9/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/build.gradle +36 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/markdownnative/MarkdownPackage.java +25 -0
- package/android/src/main/java/com/markdownnative/MarkdownView.java +516 -0
- package/android/src/main/java/com/markdownnative/MarkdownViewManager.java +107 -0
- package/ios/MarkdownView.swift +771 -0
- package/ios/MarkdownViewManager.m +27 -0
- package/ios/MarkdownViewManager.swift +20 -0
- package/lib/commonjs/index.js +97 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/types.js +154 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/index.d.ts +26 -0
- package/lib/index.js +97 -0
- package/lib/module/index.js +80 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/types.js +153 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/index.d.ts +30 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +80 -0
- package/lib/typescript/types.d.ts.map +1 -0
- package/package.json +92 -0
- package/react-native.config.js +11 -0
- package/src/index.tsx +117 -0
- package/src/types.ts +205 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["MarkdownElementType","DEFAULT_MARKDOWN_RULES","HEADING1","fontSize","fontWeight","marginTop","marginBottom","HEADING2","HEADING3","HEADING4","HEADING5","HEADING6","PARAGRAPH","BLOCKQUOTE","marginLeft","paddingLeft","borderLeftWidth","borderLeftColor","fontStyle","color","LIST","LIST_ITEM","listLeftInset","bulletIndent","ORDERED_LIST","ORDERED_LIST_ITEM","CODE_INLINE","fontFamily","backgroundColor","paddingRight","paddingTop","paddingBottom","borderRadius","CODE_BLOCK","padding","STRONG","EM","STRIKETHROUGH","textDecorationLine","LINK","HR","borderBottomWidth","borderBottomColor"],"sourceRoot":"../../src","sources":["types.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ViewProps, NativeSyntheticEvent } from 'react-native';
|
|
3
|
+
import { MarkdownRules } from './types';
|
|
4
|
+
export type NativeMarkdownSizeEvent = {
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
};
|
|
8
|
+
export interface NativeMarkdownViewProps extends ViewProps {
|
|
9
|
+
markdownText: string;
|
|
10
|
+
markdownFontSize?: number;
|
|
11
|
+
markdownColor?: string;
|
|
12
|
+
markdownFontFamily?: string;
|
|
13
|
+
markdownSelectionColor?: string;
|
|
14
|
+
markdownScrollEnabled?: boolean;
|
|
15
|
+
markdownSelectable?: boolean;
|
|
16
|
+
markdownLinkColor?: string;
|
|
17
|
+
markdownLineSpacing?: number;
|
|
18
|
+
markdownParagraphSpacing?: number;
|
|
19
|
+
markdownBulletIndent?: number;
|
|
20
|
+
markdownListLeftInset?: number;
|
|
21
|
+
markdownListSpacingBefore?: number;
|
|
22
|
+
markdownListSpacingAfter?: number;
|
|
23
|
+
markdownRules?: MarkdownRules;
|
|
24
|
+
markdownRulesJson?: string;
|
|
25
|
+
onNativeSizeChange?: (event: NativeSyntheticEvent<NativeMarkdownSizeEvent>) => void;
|
|
26
|
+
}
|
|
27
|
+
export type { MarkdownRules, MarkdownElementStyle } from './types';
|
|
28
|
+
export { MarkdownElementType, DEFAULT_MARKDOWN_RULES } from './types';
|
|
29
|
+
export declare const MarkdownView: React.FC<NativeMarkdownViewProps>;
|
|
30
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAC9D,OAAO,EAEL,SAAS,EACT,oBAAoB,EACrB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAA0B,MAAM,SAAS,CAAC;AAEhE,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,WAAW,uBAAwB,SAAQ,SAAS;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAE9B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAElC,aAAa,CAAC,EAAE,aAAa,CAAC;IAE9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,CACnB,KAAK,EAAE,oBAAoB,CAAC,uBAAuB,CAAC,KACjD,IAAI,CAAC;CACX;AAGD,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAKtE,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAsE1D,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { TextStyle } from 'react-native';
|
|
2
|
+
/**
|
|
3
|
+
* All supported markdown element types
|
|
4
|
+
*/
|
|
5
|
+
export declare enum MarkdownElementType {
|
|
6
|
+
HEADING1 = "heading1",
|
|
7
|
+
HEADING2 = "heading2",
|
|
8
|
+
HEADING3 = "heading3",
|
|
9
|
+
HEADING4 = "heading4",
|
|
10
|
+
HEADING5 = "heading5",
|
|
11
|
+
HEADING6 = "heading6",
|
|
12
|
+
PARAGRAPH = "paragraph",
|
|
13
|
+
BLOCKQUOTE = "blockquote",
|
|
14
|
+
LIST = "list",
|
|
15
|
+
LIST_ITEM = "listItem",
|
|
16
|
+
ORDERED_LIST = "orderedList",
|
|
17
|
+
ORDERED_LIST_ITEM = "orderedListItem",
|
|
18
|
+
CODE_INLINE = "codeInline",
|
|
19
|
+
CODE_BLOCK = "codeBlock",
|
|
20
|
+
STRONG = "strong",
|
|
21
|
+
EM = "em",
|
|
22
|
+
STRIKETHROUGH = "strikethrough",
|
|
23
|
+
LINK = "link",
|
|
24
|
+
HR = "hr"
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Style definition for a markdown element
|
|
28
|
+
* Extends React Native TextStyle with additional custom properties
|
|
29
|
+
*/
|
|
30
|
+
export interface MarkdownElementStyle extends TextStyle {
|
|
31
|
+
marginTop?: number;
|
|
32
|
+
marginBottom?: number;
|
|
33
|
+
marginLeft?: number;
|
|
34
|
+
marginRight?: number;
|
|
35
|
+
paddingTop?: number;
|
|
36
|
+
paddingBottom?: number;
|
|
37
|
+
paddingLeft?: number;
|
|
38
|
+
paddingRight?: number;
|
|
39
|
+
padding?: number;
|
|
40
|
+
bulletIndent?: number;
|
|
41
|
+
listLeftInset?: number;
|
|
42
|
+
borderLeftWidth?: number;
|
|
43
|
+
borderLeftColor?: string;
|
|
44
|
+
backgroundColor?: string;
|
|
45
|
+
borderRadius?: number;
|
|
46
|
+
borderWidth?: number;
|
|
47
|
+
borderColor?: string;
|
|
48
|
+
borderBottomWidth?: number;
|
|
49
|
+
borderBottomColor?: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Complete rules configuration for all markdown elements
|
|
53
|
+
*/
|
|
54
|
+
export type MarkdownRules = Partial<{
|
|
55
|
+
[MarkdownElementType.HEADING1]: MarkdownElementStyle;
|
|
56
|
+
[MarkdownElementType.HEADING2]: MarkdownElementStyle;
|
|
57
|
+
[MarkdownElementType.HEADING3]: MarkdownElementStyle;
|
|
58
|
+
[MarkdownElementType.HEADING4]: MarkdownElementStyle;
|
|
59
|
+
[MarkdownElementType.HEADING5]: MarkdownElementStyle;
|
|
60
|
+
[MarkdownElementType.HEADING6]: MarkdownElementStyle;
|
|
61
|
+
[MarkdownElementType.PARAGRAPH]: MarkdownElementStyle;
|
|
62
|
+
[MarkdownElementType.BLOCKQUOTE]: MarkdownElementStyle;
|
|
63
|
+
[MarkdownElementType.LIST]: MarkdownElementStyle;
|
|
64
|
+
[MarkdownElementType.LIST_ITEM]: MarkdownElementStyle;
|
|
65
|
+
[MarkdownElementType.ORDERED_LIST]: MarkdownElementStyle;
|
|
66
|
+
[MarkdownElementType.ORDERED_LIST_ITEM]: MarkdownElementStyle;
|
|
67
|
+
[MarkdownElementType.CODE_INLINE]: MarkdownElementStyle;
|
|
68
|
+
[MarkdownElementType.CODE_BLOCK]: MarkdownElementStyle;
|
|
69
|
+
[MarkdownElementType.STRONG]: MarkdownElementStyle;
|
|
70
|
+
[MarkdownElementType.EM]: MarkdownElementStyle;
|
|
71
|
+
[MarkdownElementType.STRIKETHROUGH]: MarkdownElementStyle;
|
|
72
|
+
[MarkdownElementType.LINK]: MarkdownElementStyle;
|
|
73
|
+
[MarkdownElementType.HR]: MarkdownElementStyle;
|
|
74
|
+
}>;
|
|
75
|
+
/**
|
|
76
|
+
* Default markdown rules that match the current behavior
|
|
77
|
+
* These ensure consistent rendering across iOS and Android
|
|
78
|
+
*/
|
|
79
|
+
export declare const DEFAULT_MARKDOWN_RULES: MarkdownRules;
|
|
80
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-native-markdown-native",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Native markdown rendering for React Native",
|
|
5
|
+
"main": "lib/commonjs/index.js",
|
|
6
|
+
"module": "lib/module/index.js",
|
|
7
|
+
"types": "lib/typescript/index.d.ts",
|
|
8
|
+
"react-native": "src/index.tsx",
|
|
9
|
+
"author": "Sandeep Mansotra",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"homepage": "https://github.com/sandeepmansotra/react-native-markdown-native",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/sandeepmansotra/react-native-markdown-native.git"
|
|
15
|
+
},
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/sandeepmansotra/react-native-markdown-native/issues"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"react-native",
|
|
21
|
+
"markdown",
|
|
22
|
+
"native",
|
|
23
|
+
"text",
|
|
24
|
+
"ios",
|
|
25
|
+
"android"
|
|
26
|
+
],
|
|
27
|
+
"files": [
|
|
28
|
+
"src",
|
|
29
|
+
"lib",
|
|
30
|
+
"android",
|
|
31
|
+
"ios",
|
|
32
|
+
"react-native.config.js",
|
|
33
|
+
"package.json",
|
|
34
|
+
"*.podspec",
|
|
35
|
+
"!lib/typescript/example",
|
|
36
|
+
"!android/build",
|
|
37
|
+
"!ios/build",
|
|
38
|
+
"!**/__tests__",
|
|
39
|
+
"!**/__fixtures__",
|
|
40
|
+
"!**/__mocks__"
|
|
41
|
+
],
|
|
42
|
+
"scripts": {
|
|
43
|
+
"test": "jest",
|
|
44
|
+
"typecheck": "tsc --noEmit",
|
|
45
|
+
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
46
|
+
"build": "bob build",
|
|
47
|
+
"release": "release-it",
|
|
48
|
+
"prepare": "bob build",
|
|
49
|
+
"prepublishOnly": "npm run build"
|
|
50
|
+
},
|
|
51
|
+
"lint-staged": {
|
|
52
|
+
"*.{js,ts,tsx}": "eslint --fix",
|
|
53
|
+
"*.{js,ts,tsx,json,md}": "prettier --write"
|
|
54
|
+
},
|
|
55
|
+
"react-native-builder-bob": {
|
|
56
|
+
"source": "src",
|
|
57
|
+
"output": "lib",
|
|
58
|
+
"targets": [
|
|
59
|
+
"commonjs",
|
|
60
|
+
"module",
|
|
61
|
+
[
|
|
62
|
+
"typescript",
|
|
63
|
+
{
|
|
64
|
+
"project": "tsconfig.json"
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
"peerDependencies": {
|
|
70
|
+
"react": "*",
|
|
71
|
+
"react-native": "*"
|
|
72
|
+
},
|
|
73
|
+
"devDependencies": {
|
|
74
|
+
"@react-native/babel-preset": "^0.83.1",
|
|
75
|
+
"@react-native/eslint-config": "^0.83.1",
|
|
76
|
+
"@types/jest": "^30.0.0",
|
|
77
|
+
"@types/react": "*",
|
|
78
|
+
"@types/react-native": "*",
|
|
79
|
+
"eslint": "^8.57.1",
|
|
80
|
+
"eslint-config-prettier": "^10.1.8",
|
|
81
|
+
"eslint-plugin-prettier": "^5.5.5",
|
|
82
|
+
"husky": "^9.1.7",
|
|
83
|
+
"jest": "^30.2.0",
|
|
84
|
+
"lint-staged": "^16.2.7",
|
|
85
|
+
"prettier": "^3.8.1",
|
|
86
|
+
"react-native-builder-bob": "^0.40.17",
|
|
87
|
+
"react-test-renderer": "^19.2.4",
|
|
88
|
+
"release-it": "^19.2.4",
|
|
89
|
+
"ts-jest": "^29.4.6",
|
|
90
|
+
"typescript": "^4.0.0"
|
|
91
|
+
}
|
|
92
|
+
}
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import React, { useState, useCallback, useMemo } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
requireNativeComponent,
|
|
4
|
+
ViewProps,
|
|
5
|
+
NativeSyntheticEvent,
|
|
6
|
+
} from 'react-native';
|
|
7
|
+
import { MarkdownRules, DEFAULT_MARKDOWN_RULES } from './types';
|
|
8
|
+
|
|
9
|
+
export type NativeMarkdownSizeEvent = {
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export interface NativeMarkdownViewProps extends ViewProps {
|
|
15
|
+
markdownText: string;
|
|
16
|
+
markdownFontSize?: number;
|
|
17
|
+
markdownColor?: string;
|
|
18
|
+
markdownFontFamily?: string;
|
|
19
|
+
markdownSelectionColor?: string;
|
|
20
|
+
markdownScrollEnabled?: boolean;
|
|
21
|
+
markdownSelectable?: boolean;
|
|
22
|
+
// Customization props (deprecated - use markdownRules instead)
|
|
23
|
+
markdownLinkColor?: string;
|
|
24
|
+
markdownLineSpacing?: number;
|
|
25
|
+
markdownParagraphSpacing?: number;
|
|
26
|
+
markdownBulletIndent?: number;
|
|
27
|
+
// List styling props (deprecated - use markdownRules instead)
|
|
28
|
+
markdownListLeftInset?: number; // Left margin for bullets
|
|
29
|
+
markdownListSpacingBefore?: number; // Space above list section
|
|
30
|
+
markdownListSpacingAfter?: number; // Space below list section
|
|
31
|
+
// New rules-based styling system
|
|
32
|
+
markdownRules?: MarkdownRules;
|
|
33
|
+
// Serialized rules for native (internal use)
|
|
34
|
+
markdownRulesJson?: string;
|
|
35
|
+
onNativeSizeChange?: (
|
|
36
|
+
event: NativeSyntheticEvent<NativeMarkdownSizeEvent>
|
|
37
|
+
) => void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Re-export types for convenience
|
|
41
|
+
export type { MarkdownRules, MarkdownElementStyle } from './types';
|
|
42
|
+
export { MarkdownElementType, DEFAULT_MARKDOWN_RULES } from './types';
|
|
43
|
+
|
|
44
|
+
const NativeMarkdownView =
|
|
45
|
+
requireNativeComponent<NativeMarkdownViewProps>('MarkdownView');
|
|
46
|
+
|
|
47
|
+
export const MarkdownView: React.FC<NativeMarkdownViewProps> = (props) => {
|
|
48
|
+
const { onNativeSizeChange, markdownRules } = props;
|
|
49
|
+
const [nativeHeight, setNativeHeight] = useState<number>(0);
|
|
50
|
+
|
|
51
|
+
// Merge user rules with defaults
|
|
52
|
+
const finalRules = useMemo(() => {
|
|
53
|
+
if (!markdownRules) {
|
|
54
|
+
return DEFAULT_MARKDOWN_RULES;
|
|
55
|
+
}
|
|
56
|
+
return { ...DEFAULT_MARKDOWN_RULES, ...markdownRules };
|
|
57
|
+
}, [markdownRules]);
|
|
58
|
+
|
|
59
|
+
// Serialize rules to JSON for native modules
|
|
60
|
+
const rulesJson = useMemo(() => {
|
|
61
|
+
return JSON.stringify(finalRules);
|
|
62
|
+
}, [finalRules]);
|
|
63
|
+
|
|
64
|
+
// Default values (maintained for backward compatibility)
|
|
65
|
+
const defaultProps = {
|
|
66
|
+
markdownFontSize: 16,
|
|
67
|
+
markdownColor: '#000000',
|
|
68
|
+
markdownFontFamily: undefined,
|
|
69
|
+
markdownSelectionColor: '#ACCEF7',
|
|
70
|
+
markdownScrollEnabled: false,
|
|
71
|
+
markdownSelectable: true,
|
|
72
|
+
markdownLinkColor: '#007AFF',
|
|
73
|
+
markdownLineSpacing: 0,
|
|
74
|
+
markdownParagraphSpacing: 0,
|
|
75
|
+
markdownBulletIndent: 20,
|
|
76
|
+
markdownListLeftInset: 10,
|
|
77
|
+
markdownListSpacingBefore: 0,
|
|
78
|
+
markdownListSpacingAfter: 0,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const mergedProps = {
|
|
82
|
+
...defaultProps,
|
|
83
|
+
...props,
|
|
84
|
+
markdownRulesJson: rulesJson,
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const fontSize = mergedProps.markdownFontSize;
|
|
88
|
+
// Minimum height based on font size (single line)
|
|
89
|
+
const minHeight = fontSize * 1.5;
|
|
90
|
+
|
|
91
|
+
const handleNativeSizeChange = useCallback(
|
|
92
|
+
(event: NativeSyntheticEvent<NativeMarkdownSizeEvent>) => {
|
|
93
|
+
const { height } = event.nativeEvent;
|
|
94
|
+
if (height > 0 && Math.abs(height - nativeHeight) > 0.5) {
|
|
95
|
+
setNativeHeight(height);
|
|
96
|
+
}
|
|
97
|
+
onNativeSizeChange?.(event);
|
|
98
|
+
},
|
|
99
|
+
[nativeHeight, onNativeSizeChange]
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
// Use nativeHeight if available, otherwise minHeight ensures visibility
|
|
103
|
+
const dynamicStyle = {
|
|
104
|
+
minHeight: minHeight,
|
|
105
|
+
height: nativeHeight > 0 ? nativeHeight : undefined,
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const nativeView = (
|
|
109
|
+
<NativeMarkdownView
|
|
110
|
+
{...mergedProps}
|
|
111
|
+
style={[dynamicStyle, props.style]}
|
|
112
|
+
onNativeSizeChange={handleNativeSizeChange}
|
|
113
|
+
/>
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
return nativeView;
|
|
117
|
+
};
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { TextStyle } from 'react-native';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* All supported markdown element types
|
|
5
|
+
*/
|
|
6
|
+
export enum MarkdownElementType {
|
|
7
|
+
// Headers
|
|
8
|
+
HEADING1 = 'heading1',
|
|
9
|
+
HEADING2 = 'heading2',
|
|
10
|
+
HEADING3 = 'heading3',
|
|
11
|
+
HEADING4 = 'heading4',
|
|
12
|
+
HEADING5 = 'heading5',
|
|
13
|
+
HEADING6 = 'heading6',
|
|
14
|
+
|
|
15
|
+
// Text blocks
|
|
16
|
+
PARAGRAPH = 'paragraph',
|
|
17
|
+
BLOCKQUOTE = 'blockquote',
|
|
18
|
+
|
|
19
|
+
// Lists
|
|
20
|
+
LIST = 'list',
|
|
21
|
+
LIST_ITEM = 'listItem',
|
|
22
|
+
ORDERED_LIST = 'orderedList',
|
|
23
|
+
ORDERED_LIST_ITEM = 'orderedListItem',
|
|
24
|
+
|
|
25
|
+
// Code
|
|
26
|
+
CODE_INLINE = 'codeInline',
|
|
27
|
+
CODE_BLOCK = 'codeBlock',
|
|
28
|
+
|
|
29
|
+
// Inline styles
|
|
30
|
+
STRONG = 'strong',
|
|
31
|
+
EM = 'em',
|
|
32
|
+
STRIKETHROUGH = 'strikethrough',
|
|
33
|
+
LINK = 'link',
|
|
34
|
+
|
|
35
|
+
// Other
|
|
36
|
+
HR = 'hr',
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Style definition for a markdown element
|
|
41
|
+
* Extends React Native TextStyle with additional custom properties
|
|
42
|
+
*/
|
|
43
|
+
export interface MarkdownElementStyle extends TextStyle {
|
|
44
|
+
// Additional spacing properties
|
|
45
|
+
marginTop?: number;
|
|
46
|
+
marginBottom?: number;
|
|
47
|
+
marginLeft?: number;
|
|
48
|
+
marginRight?: number;
|
|
49
|
+
paddingTop?: number;
|
|
50
|
+
paddingBottom?: number;
|
|
51
|
+
paddingLeft?: number;
|
|
52
|
+
paddingRight?: number;
|
|
53
|
+
padding?: number;
|
|
54
|
+
|
|
55
|
+
// List-specific properties
|
|
56
|
+
bulletIndent?: number;
|
|
57
|
+
listLeftInset?: number;
|
|
58
|
+
|
|
59
|
+
// Blockquote-specific properties (these overlap with View styles)
|
|
60
|
+
borderLeftWidth?: number;
|
|
61
|
+
borderLeftColor?: string;
|
|
62
|
+
|
|
63
|
+
// Code block-specific properties
|
|
64
|
+
backgroundColor?: string;
|
|
65
|
+
borderRadius?: number;
|
|
66
|
+
borderWidth?: number;
|
|
67
|
+
borderColor?: string;
|
|
68
|
+
borderBottomWidth?: number;
|
|
69
|
+
borderBottomColor?: string;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Complete rules configuration for all markdown elements
|
|
74
|
+
*/
|
|
75
|
+
export type MarkdownRules = Partial<{
|
|
76
|
+
[MarkdownElementType.HEADING1]: MarkdownElementStyle;
|
|
77
|
+
[MarkdownElementType.HEADING2]: MarkdownElementStyle;
|
|
78
|
+
[MarkdownElementType.HEADING3]: MarkdownElementStyle;
|
|
79
|
+
[MarkdownElementType.HEADING4]: MarkdownElementStyle;
|
|
80
|
+
[MarkdownElementType.HEADING5]: MarkdownElementStyle;
|
|
81
|
+
[MarkdownElementType.HEADING6]: MarkdownElementStyle;
|
|
82
|
+
[MarkdownElementType.PARAGRAPH]: MarkdownElementStyle;
|
|
83
|
+
[MarkdownElementType.BLOCKQUOTE]: MarkdownElementStyle;
|
|
84
|
+
[MarkdownElementType.LIST]: MarkdownElementStyle;
|
|
85
|
+
[MarkdownElementType.LIST_ITEM]: MarkdownElementStyle;
|
|
86
|
+
[MarkdownElementType.ORDERED_LIST]: MarkdownElementStyle;
|
|
87
|
+
[MarkdownElementType.ORDERED_LIST_ITEM]: MarkdownElementStyle;
|
|
88
|
+
[MarkdownElementType.CODE_INLINE]: MarkdownElementStyle;
|
|
89
|
+
[MarkdownElementType.CODE_BLOCK]: MarkdownElementStyle;
|
|
90
|
+
[MarkdownElementType.STRONG]: MarkdownElementStyle;
|
|
91
|
+
[MarkdownElementType.EM]: MarkdownElementStyle;
|
|
92
|
+
[MarkdownElementType.STRIKETHROUGH]: MarkdownElementStyle;
|
|
93
|
+
[MarkdownElementType.LINK]: MarkdownElementStyle;
|
|
94
|
+
[MarkdownElementType.HR]: MarkdownElementStyle;
|
|
95
|
+
}>;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Default markdown rules that match the current behavior
|
|
99
|
+
* These ensure consistent rendering across iOS and Android
|
|
100
|
+
*/
|
|
101
|
+
export const DEFAULT_MARKDOWN_RULES: MarkdownRules = {
|
|
102
|
+
[MarkdownElementType.HEADING1]: {
|
|
103
|
+
fontSize: 32,
|
|
104
|
+
fontWeight: 'bold',
|
|
105
|
+
marginTop: 8,
|
|
106
|
+
marginBottom: 4,
|
|
107
|
+
},
|
|
108
|
+
[MarkdownElementType.HEADING2]: {
|
|
109
|
+
fontSize: 24,
|
|
110
|
+
fontWeight: 'bold',
|
|
111
|
+
marginTop: 8,
|
|
112
|
+
marginBottom: 4,
|
|
113
|
+
},
|
|
114
|
+
[MarkdownElementType.HEADING3]: {
|
|
115
|
+
fontSize: 20,
|
|
116
|
+
fontWeight: 'bold',
|
|
117
|
+
marginTop: 8,
|
|
118
|
+
marginBottom: 4,
|
|
119
|
+
},
|
|
120
|
+
[MarkdownElementType.HEADING4]: {
|
|
121
|
+
fontSize: 18,
|
|
122
|
+
fontWeight: 'bold',
|
|
123
|
+
marginTop: 8,
|
|
124
|
+
marginBottom: 4,
|
|
125
|
+
},
|
|
126
|
+
[MarkdownElementType.HEADING5]: {
|
|
127
|
+
fontSize: 16,
|
|
128
|
+
fontWeight: 'bold',
|
|
129
|
+
marginTop: 8,
|
|
130
|
+
marginBottom: 4,
|
|
131
|
+
},
|
|
132
|
+
[MarkdownElementType.HEADING6]: {
|
|
133
|
+
fontSize: 14,
|
|
134
|
+
fontWeight: 'bold',
|
|
135
|
+
marginTop: 8,
|
|
136
|
+
marginBottom: 4,
|
|
137
|
+
},
|
|
138
|
+
[MarkdownElementType.PARAGRAPH]: {
|
|
139
|
+
marginBottom: 12,
|
|
140
|
+
},
|
|
141
|
+
[MarkdownElementType.BLOCKQUOTE]: {
|
|
142
|
+
marginLeft: 16,
|
|
143
|
+
marginTop: 8,
|
|
144
|
+
marginBottom: 8,
|
|
145
|
+
paddingLeft: 12,
|
|
146
|
+
borderLeftWidth: 4,
|
|
147
|
+
borderLeftColor: '#CCCCCC',
|
|
148
|
+
fontStyle: 'italic',
|
|
149
|
+
color: '#666666',
|
|
150
|
+
},
|
|
151
|
+
[MarkdownElementType.LIST]: {
|
|
152
|
+
marginTop: 8,
|
|
153
|
+
marginBottom: 8,
|
|
154
|
+
},
|
|
155
|
+
[MarkdownElementType.LIST_ITEM]: {
|
|
156
|
+
marginBottom: 4,
|
|
157
|
+
listLeftInset: 10,
|
|
158
|
+
bulletIndent: 20,
|
|
159
|
+
},
|
|
160
|
+
[MarkdownElementType.ORDERED_LIST]: {
|
|
161
|
+
marginTop: 8,
|
|
162
|
+
marginBottom: 8,
|
|
163
|
+
},
|
|
164
|
+
[MarkdownElementType.ORDERED_LIST_ITEM]: {
|
|
165
|
+
marginBottom: 4,
|
|
166
|
+
listLeftInset: 10,
|
|
167
|
+
bulletIndent: 20,
|
|
168
|
+
},
|
|
169
|
+
[MarkdownElementType.CODE_INLINE]: {
|
|
170
|
+
fontFamily: 'Menlo, Monaco, Courier New, monospace',
|
|
171
|
+
backgroundColor: '#F5F5F5',
|
|
172
|
+
paddingLeft: 4,
|
|
173
|
+
paddingRight: 4,
|
|
174
|
+
paddingTop: 2,
|
|
175
|
+
paddingBottom: 2,
|
|
176
|
+
borderRadius: 3,
|
|
177
|
+
},
|
|
178
|
+
[MarkdownElementType.CODE_BLOCK]: {
|
|
179
|
+
fontFamily: 'Menlo, Monaco, Courier New, monospace',
|
|
180
|
+
backgroundColor: '#F5F5F5',
|
|
181
|
+
padding: 12,
|
|
182
|
+
borderRadius: 4,
|
|
183
|
+
marginTop: 8,
|
|
184
|
+
marginBottom: 8,
|
|
185
|
+
},
|
|
186
|
+
[MarkdownElementType.STRONG]: {
|
|
187
|
+
fontWeight: 'bold',
|
|
188
|
+
},
|
|
189
|
+
[MarkdownElementType.EM]: {
|
|
190
|
+
fontStyle: 'italic',
|
|
191
|
+
},
|
|
192
|
+
[MarkdownElementType.STRIKETHROUGH]: {
|
|
193
|
+
textDecorationLine: 'line-through',
|
|
194
|
+
},
|
|
195
|
+
[MarkdownElementType.LINK]: {
|
|
196
|
+
color: '#007AFF',
|
|
197
|
+
textDecorationLine: 'underline',
|
|
198
|
+
},
|
|
199
|
+
[MarkdownElementType.HR]: {
|
|
200
|
+
marginTop: 16,
|
|
201
|
+
marginBottom: 16,
|
|
202
|
+
borderBottomWidth: 1,
|
|
203
|
+
borderBottomColor: '#CCCCCC',
|
|
204
|
+
},
|
|
205
|
+
};
|