@create-markdown/react 0.1.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/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # @create-markdown/react
2
+
3
+ React components and hooks for @create-markdown.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ # Using bun
9
+ bun add @create-markdown/react
10
+
11
+ # Using npm
12
+ npm install @create-markdown/react
13
+
14
+ # Using yarn
15
+ yarn add @create-markdown/react
16
+ ```
17
+
18
+ ## Quick Start
19
+
20
+ ### Render Blocks
21
+
22
+ ```tsx
23
+ import { BlockRenderer, useDocument, h1, paragraph } from '@create-markdown/react';
24
+
25
+ function Editor() {
26
+ const doc = useDocument([
27
+ h1('Welcome'),
28
+ paragraph('Start editing...'),
29
+ ]);
30
+
31
+ return <BlockRenderer blocks={doc.blocks} />;
32
+ }
33
+ ```
34
+
35
+ ### Bidirectional Markdown
36
+
37
+ ```tsx
38
+ import { BlockRenderer, useMarkdown } from '@create-markdown/react';
39
+
40
+ function MarkdownEditor() {
41
+ const { markdown, blocks, setMarkdown } = useMarkdown('# Hello');
42
+
43
+ return (
44
+ <div>
45
+ <textarea
46
+ value={markdown}
47
+ onChange={(e) => setMarkdown(e.target.value)}
48
+ />
49
+ <BlockRenderer blocks={blocks} />
50
+ </div>
51
+ );
52
+ }
53
+ ```
54
+
55
+ ### Block Selection and Editing
56
+
57
+ ```tsx
58
+ import { BlockRenderer, useDocument, useBlockEditor, BlockElement } from '@create-markdown/react';
59
+
60
+ function Editor() {
61
+ const doc = useDocument();
62
+ const editor = useBlockEditor(doc);
63
+
64
+ return (
65
+ <div>
66
+ {doc.blocks.map((block) => (
67
+ <div
68
+ key={block.id}
69
+ onClick={() => editor.selectBlock(block.id)}
70
+ style={{
71
+ border: editor.selectedBlockId === block.id ? '2px solid blue' : 'none'
72
+ }}
73
+ >
74
+ <BlockElement block={block} />
75
+ </div>
76
+ ))}
77
+ </div>
78
+ );
79
+ }
80
+ ```
81
+
82
+ ## Components
83
+
84
+ ### `BlockRenderer`
85
+
86
+ Renders an array of blocks as React elements.
87
+
88
+ ```tsx
89
+ <BlockRenderer
90
+ blocks={blocks}
91
+ className="my-editor"
92
+ customRenderers={{
93
+ codeBlock: MyCustomCodeBlock,
94
+ }}
95
+ />
96
+ ```
97
+
98
+ ### `BlockElement`
99
+
100
+ Renders a single block.
101
+
102
+ ### `InlineContent`
103
+
104
+ Renders inline content (text spans with styles).
105
+
106
+ ## Hooks
107
+
108
+ ### `useDocument(initialBlocks?, options?)`
109
+
110
+ Full document state management with CRUD operations.
111
+
112
+ ### `useMarkdown(initialMarkdown?)`
113
+
114
+ Bidirectional markdown/blocks state.
115
+
116
+ ### `useBlockEditor(documentHook)`
117
+
118
+ Block selection and editing operations.
119
+
120
+ ## License
121
+
122
+ MIT
@@ -0,0 +1,70 @@
1
+ /**
2
+ * @create-markdown/react - Block Renderer
3
+ * Render blocks as React elements
4
+ */
5
+ import React from 'react';
6
+ import type { Block, TextSpan, HeadingBlock, CodeBlockBlock, ImageBlock, TableBlock, CalloutBlock, CheckListBlock } from '@create-markdown/core';
7
+ export interface BlockRendererProps {
8
+ /** Blocks to render */
9
+ blocks: Block[];
10
+ /** Custom class name for the container */
11
+ className?: string;
12
+ /** Custom renderers for specific block types */
13
+ customRenderers?: Partial<BlockRenderers>;
14
+ }
15
+ export interface BlockRenderers {
16
+ paragraph: React.ComponentType<{
17
+ block: Block;
18
+ }>;
19
+ heading: React.ComponentType<{
20
+ block: HeadingBlock;
21
+ }>;
22
+ bulletList: React.ComponentType<{
23
+ block: Block;
24
+ }>;
25
+ numberedList: React.ComponentType<{
26
+ block: Block;
27
+ }>;
28
+ checkList: React.ComponentType<{
29
+ block: CheckListBlock;
30
+ }>;
31
+ codeBlock: React.ComponentType<{
32
+ block: CodeBlockBlock;
33
+ }>;
34
+ blockquote: React.ComponentType<{
35
+ block: Block;
36
+ }>;
37
+ table: React.ComponentType<{
38
+ block: TableBlock;
39
+ }>;
40
+ image: React.ComponentType<{
41
+ block: ImageBlock;
42
+ }>;
43
+ divider: React.ComponentType<{
44
+ block: Block;
45
+ }>;
46
+ callout: React.ComponentType<{
47
+ block: CalloutBlock;
48
+ }>;
49
+ }
50
+ export interface SingleBlockProps {
51
+ block: Block;
52
+ customRenderers?: Partial<BlockRenderers>;
53
+ }
54
+ /**
55
+ * Renders: array of blocks as React elements
56
+ */
57
+ export declare function BlockRenderer({ blocks, className, customRenderers, }: BlockRendererProps): React.ReactElement;
58
+ /**
59
+ * Renders: single block
60
+ */
61
+ export declare function BlockElement({ block, customRenderers, }: SingleBlockProps): React.ReactElement | null;
62
+ interface InlineContentProps {
63
+ spans: TextSpan[];
64
+ }
65
+ /**
66
+ * Renders: inline content (text spans with styles)
67
+ */
68
+ export declare function InlineContent({ spans }: InlineContentProps): React.ReactElement;
69
+ export default BlockRenderer;
70
+ //# sourceMappingURL=block-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-renderer.d.ts","sourceRoot":"","sources":["../src/block-renderer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EACR,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,UAAU,EACV,UAAU,EACV,YAAY,EACZ,cAAc,EACjB,MAAM,uBAAuB,CAAC;AAM/B,MAAM,WAAW,kBAAkB;IAC/B,uBAAuB;IACvB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,eAAe,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,cAAc;IAC3B,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC;IACjD,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,KAAK,EAAE,YAAY,CAAA;KAAE,CAAC,CAAC;IACtD,UAAU,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC;IAClD,YAAY,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC;IACpD,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,KAAK,EAAE,cAAc,CAAA;KAAE,CAAC,CAAC;IAC1D,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,KAAK,EAAE,cAAc,CAAA;KAAE,CAAC,CAAC;IAC1D,UAAU,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC;IAClD,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;IAClD,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;IAClD,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,KAAK,EAAE,YAAY,CAAA;KAAE,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,KAAK,CAAC;IACb,eAAe,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;CAC7C;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAC1B,MAAM,EACN,SAAS,EACT,eAAe,GAClB,EAAE,kBAAkB,GAAG,KAAK,CAAC,YAAY,CAYzC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,EACzB,KAAK,EACL,eAAe,GAClB,EAAE,gBAAgB,GAAG,KAAK,CAAC,YAAY,GAAG,IAAI,CA6C9C;AAMD,UAAU,kBAAkB;IACxB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,EAAE,kBAAkB,GAAG,KAAK,CAAC,YAAY,CAQ/E;AAuRD,eAAe,aAAa,CAAC"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * @create-markdown/react - Hooks
3
+ * State management hooks for document manipulation
4
+ */
5
+ import type { Block, Document, DocumentOptions, TextSpan } from '@create-markdown/core';
6
+ export interface UseDocumentReturn {
7
+ /** Current document state */
8
+ document: Document;
9
+ /** Blocks in the document */
10
+ blocks: Block[];
11
+ /** Insert: block at a specific index */
12
+ insertBlock: (block: Block, index?: number) => void;
13
+ /** Append: block to the end */
14
+ appendBlock: (block: Block) => void;
15
+ /** Remove: block by ID */
16
+ removeBlock: (blockId: string) => void;
17
+ /** Update: block by ID */
18
+ updateBlock: (blockId: string, updates: Partial<Omit<Block, 'id' | 'type'>>) => void;
19
+ /** Move: block to a new index */
20
+ moveBlock: (blockId: string, newIndex: number) => void;
21
+ /** Find: block by ID */
22
+ findBlock: (blockId: string) => Block | undefined;
23
+ /** Get: index of a block */
24
+ getBlockIndex: (blockId: string) => number;
25
+ /** Clear: all blocks */
26
+ clearBlocks: () => void;
27
+ /** Replace: entire document with new blocks */
28
+ setBlocks: (blocks: Block[]) => void;
29
+ /** Set: entire document */
30
+ setDocument: (doc: Document) => void;
31
+ /** Get: document as markdown */
32
+ toMarkdown: () => string;
33
+ /** Load: markdown into the document */
34
+ fromMarkdown: (markdown: string) => void;
35
+ /** Update: document metadata */
36
+ updateMeta: (meta: Partial<Document['meta']>) => void;
37
+ }
38
+ /**
39
+ * Hook for managing: document with blocks
40
+ *
41
+ * @example
42
+ * ```tsx
43
+ * function Editor() {
44
+ * const { blocks, appendBlock, toMarkdown } = useDocument();
45
+ *
46
+ * const addParagraph = () => {
47
+ * appendBlock(paragraph('New paragraph'));
48
+ * };
49
+ *
50
+ * return (
51
+ * <div>
52
+ * <BlockRenderer blocks={blocks} />
53
+ * <button onClick={addParagraph}>Add Paragraph</button>
54
+ * <button onClick={() => console.log(toMarkdown())}>Export</button>
55
+ * </div>
56
+ * );
57
+ * }
58
+ * ```
59
+ */
60
+ export declare function useDocument(initialBlocks?: Block[], options?: DocumentOptions): UseDocumentReturn;
61
+ export interface UseMarkdownReturn {
62
+ /** Current markdown string */
63
+ markdown: string;
64
+ /** Parsed blocks */
65
+ blocks: Block[];
66
+ /** Update: markdown content */
67
+ setMarkdown: (markdown: string) => void;
68
+ /** Update: blocks (will update markdown too) */
69
+ setBlocks: (blocks: Block[]) => void;
70
+ }
71
+ /**
72
+ * Hook for bidirectional: markdown/blocks state
73
+ *
74
+ * @example
75
+ * ```tsx
76
+ * function MarkdownEditor() {
77
+ * const { markdown, blocks, setMarkdown } = useMarkdown('# Hello');
78
+ *
79
+ * return (
80
+ * <div>
81
+ * <textarea
82
+ * value={markdown}
83
+ * onChange={(e) => setMarkdown(e.target.value)}
84
+ * />
85
+ * <BlockRenderer blocks={blocks} />
86
+ * </div>
87
+ * );
88
+ * }
89
+ * ```
90
+ */
91
+ export declare function useMarkdown(initialMarkdown?: string): UseMarkdownReturn;
92
+ export interface UseBlockEditorReturn {
93
+ /** Current selected block ID */
94
+ selectedBlockId: string | null;
95
+ /** Current selected block */
96
+ selectedBlock: Block | undefined;
97
+ /** Select: block by ID */
98
+ selectBlock: (blockId: string | null) => void;
99
+ /** Select: next block */
100
+ selectNext: () => void;
101
+ /** Select: previous block */
102
+ selectPrevious: () => void;
103
+ /** Delete: selected block */
104
+ deleteSelected: () => void;
105
+ /** Update: selected block's content */
106
+ updateSelectedContent: (content: TextSpan[]) => void;
107
+ /** Duplicate: selected block */
108
+ duplicateSelected: () => void;
109
+ /** Move: selected block up */
110
+ moveSelectedUp: () => void;
111
+ /** Move: selected block down */
112
+ moveSelectedDown: () => void;
113
+ }
114
+ /**
115
+ * Hook for: block selection and editing operations
116
+ *
117
+ * @example
118
+ * ```tsx
119
+ * function Editor() {
120
+ * const doc = useDocument();
121
+ * const editor = useBlockEditor(doc);
122
+ *
123
+ * return (
124
+ * <div>
125
+ * {doc.blocks.map((block) => (
126
+ * <div
127
+ * key={block.id}
128
+ * onClick={() => editor.selectBlock(block.id)}
129
+ * style={{
130
+ * border: editor.selectedBlockId === block.id ? '2px solid blue' : 'none'
131
+ * }}
132
+ * >
133
+ * <BlockElement block={block} />
134
+ * </div>
135
+ * ))}
136
+ * </div>
137
+ * );
138
+ * }
139
+ * ```
140
+ */
141
+ export declare function useBlockEditor(documentHook: UseDocumentReturn): UseBlockEditorReturn;
142
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}