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.
Files changed (39) hide show
  1. package/LICENSE +21 -0
  2. package/MarkdownNative.podspec +19 -0
  3. package/README.md +109 -0
  4. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  5. package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
  6. package/android/.gradle/8.9/executionHistory/executionHistory.lock +0 -0
  7. package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
  8. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  9. package/android/.gradle/8.9/gc.properties +0 -0
  10. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  11. package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
  12. package/android/.gradle/vcs-1/gc.properties +0 -0
  13. package/android/build.gradle +36 -0
  14. package/android/src/main/AndroidManifest.xml +2 -0
  15. package/android/src/main/java/com/markdownnative/MarkdownPackage.java +25 -0
  16. package/android/src/main/java/com/markdownnative/MarkdownView.java +516 -0
  17. package/android/src/main/java/com/markdownnative/MarkdownViewManager.java +107 -0
  18. package/ios/MarkdownView.swift +771 -0
  19. package/ios/MarkdownViewManager.m +27 -0
  20. package/ios/MarkdownViewManager.swift +20 -0
  21. package/lib/commonjs/index.js +97 -0
  22. package/lib/commonjs/index.js.map +1 -0
  23. package/lib/commonjs/package.json +1 -0
  24. package/lib/commonjs/types.js +154 -0
  25. package/lib/commonjs/types.js.map +1 -0
  26. package/lib/index.d.ts +26 -0
  27. package/lib/index.js +97 -0
  28. package/lib/module/index.js +80 -0
  29. package/lib/module/index.js.map +1 -0
  30. package/lib/module/types.js +153 -0
  31. package/lib/module/types.js.map +1 -0
  32. package/lib/typescript/index.d.ts +30 -0
  33. package/lib/typescript/index.d.ts.map +1 -0
  34. package/lib/typescript/types.d.ts +80 -0
  35. package/lib/typescript/types.d.ts.map +1 -0
  36. package/package.json +92 -0
  37. package/react-native.config.js +11 -0
  38. package/src/index.tsx +117 -0
  39. 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
+ }
@@ -0,0 +1,11 @@
1
+ module.exports = {
2
+ dependency: {
3
+ platforms: {
4
+ android: {
5
+ packageImportPath: 'import com.markdownnative.MarkdownPackage;',
6
+ packageInstance: 'new MarkdownPackage()',
7
+ },
8
+ ios: {},
9
+ },
10
+ },
11
+ };
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
+ };