markdown-text-editor 0.0.17-beta.1 → 0.0.18-beta.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,140 +1,140 @@
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
- "p-1.5",
40
- "max-w-full",
41
- "size-full",
42
- "bg-transparent",
43
- "outline-0",
44
- "appearance-none",
45
- "prose",
46
- "prose-sm",
47
- "md:prose-base",
48
- "dark:prose-invert",
49
- "text-stone-700",
50
- "dark:text-stone-200",
51
- "overflow-y-auto"
52
- );
53
- if (!this.usertextarea.hasAttribute('placeholder')) {
54
- this.usertextarea.placeholder = this.options.placeholder || 'Write your markdown...';
55
- }
56
- }
57
-
58
- buildEditorLayout() {
59
- this.editorContainer = document.createElement('div');
60
- this.editorContainer.className = `
61
- markdown-editor-wrapper
62
- border border-stone-200
63
- dark:border-stone-700
64
- rounded-md
65
- overflow-hidden
66
- `;
67
- this.usertextarea.parentNode.insertBefore(this.editorContainer, this.usertextarea);
68
-
69
- this.markdownEditorDiv = document.createElement('div');
70
- this.markdownEditorDiv.className = `editor-layout`;
71
- this.editorContainer.appendChild(this.markdownEditorDiv);
72
-
73
- this.addTextareaWrapper();
74
- if (this.preview) this.addPreviewWrapper();
75
- }
76
-
77
- addTextareaWrapper() {
78
- const textareaContainer = document.createElement('div');
79
- textareaContainer.className = `
80
- textarea-wrapper
81
- p-2
82
- bg-white
83
- dark:bg-stone-800
84
- grid
85
- after:px-3.5
86
- after:py-2.5
87
- after:text-inherit
88
- [&>textarea]:resize-none
89
- [&>textarea]:[grid-area:1/1/2/2]
90
- after:[grid-area:1/1/2/2]
91
- after:whitespace-pre-wrap
92
- after:invisible
93
- after:content-[attr(data-cloned-val)_'_']
94
- after:border
95
- `;
96
- textareaContainer.appendChild(this.usertextarea);
97
- this.markdownEditorDiv.appendChild(textareaContainer);
98
- }
99
-
100
-
101
-
102
- addPreviewWrapper() {
103
- const preview = new Preview(this.markdownEditorDiv);
104
- this.previewContent = preview.getPreviewContent();
105
- }
106
-
107
- addInputListener() {
108
- this.usertextarea.addEventListener('input', () => this.render());
109
- this.usertextarea.addEventListener('scroll', () => {
110
- const textarea = this.usertextarea;
111
- const previewPane = this.previewContent;
112
-
113
- // Calculate the proportion of the textarea that has been scrolled
114
- const textareaScrollRatio = textarea.scrollTop / (textarea.scrollHeight - textarea.clientHeight);
115
-
116
- // Apply the same scroll ratio to the preview pane
117
- previewPane.scrollTop = textareaScrollRatio * (previewPane.scrollHeight - previewPane.clientHeight);
118
- });
119
- }
120
-
121
- addToolbar() {
122
- new Toolbar(this, this.options.toolbar || ['bold', 'italic', 'strikethrough']);
123
- }
124
-
125
- insertText(text) {
126
- const { selectionStart, selectionEnd } = this.usertextarea;
127
- const value = this.usertextarea.value;
128
- this.usertextarea.value = `${value.substring(0, selectionStart)}${text}${value.substring(selectionEnd)}`;
129
- this.usertextarea.focus();
130
- this.usertextarea.setSelectionRange(selectionStart, selectionStart + text.length);
131
- this.render();
132
- }
133
-
134
- render() {
135
- const html = marked(this.usertextarea.value);
136
- this.previewContent.innerHTML = html;
137
- }
138
- }
139
-
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
+ "p-1.5",
40
+ "max-w-full",
41
+ "size-full",
42
+ "bg-transparent",
43
+ "outline-0",
44
+ "appearance-none",
45
+ "prose",
46
+ "prose-sm",
47
+ "md:prose-base",
48
+ "dark:prose-invert",
49
+ "text-stone-700",
50
+ "dark:text-stone-200",
51
+ "overflow-y-auto"
52
+ );
53
+ if (!this.usertextarea.hasAttribute('placeholder')) {
54
+ this.usertextarea.placeholder = this.options.placeholder || 'Write your markdown...';
55
+ }
56
+ }
57
+
58
+ buildEditorLayout() {
59
+ this.editorContainer = document.createElement('div');
60
+ this.editorContainer.className = `
61
+ markdown-editor-wrapper
62
+ border border-stone-200
63
+ dark:border-stone-700
64
+ rounded-md
65
+ overflow-hidden
66
+ `;
67
+ this.usertextarea.parentNode.insertBefore(this.editorContainer, this.usertextarea);
68
+
69
+ this.markdownEditorDiv = document.createElement('div');
70
+ this.markdownEditorDiv.className = `editor-layout`;
71
+ this.editorContainer.appendChild(this.markdownEditorDiv);
72
+
73
+ this.addTextareaWrapper();
74
+ if (this.preview) this.addPreviewWrapper();
75
+ }
76
+
77
+ addTextareaWrapper() {
78
+ const textareaContainer = document.createElement('div');
79
+ textareaContainer.className = `
80
+ textarea-wrapper
81
+ p-2
82
+ bg-white
83
+ dark:bg-stone-800
84
+ grid
85
+ after:px-3.5
86
+ after:py-2.5
87
+ after:text-inherit
88
+ [&>textarea]:resize-none
89
+ [&>textarea]:[grid-area:1/1/2/2]
90
+ after:[grid-area:1/1/2/2]
91
+ after:whitespace-pre-wrap
92
+ after:invisible
93
+ after:content-[attr(data-cloned-val)_'_']
94
+ after:border
95
+ `;
96
+ textareaContainer.appendChild(this.usertextarea);
97
+ this.markdownEditorDiv.appendChild(textareaContainer);
98
+ }
99
+
100
+
101
+
102
+ addPreviewWrapper() {
103
+ const preview = new Preview(this.markdownEditorDiv);
104
+ this.previewContent = preview.getPreviewContent();
105
+ }
106
+
107
+ addInputListener() {
108
+ this.usertextarea.addEventListener('input', () => this.render());
109
+ this.usertextarea.addEventListener('scroll', () => {
110
+ const textarea = this.usertextarea;
111
+ const previewPane = this.previewContent;
112
+
113
+ // Calculate the proportion of the textarea that has been scrolled
114
+ const textareaScrollRatio = textarea.scrollTop / (textarea.scrollHeight - textarea.clientHeight);
115
+
116
+ // Apply the same scroll ratio to the preview pane
117
+ previewPane.scrollTop = textareaScrollRatio * (previewPane.scrollHeight - previewPane.clientHeight);
118
+ });
119
+ }
120
+
121
+ addToolbar() {
122
+ new Toolbar(this, this.options.toolbar || ['bold', 'italic', 'strikethrough']);
123
+ }
124
+
125
+ insertText(text) {
126
+ const { selectionStart, selectionEnd } = this.usertextarea;
127
+ const value = this.usertextarea.value;
128
+ this.usertextarea.value = `${value.substring(0, selectionStart)}${text}${value.substring(selectionEnd)}`;
129
+ this.usertextarea.focus();
130
+ this.usertextarea.setSelectionRange(selectionStart, selectionStart + text.length);
131
+ this.render();
132
+ }
133
+
134
+ render() {
135
+ const html = marked(this.usertextarea.value);
136
+ this.previewContent.innerHTML = html;
137
+ }
138
+ }
139
+
140
140
  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-lvh 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-lvh 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
+ }