markdown-text-editor 0.1.0 → 0.1.1

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.
@@ -1,98 +1,110 @@
1
- // #components/Toolbar/tools/PreviewToggleTool.js
2
- import MakeTool from '../MakeTool.js';
3
-
4
- class PreviewTool extends MakeTool {
5
- constructor(editor) {
6
- // No markdown syntax for preview toggle, so we call the parent constructor with empty values
7
- super(editor, '', 'Preview');
8
- this.button = this.createButton(`
9
- <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
10
- <rect width="18" height="18" x="3" y="3" rx="2"/><path d="M12 3v18"/>
11
- </svg>
12
- `);
13
- }
14
-
15
- // Override applySyntax to handle preview toggling
16
- applySyntax() {
17
- const previewWrapper = this.editor.previewContent?.parentNode;
18
- const editorDiv = this.editor.markdownEditorDiv;
19
-
20
- if (!previewWrapper || !editorDiv) return;
21
-
22
- // Toggle the preview's visibility by switching between 'block' and 'hidden' classes
23
- if (this.editor.preview) {
24
- this.enablePreview(previewWrapper, editorDiv);
25
- } else {
26
- this.disablePreview(previewWrapper, editorDiv);
27
- }
28
- }
29
-
30
- // Method to hide the preview (disable it)
31
- disablePreview(previewWrapper, editorDiv) {
32
-
33
- this.editor.preview = true;
34
-
35
- editorDiv.parentNode.classList.toggle('fixed');
36
- editorDiv.parentNode.classList.toggle('top-0');
37
- editorDiv.parentNode.classList.toggle('inset-x-0');
38
- editorDiv.parentNode.classList.toggle('rounded-md');
39
- editorDiv.parentNode.classList.toggle('z-[999]');
40
-
41
- previewWrapper.classList.toggle('hidden');
42
-
43
- // Add grid layout and divide classes to the editor div
44
- editorDiv.classList.remove(
45
- 'md:grid',
46
- 'md:grid-cols-2',
47
- 'md:divide-x',
48
- 'rtl:md:divide-x-reverse',
49
- 'md:divide-stone-300',
50
- 'dark:md:divide-stone-700'
51
- );
52
-
53
- editorDiv.querySelector(".textarea-wrapper").classList.remove(
54
- 'h-[90lvh]',
55
- 'hidden',
56
- 'md:block'
57
- );
58
- this.editor.render(); // Re-render content in the preview
59
-
60
- editorDiv.querySelector(".textarea-wrapper").querySelector("textarea").classList.remove("!h-[90lvh]");
61
-
62
- document.querySelector("body").classList.remove('overflow-hidden');
63
- }
64
-
65
- // Method to show the preview (enable it)
66
- enablePreview(previewWrapper, editorDiv) {
67
-
68
- this.editor.preview = false;
69
-
70
- editorDiv.parentNode.classList.toggle('fixed');
71
- editorDiv.parentNode.classList.toggle('top-0');
72
- editorDiv.parentNode.classList.toggle('inset-x-0');
73
- editorDiv.parentNode.classList.toggle('rounded-md');
74
- editorDiv.parentNode.classList.toggle('z-[999]');
75
-
76
- previewWrapper.classList.toggle('hidden');
77
- // Remove grid layout and divide classes from the editor div
78
- editorDiv.classList.add(
79
- 'md:grid',
80
- 'md:grid-cols-2',
81
- 'md:divide-x',
82
- 'rtl:md:divide-x-reverse',
83
- 'md:divide-stone-300',
84
- 'dark:md:divide-stone-700'
85
- );
86
-
87
- editorDiv.querySelector(".textarea-wrapper").classList.add(
88
- 'h-[90lvh]',
89
- 'hidden',
90
- 'md:block'
91
- );
92
- editorDiv.querySelector(".textarea-wrapper").querySelector("textarea").classList.add("!h-[90lvh]");
93
-
94
- document.querySelector("body").classList.add('overflow-hidden');
95
- }
96
- }
97
-
98
- export default PreviewTool;
1
+ // #components/Toolbar/tools/PreviewToggleTool.js
2
+ import MakeTool from '../MakeTool.js';
3
+
4
+ class PreviewTool extends MakeTool {
5
+ constructor(editor) {
6
+ // No markdown syntax for preview toggle, so we call the parent constructor with empty values
7
+ super(editor, '', 'Preview');
8
+ this.button = this.createButton(`
9
+ <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
10
+ <rect width="18" height="18" x="3" y="3" rx="2"/><path d="M12 3v18"/>
11
+ </svg>
12
+ `);
13
+ }
14
+
15
+ // Override applySyntax to handle preview toggling
16
+ applySyntax() {
17
+ const previewWrapper = this.editor.previewContent?.parentNode;
18
+ const editorDiv = this.editor.markdownEditorDiv;
19
+
20
+ if (!previewWrapper || !editorDiv) return;
21
+
22
+ // Toggle the preview's visibility by switching between 'block' and 'hidden' classes
23
+ if (this.editor.preview) {
24
+ this.enablePreview(previewWrapper, editorDiv);
25
+ } else {
26
+ this.disablePreview(previewWrapper, editorDiv);
27
+ }
28
+ }
29
+
30
+ // Method to hide the preview (disable it)
31
+ disablePreview(previewWrapper, editorDiv) {
32
+
33
+ this.editor.preview = true;
34
+
35
+ editorDiv.parentNode.classList.toggle('fixed');
36
+ editorDiv.parentNode.classList.toggle('top-0');
37
+ editorDiv.parentNode.classList.toggle('inset-x-0');
38
+ editorDiv.parentNode.classList.toggle('rounded-md');
39
+ editorDiv.parentNode.classList.toggle('z-[999]');
40
+
41
+ previewWrapper.classList.toggle('hidden');
42
+
43
+ // Add grid layout and divide classes to the editor div
44
+ editorDiv.classList.remove(
45
+ 'md:grid',
46
+ 'md:grid-cols-2',
47
+ 'md:divide-x',
48
+ 'rtl:md:divide-x-reverse',
49
+ 'md:divide-stone-300',
50
+ 'dark:md:divide-stone-700'
51
+ );
52
+
53
+ editorDiv.querySelector(".textarea-wrapper").classList.remove(
54
+ 'h-[90lvh]',
55
+ 'hidden',
56
+ 'md:block'
57
+ );
58
+ this.editor.render(); // Re-render content in the preview
59
+
60
+ editorDiv.querySelector(".textarea-wrapper").querySelector("textarea").classList.remove("!h-[90lvh]");
61
+
62
+ document.querySelector("body").classList.remove('overflow-hidden');
63
+
64
+ document.querySelectorAll('.markdown-btn').forEach(button => {
65
+ if (!button.classList.contains('preview-btn')) {
66
+ button.classList.remove('pointer-events-none', 'md:pointer-events-auto', 'opacity-25', 'md:opacity-100');
67
+ }
68
+ });
69
+ }
70
+
71
+ // Method to show the preview (enable it)
72
+ enablePreview(previewWrapper, editorDiv) {
73
+
74
+ this.editor.preview = false;
75
+
76
+ editorDiv.parentNode.classList.toggle('fixed');
77
+ editorDiv.parentNode.classList.toggle('top-0');
78
+ editorDiv.parentNode.classList.toggle('inset-x-0');
79
+ editorDiv.parentNode.classList.toggle('rounded-md');
80
+ editorDiv.parentNode.classList.toggle('z-[999]');
81
+
82
+ previewWrapper.classList.toggle('hidden');
83
+ // Remove grid layout and divide classes from the editor div
84
+ editorDiv.classList.add(
85
+ 'md:grid',
86
+ 'md:grid-cols-2',
87
+ 'md:divide-x',
88
+ 'rtl:md:divide-x-reverse',
89
+ 'md:divide-stone-300',
90
+ 'dark:md:divide-stone-700'
91
+ );
92
+
93
+ editorDiv.querySelector(".textarea-wrapper").classList.add(
94
+ 'h-[90lvh]',
95
+ 'hidden',
96
+ 'md:block'
97
+ );
98
+ editorDiv.querySelector(".textarea-wrapper").querySelector("textarea").classList.add("!h-[90lvh]");
99
+
100
+ document.querySelector("body").classList.add('overflow-hidden');
101
+
102
+ document.querySelectorAll('.markdown-btn').forEach(button => {
103
+ if (!button.classList.contains('preview-btn')) {
104
+ button.classList.add('pointer-events-none', 'md:pointer-events-auto', 'opacity-25', 'md:opacity-100');
105
+ }
106
+ });
107
+ }
108
+ }
109
+
110
+ export default PreviewTool;
@@ -1,16 +1,16 @@
1
- import MakeTool from '../MakeTool.js';
2
-
3
- class StrikethroughTool extends MakeTool {
4
- constructor(editor) {
5
- // Call the parent constructor with the markdown syntax for strikethrough (~~)
6
- super(editor, '~~', 'strikethrough text');
7
- this.button = this.createButton(`
8
- <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
9
- <path d="M16 4H9a3 3 0 0 0-2.83 4"/>
10
- <path d="M14 12a4 4 0 0 1 0 8H6"/><line x1="4" x2="20" y1="12" y2="12"/>
11
- </svg>
12
- `);
13
- }
14
- }
15
-
1
+ import MakeTool from '../MakeTool.js';
2
+
3
+ class StrikethroughTool extends MakeTool {
4
+ constructor(editor) {
5
+ // Call the parent constructor with the markdown syntax for strikethrough (~~)
6
+ super(editor, '~~', 'Strikethrough');
7
+ this.button = this.createButton(`
8
+ <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
9
+ <path d="M16 4H9a3 3 0 0 0-2.83 4"/>
10
+ <path d="M14 12a4 4 0 0 1 0 8H6"/><line x1="4" x2="20" y1="12" y2="12"/>
11
+ </svg>
12
+ `);
13
+ }
14
+ }
15
+
16
16
  export default StrikethroughTool;
@@ -1,18 +1,18 @@
1
- import MakeTool from '../MakeTool.js';
2
-
3
- class ULTool extends MakeTool {
4
- constructor(editor) {
5
- super(editor, '-', 'Unordered list');
6
- this.button = this.createButton(`
7
- <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12h.01"/><path d="M3 18h.01"/><path d="M3 6h.01"/><path d="M8 12h13"/><path d="M8 18h13"/><path d="M8 6h13"/></svg>
8
- `);
9
- }
10
-
11
- // You can change how the syntax is applied for this specific tool:
12
- applySyntax() {
13
- super.applySyntax('start'); // Only apply strikethrough at the start
14
- }
15
- }
16
-
17
-
1
+ import MakeTool from '../MakeTool.js';
2
+
3
+ class ULTool extends MakeTool {
4
+ constructor(editor) {
5
+ super(editor, '-', 'Unordered list');
6
+ this.button = this.createButton(`
7
+ <svg xmlns="http://www.w3.org/2000/svg" width="18" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12h.01"/><path d="M3 18h.01"/><path d="M3 6h.01"/><path d="M8 12h13"/><path d="M8 18h13"/><path d="M8 6h13"/></svg>
8
+ `);
9
+ }
10
+
11
+ // You can change how the syntax is applied for this specific tool:
12
+ applySyntax() {
13
+ super.applySyntax('start'); // Only apply strikethrough at the start
14
+ }
15
+ }
16
+
17
+
18
18
  export default ULTool;
@@ -1,142 +1,169 @@
1
- // #markdown\editor.js
2
- import './styles/main.css';
3
- import { marked } from 'marked';
4
- import Toolbar from './Toolbar/index.js';
5
- import Preview from './preview.js';
6
-
7
- marked.setOptions({
8
- breaks: true
9
- });
10
-
11
- class MarkdownEditor {
12
- constructor(selector, options = {}) {
13
- this.usertextarea = typeof selector === 'string' ? document.querySelector(selector) : selector;
14
- this.options = options;
15
- this.preview = this.options.toolbar.includes('preview');
16
- this.init();
17
- }
18
-
19
- init() {
20
- this.createEditor();
21
- if (this.options.toolbar) this.addToolbar();
22
- }
23
-
24
- createEditor() {
25
- if (!this.isTextareaValid()) return;
26
-
27
- this.applyDefaultAttributes();
28
- this.buildEditorLayout();
29
- this.addInputListener();
30
- this.render();
31
- }
32
-
33
- isTextareaValid() {
34
- return this.usertextarea.tagName === 'TEXTAREA';
35
- }
36
-
37
- applyDefaultAttributes() {
38
- this.usertextarea.classList.add(
39
- "focus:outline-0",
40
- "border-0",
41
- "p-1.5",
42
- "max-w-full",
43
- "size-full",
44
- "bg-transparent",
45
- "outline-0",
46
- "appearance-none",
47
- "prose",
48
- "prose-sm",
49
- "md:prose-base",
50
- "dark:prose-invert",
51
- "text-stone-700",
52
- "dark:text-stone-200",
53
- "overflow-y-auto"
54
- );
55
- if (!this.usertextarea.hasAttribute('placeholder')) {
56
- this.usertextarea.placeholder = this.options.placeholder || 'Write your markdown...';
57
- }
58
- }
59
-
60
- buildEditorLayout() {
61
- this.editorContainer = document.createElement('div');
62
- this.editorContainer.className = `
63
- markdown-editor-wrapper
64
- border border-stone-200
65
- dark:border-stone-700
66
- rounded-md
67
- overflow-hidden
68
- `;
69
- this.usertextarea.parentNode.insertBefore(this.editorContainer, this.usertextarea);
70
-
71
- this.markdownEditorDiv = document.createElement('div');
72
- this.markdownEditorDiv.className = `editor-layout`;
73
- this.editorContainer.appendChild(this.markdownEditorDiv);
74
-
75
- this.addTextareaWrapper();
76
- if (this.preview) this.addPreviewWrapper();
77
- }
78
-
79
- addTextareaWrapper() {
80
- const textareaContainer = document.createElement('div');
81
- textareaContainer.className = `
82
- textarea-wrapper
83
- p-2
84
- bg-white
85
- dark:bg-stone-800
86
- grid
87
- after:px-3.5
88
- after:py-2.5
89
- after:text-inherit
90
- [&>textarea]:resize-none
91
- [&>textarea]:[grid-area:1/1/2/2]
92
- after:[grid-area:1/1/2/2]
93
- after:whitespace-pre-wrap
94
- after:invisible
95
- after:content-[attr(data-cloned-val)_'_']
96
- after:border
97
- `;
98
- textareaContainer.appendChild(this.usertextarea);
99
- this.markdownEditorDiv.appendChild(textareaContainer);
100
- }
101
-
102
-
103
-
104
- addPreviewWrapper() {
105
- const preview = new Preview(this.markdownEditorDiv);
106
- this.previewContent = preview.getPreviewContent();
107
- }
108
-
109
- addInputListener() {
110
- this.usertextarea.addEventListener('input', () => this.render());
111
- this.usertextarea.addEventListener('scroll', () => {
112
- const textarea = this.usertextarea;
113
- const previewPane = this.previewContent;
114
-
115
- // Calculate the proportion of the textarea that has been scrolled
116
- const textareaScrollRatio = textarea.scrollTop / (textarea.scrollHeight - textarea.clientHeight);
117
-
118
- // Apply the same scroll ratio to the preview pane
119
- previewPane.scrollTop = textareaScrollRatio * (previewPane.scrollHeight - previewPane.clientHeight);
120
- });
121
- }
122
-
123
- addToolbar() {
124
- new Toolbar(this, this.options.toolbar || ['bold', 'italic', 'strikethrough']);
125
- }
126
-
127
- insertText(text) {
128
- const { selectionStart, selectionEnd } = this.usertextarea;
129
- const value = this.usertextarea.value;
130
- this.usertextarea.value = `${value.substring(0, selectionStart)}${text}${value.substring(selectionEnd)}`;
131
- this.usertextarea.focus();
132
- this.usertextarea.setSelectionRange(selectionStart, selectionStart + text.length);
133
- this.render();
134
- }
135
-
136
- render() {
137
- const html = marked(this.usertextarea.value);
138
- this.previewContent.innerHTML = html;
139
- }
140
- }
141
-
1
+ // #markdown\editor.js
2
+ import './styles/main.css';
3
+ import { marked } from 'marked';
4
+ import Toolbar from './Toolbar/index.js';
5
+ import Preview from './preview.js';
6
+
7
+ marked.setOptions({
8
+ breaks: true
9
+ });
10
+
11
+ class MarkdownEditor {
12
+ constructor(selector, options = {}) {
13
+ this.usertextarea = typeof selector === 'string' ? document.querySelector(selector) : selector;
14
+ this.options = options;
15
+ this.preview = this.options.toolbar.includes('preview');
16
+ this.init();
17
+ }
18
+
19
+ init() {
20
+ this.createEditor();
21
+ if (this.options.toolbar) this.addToolbar();
22
+ }
23
+
24
+ createEditor() {
25
+ if (!this.isTextareaValid()) return;
26
+
27
+ this.applyDefaultAttributes();
28
+ this.buildEditorLayout();
29
+ this.addInputListener();
30
+ this.render();
31
+ }
32
+
33
+ isTextareaValid() {
34
+ return this.usertextarea.tagName === 'TEXTAREA';
35
+ }
36
+
37
+ applyDefaultAttributes() {
38
+ this.usertextarea.classList.add(
39
+ "focus:outline-0",
40
+ "border-0",
41
+ "p-1.5",
42
+ "max-w-full",
43
+ "size-full",
44
+ "bg-transparent",
45
+ "outline-0",
46
+ "appearance-none",
47
+ "prose",
48
+ "prose-sm",
49
+ "md:prose-base",
50
+ "dark:prose-invert",
51
+ "text-stone-700",
52
+ "dark:text-stone-200",
53
+ "overflow-y-auto"
54
+ );
55
+ if (!this.usertextarea.hasAttribute('placeholder')) {
56
+ this.usertextarea.placeholder = this.options.placeholder || 'Write your markdown...';
57
+ }
58
+ }
59
+
60
+ buildEditorLayout() {
61
+ this.editorContainer = document.createElement('div');
62
+ this.editorContainer.className = `
63
+ markdown-editor-wrapper
64
+ border border-stone-200
65
+ dark:border-stone-700
66
+ rounded-md
67
+ overflow-hidden
68
+ `;
69
+ this.usertextarea.parentNode.insertBefore(this.editorContainer, this.usertextarea);
70
+
71
+ this.markdownEditorDiv = document.createElement('div');
72
+ this.markdownEditorDiv.className = `editor-layout`;
73
+ this.editorContainer.appendChild(this.markdownEditorDiv);
74
+
75
+ this.addTextareaWrapper();
76
+ if (this.preview) this.addPreviewWrapper();
77
+ }
78
+
79
+ addTextareaWrapper() {
80
+ const textareaContainer = document.createElement('div');
81
+ textareaContainer.className = `
82
+ textarea-wrapper
83
+ p-2
84
+ bg-white
85
+ dark:bg-stone-800
86
+ grid
87
+ after:px-3.5
88
+ after:py-2.5
89
+ after:text-inherit
90
+ [&>textarea]:resize-none
91
+ [&>textarea]:[grid-area:1/1/2/2]
92
+ after:[grid-area:1/1/2/2]
93
+ after:whitespace-pre-wrap
94
+ after:invisible
95
+ after:content-[attr(data-cloned-val)_'_']
96
+ after:border
97
+ `;
98
+ textareaContainer.appendChild(this.usertextarea);
99
+ this.markdownEditorDiv.appendChild(textareaContainer);
100
+ }
101
+
102
+
103
+
104
+ addPreviewWrapper() {
105
+ const preview = new Preview(this.markdownEditorDiv);
106
+ this.previewContent = preview.getPreviewContent();
107
+ }
108
+
109
+ addInputListener() {
110
+ this.usertextarea.addEventListener('input', () => this.render());
111
+ this.usertextarea.addEventListener('scroll', () => {
112
+ const textarea = this.usertextarea;
113
+ const previewPane = this.previewContent;
114
+
115
+ // Calculate the proportion of the textarea that has been scrolled
116
+ const textareaScrollRatio = textarea.scrollTop / (textarea.scrollHeight - textarea.clientHeight);
117
+
118
+ // Apply the same scroll ratio to the preview pane
119
+ previewPane.scrollTop = textareaScrollRatio * (previewPane.scrollHeight - previewPane.clientHeight);
120
+ });
121
+ }
122
+
123
+ addToolbar() {
124
+ new Toolbar(this, this.options.toolbar || ['bold', 'italic', 'strikethrough']);
125
+ }
126
+
127
+ insertText(text) {
128
+ const { selectionStart, selectionEnd } = this.usertextarea;
129
+ const value = this.usertextarea.value;
130
+ this.usertextarea.value = `${value.substring(0, selectionStart)}${text}${value.substring(selectionEnd)}`;
131
+ this.usertextarea.focus();
132
+ this.usertextarea.setSelectionRange(selectionStart, selectionStart + text.length);
133
+
134
+ // Scroll the textarea to the inserted text
135
+ this.scrollToView();
136
+
137
+ this.render();
138
+ }
139
+
140
+ scrollToView() {
141
+ const textarea = this.usertextarea;
142
+
143
+ // Calculate the position of the inserted text
144
+ const selectionStart = textarea.selectionStart;
145
+
146
+ // Get the line height (height of each row of text)
147
+ const lineHeight = parseInt(window.getComputedStyle(textarea).lineHeight);
148
+
149
+ // Get how many rows fit into the visible area of the textarea
150
+ const rowsInView = Math.floor(textarea.clientHeight / lineHeight);
151
+
152
+ // Calculate the current line number of the selectionStart
153
+ const currentLine = Math.floor(selectionStart / textarea.cols);
154
+
155
+ // Scroll to the line number that places the inserted text in the center
156
+ const targetScrollTop = (currentLine - Math.floor(rowsInView / 2)) * lineHeight;
157
+
158
+ // Adjust scrollTop to center the cursor's line in the view
159
+ textarea.scrollTop = targetScrollTop;
160
+ }
161
+
162
+
163
+ render() {
164
+ const html = marked(this.usertextarea.value);
165
+ this.previewContent.innerHTML = html;
166
+ }
167
+ }
168
+
142
169
  export default MarkdownEditor;
@@ -1,17 +1,17 @@
1
- // markdown\preview.js
2
- class Preview {
3
- constructor(container) {
4
- this.previewContainer = document.createElement('div');
5
- this.previewContainer.className = 'preview-wrapper bg-white dark:bg-stone-800 p-2 hidden';
6
- this.previewContent = document.createElement('div');
7
- this.previewContent.className = 'preview-content prose prose-sm md:prose-base dark:prose-invert p-1.5 overflow-y-auto h-[90lvh] max-w-max';
8
- this.previewContainer.appendChild(this.previewContent);
9
- container.appendChild(this.previewContainer);
10
- }
11
-
12
- getPreviewContent() {
13
- return this.previewContent;
14
- }
15
- }
16
-
1
+ // markdown\preview.js
2
+ class Preview {
3
+ constructor(container) {
4
+ this.previewContainer = document.createElement('div');
5
+ this.previewContainer.className = 'preview-wrapper bg-white dark:bg-stone-800 p-2 hidden';
6
+ this.previewContent = document.createElement('div');
7
+ this.previewContent.className = 'preview-content prose prose-sm md:prose-base dark:prose-invert p-1.5 overflow-y-auto h-[90lvh] max-w-max';
8
+ this.previewContainer.appendChild(this.previewContent);
9
+ container.appendChild(this.previewContainer);
10
+ }
11
+
12
+ getPreviewContent() {
13
+ return this.previewContent;
14
+ }
15
+ }
16
+
17
17
  export default Preview;
@@ -1,3 +1,3 @@
1
- @tailwind base;
2
- @tailwind components;
1
+ @tailwind base;
2
+ @tailwind components;
3
3
  @tailwind utilities;
@@ -1,7 +1,7 @@
1
- // utils/markdownUtils.js
2
-
3
- import { marked } from 'marked';
4
-
5
- export function renderMarkdown(content) {
6
- return marked(content);
7
- }
1
+ // utils/markdownUtils.js
2
+
3
+ import { marked } from 'marked';
4
+
5
+ export function renderMarkdown(content) {
6
+ return marked(content);
7
+ }