@leviosa-ai/detail-page-editor 0.15.0 → 0.15.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.
|
@@ -115,6 +115,14 @@ export function LeviosaCanvasWorkspace({
|
|
|
115
115
|
const outerRef = useRef<HTMLDivElement>(null);
|
|
116
116
|
const innerRef = useRef<HTMLDivElement>(null);
|
|
117
117
|
const [viewport, setViewport] = useState({ width: 0, height: 0 });
|
|
118
|
+
const [panning, setPanning] = useState(false);
|
|
119
|
+
const pan = useRef<{
|
|
120
|
+
pointerId: number;
|
|
121
|
+
x: number;
|
|
122
|
+
y: number;
|
|
123
|
+
left: number;
|
|
124
|
+
top: number;
|
|
125
|
+
} | null>(null);
|
|
118
126
|
// 배율은 **스토어**에 산다. 확대 버튼도, 여기 휠도 같은 자리를 만져야 한 쪽이
|
|
119
127
|
// 다른 쪽을 되돌려 놓지 않는다.
|
|
120
128
|
const scale = store.scale;
|
|
@@ -415,7 +423,10 @@ export function LeviosaCanvasWorkspace({
|
|
|
415
423
|
const target = event.target as HTMLElement;
|
|
416
424
|
if (
|
|
417
425
|
target.closest("[data-lc-page]") ||
|
|
418
|
-
target.closest("[data-dp-quicktoolbar]")
|
|
426
|
+
target.closest("[data-dp-quicktoolbar]") ||
|
|
427
|
+
target.closest(
|
|
428
|
+
"button, a, input, textarea, select, [contenteditable='true']",
|
|
429
|
+
)
|
|
419
430
|
) {
|
|
420
431
|
return;
|
|
421
432
|
}
|
|
@@ -424,21 +435,49 @@ export function LeviosaCanvasWorkspace({
|
|
|
424
435
|
// 여기가 «저 벌을 보겠다»고 말하는 유일한 자리다.
|
|
425
436
|
const key = target.closest<HTMLElement>("[data-lc-frame]")?.dataset
|
|
426
437
|
.lcFrame;
|
|
427
|
-
if (key
|
|
428
|
-
|
|
429
|
-
|
|
438
|
+
if (key !== undefined) {
|
|
439
|
+
const first = store.pages.find((page) => frameOf(page) === key);
|
|
440
|
+
if (first) store.selectPage(first.id);
|
|
441
|
+
}
|
|
442
|
+
if (event.button !== 0) return;
|
|
443
|
+
pan.current = {
|
|
444
|
+
pointerId: event.pointerId,
|
|
445
|
+
x: event.clientX,
|
|
446
|
+
y: event.clientY,
|
|
447
|
+
left: event.currentTarget.scrollLeft,
|
|
448
|
+
top: event.currentTarget.scrollTop,
|
|
449
|
+
};
|
|
450
|
+
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
451
|
+
setPanning(true);
|
|
452
|
+
event.preventDefault();
|
|
453
|
+
}}
|
|
454
|
+
onPointerMove={(event) => {
|
|
455
|
+
const start = pan.current;
|
|
456
|
+
if (!start || start.pointerId !== event.pointerId) return;
|
|
457
|
+
event.currentTarget.scrollLeft = start.left + start.x - event.clientX;
|
|
458
|
+
event.currentTarget.scrollTop = start.top + start.y - event.clientY;
|
|
459
|
+
}}
|
|
460
|
+
onPointerUp={(event) => {
|
|
461
|
+
if (pan.current?.pointerId !== event.pointerId) return;
|
|
462
|
+
pan.current = null;
|
|
463
|
+
event.currentTarget.releasePointerCapture?.(event.pointerId);
|
|
464
|
+
setPanning(false);
|
|
465
|
+
}}
|
|
466
|
+
onPointerCancel={(event) => {
|
|
467
|
+
if (pan.current?.pointerId !== event.pointerId) return;
|
|
468
|
+
pan.current = null;
|
|
469
|
+
setPanning(false);
|
|
430
470
|
}}
|
|
431
471
|
style={{
|
|
432
472
|
position: "absolute",
|
|
433
473
|
inset: 0,
|
|
434
|
-
//
|
|
435
|
-
|
|
436
|
-
// 붙여 놓고 가로 스크롤을 연다.
|
|
437
|
-
overflowX: frameCount > 1 ? "auto" : "hidden",
|
|
474
|
+
// 자동 여백으로 가운데를 잡으면 확대해 넘친 뒤에도 양쪽으로 스크롤할 수 있다.
|
|
475
|
+
overflowX: "auto",
|
|
438
476
|
overflowY: "auto",
|
|
439
477
|
display: "flex",
|
|
440
478
|
flexDirection: "column",
|
|
441
|
-
alignItems:
|
|
479
|
+
alignItems: "flex-start",
|
|
480
|
+
cursor: panning ? "grabbing" : "default",
|
|
442
481
|
padding: `${frameCount > 1 ? gap + FRAME_HEAD : gap}px ${paddingX}px ${gap}px`,
|
|
443
482
|
}}
|
|
444
483
|
>
|
|
@@ -446,9 +485,9 @@ export function LeviosaCanvasWorkspace({
|
|
|
446
485
|
store={store}
|
|
447
486
|
scale={scale}
|
|
448
487
|
gap={gap}
|
|
449
|
-
//
|
|
450
|
-
//
|
|
451
|
-
center
|
|
488
|
+
// 가운데 정렬은 자동 여백으로 준다 — 축소해서 남는 자리가 생겨도 가운데를
|
|
489
|
+
// 지키고, 커지면 여백이 0이 되어 좌우 스크롤이 열린다.
|
|
490
|
+
center
|
|
452
491
|
// 손잡이는 판 상자 **안**에 산다. 밖에서 자리를 재어 띄우면 손이 다가가는
|
|
453
492
|
// 동안 «판 밖»을 지나며 깜빡인다.
|
|
454
493
|
renderPageChrome={
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leviosa-ai/detail-page-editor",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"description": "Leviosa detail-page editor shell. Source-only: consumers compile it through Next transpilePackages. Every app coupling (sourcing server, brand store, cache keys, toast) arrives through the DetailPageHost interface, and every URL it fetches comes from configureDetailPageEditor.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|