Harry00 commited on
Commit
edb4184
·
verified ·
1 Parent(s): 71bbda8

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +797 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Notion
3
- emoji: 👁
4
- colorFrom: yellow
5
- colorTo: indigo
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: notion
3
+ emoji: 🐳
4
+ colorFrom: pink
5
+ colorTo: red
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,797 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en" class="dark">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Notion Lite</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <script>
10
+ tailwind.config = {
11
+ darkMode: 'class',
12
+ theme: {
13
+ extend: {
14
+ colors: {
15
+ primary: {
16
+ 50: '#f0f9ff',
17
+ 100: '#e0f2fe',
18
+ 200: '#bae6fd',
19
+ 300: '#7dd3fc',
20
+ 400: '#38bdf8',
21
+ 500: '#0ea5e9',
22
+ 600: '#0284c7',
23
+ 700: '#0369a1',
24
+ 800: '#075985',
25
+ 900: '#0c4a6e',
26
+ },
27
+ dark: {
28
+ 800: '#1e293b',
29
+ 900: '#0f172a',
30
+ }
31
+ },
32
+ animation: {
33
+ 'fade-in': 'fadeIn 0.3s ease-in-out',
34
+ 'slide-in': 'slideIn 0.2s ease-out',
35
+ },
36
+ keyframes: {
37
+ fadeIn: {
38
+ '0%': { opacity: '0' },
39
+ '100%': { opacity: '1' },
40
+ },
41
+ slideIn: {
42
+ '0%': { transform: 'translateX(20px)', opacity: '0' },
43
+ '100%': { transform: 'translateX(0)', opacity: '1' },
44
+ }
45
+ }
46
+ }
47
+ }
48
+ }
49
+ </script>
50
+ <style>
51
+ .ProseMirror {
52
+ min-height: 100px;
53
+ padding: 10px;
54
+ outline: none;
55
+ }
56
+ .ProseMirror:focus {
57
+ outline: none;
58
+ }
59
+ .ProseMirror p {
60
+ margin-bottom: 1rem;
61
+ }
62
+ .ProseMirror h1 {
63
+ font-size: 2rem;
64
+ font-weight: bold;
65
+ margin: 1rem 0;
66
+ }
67
+ .ProseMirror h2 {
68
+ font-size: 1.5rem;
69
+ font-weight: bold;
70
+ margin: 0.75rem 0;
71
+ }
72
+ .ProseMirror h3 {
73
+ font-size: 1.25rem;
74
+ font-weight: bold;
75
+ margin: 0.5rem 0;
76
+ }
77
+ .ProseMirror ul, .ProseMirror ol {
78
+ padding-left: 1.5rem;
79
+ margin-bottom: 1rem;
80
+ }
81
+ .ProseMirror ul {
82
+ list-style-type: disc;
83
+ }
84
+ .ProseMirror ol {
85
+ list-style-type: decimal;
86
+ }
87
+ .ProseMirror blockquote {
88
+ border-left: 3px solid #94a3b8;
89
+ padding-left: 1rem;
90
+ margin: 1rem 0;
91
+ color: #64748b;
92
+ }
93
+ .ProseMirror pre {
94
+ background: #1e293b;
95
+ color: #f8fafc;
96
+ padding: 1rem;
97
+ border-radius: 0.5rem;
98
+ margin: 1rem 0;
99
+ overflow-x: auto;
100
+ }
101
+ .ProseMirror code {
102
+ background: #e2e8f0;
103
+ padding: 0.2rem 0.4rem;
104
+ border-radius: 0.25rem;
105
+ font-family: monospace;
106
+ }
107
+ .ProseMirror table {
108
+ border-collapse: collapse;
109
+ margin: 1rem 0;
110
+ width: 100%;
111
+ }
112
+ .ProseMirror th, .ProseMirror td {
113
+ border: 1px solid #cbd5e1;
114
+ padding: 0.5rem;
115
+ }
116
+ .ProseMirror th {
117
+ background-color: #f1f5f9;
118
+ }
119
+ .ProseMirror img {
120
+ max-width: 100%;
121
+ height: auto;
122
+ margin: 1rem 0;
123
+ border-radius: 0.5rem;
124
+ }
125
+ .ProseMirror a {
126
+ color: #3b82f6;
127
+ text-decoration: underline;
128
+ }
129
+ .ProseMirror .task-item {
130
+ display: flex;
131
+ align-items: center;
132
+ margin-bottom: 0.5rem;
133
+ }
134
+ .ProseMirror .task-item input[type="checkbox"] {
135
+ margin-right: 0.5rem;
136
+ }
137
+ .ProseMirror .task-item.checked {
138
+ color: #64748b;
139
+ text-decoration: line-through;
140
+ }
141
+ .custom-scrollbar::-webkit-scrollbar {
142
+ width: 6px;
143
+ height: 6px;
144
+ }
145
+ .custom-scrollbar::-webkit-scrollbar-track {
146
+ background: #f1f5f9;
147
+ }
148
+ .custom-scrollbar::-webkit-scrollbar-thumb {
149
+ background: #cbd5e1;
150
+ border-radius: 3px;
151
+ }
152
+ .dark .custom-scrollbar::-webkit-scrollbar-track {
153
+ background: #1e293b;
154
+ }
155
+ .dark .custom-scrollbar::-webkit-scrollbar-thumb {
156
+ background: #475569;
157
+ }
158
+ .resize-handle {
159
+ position: absolute;
160
+ right: 0;
161
+ top: 0;
162
+ bottom: 0;
163
+ width: 4px;
164
+ background: #cbd5e1;
165
+ cursor: col-resize;
166
+ transition: background 0.2s;
167
+ }
168
+ .resize-handle:hover {
169
+ background: #94a3b8;
170
+ }
171
+ .dark .resize-handle {
172
+ background: #475569;
173
+ }
174
+ .dark .resize-handle:hover {
175
+ background: #64748b;
176
+ }
177
+ .floating-toolbar {
178
+ opacity: 0;
179
+ transform: translateY(10px);
180
+ transition: opacity 0.2s, transform 0.2s;
181
+ }
182
+ .floating-toolbar.visible {
183
+ opacity: 1;
184
+ transform: translateY(0);
185
+ }
186
+ .slate-insert-menu {
187
+ opacity: 0;
188
+ transform: translateY(10px);
189
+ transition: opacity 0.2s, transform 0.2s;
190
+ pointer-events: none;
191
+ }
192
+ .slate-insert-menu.visible {
193
+ opacity: 1;
194
+ transform: translateY(0);
195
+ pointer-events: all;
196
+ }
197
+ </style>
198
+ </head>
199
+ <body class="bg-gray-50 dark:bg-dark-900 text-gray-800 dark:text-gray-200 transition-colors duration-200 min-h-screen flex">
200
+ <!-- Sidebar -->
201
+ <div class="w-64 bg-white dark:bg-dark-800 border-r border-gray-200 dark:border-gray-700 flex flex-col h-screen sticky top-0">
202
+ <div class="p-4 border-b border-gray-200 dark:border-gray-700 flex items-center justify-between">
203
+ <div class="flex items-center space-x-2">
204
+ <div class="w-8 h-8 rounded-md bg-primary-500 flex items-center justify-center text-white">
205
+ <i class="fas fa-book"></i>
206
+ </div>
207
+ <span class="font-semibold">Notion Lite</span>
208
+ </div>
209
+ <button id="toggle-dark" class="p-2 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700">
210
+ <i class="fas fa-moon dark:hidden"></i>
211
+ <i class="fas fa-sun hidden dark:block"></i>
212
+ </button>
213
+ </div>
214
+ <div class="flex-1 overflow-y-auto custom-scrollbar p-2">
215
+ <div class="space-y-1">
216
+ <button id="new-page" class="w-full flex items-center space-x-2 p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 text-left">
217
+ <i class="fas fa-plus text-gray-500 dark:text-gray-400"></i>
218
+ <span>New page</span>
219
+ </button>
220
+ <div class="px-2 py-1 text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider">Pages</div>
221
+ <div id="pages-list" class="space-y-1">
222
+ <!-- Pages will be loaded here -->
223
+ </div>
224
+ </div>
225
+ </div>
226
+ <div class="p-4 border-t border-gray-200 dark:border-gray-700">
227
+ <div class="flex items-center space-x-2">
228
+ <div class="w-8 h-8 rounded-full bg-primary-500 flex items-center justify-center text-white">
229
+ <span class="text-sm">U</span>
230
+ </div>
231
+ <span class="text-sm font-medium">User</span>
232
+ </div>
233
+ </div>
234
+ </div>
235
+
236
+ <!-- Main Content -->
237
+ <div class="flex-1 flex flex-col h-screen overflow-hidden">
238
+ <!-- Toolbar -->
239
+ <div class="bg-white dark:bg-dark-800 border-b border-gray-200 dark:border-gray-700 p-2 flex items-center justify-between">
240
+ <div class="flex items-center space-x-2">
241
+ <button id="toggle-sidebar" class="p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 md:hidden">
242
+ <i class="fas fa-bars"></i>
243
+ </button>
244
+ <div id="breadcrumbs" class="flex items-center space-x-1 text-sm">
245
+ <!-- Breadcrumbs will be loaded here -->
246
+ </div>
247
+ </div>
248
+ <div class="flex items-center space-x-2">
249
+ <button id="save-button" class="px-3 py-1 rounded-lg bg-primary-500 text-white hover:bg-primary-600 flex items-center space-x-1">
250
+ <i class="fas fa-save"></i>
251
+ <span class="hidden md:inline">Save</span>
252
+ </button>
253
+ </div>
254
+ </div>
255
+
256
+ <!-- Editor Area -->
257
+ <div class="flex-1 overflow-auto custom-scrollbar">
258
+ <div id="editor-container" class="max-w-4xl mx-auto p-4">
259
+ <div id="editor" class="ProseMirror"></div>
260
+ </div>
261
+ </div>
262
+ </div>
263
+
264
+ <!-- Floating Format Toolbar -->
265
+ <div id="floating-toolbar" class="floating-toolbar fixed bg-white dark:bg-dark-800 shadow-lg rounded-lg p-1 border border-gray-200 dark:border-gray-700 z-50 flex items-center space-x-1">
266
+ <button data-command="bold" class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
267
+ <i class="fas fa-bold"></i>
268
+ </button>
269
+ <button data-command="italic" class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
270
+ <i class="fas fa-italic"></i>
271
+ </button>
272
+ <button data-command="underline" class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
273
+ <i class="fas fa-underline"></i>
274
+ </button>
275
+ <button data-command="strike" class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
276
+ <i class="fas fa-strikethrough"></i>
277
+ </button>
278
+ <div class="w-px h-6 bg-gray-200 dark:bg-gray-700 mx-1"></div>
279
+ <button data-command="heading1" class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
280
+ <span class="font-bold">H1</span>
281
+ </button>
282
+ <button data-command="heading2" class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
283
+ <span class="font-bold">H2</span>
284
+ </button>
285
+ <button data-command="heading3" class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
286
+ <span class="font-bold">H3</span>
287
+ </button>
288
+ <div class="w-px h-6 bg-gray-200 dark:bg-gray-700 mx-1"></div>
289
+ <button data-command="bulletList" class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
290
+ <i class="fas fa-list-ul"></i>
291
+ </button>
292
+ <button data-command="orderedList" class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
293
+ <i class="fas fa-list-ol"></i>
294
+ </button>
295
+ <button data-command="taskList" class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
296
+ <i class="fas fa-tasks"></i>
297
+ </button>
298
+ <div class="w-px h-6 bg-gray-200 dark:bg-gray-700 mx-1"></div>
299
+ <button data-command="blockquote" class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
300
+ <i class="fas fa-quote-right"></i>
301
+ </button>
302
+ <button data-command="codeBlock" class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
303
+ <i class="fas fa-code"></i>
304
+ </button>
305
+ <button data-command="horizontalRule" class="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700">
306
+ <i class="fas fa-minus"></i>
307
+ </button>
308
+ </div>
309
+
310
+ <!-- Slate Insert Menu -->
311
+ <div id="slate-insert-menu" class="slate-insert-menu fixed bg-white dark:bg-dark-800 shadow-lg rounded-lg p-2 border border-gray-200 dark:border-gray-700 z-50 w-64">
312
+ <div class="text-xs font-semibold text-gray-500 dark:text-gray-400 px-2 py-1">Insert</div>
313
+ <div class="space-y-1">
314
+ <button data-insert="heading1" class="w-full flex items-center space-x-2 p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700 text-left">
315
+ <div class="w-8 h-8 rounded bg-blue-100 dark:bg-blue-900 flex items-center justify-center">
316
+ <span class="font-bold text-blue-600 dark:text-blue-300">H1</span>
317
+ </div>
318
+ <div>
319
+ <div class="font-medium">Heading 1</div>
320
+ <div class="text-xs text-gray-500 dark:text-gray-400">Large section heading</div>
321
+ </div>
322
+ </button>
323
+ <button data-insert="heading2" class="w-full flex items-center space-x-2 p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700 text-left">
324
+ <div class="w-8 h-8 rounded bg-blue-100 dark:bg-blue-900 flex items-center justify-center">
325
+ <span class="font-bold text-blue-600 dark:text-blue-300">H2</span>
326
+ </div>
327
+ <div>
328
+ <div class="font-medium">Heading 2</div>
329
+ <div class="text-xs text-gray-500 dark:text-gray-400">Medium section heading</div>
330
+ </div>
331
+ </button>
332
+ <button data-insert="bulletList" class="w-full flex items-center space-x-2 p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700 text-left">
333
+ <div class="w-8 h-8 rounded bg-purple-100 dark:bg-purple-900 flex items-center justify-center">
334
+ <i class="fas fa-list-ul text-purple-600 dark:text-purple-300"></i>
335
+ </div>
336
+ <div>
337
+ <div class="font-medium">Bulleted list</div>
338
+ <div class="text-xs text-gray-500 dark:text-gray-400">Create a simple bulleted list</div>
339
+ </div>
340
+ </button>
341
+ <button data-insert="orderedList" class="w-full flex items-center space-x-2 p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700 text-left">
342
+ <div class="w-8 h-8 rounded bg-green-100 dark:bg-green-900 flex items-center justify-center">
343
+ <i class="fas fa-list-ol text-green-600 dark:text-green-300"></i>
344
+ </div>
345
+ <div>
346
+ <div class="font-medium">Numbered list</div>
347
+ <div class="text-xs text-gray-500 dark:text-gray-400">Create a list with numbering</div>
348
+ </div>
349
+ </button>
350
+ <button data-insert="taskList" class="w-full flex items-center space-x-2 p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700 text-left">
351
+ <div class="w-8 h-8 rounded bg-yellow-100 dark:bg-yellow-900 flex items-center justify-center">
352
+ <i class="fas fa-tasks text-yellow-600 dark:text-yellow-300"></i>
353
+ </div>
354
+ <div>
355
+ <div class="font-medium">Task list</div>
356
+ <div class="text-xs text-gray-500 dark:text-gray-400">Track tasks with checkboxes</div>
357
+ </div>
358
+ </button>
359
+ <button data-insert="table" class="w-full flex items-center space-x-2 p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700 text-left">
360
+ <div class="w-8 h-8 rounded bg-red-100 dark:bg-red-900 flex items-center justify-center">
361
+ <i class="fas fa-table text-red-600 dark:text-red-300"></i>
362
+ </div>
363
+ <div>
364
+ <div class="font-medium">Table</div>
365
+ <div class="text-xs text-gray-500 dark:text-gray-400">Insert a table</div>
366
+ </div>
367
+ </button>
368
+ <button data-insert="codeBlock" class="w-full flex items-center space-x-2 p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-700 text-left">
369
+ <div class="w-8 h-8 rounded bg-gray-100 dark:bg-gray-700 flex items-center justify-center">
370
+ <i class="fas fa-code text-gray-600 dark:text-gray-300"></i>
371
+ </div>
372
+ <div>
373
+ <div class="font-medium">Code block</div>
374
+ <div class="text-xs text-gray-500 dark:text-gray-400">Insert a block of code</div>
375
+ </div>
376
+ </button>
377
+ </div>
378
+ </div>
379
+
380
+ <script>
381
+ document.addEventListener('DOMContentLoaded', function() {
382
+ // Initialize app
383
+ class NotionLite {
384
+ constructor() {
385
+ this.pages = [];
386
+ this.currentPage = null;
387
+ this.editor = null;
388
+ this.initElements();
389
+ this.initEventListeners();
390
+ this.loadPages();
391
+ this.initEditor();
392
+ this.updateUI();
393
+ }
394
+
395
+ initElements() {
396
+ this.elements = {
397
+ sidebar: document.querySelector('.w-64'),
398
+ toggleSidebar: document.getElementById('toggle-sidebar'),
399
+ toggleDark: document.getElementById('toggle-dark'),
400
+ newPage: document.getElementById('new-page'),
401
+ pagesList: document.getElementById('pages-list'),
402
+ breadcrumbs: document.getElementById('breadcrumbs'),
403
+ saveButton: document.getElementById('save-button'),
404
+ editor: document.getElementById('editor'),
405
+ editorContainer: document.getElementById('editor-container'),
406
+ floatingToolbar: document.getElementById('floating-toolbar'),
407
+ slateInsertMenu: document.getElementById('slate-insert-menu'),
408
+ };
409
+ }
410
+
411
+ initEventListeners() {
412
+ // Toggle sidebar on mobile
413
+ this.elements.toggleSidebar.addEventListener('click', () => {
414
+ this.elements.sidebar.classList.toggle('hidden');
415
+ });
416
+
417
+ // Toggle dark mode
418
+ this.elements.toggleDark.addEventListener('click', () => {
419
+ document.documentElement.classList.toggle('dark');
420
+ localStorage.setItem('darkMode', document.documentElement.classList.contains('dark'));
421
+ });
422
+
423
+ // Create new page
424
+ this.elements.newPage.addEventListener('click', () => this.createNewPage());
425
+
426
+ // Save button
427
+ this.elements.saveButton.addEventListener('click', () => this.saveCurrentPage());
428
+
429
+ // Formatting buttons
430
+ document.querySelectorAll('[data-command]').forEach(button => {
431
+ button.addEventListener('click', (e) => {
432
+ const command = e.currentTarget.getAttribute('data-command');
433
+ this.executeCommand(command);
434
+ });
435
+ });
436
+
437
+ // Insert menu buttons
438
+ document.querySelectorAll('[data-insert]').forEach(button => {
439
+ button.addEventListener('click', (e) => {
440
+ const command = e.currentTarget.getAttribute('data-insert');
441
+ this.executeCommand(command);
442
+ this.hideInsertMenu();
443
+ });
444
+ });
445
+
446
+ // Editor events
447
+ this.elements.editor.addEventListener('click', () => this.updateFloatingToolbar());
448
+ this.elements.editor.addEventListener('keyup', () => this.updateFloatingToolbar());
449
+ this.elements.editor.addEventListener('input', () => this.saveCurrentPage());
450
+
451
+ // Slash command
452
+ this.elements.editor.addEventListener('keydown', (e) => {
453
+ if (e.key === '/' && this.getCurrentTextBeforeCursor() === '') {
454
+ this.showInsertMenu();
455
+ e.preventDefault();
456
+ } else if (e.key === 'Escape') {
457
+ this.hideInsertMenu();
458
+ }
459
+ });
460
+
461
+ // Click outside to hide insert menu
462
+ document.addEventListener('click', (e) => {
463
+ if (!this.elements.slateInsertMenu.contains(e.target) &&
464
+ !this.elements.editor.contains(e.target)) {
465
+ this.hideInsertMenu();
466
+ }
467
+ });
468
+
469
+ // Auto-save every 10 seconds
470
+ setInterval(() => this.saveCurrentPage(), 10000);
471
+ }
472
+
473
+ initEditor() {
474
+ // Simple content editable with formatting support
475
+ this.elements.editor.contentEditable = true;
476
+
477
+ // Load first page if exists
478
+ if (this.pages.length > 0) {
479
+ this.loadPage(this.pages[0].id);
480
+ } else {
481
+ this.createNewPage();
482
+ }
483
+ }
484
+
485
+ executeCommand(command) {
486
+ document.execCommand('styleWithCSS', false, true);
487
+
488
+ switch (command) {
489
+ case 'bold':
490
+ document.execCommand('bold', false, null);
491
+ break;
492
+ case 'italic':
493
+ document.execCommand('italic', false, null);
494
+ break;
495
+ case 'underline':
496
+ document.execCommand('underline', false, null);
497
+ break;
498
+ case 'strike':
499
+ document.execCommand('strikeThrough', false, null);
500
+ break;
501
+ case 'heading1':
502
+ document.execCommand('formatBlock', false, '<h1>');
503
+ break;
504
+ case 'heading2':
505
+ document.execCommand('formatBlock', false, '<h2>');
506
+ break;
507
+ case 'heading3':
508
+ document.execCommand('formatBlock', false, '<h3>');
509
+ break;
510
+ case 'bulletList':
511
+ document.execCommand('insertUnorderedList', false, null);
512
+ break;
513
+ case 'orderedList':
514
+ document.execCommand('insertOrderedList', false, null);
515
+ break;
516
+ case 'taskList':
517
+ this.insertTaskItem();
518
+ break;
519
+ case 'blockquote':
520
+ document.execCommand('formatBlock', false, '<blockquote>');
521
+ break;
522
+ case 'codeBlock':
523
+ this.insertCodeBlock();
524
+ break;
525
+ case 'horizontalRule':
526
+ document.execCommand('insertHorizontalRule', false, null);
527
+ break;
528
+ case 'table':
529
+ this.insertTable();
530
+ break;
531
+ }
532
+
533
+ this.elements.editor.focus();
534
+ this.saveCurrentPage();
535
+ }
536
+
537
+ insertTaskItem() {
538
+ const selection = window.getSelection();
539
+ const range = selection.getRangeAt(0);
540
+ const container = document.createElement('div');
541
+ container.className = 'task-item';
542
+
543
+ const checkbox = document.createElement('input');
544
+ checkbox.type = 'checkbox';
545
+ checkbox.className = 'task-checkbox';
546
+ checkbox.addEventListener('change', function() {
547
+ if (this.checked) {
548
+ container.classList.add('checked');
549
+ } else {
550
+ container.classList.remove('checked');
551
+ }
552
+ });
553
+
554
+ const text = document.createElement('span');
555
+ text.className = 'task-text';
556
+ text.contentEditable = true;
557
+ text.textContent = 'New task';
558
+
559
+ container.appendChild(checkbox);
560
+ container.appendChild(text);
561
+
562
+ range.deleteContents();
563
+ range.insertNode(container);
564
+
565
+ // Move cursor inside the task text
566
+ const newRange = document.createRange();
567
+ newRange.selectNodeContents(text);
568
+ newRange.collapse(false);
569
+ selection.removeAllRanges();
570
+ selection.addRange(newRange);
571
+
572
+ text.focus();
573
+ }
574
+
575
+ insertCodeBlock() {
576
+ const selection = window.getSelection();
577
+ const range = selection.getRangeAt(0);
578
+ const pre = document.createElement('pre');
579
+ const code = document.createElement('code');
580
+ code.textContent = '// Your code here';
581
+ pre.appendChild(code);
582
+
583
+ range.deleteContents();
584
+ range.insertNode(pre);
585
+
586
+ // Move cursor inside the code block
587
+ const newRange = document.createRange();
588
+ newRange.selectNodeContents(code);
589
+ newRange.collapse(false);
590
+ selection.removeAllRanges();
591
+ selection.addRange(newRange);
592
+
593
+ code.focus();
594
+ }
595
+
596
+ insertTable() {
597
+ const selection = window.getSelection();
598
+ const range = selection.getRangeAt(0);
599
+
600
+ const table = document.createElement('table');
601
+ const thead = document.createElement('thead');
602
+ const tbody = document.createElement('tbody');
603
+ const headerRow = document.createElement('tr');
604
+
605
+ // Create header row with 3 columns
606
+ for (let i = 0; i < 3; i++) {
607
+ const th = document.createElement('th');
608
+ th.textContent = i === 0 ? 'Header 1' : i === 1 ? 'Header 2' : 'Header 3';
609
+ headerRow.appendChild(th);
610
+ }
611
+
612
+ // Create 3 rows with 3 columns each
613
+ for (let i = 0; i < 3; i++) {
614
+ const row = document.createElement('tr');
615
+ for (let j = 0; j < 3; j++) {
616
+ const td = document.createElement('td');
617
+ td.textContent = `Row ${i+1}, Col ${j+1}`;
618
+ row.appendChild(td);
619
+ }
620
+ tbody.appendChild(row);
621
+ }
622
+
623
+ thead.appendChild(headerRow);
624
+ table.appendChild(thead);
625
+ table.appendChild(tbody);
626
+
627
+ range.deleteContents();
628
+ range.insertNode(table);
629
+
630
+ // Move cursor after the table
631
+ const newRange = document.createRange();
632
+ newRange.setStartAfter(table);
633
+ newRange.collapse(true);
634
+ selection.removeAllRanges();
635
+ selection.addRange(newRange);
636
+
637
+ this.elements.editor.focus();
638
+ }
639
+
640
+ updateFloatingToolbar() {
641
+ const selection = window.getSelection();
642
+ if (!selection.rangeCount) return;
643
+
644
+ const range = selection.getRangeAt(0);
645
+ const rect = range.getBoundingClientRect();
646
+
647
+ // Position the toolbar above the selection
648
+ this.elements.floatingToolbar.style.top = `${rect.top + window.scrollY - 40}px`;
649
+ this.elements.floatingToolbar.style.left = `${rect.left + window.scrollX - 10}px`;
650
+
651
+ // Show the toolbar if there's a selection
652
+ if (!selection.isCollapsed) {
653
+ this.elements.floatingToolbar.classList.add('visible');
654
+ } else {
655
+ this.elements.floatingToolbar.classList.remove('visible');
656
+ }
657
+ }
658
+
659
+ showInsertMenu() {
660
+ const selection = window.getSelection();
661
+ if (!selection.rangeCount) return;
662
+
663
+ const range = selection.getRangeAt(0);
664
+ const rect = range.getBoundingClientRect();
665
+
666
+ // Position the menu below the cursor
667
+ this.elements.slateInsertMenu.style.top = `${rect.bottom + window.scrollY + 5}px`;
668
+ this.elements.slateInsertMenu.style.left = `${rect.left + window.scrollX}px`;
669
+ this.elements.slateInsertMenu.classList.add('visible');
670
+ }
671
+
672
+ hideInsertMenu() {
673
+ this.elements.slateInsertMenu.classList.remove('visible');
674
+ }
675
+
676
+ getCurrentTextBeforeCursor() {
677
+ const selection = window.getSelection();
678
+ if (!selection.rangeCount) return '';
679
+
680
+ const range = selection.getRangeAt(0);
681
+ const node = range.startContainer;
682
+ const offset = range.startOffset;
683
+
684
+ if (node.nodeType === Node.TEXT_NODE) {
685
+ return node.textContent.substring(0, offset);
686
+ }
687
+
688
+ return '';
689
+ }
690
+
691
+ createNewPage() {
692
+ const newPage = {
693
+ id: Date.now().toString(),
694
+ title: 'Untitled',
695
+ content: '',
696
+ createdAt: new Date().toISOString(),
697
+ updatedAt: new Date().toISOString(),
698
+ };
699
+
700
+ this.pages.push(newPage);
701
+ this.currentPage = newPage;
702
+ this.savePages();
703
+ this.updateUI();
704
+
705
+ // Focus the editor
706
+ setTimeout(() => {
707
+ this.elements.editor.focus();
708
+ }, 100);
709
+ }
710
+
711
+ loadPage(pageId) {
712
+ const page = this.pages.find(p => p.id === pageId);
713
+ if (!page) return;
714
+
715
+ this.currentPage = page;
716
+ this.elements.editor.innerHTML = page.content || '';
717
+ this.updateUI();
718
+
719
+ // Focus the editor
720
+ setTimeout(() => {
721
+ this.elements.editor.focus();
722
+ }, 100);
723
+ }
724
+
725
+ saveCurrentPage() {
726
+ if (!this.currentPage) return;
727
+
728
+ this.currentPage.content = this.elements.editor.innerHTML;
729
+ this.currentPage.updatedAt = new Date().toISOString();
730
+
731
+ // Extract title from content (first heading or first line of text)
732
+ const tempDiv = document.createElement('div');
733
+ tempDiv.innerHTML = this.currentPage.content;
734
+
735
+ const heading = tempDiv.querySelector('h1, h2, h3');
736
+ if (heading) {
737
+ this.currentPage.title = heading.textContent.trim();
738
+ } else {
739
+ const firstText = tempDiv.textContent.trim().split('\n')[0];
740
+ this.currentPage.title = firstText || 'Untitled';
741
+ }
742
+
743
+ this.savePages();
744
+ this.updateUI();
745
+ }
746
+
747
+ loadPages() {
748
+ const savedPages = localStorage.getItem('notion-lite-pages');
749
+ if (savedPages) {
750
+ this.pages = JSON.parse(savedPages);
751
+ }
752
+
753
+ // Check for dark mode preference
754
+ const darkMode = localStorage.getItem('darkMode') === 'true';
755
+ if (darkMode) {
756
+ document.documentElement.classList.add('dark');
757
+ } else {
758
+ document.documentElement.classList.remove('dark');
759
+ }
760
+ }
761
+
762
+ savePages() {
763
+ localStorage.setItem('notion-lite-pages', JSON.stringify(this.pages));
764
+ }
765
+
766
+ updateUI() {
767
+ // Update pages list
768
+ this.elements.pagesList.innerHTML = '';
769
+
770
+ this.pages.forEach(page => {
771
+ const pageElement = document.createElement('button');
772
+ pageElement.className = `w-full flex items-center space-x-2 p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 text-left ${this.currentPage?.id === page.id ? 'bg-gray-100 dark:bg-gray-700' : ''}`;
773
+ pageElement.innerHTML = `
774
+ <i class="fas fa-file-alt text-gray-500 dark:text-gray-400"></i>
775
+ <span class="truncate">${page.title}</span>
776
+ `;
777
+ pageElement.addEventListener('click', () => this.loadPage(page.id));
778
+ this.elements.pagesList.appendChild(pageElement);
779
+ });
780
+
781
+ // Update breadcrumbs
782
+ if (this.currentPage) {
783
+ this.elements.breadcrumbs.innerHTML = `
784
+ <span class="text-gray-500 dark:text-gray-400">Pages</span>
785
+ <span class="text-gray-500 dark:text-gray-400">/</span>
786
+ <span class="truncate max-w-xs">${this.currentPage.title}</span>
787
+ `;
788
+ }
789
+ }
790
+ }
791
+
792
+ // Initialize the app
793
+ const app = new NotionLite();
794
+ });
795
+ </script>
796
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - <a href="https://enzostvs-deepsite.hf.space?remix=Harry00/notion" style="color: #fff;text-decoration: underline;" target="_blank" >🧬 Remix</a></p></body>
797
+ </html>