react-native-marked 8.1.1 → 8.2.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 (70) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +354 -354
  3. package/dist/commonjs/components/MDImage.js +3 -3
  4. package/dist/commonjs/components/MDImage.js.map +1 -1
  5. package/dist/commonjs/components/MDList.js.map +1 -1
  6. package/dist/commonjs/components/MDSvg.js.map +1 -1
  7. package/dist/commonjs/components/MDTable.js.map +1 -1
  8. package/dist/commonjs/hooks/useMarkdown.js.map +1 -1
  9. package/dist/commonjs/hooks/useMarkdownWithComponents.js.map +1 -1
  10. package/dist/commonjs/index.js.map +1 -1
  11. package/dist/commonjs/lib/Markdown.js.map +1 -1
  12. package/dist/commonjs/lib/Parser.js +4 -4
  13. package/dist/commonjs/lib/Parser.js.map +1 -1
  14. package/dist/commonjs/lib/ReactComponentRegistry.js.map +1 -1
  15. package/dist/commonjs/lib/ReactComponentTokenizer.js.map +1 -1
  16. package/dist/commonjs/lib/Renderer.js.map +1 -1
  17. package/dist/commonjs/lib/types.js.map +1 -1
  18. package/dist/commonjs/theme/colors.js.map +1 -1
  19. package/dist/commonjs/theme/spacing.js.map +1 -1
  20. package/dist/commonjs/theme/styles.js.map +1 -1
  21. package/dist/commonjs/theme/types.js.map +1 -1
  22. package/dist/commonjs/utils/handlers.js.map +1 -1
  23. package/dist/commonjs/utils/svg.js.map +1 -1
  24. package/dist/commonjs/utils/table.js.map +1 -1
  25. package/dist/commonjs/utils/url.js.map +1 -1
  26. package/dist/module/components/MDImage.js +3 -3
  27. package/dist/module/components/MDImage.js.map +1 -1
  28. package/dist/module/components/MDList.js.map +1 -1
  29. package/dist/module/components/MDSvg.js.map +1 -1
  30. package/dist/module/components/MDTable.js.map +1 -1
  31. package/dist/module/hooks/useMarkdown.js.map +1 -1
  32. package/dist/module/hooks/useMarkdownWithComponents.js.map +1 -1
  33. package/dist/module/index.js.map +1 -1
  34. package/dist/module/lib/Markdown.js.map +1 -1
  35. package/dist/module/lib/Parser.js +4 -4
  36. package/dist/module/lib/Parser.js.map +1 -1
  37. package/dist/module/lib/ReactComponentRegistry.js.map +1 -1
  38. package/dist/module/lib/ReactComponentTokenizer.js.map +1 -1
  39. package/dist/module/lib/Renderer.js.map +1 -1
  40. package/dist/module/lib/types.js.map +1 -1
  41. package/dist/module/theme/colors.js.map +1 -1
  42. package/dist/module/theme/spacing.js.map +1 -1
  43. package/dist/module/theme/styles.js.map +1 -1
  44. package/dist/module/theme/types.js.map +1 -1
  45. package/dist/module/utils/handlers.js.map +1 -1
  46. package/dist/module/utils/svg.js.map +1 -1
  47. package/dist/module/utils/table.js.map +1 -1
  48. package/dist/module/utils/url.js.map +1 -1
  49. package/package.json +175 -175
  50. package/src/components/MDImage.tsx +90 -90
  51. package/src/components/MDList.tsx +46 -46
  52. package/src/components/MDSvg.tsx +108 -108
  53. package/src/components/MDTable.tsx +60 -60
  54. package/src/hooks/useMarkdown.ts +51 -51
  55. package/src/hooks/useMarkdownWithComponents.tsx +89 -89
  56. package/src/index.ts +43 -43
  57. package/src/lib/Markdown.tsx +53 -53
  58. package/src/lib/Parser.tsx +316 -316
  59. package/src/lib/ReactComponentRegistry.tsx +52 -52
  60. package/src/lib/ReactComponentTokenizer.ts +149 -149
  61. package/src/lib/Renderer.tsx +238 -238
  62. package/src/lib/types.ts +87 -87
  63. package/src/theme/colors.ts +31 -31
  64. package/src/theme/spacing.ts +10 -10
  65. package/src/theme/styles.ts +198 -198
  66. package/src/theme/types.ts +33 -33
  67. package/src/utils/handlers.ts +9 -9
  68. package/src/utils/svg.ts +14 -14
  69. package/src/utils/table.ts +29 -29
  70. package/src/utils/url.ts +22 -22
@@ -1,51 +1,51 @@
1
- import { type Hooks, lexer, type Tokenizer } from "marked";
2
- import { type ReactNode, useMemo } from "react";
3
- import type { ColorSchemeName } from "react-native";
4
- import Parser from "../lib/Parser";
5
- import Renderer from "../lib/Renderer";
6
- import type { RendererInterface } from "../lib/types";
7
- import getStyles from "./../theme/styles";
8
- import type { MarkedStyles, UserTheme } from "./../theme/types";
9
-
10
- export interface useMarkdownHookOptions {
11
- colorScheme?: ColorSchemeName;
12
- renderer?: RendererInterface;
13
- theme?: UserTheme;
14
- styles?: MarkedStyles;
15
- baseUrl?: string;
16
- tokenizer?: Tokenizer;
17
- hooks?: Hooks;
18
- }
19
-
20
- const useMarkdown = (
21
- value: string,
22
- options?: useMarkdownHookOptions,
23
- ): ReactNode[] => {
24
- const styles = useMemo(
25
- () => getStyles(options?.styles, options?.colorScheme, options?.theme),
26
- [options?.styles, options?.theme, options?.colorScheme],
27
- );
28
-
29
- const parser = useMemo(
30
- () =>
31
- new Parser({
32
- styles: styles,
33
- baseUrl: options?.baseUrl,
34
- renderer: options?.renderer ?? new Renderer(),
35
- }),
36
- [options?.renderer, options?.baseUrl, styles],
37
- );
38
-
39
- const elements = useMemo(() => {
40
- const tokens = lexer(value, {
41
- gfm: true,
42
- tokenizer: options?.tokenizer,
43
- hooks: options?.hooks,
44
- });
45
- return parser.parse(tokens);
46
- }, [value, parser, options?.tokenizer, options?.hooks]);
47
-
48
- return elements;
49
- };
50
-
51
- export default useMarkdown;
1
+ import { type Hooks, lexer, type Tokenizer } from "marked";
2
+ import { type ReactNode, useMemo } from "react";
3
+ import type { ColorSchemeName } from "react-native";
4
+ import Parser from "../lib/Parser";
5
+ import Renderer from "../lib/Renderer";
6
+ import type { RendererInterface } from "../lib/types";
7
+ import getStyles from "./../theme/styles";
8
+ import type { MarkedStyles, UserTheme } from "./../theme/types";
9
+
10
+ export interface useMarkdownHookOptions {
11
+ colorScheme?: ColorSchemeName;
12
+ renderer?: RendererInterface;
13
+ theme?: UserTheme;
14
+ styles?: MarkedStyles;
15
+ baseUrl?: string;
16
+ tokenizer?: Tokenizer;
17
+ hooks?: Hooks;
18
+ }
19
+
20
+ const useMarkdown = (
21
+ value: string,
22
+ options?: useMarkdownHookOptions,
23
+ ): ReactNode[] => {
24
+ const styles = useMemo(
25
+ () => getStyles(options?.styles, options?.colorScheme, options?.theme),
26
+ [options?.styles, options?.theme, options?.colorScheme],
27
+ );
28
+
29
+ const parser = useMemo(
30
+ () =>
31
+ new Parser({
32
+ styles: styles,
33
+ baseUrl: options?.baseUrl,
34
+ renderer: options?.renderer ?? new Renderer(),
35
+ }),
36
+ [options?.renderer, options?.baseUrl, styles],
37
+ );
38
+
39
+ const elements = useMemo(() => {
40
+ const tokens = lexer(value, {
41
+ gfm: true,
42
+ tokenizer: options?.tokenizer,
43
+ hooks: options?.hooks,
44
+ });
45
+ return parser.parse(tokens);
46
+ }, [value, parser, options?.tokenizer, options?.hooks]);
47
+
48
+ return elements;
49
+ };
50
+
51
+ export default useMarkdown;
@@ -1,89 +1,89 @@
1
- import type { ReactNode } from "react";
2
- import React, { useMemo } from "react";
3
- import { useReactComponentRegistry } from "../lib/ReactComponentRegistry";
4
- import type { ReactComponentToken } from "../lib/ReactComponentTokenizer";
5
- import {
6
- isReactComponentToken,
7
- ReactComponentTokenizer,
8
- } from "../lib/ReactComponentTokenizer";
9
- import Renderer from "../lib/Renderer";
10
- import type { RendererInterface } from "../lib/types";
11
- import type { useMarkdownHookOptions } from "./useMarkdown";
12
- import useMarkdown from "./useMarkdown";
13
-
14
- export interface useMarkdownWithComponentsOptions
15
- extends Omit<useMarkdownHookOptions, "tokenizer"> {}
16
-
17
- interface ComponentData {
18
- token: ReactComponentToken;
19
- id: string;
20
- }
21
-
22
- export function useMarkdownWithComponents(
23
- value: string,
24
- options?: useMarkdownWithComponentsOptions,
25
- ): ReactNode[] {
26
- const registry = useReactComponentRegistry();
27
-
28
- const { tokenizer, componentMap } = useMemo(() => {
29
- const map = new Map<string, ComponentData>();
30
-
31
- const customTokenizer = new ReactComponentTokenizer();
32
- const originalHtml = customTokenizer.html.bind(customTokenizer);
33
-
34
- let componentCounter = 0;
35
-
36
- customTokenizer.html = (src: string) => {
37
- const token = originalHtml(src);
38
- if (token && isReactComponentToken(token)) {
39
- const id = `${token.componentName}-${componentCounter++}`;
40
- map.set(token.raw, { token, id });
41
- }
42
- return token;
43
- };
44
-
45
- return { tokenizer: customTokenizer, componentMap: map };
46
- }, []);
47
-
48
- const baseRenderer = useMemo(
49
- () => options?.renderer ?? new Renderer(),
50
- [options?.renderer],
51
- );
52
-
53
- const renderer = useMemo<RendererInterface>(() => {
54
- const wrappedRenderer = Object.create(baseRenderer) as typeof baseRenderer;
55
-
56
- wrappedRenderer.html = (text: string | ReactNode[], styles): ReactNode => {
57
- if (typeof text === "string") {
58
- const data = componentMap.get(text);
59
- if (data) {
60
- if (registry?.hasComponent(data.token.componentName)) {
61
- const Component = registry.getComponent(data.token.componentName);
62
- if (Component) {
63
- return (
64
- <Component key={data.id} props={data.token.componentProps}>
65
- {data.token.componentChildren || undefined}
66
- </Component>
67
- );
68
- }
69
- }
70
- return null;
71
- }
72
- }
73
-
74
- return baseRenderer.html(text, styles);
75
- };
76
-
77
- return wrappedRenderer;
78
- }, [baseRenderer, componentMap, registry]);
79
-
80
- const elements = useMarkdown(value, {
81
- ...options,
82
- tokenizer,
83
- renderer,
84
- });
85
-
86
- return elements;
87
- }
88
-
89
- export default useMarkdownWithComponents;
1
+ import type { ReactNode } from "react";
2
+ import React, { useMemo } from "react";
3
+ import { useReactComponentRegistry } from "../lib/ReactComponentRegistry";
4
+ import type { ReactComponentToken } from "../lib/ReactComponentTokenizer";
5
+ import {
6
+ isReactComponentToken,
7
+ ReactComponentTokenizer,
8
+ } from "../lib/ReactComponentTokenizer";
9
+ import Renderer from "../lib/Renderer";
10
+ import type { RendererInterface } from "../lib/types";
11
+ import type { useMarkdownHookOptions } from "./useMarkdown";
12
+ import useMarkdown from "./useMarkdown";
13
+
14
+ export interface useMarkdownWithComponentsOptions
15
+ extends Omit<useMarkdownHookOptions, "tokenizer"> {}
16
+
17
+ interface ComponentData {
18
+ token: ReactComponentToken;
19
+ id: string;
20
+ }
21
+
22
+ export function useMarkdownWithComponents(
23
+ value: string,
24
+ options?: useMarkdownWithComponentsOptions,
25
+ ): ReactNode[] {
26
+ const registry = useReactComponentRegistry();
27
+
28
+ const { tokenizer, componentMap } = useMemo(() => {
29
+ const map = new Map<string, ComponentData>();
30
+
31
+ const customTokenizer = new ReactComponentTokenizer();
32
+ const originalHtml = customTokenizer.html.bind(customTokenizer);
33
+
34
+ let componentCounter = 0;
35
+
36
+ customTokenizer.html = (src: string) => {
37
+ const token = originalHtml(src);
38
+ if (token && isReactComponentToken(token)) {
39
+ const id = `${token.componentName}-${componentCounter++}`;
40
+ map.set(token.raw, { token, id });
41
+ }
42
+ return token;
43
+ };
44
+
45
+ return { tokenizer: customTokenizer, componentMap: map };
46
+ }, []);
47
+
48
+ const baseRenderer = useMemo(
49
+ () => options?.renderer ?? new Renderer(),
50
+ [options?.renderer],
51
+ );
52
+
53
+ const renderer = useMemo<RendererInterface>(() => {
54
+ const wrappedRenderer = Object.create(baseRenderer) as typeof baseRenderer;
55
+
56
+ wrappedRenderer.html = (text: string | ReactNode[], styles): ReactNode => {
57
+ if (typeof text === "string") {
58
+ const data = componentMap.get(text);
59
+ if (data) {
60
+ if (registry?.hasComponent(data.token.componentName)) {
61
+ const Component = registry.getComponent(data.token.componentName);
62
+ if (Component) {
63
+ return (
64
+ <Component key={data.id} props={data.token.componentProps}>
65
+ {data.token.componentChildren || undefined}
66
+ </Component>
67
+ );
68
+ }
69
+ }
70
+ return null;
71
+ }
72
+ }
73
+
74
+ return baseRenderer.html(text, styles);
75
+ };
76
+
77
+ return wrappedRenderer;
78
+ }, [baseRenderer, componentMap, registry]);
79
+
80
+ const elements = useMarkdown(value, {
81
+ ...options,
82
+ tokenizer,
83
+ renderer,
84
+ });
85
+
86
+ return elements;
87
+ }
88
+
89
+ export default useMarkdownWithComponents;
package/src/index.ts CHANGED
@@ -1,43 +1,43 @@
1
- import type { Token, Tokens } from "marked";
2
- import {
3
- Hooks as MarkedHooks,
4
- Tokenizer as MarkedTokenizer,
5
- marked,
6
- } from "marked";
7
- import useMarkdown, { type useMarkdownHookOptions } from "./hooks/useMarkdown";
8
- import useMarkdownWithComponents from "./hooks/useMarkdownWithComponents";
9
- import Markdown from "./lib/Markdown";
10
- import type { ReactComponentRegistry } from "./lib/ReactComponentRegistry";
11
- import { ReactComponentRegistryProvider } from "./lib/ReactComponentRegistry";
12
- import Renderer from "./lib/Renderer";
13
- import type {
14
- MarkdownProps,
15
- ParserOptions,
16
- RendererInterface,
17
- } from "./lib/types";
18
- import type { MarkedStyles } from "./theme/types";
19
-
20
- const MarkedLexer = marked.lexer;
21
-
22
- export type {
23
- MarkdownProps,
24
- MarkedStyles,
25
- ParserOptions,
26
- ReactComponentRegistry,
27
- RendererInterface,
28
- Token,
29
- Tokens,
30
- useMarkdownHookOptions,
31
- };
32
-
33
- export {
34
- MarkedHooks,
35
- MarkedLexer,
36
- MarkedTokenizer,
37
- ReactComponentRegistryProvider,
38
- Renderer,
39
- useMarkdown,
40
- useMarkdownWithComponents,
41
- };
42
-
43
- export default Markdown;
1
+ import type { Token, Tokens } from "marked";
2
+ import {
3
+ Hooks as MarkedHooks,
4
+ Tokenizer as MarkedTokenizer,
5
+ marked,
6
+ } from "marked";
7
+ import useMarkdown, { type useMarkdownHookOptions } from "./hooks/useMarkdown";
8
+ import useMarkdownWithComponents from "./hooks/useMarkdownWithComponents";
9
+ import Markdown from "./lib/Markdown";
10
+ import type { ReactComponentRegistry } from "./lib/ReactComponentRegistry";
11
+ import { ReactComponentRegistryProvider } from "./lib/ReactComponentRegistry";
12
+ import Renderer from "./lib/Renderer";
13
+ import type {
14
+ MarkdownProps,
15
+ ParserOptions,
16
+ RendererInterface,
17
+ } from "./lib/types";
18
+ import type { MarkedStyles } from "./theme/types";
19
+
20
+ const MarkedLexer = marked.lexer;
21
+
22
+ export type {
23
+ MarkdownProps,
24
+ MarkedStyles,
25
+ ParserOptions,
26
+ ReactComponentRegistry,
27
+ RendererInterface,
28
+ Token,
29
+ Tokens,
30
+ useMarkdownHookOptions,
31
+ };
32
+
33
+ export {
34
+ MarkedHooks,
35
+ MarkedLexer,
36
+ MarkedTokenizer,
37
+ ReactComponentRegistryProvider,
38
+ Renderer,
39
+ useMarkdown,
40
+ useMarkdownWithComponents,
41
+ };
42
+
43
+ export default Markdown;
@@ -1,53 +1,53 @@
1
- import React, { type ReactElement, type ReactNode, useCallback } from "react";
2
- import { FlatList, useColorScheme } from "react-native";
3
- import useMarkdown from "../hooks/useMarkdown";
4
- import type { MarkdownProps } from "./types";
5
-
6
- const Markdown = ({
7
- value,
8
- flatListProps,
9
- theme,
10
- baseUrl,
11
- renderer,
12
- styles,
13
- tokenizer,
14
- hooks,
15
- }: MarkdownProps) => {
16
- const colorScheme = useColorScheme();
17
-
18
- const rnElements = useMarkdown(value, {
19
- theme,
20
- baseUrl,
21
- renderer,
22
- colorScheme,
23
- styles,
24
- tokenizer,
25
- hooks,
26
- });
27
-
28
- const renderItem = useCallback(({ item }: { item: ReactNode }) => {
29
- return item as ReactElement;
30
- }, []);
31
-
32
- const keyExtractor = useCallback(
33
- (_: ReactNode, index: number) => index.toString(),
34
- [],
35
- );
36
-
37
- return (
38
- <FlatList
39
- removeClippedSubviews={false}
40
- keyExtractor={keyExtractor}
41
- maxToRenderPerBatch={8}
42
- initialNumToRender={8}
43
- style={{
44
- backgroundColor: colorScheme === "light" ? "#ffffff" : "#000000",
45
- }}
46
- {...flatListProps}
47
- data={rnElements}
48
- renderItem={renderItem}
49
- />
50
- );
51
- };
52
-
53
- export default Markdown;
1
+ import React, { type ReactElement, type ReactNode, useCallback } from "react";
2
+ import { FlatList, useColorScheme } from "react-native";
3
+ import useMarkdown from "../hooks/useMarkdown";
4
+ import type { MarkdownProps } from "./types";
5
+
6
+ const Markdown = ({
7
+ value,
8
+ flatListProps,
9
+ theme,
10
+ baseUrl,
11
+ renderer,
12
+ styles,
13
+ tokenizer,
14
+ hooks,
15
+ }: MarkdownProps) => {
16
+ const colorScheme = useColorScheme();
17
+
18
+ const rnElements = useMarkdown(value, {
19
+ theme,
20
+ baseUrl,
21
+ renderer,
22
+ colorScheme,
23
+ styles,
24
+ tokenizer,
25
+ hooks,
26
+ });
27
+
28
+ const renderItem = useCallback(({ item }: { item: ReactNode }) => {
29
+ return item as ReactElement;
30
+ }, []);
31
+
32
+ const keyExtractor = useCallback(
33
+ (_: ReactNode, index: number) => index.toString(),
34
+ [],
35
+ );
36
+
37
+ return (
38
+ <FlatList
39
+ removeClippedSubviews={false}
40
+ keyExtractor={keyExtractor}
41
+ maxToRenderPerBatch={8}
42
+ initialNumToRender={8}
43
+ style={{
44
+ backgroundColor: colorScheme === "light" ? "#ffffff" : "#000000",
45
+ }}
46
+ {...flatListProps}
47
+ data={rnElements}
48
+ renderItem={renderItem}
49
+ />
50
+ );
51
+ };
52
+
53
+ export default Markdown;