@moda-editor/core 0.1.1 → 0.1.3
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.
- package/dist/conformance.d.ts.map +1 -1
- package/dist/conformance.js +140 -0
- package/dist/conformance.js.map +1 -1
- package/dist/editor/extension.d.ts +4 -2
- package/dist/editor/extension.d.ts.map +1 -1
- package/dist/features/ace.d.ts.map +1 -1
- package/dist/features/ace.js +23 -12
- package/dist/features/ace.js.map +1 -1
- package/dist/features/code-block.d.ts +29 -0
- package/dist/features/code-block.d.ts.map +1 -1
- package/dist/features/code-block.js +551 -36
- package/dist/features/code-block.js.map +1 -1
- package/dist/features/image.d.ts +14 -1
- package/dist/features/image.d.ts.map +1 -1
- package/dist/features/image.js +279 -11
- package/dist/features/image.js.map +1 -1
- package/dist/features/marks.d.ts.map +1 -1
- package/dist/features/marks.js +28 -1
- package/dist/features/marks.js.map +1 -1
- package/dist/features/table.d.ts +16 -3
- package/dist/features/table.d.ts.map +1 -1
- package/dist/features/table.js +295 -8
- package/dist/features/table.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/parse/sanitize.d.ts.map +1 -1
- package/dist/parse/sanitize.js +10 -1
- package/dist/parse/sanitize.js.map +1 -1
- package/dist/presets/highlight.d.ts +17 -0
- package/dist/presets/highlight.d.ts.map +1 -1
- package/dist/presets/highlight.js +51 -0
- package/dist/presets/highlight.js.map +1 -1
- package/dist/state/transaction.d.ts +0 -7
- package/dist/state/transaction.d.ts.map +1 -1
- package/dist/state/transaction.js +30 -1
- package/dist/state/transaction.js.map +1 -1
- package/dist/styles.css +441 -28
- package/dist/view/dom.d.ts.map +1 -1
- package/dist/view/dom.js +62 -22
- package/dist/view/dom.js.map +1 -1
- package/dist/view/input.d.ts.map +1 -1
- package/dist/view/input.js +158 -20
- package/dist/view/input.js.map +1 -1
- package/dist/view/mount.d.ts.map +1 -1
- package/dist/view/mount.js +16 -4
- package/dist/view/mount.js.map +1 -1
- package/dist/view/render.d.ts +7 -1
- package/dist/view/render.d.ts.map +1 -1
- package/dist/view/render.js +5 -1
- package/dist/view/render.js.map +1 -1
- package/dist/view/serialize.d.ts +8 -0
- package/dist/view/serialize.d.ts.map +1 -1
- package/dist/view/serialize.js +19 -0
- package/dist/view/serialize.js.map +1 -1
- package/package.json +1 -1
package/dist/styles.css
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
--me-gutter-bg: rgba(15, 23, 42, 0.035);
|
|
13
13
|
--me-gutter-color: #94a3b8;
|
|
14
14
|
--me-line-active-num: #3b82f6;
|
|
15
|
+
/* atom 노드 셀렉션 링 + 이미지 핸들 — 거터와 같은 이유로 루트에 둔다 */
|
|
16
|
+
--me-node-sel-color: #3b82f6;
|
|
15
17
|
display: flex;
|
|
16
18
|
flex-direction: column;
|
|
17
19
|
gap: 8px;
|
|
@@ -53,7 +55,6 @@
|
|
|
53
55
|
* 크롬을 담당한다 ─────────────────────────────────────────── */
|
|
54
56
|
.me-frame {
|
|
55
57
|
--me-frame-shadow: 0 1px 2px rgba(15, 23, 42, 0.06);
|
|
56
|
-
--me-focus-ring: rgba(59, 130, 246, 0.18);
|
|
57
58
|
--me-border-color: #e2e8f0;
|
|
58
59
|
--me-text-color: #1e293b;
|
|
59
60
|
--me-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas,
|
|
@@ -67,9 +68,10 @@
|
|
|
67
68
|
overflow: hidden;
|
|
68
69
|
}
|
|
69
70
|
|
|
71
|
+
/* 포커스 표시는 테두리 색만 — 글로우 링은 입력 중 카드 전체를
|
|
72
|
+
* 파란 띠로 둘러 산만했다 */
|
|
70
73
|
.me-frame:focus-within {
|
|
71
74
|
border-color: var(--me-editor-focus, #3b82f6);
|
|
72
|
-
box-shadow: 0 0 0 3px var(--me-focus-ring);
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
/* ── 에디터 — Ace 계열 코드 에디터 서페이스: 모노스페이스 본문 +
|
|
@@ -82,7 +84,6 @@
|
|
|
82
84
|
--me-code-bg: #f1f5f9;
|
|
83
85
|
--me-code-border: #e2e8f0;
|
|
84
86
|
--me-gutter-border: var(--me-border-color);
|
|
85
|
-
--me-line-active-bg: rgba(59, 130, 246, 0.07);
|
|
86
87
|
--me-sel-bg: rgba(59, 130, 246, 0.22);
|
|
87
88
|
--me-print-margin: rgba(148, 163, 184, 0.4);
|
|
88
89
|
|
|
@@ -182,11 +183,11 @@
|
|
|
182
183
|
}
|
|
183
184
|
|
|
184
185
|
/* 활성 라인 — aceFeature의 paintOverlay가 캐럿의 최상위 블록에
|
|
185
|
-
* me-line-active를
|
|
186
|
-
*
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
186
|
+
* me-line-active를 단다. 배경 띠는 칠하지 않는다(문서 편집에서
|
|
187
|
+
* 파란 띠가 산만하다는 피드백) — 활성 표시는 거터 번호 강조
|
|
188
|
+
* (.me-gnum.is-active)로만 한다. 코드블록은 코드 에디터 관례대로
|
|
189
|
+
* .me-cl.is-active가 줄 단위 배경을 칠한다. 클래스는 계속 달리므로
|
|
190
|
+
* 원하면 제품 CSS에서 배경을 되살릴 수 있다 */
|
|
190
191
|
|
|
191
192
|
/* 선택 영역 — Ace 선택색 관례 (코드블록 안도 같은 변수) */
|
|
192
193
|
.me-editor ::selection {
|
|
@@ -243,10 +244,12 @@
|
|
|
243
244
|
font-size: 0.88em;
|
|
244
245
|
}
|
|
245
246
|
|
|
246
|
-
/* 리스트 — li 안 문단은 자체 여백이 없다 (li가 줄 간격을 담당)
|
|
247
|
+
/* 리스트 — li 안 문단은 자체 여백이 없다 (li가 줄 간격을 담당).
|
|
248
|
+
* 패딩이 마커 열이다: outside 마커(•, 1.)가 텍스트 왼쪽에 붙어
|
|
249
|
+
* 그려지므로, 마커가 거터 구분선에 닿지 않을 만큼의 들여쓰기가 필요 */
|
|
247
250
|
.me-editor ul,
|
|
248
251
|
.me-editor ol {
|
|
249
|
-
padding-left:
|
|
252
|
+
padding-left: 2.1em;
|
|
250
253
|
}
|
|
251
254
|
.me-editor li > p {
|
|
252
255
|
margin: 0;
|
|
@@ -256,14 +259,15 @@
|
|
|
256
259
|
margin: 2px 0;
|
|
257
260
|
}
|
|
258
261
|
|
|
259
|
-
/* 할일 목록 — 마커는 ::before, 클릭 영역은 li의 왼쪽 패딩(~
|
|
262
|
+
/* 할일 목록 — 마커는 ::before, 클릭 영역은 li의 왼쪽 패딩(~24px).
|
|
263
|
+
* ul 패딩과 li 패딩을 더해 텍스트 시작점이 다른 리스트와 맞는다 */
|
|
260
264
|
.me-editor ul.me-tasks {
|
|
261
|
-
padding-left:
|
|
265
|
+
padding-left: 8px;
|
|
262
266
|
}
|
|
263
267
|
.me-editor li.me-task {
|
|
264
268
|
list-style: none;
|
|
265
269
|
position: relative;
|
|
266
|
-
padding-left:
|
|
270
|
+
padding-left: 24px;
|
|
267
271
|
}
|
|
268
272
|
.me-editor li.me-task::before {
|
|
269
273
|
--me-checkbox-border: #94a3b8;
|
|
@@ -322,6 +326,280 @@
|
|
|
322
326
|
max-width: 100%;
|
|
323
327
|
border-radius: 6px;
|
|
324
328
|
margin: 0 0 8px;
|
|
329
|
+
cursor: default;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/* atom 노드 셀렉션 — 클릭으로 선택된 img/hr 등에 파란 링을 둔다
|
|
333
|
+
* (input.ts의 paintOverlays가 is-selected를 마킹한다) */
|
|
334
|
+
.me-editor [data-me-path].is-selected {
|
|
335
|
+
outline: 2px solid var(--me-node-sel-color);
|
|
336
|
+
outline-offset: 2px;
|
|
337
|
+
}
|
|
338
|
+
.me-editor hr.is-selected {
|
|
339
|
+
/* hr은 테두리가 굵어 outline이 묻힌다 — 위아래 여백으로 링을 띄운다 */
|
|
340
|
+
outline-offset: 4px;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/* ── 이미지 선택 오버레이 — 선택된 img 위에 얹히는 편집/리사이즈 UI.
|
|
344
|
+
* .me-editor의 형제(.me-root의 absolute 자식)로 둬 DOM↔Point 매핑을
|
|
345
|
+
* 깨지 않는다. 래퍼는 pointer-events:none — 이미지 자체 클릭은 그대로
|
|
346
|
+
* 통과하고 핸들/바만 이벤트를 받는다 */
|
|
347
|
+
.me-imgui {
|
|
348
|
+
position: absolute;
|
|
349
|
+
z-index: 40;
|
|
350
|
+
pointer-events: none;
|
|
351
|
+
}
|
|
352
|
+
.me-imgui[hidden] {
|
|
353
|
+
display: none;
|
|
354
|
+
}
|
|
355
|
+
/* 우하단 크기 핸들 — nwse-resize (GDocs/Word 관례) */
|
|
356
|
+
.me-imgui .me-img-handle {
|
|
357
|
+
position: absolute;
|
|
358
|
+
right: -6px;
|
|
359
|
+
bottom: -6px;
|
|
360
|
+
width: 12px;
|
|
361
|
+
height: 12px;
|
|
362
|
+
border-radius: 4px;
|
|
363
|
+
background: var(--me-toolbar-bg, #fff);
|
|
364
|
+
border: 2px solid var(--me-node-sel-color);
|
|
365
|
+
box-shadow: 0 1px 3px rgba(15, 23, 42, 0.3);
|
|
366
|
+
cursor: nwse-resize;
|
|
367
|
+
pointer-events: auto;
|
|
368
|
+
touch-action: none;
|
|
369
|
+
}
|
|
370
|
+
/* 액션 바 — 이미지 위쪽. 루트 상단에 붙으면 is-below로 아래로 뒤집는다 */
|
|
371
|
+
.me-imgui .me-img-bar {
|
|
372
|
+
position: absolute;
|
|
373
|
+
left: 0;
|
|
374
|
+
top: -6px;
|
|
375
|
+
transform: translateY(-100%);
|
|
376
|
+
display: flex;
|
|
377
|
+
flex-wrap: wrap;
|
|
378
|
+
gap: 3px;
|
|
379
|
+
padding: 4px;
|
|
380
|
+
max-width: min(320px, 90vw);
|
|
381
|
+
background: var(--me-toolbar-bg, #fff);
|
|
382
|
+
border: 1px solid var(--me-border-color);
|
|
383
|
+
border-radius: 6px;
|
|
384
|
+
box-shadow: 0 4px 14px rgba(15, 23, 42, 0.18);
|
|
385
|
+
pointer-events: auto;
|
|
386
|
+
}
|
|
387
|
+
.me-imgui.is-below .me-img-bar {
|
|
388
|
+
top: auto;
|
|
389
|
+
bottom: -6px;
|
|
390
|
+
transform: translateY(100%);
|
|
391
|
+
}
|
|
392
|
+
.me-imgui .me-imgbtn {
|
|
393
|
+
padding: 3px 8px;
|
|
394
|
+
font: inherit;
|
|
395
|
+
font-size: 12px;
|
|
396
|
+
color: inherit;
|
|
397
|
+
background: var(--me-btn-bg, transparent);
|
|
398
|
+
border: 1px solid var(--me-border-color);
|
|
399
|
+
border-radius: 4px;
|
|
400
|
+
cursor: pointer;
|
|
401
|
+
}
|
|
402
|
+
.me-imgui .me-imgbtn:hover {
|
|
403
|
+
background: var(--me-tool-hover-bg, #e2e8f0);
|
|
404
|
+
}
|
|
405
|
+
.me-imgui .me-imgbtn[data-img-act="del"]:hover {
|
|
406
|
+
color: #dc2626;
|
|
407
|
+
border-color: #dc2626;
|
|
408
|
+
}
|
|
409
|
+
/* 편집 폼 — 액션 바 안의 두 번째 행 (wrap으로 전체 폭을 차지) */
|
|
410
|
+
.me-imgui .me-imgedit {
|
|
411
|
+
flex-basis: 100%;
|
|
412
|
+
display: flex;
|
|
413
|
+
gap: 4px;
|
|
414
|
+
}
|
|
415
|
+
.me-imgui .me-imgedit[hidden] {
|
|
416
|
+
display: none;
|
|
417
|
+
}
|
|
418
|
+
.me-imgui .me-imged-src,
|
|
419
|
+
.me-imgui .me-imged-alt {
|
|
420
|
+
width: min(150px, 30vw);
|
|
421
|
+
padding: 4px 6px;
|
|
422
|
+
font: inherit;
|
|
423
|
+
font-size: 12px;
|
|
424
|
+
color: inherit;
|
|
425
|
+
background: transparent;
|
|
426
|
+
border: 1px solid var(--me-border-color);
|
|
427
|
+
border-radius: 4px;
|
|
428
|
+
outline: none;
|
|
429
|
+
}
|
|
430
|
+
.me-imgui .me-imged-src:focus,
|
|
431
|
+
.me-imgui .me-imged-alt:focus {
|
|
432
|
+
border-color: var(--me-accent, #2563eb);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/* ── 표 편집 오버레이 — 캐럿이 셀 안에 있을 때 표 위에 얹히는 UI.
|
|
436
|
+
* .me-imgui와 같은 패턴: 래퍼 pointer-events:none, 바/핸들만 받는다 */
|
|
437
|
+
.me-tableui {
|
|
438
|
+
position: absolute;
|
|
439
|
+
z-index: 40;
|
|
440
|
+
pointer-events: none;
|
|
441
|
+
}
|
|
442
|
+
.me-tableui[hidden] {
|
|
443
|
+
display: none;
|
|
444
|
+
}
|
|
445
|
+
/* 액션 바 — 표 위쪽 중앙. 루트 상단에 붙으면 is-below로 안쪽에 띄운다 */
|
|
446
|
+
.me-tableui .me-tbl-bar {
|
|
447
|
+
position: absolute;
|
|
448
|
+
left: 50%;
|
|
449
|
+
top: -6px;
|
|
450
|
+
transform: translate(-50%, -100%);
|
|
451
|
+
display: flex;
|
|
452
|
+
gap: 3px;
|
|
453
|
+
padding: 4px;
|
|
454
|
+
background: var(--me-toolbar-bg, #fff);
|
|
455
|
+
border: 1px solid var(--me-border-color);
|
|
456
|
+
border-radius: 6px;
|
|
457
|
+
box-shadow: 0 4px 14px rgba(15, 23, 42, 0.18);
|
|
458
|
+
white-space: nowrap;
|
|
459
|
+
pointer-events: auto;
|
|
460
|
+
}
|
|
461
|
+
.me-tableui.is-below .me-tbl-bar {
|
|
462
|
+
top: 4px;
|
|
463
|
+
transform: translate(-50%, 0);
|
|
464
|
+
}
|
|
465
|
+
.me-tableui .me-tblbtn {
|
|
466
|
+
padding: 3px 8px;
|
|
467
|
+
font: inherit;
|
|
468
|
+
font-size: 12px;
|
|
469
|
+
color: inherit;
|
|
470
|
+
background: var(--me-btn-bg, transparent);
|
|
471
|
+
border: 1px solid var(--me-border-color);
|
|
472
|
+
border-radius: 4px;
|
|
473
|
+
cursor: pointer;
|
|
474
|
+
}
|
|
475
|
+
.me-tableui .me-tblbtn:hover {
|
|
476
|
+
background: var(--me-tool-hover-bg, #e2e8f0);
|
|
477
|
+
}
|
|
478
|
+
.me-tableui .me-tblbtn[data-tbl-act="tabledel"]:hover,
|
|
479
|
+
.me-tableui .me-tblbtn[data-tbl-act="rowdel"]:hover,
|
|
480
|
+
.me-tableui .me-tblbtn[data-tbl-act="coldel"]:hover {
|
|
481
|
+
color: #dc2626;
|
|
482
|
+
border-color: #dc2626;
|
|
483
|
+
}
|
|
484
|
+
/* 열 경계 핸들 — 각 열 우측 경계의 8px 스트립. 평소엔 투명하고
|
|
485
|
+
* hover/드래그 시 리사이즈 커서 + 강조선 (GDocs 열 리사이즈 관례) */
|
|
486
|
+
.me-tableui .me-tbl-cols {
|
|
487
|
+
position: absolute;
|
|
488
|
+
inset: 0;
|
|
489
|
+
}
|
|
490
|
+
.me-tableui .me-col-handle {
|
|
491
|
+
position: absolute;
|
|
492
|
+
top: 0;
|
|
493
|
+
width: 8px;
|
|
494
|
+
cursor: col-resize;
|
|
495
|
+
pointer-events: auto;
|
|
496
|
+
touch-action: none;
|
|
497
|
+
}
|
|
498
|
+
.me-tableui .me-col-handle::after {
|
|
499
|
+
content: "";
|
|
500
|
+
position: absolute;
|
|
501
|
+
top: 0;
|
|
502
|
+
bottom: 0;
|
|
503
|
+
left: 3px;
|
|
504
|
+
width: 2px;
|
|
505
|
+
background: transparent;
|
|
506
|
+
transition: background 0.1s;
|
|
507
|
+
}
|
|
508
|
+
.me-tableui .me-col-handle:hover::after,
|
|
509
|
+
.me-tableui .me-col-handle:active::after {
|
|
510
|
+
background: var(--me-node-sel-color, #2563eb);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/* 코드블록 크롬 바 — 캐럿이 들어간 pre의 우측 상단(언어 라벨 자리).
|
|
514
|
+
* Notion 코드블록 언어 피커 관례. 래퍼는 좌표만 잡고 자식이 이벤트를 받는다 */
|
|
515
|
+
.me-codeui {
|
|
516
|
+
position: absolute;
|
|
517
|
+
z-index: 40;
|
|
518
|
+
transform: translateX(-100%);
|
|
519
|
+
display: flex;
|
|
520
|
+
align-items: center;
|
|
521
|
+
gap: 3px;
|
|
522
|
+
padding: 2px 4px;
|
|
523
|
+
background: var(--me-toolbar-bg, #fff);
|
|
524
|
+
border: 1px solid var(--me-border-color);
|
|
525
|
+
border-radius: 6px;
|
|
526
|
+
box-shadow: 0 2px 8px rgba(15, 23, 42, 0.12);
|
|
527
|
+
white-space: nowrap;
|
|
528
|
+
}
|
|
529
|
+
.me-codeui[hidden] {
|
|
530
|
+
display: none;
|
|
531
|
+
}
|
|
532
|
+
.me-codeui .me-codelang,
|
|
533
|
+
.me-codehead .me-codelang {
|
|
534
|
+
font: inherit;
|
|
535
|
+
font-size: 11px;
|
|
536
|
+
max-width: 7.5em;
|
|
537
|
+
padding: 1px 2px;
|
|
538
|
+
color: var(--me-text-muted, #64748b);
|
|
539
|
+
background: transparent;
|
|
540
|
+
border: none;
|
|
541
|
+
border-radius: 3px;
|
|
542
|
+
cursor: pointer;
|
|
543
|
+
}
|
|
544
|
+
.me-codeui .me-codelang:hover,
|
|
545
|
+
.me-codehead .me-codelang:hover {
|
|
546
|
+
background: var(--me-tool-hover-bg, #e2e8f0);
|
|
547
|
+
}
|
|
548
|
+
.me-codeui .me-codebtn,
|
|
549
|
+
.me-codehead .me-codebtn {
|
|
550
|
+
padding: 1px 7px;
|
|
551
|
+
font: inherit;
|
|
552
|
+
font-size: 11px;
|
|
553
|
+
color: var(--me-text-muted, #64748b);
|
|
554
|
+
background: transparent;
|
|
555
|
+
border: none;
|
|
556
|
+
border-radius: 3px;
|
|
557
|
+
cursor: pointer;
|
|
558
|
+
}
|
|
559
|
+
.me-codeui .me-codebtn:hover,
|
|
560
|
+
.me-codehead .me-codebtn:hover {
|
|
561
|
+
color: inherit;
|
|
562
|
+
background: var(--me-tool-hover-bg, #e2e8f0);
|
|
563
|
+
}
|
|
564
|
+
/* 캐럿이 들어간 코드블록은 첫 줄 우측에 바 자리를 넓힌다 —
|
|
565
|
+
* 바가 코드 텍스트를 가리지 않도록 (기본 언어 라벨 패딩 5em을 덮는다) */
|
|
566
|
+
.me-editor pre.me-line-active .me-cl:first-child {
|
|
567
|
+
padding-right: 13.5em;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/* 코드블록 노드 뷰 — 언어/정리/복사 크롬 헤더(.me-codehead) + pre
|
|
571
|
+
* 아울렛을 한 장의 카드로 묶는다 (Notion/VS Code 코드 카드 관례).
|
|
572
|
+
* 헤더는 .me-node-view의 ce=false 영역이라 캐럿 매핑에 무영향 */
|
|
573
|
+
.me-codeview {
|
|
574
|
+
background: var(--me-code-bg);
|
|
575
|
+
border: 1px solid var(--me-code-border);
|
|
576
|
+
border-radius: 6px;
|
|
577
|
+
}
|
|
578
|
+
.me-codehead {
|
|
579
|
+
display: flex;
|
|
580
|
+
align-items: center;
|
|
581
|
+
justify-content: flex-end;
|
|
582
|
+
gap: 3px;
|
|
583
|
+
padding: 2px 6px;
|
|
584
|
+
border-bottom: 1px solid var(--me-code-border);
|
|
585
|
+
border-radius: 6px 6px 0 0;
|
|
586
|
+
user-select: none;
|
|
587
|
+
}
|
|
588
|
+
/* Notion 관례 — 언어 표시는 좌측, 액션 버튼은 우측 */
|
|
589
|
+
.me-codehead .me-codelang {
|
|
590
|
+
margin-right: auto;
|
|
591
|
+
}
|
|
592
|
+
/* 카드 안 pre — 카드가 배경/테두리를 담당하므로 pre 자체 크롬은 뗀다 */
|
|
593
|
+
.me-codeview > .me-node-content {
|
|
594
|
+
margin: 0;
|
|
595
|
+
border: none;
|
|
596
|
+
border-radius: 0;
|
|
597
|
+
background: transparent;
|
|
598
|
+
}
|
|
599
|
+
/* 노드 뷰 코드블록은 헤더가 언어·액션을 담당 — 오버레이 라벨/바용
|
|
600
|
+
* 첫 줄 우측 패딩(5em/13.5em 규칙보다 뒤에 선언해 덮는다)을 되돌린다 */
|
|
601
|
+
.me-editor .me-codeview .me-cl:first-child {
|
|
602
|
+
padding-right: 0;
|
|
325
603
|
}
|
|
326
604
|
|
|
327
605
|
/* 형광펜 — 브라우저 기본 mark 색을 attr 색이 덮는다 */
|
|
@@ -509,21 +787,25 @@
|
|
|
509
787
|
font-size: 12px;
|
|
510
788
|
}
|
|
511
789
|
|
|
512
|
-
/* 팝오버 — 링크/이미지 입력 패널 (버블 메뉴와 같은
|
|
790
|
+
/* 팝오버 — 링크/이미지 입력 패널 + 표 크기 피커 (버블 메뉴와 같은
|
|
791
|
+
* 크롬). 트리거 버튼 아래에 앵커로 뜨고, 좁은 뷰포트에서는 접혀서
|
|
792
|
+
* 넘치지 않는다 (flex-wrap + max-width) */
|
|
513
793
|
.me-pop {
|
|
514
794
|
position: fixed;
|
|
515
795
|
z-index: 60;
|
|
516
796
|
display: flex;
|
|
517
797
|
align-items: center;
|
|
798
|
+
flex-wrap: wrap;
|
|
518
799
|
gap: 4px;
|
|
519
800
|
padding: 6px;
|
|
801
|
+
max-width: calc(100vw - 16px);
|
|
520
802
|
background: var(--me-toolbar-bg, #fff);
|
|
521
803
|
border: 1px solid var(--me-border-color);
|
|
522
804
|
border-radius: 8px;
|
|
523
805
|
box-shadow: 0 8px 24px rgba(15, 23, 42, 0.18);
|
|
524
806
|
}
|
|
525
807
|
.me-pop-input {
|
|
526
|
-
width: 220px;
|
|
808
|
+
width: min(220px, 46vw);
|
|
527
809
|
padding: 5px 8px;
|
|
528
810
|
font-size: 12px;
|
|
529
811
|
color: inherit;
|
|
@@ -557,6 +839,38 @@
|
|
|
557
839
|
align-items: center;
|
|
558
840
|
}
|
|
559
841
|
|
|
842
|
+
/* 표 크기 피커 — GDocs 표 삽입 그리드 관례. 열 수는 data.ts의
|
|
843
|
+
* TGRID_COLS(10)와 짝 — 바꾸면 둘 다 갱신한다 */
|
|
844
|
+
.me-tgrid {
|
|
845
|
+
display: grid;
|
|
846
|
+
grid-template-columns: repeat(10, 18px);
|
|
847
|
+
gap: 2px;
|
|
848
|
+
}
|
|
849
|
+
.me-tcell {
|
|
850
|
+
width: 18px;
|
|
851
|
+
height: 18px;
|
|
852
|
+
padding: 0;
|
|
853
|
+
border: 1px solid var(--me-border-color);
|
|
854
|
+
border-radius: 3px;
|
|
855
|
+
background: transparent;
|
|
856
|
+
cursor: pointer;
|
|
857
|
+
}
|
|
858
|
+
.me-tcell.is-on {
|
|
859
|
+
background: var(--me-tool-active-bg, #dbeafe);
|
|
860
|
+
border-color: var(--me-accent, #2563eb);
|
|
861
|
+
}
|
|
862
|
+
.me-tcell:focus-visible {
|
|
863
|
+
outline: 2px solid var(--me-editor-focus, #3b82f6);
|
|
864
|
+
outline-offset: -2px;
|
|
865
|
+
}
|
|
866
|
+
.me-tgrid-label {
|
|
867
|
+
padding: 0 4px;
|
|
868
|
+
font-size: 11px;
|
|
869
|
+
color: var(--me-text-color);
|
|
870
|
+
opacity: 0.7;
|
|
871
|
+
white-space: nowrap;
|
|
872
|
+
}
|
|
873
|
+
|
|
560
874
|
/* 링크 카드 — 캐럿이 링크 위에 있을 때 뜨는 액션 칩 (GDocs 관례):
|
|
561
875
|
* URL 표시 + 복사/수정/제거. 수정은 링크 팝오버로 이어진다 */
|
|
562
876
|
.me-linkcard {
|
|
@@ -640,9 +954,19 @@
|
|
|
640
954
|
|
|
641
955
|
display: flex;
|
|
642
956
|
align-items: center;
|
|
643
|
-
|
|
957
|
+
/* 한 줄 원칙 — 넘치는 항목은 두 줄로 내리지 않고 ⋯ 메뉴로 보낸다
|
|
958
|
+
* (data-rsp 티어, 아래 미디어 쿼리).
|
|
959
|
+
* overflow:hidden을 쓰지 않는다 — absolute인 ⋯/A▾의 .me-menu가
|
|
960
|
+
* 툴바 아래로 열릴 때 같이 잘린다. ⋯는 absolute로 우측에 고정하고
|
|
961
|
+
* padding-right로 그 자리를 비워 넘치는 항목이 그 밑으로 스치게 한다 */
|
|
962
|
+
flex-wrap: nowrap;
|
|
963
|
+
/* relative+z-index: 툴바 전체를 에디터(.me-editor relative) 위에
|
|
964
|
+
* 올려 ⋯/A▾ 드롭다운이 본문에 가려지지 않게 한다. 팝오버/버블
|
|
965
|
+
* (fixed, z 50~60)보다는 아래라 겹쳐도 그쪽이 위에 뜬다 */
|
|
966
|
+
position: relative;
|
|
967
|
+
z-index: 20;
|
|
644
968
|
gap: 2px;
|
|
645
|
-
padding: 6px 8px;
|
|
969
|
+
padding: 6px 44px 6px 8px;
|
|
646
970
|
background: var(--me-toolbar-bg);
|
|
647
971
|
border-bottom: 1px solid var(--me-border-color);
|
|
648
972
|
/* IDE 크롬 — 툴 라벨도 코드 에디터 폰트로 */
|
|
@@ -669,9 +993,25 @@
|
|
|
669
993
|
font-size: 13px;
|
|
670
994
|
font-weight: 600;
|
|
671
995
|
cursor: pointer;
|
|
996
|
+
display: inline-flex;
|
|
997
|
+
align-items: center;
|
|
998
|
+
justify-content: center;
|
|
672
999
|
transition: background-color 0.12s ease, color 0.12s ease;
|
|
673
1000
|
}
|
|
674
1001
|
|
|
1002
|
+
/* 툴바 아이콘 — 24px viewBox stroke 아이콘을 currentColor로.
|
|
1003
|
+
* fragment는 경로만 들고 있으므로 스트로크는 여기서 공급한다 */
|
|
1004
|
+
.me-ic {
|
|
1005
|
+
display: block;
|
|
1006
|
+
width: 16px;
|
|
1007
|
+
height: 16px;
|
|
1008
|
+
fill: none;
|
|
1009
|
+
stroke: currentColor;
|
|
1010
|
+
stroke-width: 2;
|
|
1011
|
+
stroke-linecap: round;
|
|
1012
|
+
stroke-linejoin: round;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
675
1015
|
.me-tool:hover:not(:disabled) {
|
|
676
1016
|
background: var(--me-tool-hover-bg);
|
|
677
1017
|
}
|
|
@@ -679,6 +1019,7 @@
|
|
|
679
1019
|
/* 키보드 포커스 표시 — VSCode 크롬 관례 (마우스 클릭엔 링 없음) */
|
|
680
1020
|
.me-tool:focus-visible,
|
|
681
1021
|
.me-overflow > summary:focus-visible,
|
|
1022
|
+
.me-styles > summary:focus-visible,
|
|
682
1023
|
.me-size:focus-visible,
|
|
683
1024
|
.me-blockfmt:focus-visible {
|
|
684
1025
|
outline: 2px solid var(--me-editor-focus, #3b82f6);
|
|
@@ -708,20 +1049,38 @@
|
|
|
708
1049
|
min-width: 74px;
|
|
709
1050
|
}
|
|
710
1051
|
|
|
711
|
-
/*
|
|
712
|
-
*
|
|
713
|
-
*
|
|
714
|
-
|
|
1052
|
+
/* 오버플로/스타일 드롭다운 — 덜 쓰는 커맨드는 ⋯ 아래, 인라인 글자
|
|
1053
|
+
* 서식은 A▾ 아래에 모은다 (GDocs ⋮ overflow·Format 메뉴 관례).
|
|
1054
|
+
* details/summary라 프레임워크 상태 없이 토글되고, 패널 크롬은
|
|
1055
|
+
* 버블 메뉴와 같다 */
|
|
1056
|
+
.me-overflow,
|
|
1057
|
+
.me-styles {
|
|
715
1058
|
position: relative;
|
|
716
1059
|
display: inline-flex;
|
|
717
1060
|
}
|
|
718
|
-
|
|
1061
|
+
/* ⋯는 항상 우측 끝에 살아있어야 한다 — absolute로 핀 고정해 항목이
|
|
1062
|
+
* 넘쳐도 오버플로 진입점이 사라지지 않는다. 넘친 항목이 밑으로
|
|
1063
|
+
* 스치므로 불투명 배경으로 덮는다. absolute라 이 details 자체가
|
|
1064
|
+
* .me-menu의 containing block이다 */
|
|
1065
|
+
.me-toolbar > .me-overflow {
|
|
1066
|
+
position: absolute;
|
|
1067
|
+
/* translateY 중앙정렬 대신 패딩과 같은 top — transform은 스태킹
|
|
1068
|
+
* 컨텍스트를 만들어 자식 .me-menu의 z-index를 가둔다 */
|
|
1069
|
+
right: 8px;
|
|
1070
|
+
top: 6px;
|
|
1071
|
+
flex-shrink: 0;
|
|
1072
|
+
background: var(--me-toolbar-bg);
|
|
1073
|
+
border-radius: 6px;
|
|
1074
|
+
}
|
|
1075
|
+
.me-overflow > summary,
|
|
1076
|
+
.me-styles > summary {
|
|
719
1077
|
list-style: none;
|
|
720
1078
|
cursor: pointer;
|
|
721
1079
|
user-select: none;
|
|
722
1080
|
display: inline-flex;
|
|
723
1081
|
align-items: center;
|
|
724
1082
|
justify-content: center;
|
|
1083
|
+
gap: 2px;
|
|
725
1084
|
min-width: 30px;
|
|
726
1085
|
height: 30px;
|
|
727
1086
|
padding: 0 7px;
|
|
@@ -730,20 +1089,34 @@
|
|
|
730
1089
|
font-weight: 600;
|
|
731
1090
|
color: var(--me-text-color);
|
|
732
1091
|
}
|
|
733
|
-
.me-overflow > summary::-webkit-details-marker
|
|
1092
|
+
.me-overflow > summary::-webkit-details-marker,
|
|
1093
|
+
.me-styles > summary::-webkit-details-marker {
|
|
734
1094
|
display: none;
|
|
735
1095
|
}
|
|
736
|
-
.me-overflow > summary:hover
|
|
1096
|
+
.me-overflow > summary:hover,
|
|
1097
|
+
.me-styles > summary:hover {
|
|
737
1098
|
background: var(--me-tool-hover-bg);
|
|
738
1099
|
}
|
|
739
|
-
.me-overflow[open] > summary
|
|
1100
|
+
.me-overflow[open] > summary,
|
|
1101
|
+
.me-styles[open] > summary {
|
|
740
1102
|
background: var(--me-tool-active-bg);
|
|
741
1103
|
color: var(--me-tool-active-color);
|
|
742
1104
|
}
|
|
1105
|
+
/* A▾ 드롭다운 표시 — 스타일 패널 버튼 뒤의 캐럿 */
|
|
1106
|
+
.me-styles > summary::after {
|
|
1107
|
+
content: "";
|
|
1108
|
+
width: 0;
|
|
1109
|
+
height: 0;
|
|
1110
|
+
border-left: 3px solid transparent;
|
|
1111
|
+
border-right: 3px solid transparent;
|
|
1112
|
+
border-top: 4px solid currentColor;
|
|
1113
|
+
opacity: 0.6;
|
|
1114
|
+
}
|
|
743
1115
|
.me-menu {
|
|
744
1116
|
position: absolute;
|
|
745
1117
|
top: calc(100% + 6px);
|
|
746
1118
|
right: 0;
|
|
1119
|
+
left: auto;
|
|
747
1120
|
z-index: 60;
|
|
748
1121
|
display: flex;
|
|
749
1122
|
align-items: center;
|
|
@@ -755,8 +1128,41 @@
|
|
|
755
1128
|
box-shadow: 0 8px 24px rgba(15, 23, 42, 0.18);
|
|
756
1129
|
white-space: nowrap;
|
|
757
1130
|
}
|
|
1131
|
+
/* A▾ 패널은 툴바 중간에서 열리므로 버튼 왼쪽 아래에 붙인다 */
|
|
1132
|
+
.me-styles .me-menu {
|
|
1133
|
+
right: auto;
|
|
1134
|
+
left: 0;
|
|
1135
|
+
}
|
|
758
1136
|
|
|
759
|
-
/* 툴바
|
|
1137
|
+
/* ── 반응형 툴바 — 한 줄 원칙 + ⋯ 오버플로 축소 ────────────────
|
|
1138
|
+
* data-rsp 티어: 1 = ≤900px(삽입/정렬 그룹), 2 = ≤620px(목록·보조
|
|
1139
|
+
* 서식 + A▾ 패널). 본줄의 티어 요소는 숨기고, ⋯ 메뉴 안의 같은
|
|
1140
|
+
* 항목(data-rsp가 달린 복사본)만 연다 — 항목은 양쪽에 렌더되고
|
|
1141
|
+
* 표시 여부만 CSS가 가른다. 브레이크포인트는 TOOL_ITEMS의 rsp
|
|
1142
|
+
* 값과 짝이다 (뷰포트 기준 — 데모 .page가 툴바 폭을 지배한다) */
|
|
1143
|
+
.me-menu [data-rsp] {
|
|
1144
|
+
display: none;
|
|
1145
|
+
}
|
|
1146
|
+
@media (max-width: 900px) {
|
|
1147
|
+
.me-toolbar > [data-rsp="1"],
|
|
1148
|
+
.me-toolbar > .me-styles[data-rsp="1"] {
|
|
1149
|
+
display: none;
|
|
1150
|
+
}
|
|
1151
|
+
.me-menu [data-rsp="1"] {
|
|
1152
|
+
display: inline-flex;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
@media (max-width: 620px) {
|
|
1156
|
+
.me-toolbar > [data-rsp="2"],
|
|
1157
|
+
.me-toolbar > .me-styles[data-rsp="2"] {
|
|
1158
|
+
display: none;
|
|
1159
|
+
}
|
|
1160
|
+
.me-menu [data-rsp="2"] {
|
|
1161
|
+
display: inline-flex;
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
/* 툴바 인라인 스타일 컨트롤 — A▾ 패널 안의 컬러 피커/크기 셀렉트 */
|
|
760
1166
|
.me-style {
|
|
761
1167
|
display: inline-flex;
|
|
762
1168
|
align-items: center;
|
|
@@ -843,10 +1249,10 @@
|
|
|
843
1249
|
--me-gutter-bg: rgba(0, 0, 0, 0.22);
|
|
844
1250
|
--me-gutter-color: #8f908a;
|
|
845
1251
|
--me-line-active-num: #c2c2bf;
|
|
1252
|
+
--me-node-sel-color: #66d9ef;
|
|
846
1253
|
}
|
|
847
1254
|
|
|
848
1255
|
.me-frame[data-me-theme="dark"] {
|
|
849
|
-
--me-focus-ring: rgba(102, 217, 239, 0.25);
|
|
850
1256
|
background: #1e1f1c;
|
|
851
1257
|
}
|
|
852
1258
|
|
|
@@ -856,7 +1262,6 @@
|
|
|
856
1262
|
--me-code-bg: #1e1f1c;
|
|
857
1263
|
--me-code-border: #3e3d32;
|
|
858
1264
|
--me-gutter-border: #3e3d32;
|
|
859
|
-
--me-line-active-bg: rgba(255, 255, 255, 0.045);
|
|
860
1265
|
--me-sel-bg: rgba(73, 72, 62, 0.95);
|
|
861
1266
|
--me-print-margin: rgba(73, 72, 62, 0.9);
|
|
862
1267
|
}
|
|
@@ -919,6 +1324,14 @@
|
|
|
919
1324
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
|
|
920
1325
|
}
|
|
921
1326
|
|
|
1327
|
+
[data-me-theme="dark"] .me-imgui {
|
|
1328
|
+
--me-toolbar-bg: #1e1f1c;
|
|
1329
|
+
--me-btn-bg: #3e3d32;
|
|
1330
|
+
--me-tool-hover-bg: #575643;
|
|
1331
|
+
--me-accent: #66d9ef;
|
|
1332
|
+
box-shadow: none;
|
|
1333
|
+
}
|
|
1334
|
+
|
|
922
1335
|
[data-me-theme="dark"] .me-pop,
|
|
923
1336
|
[data-me-theme="dark"] .me-linkcard {
|
|
924
1337
|
--me-toolbar-bg: #1e1f1c;
|
package/dist/view/dom.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["../../src/view/dom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD;;;;;;;;GAQG;AAEH,eAAO,MAAM,SAAS,iBAAiB,CAAC;AAqDxC,wCAAwC;AACxC,wBAAgB,UAAU,CACxB,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,IAAI,EACb,SAAS,EAAE,MAAM,GAChB,KAAK,GAAG,IAAI,CA0Cd;AAED,+CAA+C;AAC/C,wBAAgB,UAAU,CACxB,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,KAAK,GACX;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"dom.d.ts","sourceRoot":"","sources":["../../src/view/dom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD;;;;;;;;GAQG;AAEH,eAAO,MAAM,SAAS,iBAAiB,CAAC;AAqDxC,wCAAwC;AACxC,wBAAgB,UAAU,CACxB,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,IAAI,EACb,SAAS,EAAE,MAAM,GAChB,KAAK,GAAG,IAAI,CA0Cd;AAED,+CAA+C;AAC/C,wBAAgB,UAAU,CACxB,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,KAAK,GACX;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAsHvC;AAED,6CAA6C;AAC7C,wBAAgB,YAAY,CAC1B,IAAI,EAAE,WAAW,GAChB;IAAE,MAAM,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG,IAAI,CAmCxC;AAED,8BAA8B;AAC9B,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,KAAK,EACb,KAAK,EAAE,KAAK,GACX,IAAI,CAMN"}
|