editium 1.0.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.
@@ -0,0 +1,69 @@
1
+ # Editium Vanilla JavaScript Example
2
+
3
+ This folder contains a complete demo/example of how to use Editium in a vanilla JavaScript environment.
4
+
5
+ ## Files
6
+
7
+ - **index.html** - Main demo page showcasing Editium features and installation methods
8
+ - **demo.css** - Styles for the demo page (not required for Editium itself)
9
+ - **demo.js** - Demo page functionality and example code
10
+
11
+ ## Running the Example
12
+
13
+ ### Option 1: Open Directly
14
+ Simply open `index.html` in your web browser.
15
+
16
+ ### Option 2: Local Server
17
+ For a better experience, serve the files using a local server:
18
+
19
+ ```bash
20
+ # Using Python
21
+ python -m http.server 8080
22
+
23
+ # Using Node.js http-server
24
+ npx http-server
25
+
26
+ # Using PHP
27
+ php -S localhost:8080
28
+ ```
29
+
30
+ Then visit `http://localhost:8080` in your browser.
31
+
32
+ ## What's Included
33
+
34
+ The demo page shows:
35
+ - ✅ Full-featured text editor with all toolbar options
36
+ - ✅ Installation instructions (NPM, Yarn, PNPM, CDN)
37
+ - ✅ Usage examples for both Vanilla JS and React
38
+ - ✅ Live interactive demo
39
+ - ✅ Single-file bundle option (recommended)
40
+ - ✅ Separate files option (more control)
41
+
42
+ ## Quick Start
43
+
44
+ The simplest way to use Editium:
45
+
46
+ ```html
47
+ <!DOCTYPE html>
48
+ <html>
49
+ <head>
50
+ <script src="https://unpkg.com/editium/vanilla/editium.bundle.js"></script>
51
+ </head>
52
+ <body>
53
+ <div id="editor"></div>
54
+ <script>
55
+ const editor = new Editium({
56
+ container: document.getElementById('editor'),
57
+ placeholder: 'Start typing...',
58
+ toolbar: 'all'
59
+ });
60
+ </script>
61
+ </body>
62
+ </html>
63
+ ```
64
+
65
+ ## Learn More
66
+
67
+ - [Main Documentation](../README.md)
68
+ - [NPM Package](https://www.npmjs.com/package/editium)
69
+ - [GitHub Repository](https://github.com/NabarupDev/Editium)
@@ -0,0 +1,351 @@
1
+ * {
2
+ margin: 0;
3
+ padding: 0;
4
+ box-sizing: border-box;
5
+ }
6
+
7
+ body {
8
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
9
+ background: #ffffff;
10
+ min-height: 100vh;
11
+ padding: 20px;
12
+ color: #333;
13
+ }
14
+
15
+ .container {
16
+ max-width: 1200px;
17
+ margin: 0 auto;
18
+ }
19
+
20
+ header {
21
+ text-align: center;
22
+ margin-bottom: 30px;
23
+ padding: 20px 0;
24
+ }
25
+
26
+ header h1 {
27
+ font-size: 2.5em;
28
+ margin-bottom: 0;
29
+ color: #333;
30
+ font-weight: 600;
31
+ letter-spacing: -0.02em;
32
+ }
33
+
34
+ .demo-section {
35
+ margin-bottom: 30px;
36
+ }
37
+
38
+ .demo-section h2 {
39
+ margin-bottom: 10px;
40
+ color: #555;
41
+ font-size: 1.4em;
42
+ font-weight: 500;
43
+ }
44
+
45
+ #editor {
46
+ margin-bottom: 20px;
47
+ }
48
+
49
+ .installation-section {
50
+ margin-top: 60px;
51
+ margin-bottom: 40px;
52
+ padding: 40px 30px;
53
+ background-color: #fafafa;
54
+ border-radius: 12px;
55
+ border: 1px solid #e5e5e5;
56
+ }
57
+
58
+ .installation-section h2 {
59
+ color: #000;
60
+ font-size: 28px;
61
+ font-weight: 600;
62
+ margin-bottom: 12px;
63
+ letter-spacing: -0.02em;
64
+ }
65
+
66
+ .installation-section > p {
67
+ color: #666;
68
+ font-size: 16px;
69
+ line-height: 1.6;
70
+ margin-bottom: 30px;
71
+ font-weight: 400;
72
+ }
73
+
74
+ /* Tab Container */
75
+ .tab-container {
76
+ background-color: #ffffff;
77
+ border-radius: 12px;
78
+ border: 1px solid #e0e0e0;
79
+ overflow: hidden;
80
+ margin-bottom: 30px;
81
+ }
82
+
83
+ /* Tab Headers */
84
+ .tab-headers {
85
+ display: flex;
86
+ border-bottom: 1px solid #e0e0e0;
87
+ background-color: #fafafa;
88
+ }
89
+
90
+ .tab-btn {
91
+ padding: 10px 20px;
92
+ background: transparent;
93
+ color: #666;
94
+ border: none;
95
+ border-bottom: 2px solid transparent;
96
+ cursor: pointer;
97
+ font-size: 14px;
98
+ font-weight: 500;
99
+ transition: all 0.2s;
100
+ outline: none;
101
+ }
102
+
103
+ .tab-btn:hover {
104
+ color: #333;
105
+ }
106
+
107
+ .tab-btn.active {
108
+ background: #2d2d2d;
109
+ color: #fff;
110
+ border-bottom: 2px solid #0066ff;
111
+ }
112
+
113
+ /* Tab Content */
114
+ .tab-content {
115
+ padding: 24px;
116
+ }
117
+
118
+ .tab-pane {
119
+ display: none;
120
+ }
121
+
122
+ .tab-pane.active {
123
+ display: block;
124
+ }
125
+
126
+ /* CDN Sub-tabs */
127
+ .cdn-subtabs {
128
+ display: flex;
129
+ gap: 12px;
130
+ margin-bottom: 20px;
131
+ border-bottom: 1px solid #e0e0e0;
132
+ padding-bottom: 8px;
133
+ }
134
+
135
+ .cdn-subtab-btn {
136
+ padding: 6px 16px;
137
+ background: transparent;
138
+ border: 1px solid transparent;
139
+ border-radius: 6px;
140
+ cursor: pointer;
141
+ font-size: 13px;
142
+ font-weight: 500;
143
+ color: #666;
144
+ transition: all 0.2s;
145
+ }
146
+
147
+ .cdn-subtab-btn.active {
148
+ background: #f0f0f0;
149
+ border: 1px solid #d0d0d0;
150
+ color: #000;
151
+ }
152
+
153
+ .cdn-tab-pane {
154
+ display: none;
155
+ }
156
+
157
+ .cdn-tab-pane.active {
158
+ display: block;
159
+ }
160
+
161
+ /* Usage Tab Headers */
162
+ .usage-tab-headers {
163
+ display: flex;
164
+ justify-content: space-between;
165
+ align-items: center;
166
+ border-bottom: 1px solid #e0e0e0;
167
+ background-color: #fafafa;
168
+ padding: 0 20px;
169
+ }
170
+
171
+ .usage-pane {
172
+ display: none;
173
+ }
174
+
175
+ .usage-pane.active {
176
+ display: block;
177
+ }
178
+
179
+ .code-block {
180
+ position: relative;
181
+ background-color: #1e1e1e;
182
+ border-radius: 8px;
183
+ padding: 16px 20px;
184
+ margin-bottom: 12px;
185
+ display: flex;
186
+ justify-content: space-between;
187
+ align-items: center;
188
+ border: 1px solid #333;
189
+ }
190
+
191
+ .code-block code {
192
+ color: #d4d4d4;
193
+ font-size: 14px;
194
+ font-family: Monaco, "Courier New", monospace;
195
+ font-weight: 400;
196
+ word-break: break-all;
197
+ }
198
+
199
+ .copy-btn {
200
+ background: #2d2d2d;
201
+ border: 1px solid #444;
202
+ border-radius: 6px;
203
+ padding: 6px 12px;
204
+ color: #d4d4d4;
205
+ font-size: 12px;
206
+ cursor: pointer;
207
+ transition: all 0.2s;
208
+ font-weight: 500;
209
+ min-width: 70px;
210
+ margin-left: 12px;
211
+ flex-shrink: 0;
212
+ }
213
+
214
+ .copy-btn:hover {
215
+ background: #383838;
216
+ border-color: #555;
217
+ }
218
+
219
+ /* Usage Pre and Code */
220
+ .usage-pane pre {
221
+ background-color: #1e1e1e;
222
+ border-radius: 6px;
223
+ padding: 16px;
224
+ overflow: auto;
225
+ margin: 0;
226
+ }
227
+
228
+ .usage-pane code {
229
+ color: #d4d4d4;
230
+ font-size: 13px;
231
+ font-family: Monaco, "Courier New", monospace;
232
+ line-height: 1.6;
233
+ }
234
+
235
+ footer {
236
+ margin-top: 80px;
237
+ padding: 50px 20px;
238
+ background-color: #ffffff;
239
+ border-top: 1px solid #eaeaea;
240
+ }
241
+
242
+ .footer-content {
243
+ max-width: 1200px;
244
+ margin: 0 auto;
245
+ display: flex;
246
+ justify-content: space-between;
247
+ align-items: flex-start;
248
+ flex-wrap: wrap;
249
+ gap: 40px;
250
+ }
251
+
252
+ .footer-brand {
253
+ flex: 1;
254
+ min-width: 200px;
255
+ }
256
+
257
+ .footer-brand h3 {
258
+ color: #000;
259
+ margin-bottom: 8px;
260
+ font-size: 18px;
261
+ font-weight: 500;
262
+ letter-spacing: -0.02em;
263
+ }
264
+
265
+ .footer-brand p {
266
+ color: #666;
267
+ font-size: 14px;
268
+ line-height: 1.5;
269
+ font-weight: 400;
270
+ margin: 0;
271
+ }
272
+
273
+ .footer-links h4 {
274
+ color: #000;
275
+ font-size: 13px;
276
+ font-weight: 500;
277
+ margin-bottom: 12px;
278
+ text-transform: uppercase;
279
+ letter-spacing: 0.05em;
280
+ }
281
+
282
+ .footer-links-list {
283
+ display: flex;
284
+ flex-direction: column;
285
+ gap: 8px;
286
+ }
287
+
288
+ .footer-links a {
289
+ color: #666;
290
+ text-decoration: none;
291
+ font-size: 14px;
292
+ font-weight: 400;
293
+ transition: color 0.2s;
294
+ }
295
+
296
+ .footer-links a:hover {
297
+ color: #000;
298
+ }
299
+
300
+ .footer-bottom {
301
+ max-width: 1200px;
302
+ margin: 40px auto 0;
303
+ padding-top: 30px;
304
+ border-top: 1px solid #eaeaea;
305
+ display: flex;
306
+ justify-content: space-between;
307
+ align-items: center;
308
+ flex-wrap: wrap;
309
+ gap: 20px;
310
+ }
311
+
312
+ .footer-bottom p {
313
+ color: #999;
314
+ font-size: 13px;
315
+ margin: 0;
316
+ font-weight: 400;
317
+ }
318
+
319
+ .footer-bottom a {
320
+ color: #666;
321
+ text-decoration: none;
322
+ font-weight: 400;
323
+ transition: color 0.2s;
324
+ }
325
+
326
+ .footer-bottom a:hover {
327
+ color: #000;
328
+ }
329
+
330
+ @media (max-width: 768px) {
331
+ header h1 {
332
+ font-size: 2em;
333
+ }
334
+
335
+ .installation-section {
336
+ padding: 30px 20px;
337
+ }
338
+
339
+ .installation-section h2 {
340
+ font-size: 24px;
341
+ }
342
+
343
+ .footer-content {
344
+ flex-direction: column;
345
+ }
346
+
347
+ .footer-bottom {
348
+ flex-direction: column;
349
+ text-align: center;
350
+ }
351
+ }
@@ -0,0 +1,122 @@
1
+ const usageCodeVanilla = `const editor = new Editium({
2
+ container: document.getElementById('editor'),
3
+ placeholder: 'Start typing...',
4
+ toolbar: 'all',
5
+ height: '300px',
6
+ minHeight: '200px',
7
+ maxHeight: '400px',
8
+ showWordCount: true,
9
+ onChange: (data) => {
10
+ console.log(data.html, data.json);
11
+ }
12
+ });`;
13
+
14
+ const usageCodeReact = `import { Editium } from 'editium';
15
+
16
+ function App() {
17
+ return (
18
+ <Editium
19
+ initialValue={[]}
20
+ toolbar="all"
21
+ placeholder="Start typing..."
22
+ height="300px"
23
+ minHeight="200px"
24
+ maxHeight="400px"
25
+ showWordCount={false}
26
+ onChange={(html, json) => {
27
+ console.log(html, json);
28
+ }}
29
+ />
30
+ );
31
+ }`;
32
+
33
+ document.getElementById('year').textContent = new Date().getFullYear();
34
+
35
+ // Tab switching functions
36
+ function switchInstallTab(event, tabName) {
37
+ // Remove active class from all tab buttons
38
+ const tabButtons = event.target.parentElement.querySelectorAll('.tab-btn');
39
+ tabButtons.forEach(btn => btn.classList.remove('active'));
40
+
41
+ // Add active class to clicked button
42
+ event.target.classList.add('active');
43
+
44
+ // Hide all tab panes
45
+ const tabPanes = event.target.closest('.tab-container').querySelectorAll('.tab-pane');
46
+ tabPanes.forEach(pane => pane.classList.remove('active'));
47
+
48
+ // Show selected tab pane
49
+ document.getElementById(`${tabName}-tab`).classList.add('active');
50
+ }
51
+
52
+ function switchCdnTab(event, tabName) {
53
+ // Remove active class from all CDN sub-tab buttons
54
+ const cdnButtons = event.target.parentElement.querySelectorAll('.cdn-subtab-btn');
55
+ cdnButtons.forEach(btn => btn.classList.remove('active'));
56
+
57
+ // Add active class to clicked button
58
+ event.target.classList.add('active');
59
+
60
+ // Hide all CDN tab panes
61
+ const cdnPanes = event.target.closest('#cdn-tab').querySelectorAll('.cdn-tab-pane');
62
+ cdnPanes.forEach(pane => pane.classList.remove('active'));
63
+
64
+ // Show selected CDN tab pane
65
+ document.getElementById(`${tabName}-tab`).classList.add('active');
66
+ }
67
+
68
+ function switchUsageTab(event, tabName) {
69
+ // Remove active class from all usage tab buttons
70
+ const tabButtons = event.target.parentElement.querySelectorAll('.tab-btn');
71
+ tabButtons.forEach(btn => btn.classList.remove('active'));
72
+
73
+ // Add active class to clicked button
74
+ event.target.classList.add('active');
75
+
76
+ // Hide all usage panes
77
+ const usagePanes = event.target.closest('.tab-container').querySelectorAll('.usage-pane');
78
+ usagePanes.forEach(pane => pane.classList.remove('active'));
79
+
80
+ // Show selected usage pane
81
+ document.getElementById(`${tabName}-tab`).classList.add('active');
82
+ }
83
+
84
+ function copyUsageCode(button) {
85
+ // Determine which tab is active
86
+ const reactTab = document.getElementById('react-tab');
87
+ const isReact = reactTab.classList.contains('active');
88
+ const code = isReact ? usageCodeReact : usageCodeVanilla;
89
+
90
+ copyToClipboard(code, button);
91
+ }
92
+
93
+ async function copyToClipboard(text, button) {
94
+ try {
95
+ await navigator.clipboard.writeText(text);
96
+ const originalText = button.textContent;
97
+ button.textContent = '✓ Copied';
98
+ setTimeout(() => {
99
+ button.textContent = originalText;
100
+ }, 2000);
101
+ } catch (err) {
102
+ console.error('Failed to copy:', err);
103
+ alert('Failed to copy to clipboard');
104
+ }
105
+ }
106
+
107
+ const editor = new Editium({
108
+ container: document.getElementById('editor'),
109
+ placeholder: 'Experience the full power of rich text editing...',
110
+ toolbar: 'all',
111
+ showWordCount: true,
112
+ height: '300px',
113
+ minHeight: '200px',
114
+ maxHeight: '400px',
115
+ onImageUpload: async (file) => {
116
+ return new Promise((resolve) => {
117
+ const reader = new FileReader();
118
+ reader.onload = (e) => resolve(e.target.result);
119
+ reader.readAsDataURL(file);
120
+ });
121
+ }
122
+ });