notra-editor 0.1.0 → 0.2.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.
@@ -2,9 +2,76 @@
2
2
  Editor-specific Variables
3
3
  ===================== */
4
4
  .notra-editor {
5
+ overflow: auto;
6
+
5
7
  --notra-cursor-color: rgba(98, 41, 255, 1);
6
8
  --notra-selection-color: rgba(157, 138, 255, 0.2);
7
9
  --notra-placeholder-color: rgba(40, 44, 51, 0.42);
10
+
11
+ /* Toolbar design tokens (from Tiptap simple-next) */
12
+ --white: rgba(255, 255, 255, 1);
13
+ --black: rgba(14, 14, 17, 1);
14
+ --transparent: rgba(255, 255, 255, 0);
15
+
16
+ /* Gray alpha scale (light mode) */
17
+ --tt-gray-light-a-50: rgba(56, 56, 56, 0.04);
18
+ --tt-gray-light-a-100: rgba(15, 22, 36, 0.05);
19
+ --tt-gray-light-a-200: rgba(37, 39, 45, 0.1);
20
+ --tt-gray-light-a-300: rgba(47, 50, 55, 0.2);
21
+ --tt-gray-light-a-400: rgba(40, 44, 51, 0.42);
22
+ --tt-gray-light-a-500: rgba(52, 55, 60, 0.64);
23
+ --tt-gray-light-a-600: rgba(36, 39, 46, 0.78);
24
+ --tt-gray-light-a-700: rgba(35, 37, 42, 0.87);
25
+ --tt-gray-light-a-800: rgba(30, 32, 36, 0.95);
26
+ --tt-gray-light-a-900: rgba(29, 30, 32, 0.98);
27
+
28
+ /* Gray solid scale (light mode) */
29
+ --tt-gray-light-200: rgba(234, 234, 235, 1);
30
+
31
+ /* Radius & transitions */
32
+ --tt-radius-lg: 0.75rem;
33
+ --tt-transition-duration-default: 0.2s;
34
+ --tt-transition-easing-default: cubic-bezier(0.46, 0.03, 0.52, 0.96);
35
+
36
+ /* Toolbar */
37
+ --tt-toolbar-height: 2.75rem;
38
+ --tt-toolbar-bg-color: var(--white);
39
+ --tt-toolbar-border-color: var(--tt-gray-light-a-100);
40
+
41
+ /* Ghost button colors */
42
+ --tt-button-default-bg-color: var(--transparent);
43
+ --tt-button-hover-bg-color: var(--tt-gray-light-200);
44
+ --tt-button-disabled-bg-color: var(--transparent);
45
+ --tt-button-default-icon-color: var(--tt-gray-light-a-600);
46
+ --tt-button-hover-icon-color: var(--tt-gray-light-a-900);
47
+ --tt-button-disabled-icon-color: var(--tt-gray-light-a-400);
48
+
49
+ /* Separator */
50
+ --tt-separator-color: var(--tt-gray-light-a-200);
51
+ }
52
+
53
+ /* =====================
54
+ Editor Layout
55
+ ===================== */
56
+ .notra-editor .notra-editor-content {
57
+ max-width: 648px;
58
+ width: 100%;
59
+ margin: 0 auto;
60
+ height: 100%;
61
+ display: flex;
62
+ flex-direction: column;
63
+ flex: 1;
64
+ }
65
+
66
+ .notra-editor .notra-editor-content .tiptap.ProseMirror {
67
+ flex: 1;
68
+ padding: 3rem 3rem 30vh;
69
+ }
70
+
71
+ @media screen and (max-width: 480px) {
72
+ .notra-editor .notra-editor-content .tiptap.ProseMirror {
73
+ padding: 1rem 1.5rem 30vh;
74
+ }
8
75
  }
9
76
 
10
77
  /* =====================
@@ -74,3 +141,290 @@
74
141
  width: 100%;
75
142
  height: 0.188rem;
76
143
  }
144
+
145
+ /* =====================
146
+ Toolbar
147
+ ===================== */
148
+ .notra-editor .tiptap-toolbar {
149
+ display: flex;
150
+ align-items: center;
151
+ gap: 0.25rem;
152
+ }
153
+
154
+ .notra-editor .tiptap-toolbar[data-variant='fixed'] {
155
+ position: sticky;
156
+ top: 0;
157
+ z-index: 50;
158
+ width: 100%;
159
+ min-height: var(--tt-toolbar-height);
160
+ background: var(--tt-toolbar-bg-color);
161
+ border-bottom: 1px solid var(--tt-toolbar-border-color);
162
+ padding: 0 0.5rem;
163
+ overflow-x: auto;
164
+ overscroll-behavior-x: contain;
165
+ -webkit-overflow-scrolling: touch;
166
+ scrollbar-width: none;
167
+ -ms-overflow-style: none;
168
+ }
169
+
170
+ .notra-editor .tiptap-toolbar[data-variant='fixed']::-webkit-scrollbar {
171
+ display: none;
172
+ }
173
+
174
+ .notra-editor .tiptap-toolbar-group {
175
+ display: flex;
176
+ align-items: center;
177
+ gap: 0.125rem;
178
+ }
179
+
180
+ .notra-editor .tiptap-toolbar-group:empty {
181
+ display: none;
182
+ }
183
+
184
+ /* =====================
185
+ Separator
186
+ ===================== */
187
+ .notra-editor .tiptap-separator {
188
+ flex-shrink: 0;
189
+ background-color: var(--tt-separator-color);
190
+ }
191
+
192
+ .notra-editor .tiptap-separator[data-orientation='vertical'] {
193
+ height: 1.5rem;
194
+ width: 1px;
195
+ }
196
+
197
+ .notra-editor .tiptap-separator[data-orientation='horizontal'] {
198
+ height: 1px;
199
+ width: 100%;
200
+ margin: 0.5rem 0;
201
+ }
202
+
203
+ /* =====================
204
+ Button
205
+ ===================== */
206
+ .notra-editor .tiptap-button {
207
+ font-size: 0.875rem;
208
+ font-weight: 500;
209
+ line-height: 1.15;
210
+ height: 2rem;
211
+ min-width: 2rem;
212
+ border: none;
213
+ padding: 0.5rem;
214
+ gap: 0.25rem;
215
+ display: flex;
216
+ align-items: center;
217
+ justify-content: center;
218
+ border-radius: var(--tt-radius-lg);
219
+ cursor: pointer;
220
+ background-color: var(--tt-button-default-bg-color);
221
+ color: var(--tt-button-default-icon-color);
222
+ transition-property: background-color, color, opacity;
223
+ transition-duration: var(--tt-transition-duration-default);
224
+ transition-timing-function: var(--tt-transition-easing-default);
225
+ }
226
+
227
+ .notra-editor .tiptap-button:focus-visible {
228
+ outline: none;
229
+ }
230
+
231
+ .notra-editor .tiptap-button .tiptap-button-icon {
232
+ width: 1rem;
233
+ height: 1rem;
234
+ flex-shrink: 0;
235
+ color: inherit;
236
+ }
237
+
238
+ .notra-editor .tiptap-button:hover:not([disabled]) {
239
+ background-color: var(--tt-button-hover-bg-color);
240
+ color: var(--tt-button-hover-icon-color);
241
+ }
242
+
243
+ .notra-editor .tiptap-button:disabled {
244
+ background-color: var(--tt-button-disabled-bg-color);
245
+ color: var(--tt-button-disabled-icon-color);
246
+ cursor: default;
247
+ }
248
+
249
+ /* =====================
250
+ Additional Variables
251
+ ===================== */
252
+ .notra-editor {
253
+ --tt-brand-color-500: rgba(98, 41, 255, 1);
254
+ --tt-shadow-elevated-md:
255
+ 0px 16px 48px 0px rgba(17, 24, 39, 0.04),
256
+ 0px 12px 24px 0px rgba(17, 24, 39, 0.04),
257
+ 0px 6px 8px 0px rgba(17, 24, 39, 0.02),
258
+ 0px 2px 3px 0px rgba(17, 24, 39, 0.02);
259
+ --tt-radius-md: 0.5rem;
260
+
261
+ /* Dropdown menu */
262
+ --tt-dropdown-menu-bg-color: var(--white);
263
+ --tt-dropdown-menu-text-color: var(--tt-gray-light-a-600);
264
+
265
+ /* Popover */
266
+ --tt-popover-bg-color: var(--white);
267
+ --tt-popover-border-color: var(--tt-gray-light-a-100);
268
+
269
+ /* Card */
270
+ --tiptap-card-bg-color: var(--white);
271
+ --tiptap-card-border-color: var(--tt-gray-light-a-100);
272
+
273
+ /* Input */
274
+ --tt-input-placeholder: var(--tt-gray-light-a-400);
275
+ --tt-input-border: var(--tt-gray-light-a-200);
276
+ --tt-input-border-focus: var(--tt-gray-light-a-300);
277
+ }
278
+
279
+ /* =====================
280
+ Button Active State
281
+ ===================== */
282
+ .notra-editor .tiptap-button[data-active-state='on'] {
283
+ background-color: var(--tt-gray-light-a-100);
284
+ color: var(--tt-brand-color-500);
285
+ }
286
+
287
+ .notra-editor .tiptap-button[data-active-state='on']:hover:not([disabled]) {
288
+ background-color: var(--tt-gray-light-200);
289
+ }
290
+
291
+ /* =====================
292
+ Button Extras
293
+ ===================== */
294
+ .notra-editor .tiptap-button-dropdown-arrows {
295
+ width: 0.75rem;
296
+ height: 0.75rem;
297
+ color: var(--tt-gray-light-a-600);
298
+ }
299
+
300
+ .notra-editor .tiptap-button-text {
301
+ padding: 0 0.125rem;
302
+ }
303
+
304
+ /* =====================
305
+ Dropdown Menu
306
+ ===================== */
307
+ .notra-editor .tiptap-dropdown-menu-content {
308
+ z-index: 9999;
309
+ min-width: 8rem;
310
+ border-radius: calc(0.375rem + var(--tt-radius-lg));
311
+ padding: 0.375rem;
312
+ background-color: var(--tt-dropdown-menu-bg-color);
313
+ color: var(--tt-dropdown-menu-text-color);
314
+ box-shadow: var(--tt-shadow-elevated-md);
315
+ overflow: hidden;
316
+ transform: translateX(-50%);
317
+ animation: dropdown-in 100ms ease forwards;
318
+ }
319
+
320
+ .notra-editor .tiptap-dropdown-menu-group {
321
+ display: flex;
322
+ flex-direction: column;
323
+ }
324
+
325
+ @keyframes dropdown-in {
326
+ from {
327
+ opacity: 0;
328
+ transform: translateX(-50%) scale(0.95) translateY(-0.25rem);
329
+ }
330
+ to {
331
+ opacity: 1;
332
+ transform: translateX(-50%) scale(1) translateY(0);
333
+ }
334
+ }
335
+
336
+ /* =====================
337
+ Popover
338
+ ===================== */
339
+ .notra-editor .tiptap-popover-content {
340
+ z-index: 9999;
341
+ transform: translateX(-50%);
342
+ animation: popover-in 150ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
343
+ }
344
+
345
+ @keyframes popover-in {
346
+ from {
347
+ opacity: 0;
348
+ transform: translateX(-50%) scale(0.95) translateY(-0.25rem);
349
+ }
350
+ to {
351
+ opacity: 1;
352
+ transform: translateX(-50%) scale(1) translateY(0);
353
+ }
354
+ }
355
+
356
+ /* =====================
357
+ Card
358
+ ===================== */
359
+ .notra-editor .tiptap-card {
360
+ display: flex;
361
+ flex-direction: column;
362
+ border-radius: calc(0.375rem + var(--tt-radius-lg));
363
+ box-shadow: var(--tt-shadow-elevated-md);
364
+ background-color: var(--tiptap-card-bg-color);
365
+ border: 1px solid var(--tiptap-card-border-color);
366
+ outline: none;
367
+ min-width: 0;
368
+ }
369
+
370
+ .notra-editor .tiptap-card-body {
371
+ padding: 0.375rem;
372
+ flex: 1 1 auto;
373
+ overflow-y: auto;
374
+ }
375
+
376
+ .notra-editor .tiptap-card-item-group {
377
+ position: relative;
378
+ display: flex;
379
+ vertical-align: middle;
380
+ min-width: max-content;
381
+ }
382
+
383
+ .notra-editor .tiptap-card-item-group[data-orientation='vertical'] {
384
+ flex-direction: column;
385
+ justify-content: center;
386
+ }
387
+
388
+ .notra-editor .tiptap-card-item-group[data-orientation='horizontal'] {
389
+ flex-direction: row;
390
+ align-items: center;
391
+ gap: 0.25rem;
392
+ }
393
+
394
+ /* =====================
395
+ Input
396
+ ===================== */
397
+ .notra-editor .tiptap-input {
398
+ width: 100%;
399
+ min-width: 0;
400
+ height: 2rem;
401
+ padding: 0.25rem 0.625rem;
402
+ border-radius: var(--tt-radius-md);
403
+ border: 1px solid var(--tt-input-border);
404
+ background: transparent;
405
+ font-size: 0.875rem;
406
+ outline: none;
407
+ transition: border-color 150ms;
408
+ }
409
+
410
+ .notra-editor .tiptap-input::placeholder {
411
+ color: var(--tt-input-placeholder);
412
+ }
413
+
414
+ .notra-editor .tiptap-input:focus-visible {
415
+ border-color: var(--tt-input-border-focus);
416
+ }
417
+
418
+ .notra-editor .tiptap-link-input {
419
+ font-size: 0.875rem;
420
+ border: none;
421
+ min-width: 12rem;
422
+ padding-right: 0;
423
+ text-overflow: ellipsis;
424
+ white-space: nowrap;
425
+ }
426
+
427
+ .notra-editor .tiptap-link-input:focus {
428
+ text-overflow: clip;
429
+ overflow: visible;
430
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "notra-editor",
3
3
  "type": "module",
4
- "version": "0.1.0",
4
+ "version": "0.2.0",
5
5
  "description": "A Markdown-first rich text editor for React",
6
6
  "license": "MIT",
7
7
  "keywords": [