ninegrid2 6.857.0 → 6.859.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.
@@ -121167,20 +121167,25 @@ class nxSplitter extends HTMLElement {
121167
121167
  this.#mode = (!prevRect || !nextRect) || (Math.abs(prevRect.top - nextRect.top) < 5) ? "h" : "v";
121168
121168
  };
121169
121169
 
121170
- #startDrag_BAK = (e) => {
121171
- e.preventDefault();
121170
+ // 이전 #startDrag_BAK 함수는 삭제하거나 주석 처리합니다.
121171
+ // #startDrag_BAK = (...) => { ... }
121172
+
121173
+ #startDrag = (e) => {
121174
+ e.preventDefault(); // 기본 drag/select 동작 제거
121172
121175
  e.stopPropagation();
121173
121176
 
121174
121177
  const splitterRect = this.getBoundingClientRect();
121175
121178
  const isHorizontal = this.#mode === "h";
121176
121179
 
121177
- // 클릭 지점에서 스플리터 경계까지의 오프셋
121180
+ // 클릭 지점에서 스플리터 경계까지의 오프셋 (이것은 dragBar 초기 위치와는 별개로, 최종 패널 사이즈 계산에 사용됨)
121178
121181
  isHorizontal
121179
121182
  ? e.clientX - splitterRect.left
121180
121183
  : e.clientY - splitterRect.top;
121181
121184
 
121182
121185
  const dragBar = document.createElement("div");
121183
121186
  dragBar.className = `nx-splitter-drag-bar-${this.#mode}`;
121187
+
121188
+ // 스타일 지정
121184
121189
  Object.assign(dragBar.style, {
121185
121190
  position: "absolute",
121186
121191
  zIndex: "999",
@@ -121190,7 +121195,6 @@ class nxSplitter extends HTMLElement {
121190
121195
  });
121191
121196
 
121192
121197
  const root = this.getRootNode({ composed: true });
121193
- // parent는 스플리터의 직접적인 컨테이너 (flex 컨테이너 역할)
121194
121198
  const parent = root instanceof ShadowRoot ? root.host : this.parentElement;
121195
121199
 
121196
121200
  const prev = this.previousElementSibling;
@@ -121201,84 +121205,88 @@ class nxSplitter extends HTMLElement {
121201
121205
  return;
121202
121206
  }
121203
121207
 
121204
- const parentRect = parent.getBoundingClientRect();
121205
- const prevRect = prev.getBoundingClientRect();
121206
- const nextRect = next.getBoundingClientRect();
121208
+ // dragBar를 먼저 DOM에 추가하여 offsetParent를 확보합니다.
121209
+ (parent.shadowRoot || parent).appendChild(dragBar);
121210
+
121211
+ // dragBar의 실제 offsetParent (position: absolute의 기준이 되는 요소)
121212
+ const dragBarOffsetParent = dragBar.offsetParent;
121213
+
121214
+ if (!dragBarOffsetParent) {
121215
+ console.error("dragBar's offsetParent could not be determined. Ensure parent or an ancestor has a position property (e.g., relative).");
121216
+ dragBar.remove(); // 실패 시 dragBar 제거
121217
+ return;
121218
+ }
121219
+
121220
+ const dragBarOffsetParentRect = dragBarOffsetParent.getBoundingClientRect();
121221
+ const prevRect = prev.getBoundingClientRect(); // 뷰포트 기준
121222
+ const nextRect = next.getBoundingClientRect(); // 뷰포트 기준
121223
+
121207
121224
 
121208
- // dragBar의 초기 위치 설정 (parent 기준)
121209
- // padding을 고려하지 않고 parentRect를 기준으로 하는 것이 일반적이며,
121210
- // 스플리터 컨테이너의 flex-basis가 padding을 포함하는지 여부에 따라 조절.
121211
- // 여기서는 parent의 content-box 기준으로 relative 위치를 계산.
121212
- let initialPos;
121225
+ // 뷰포트 기준 클릭 위치를 dragBarOffsetParent 기준으로 변환하여 초기 dragBar 위치 설정
121226
+ let initialPosInOffsetParent;
121213
121227
  if (isHorizontal) {
121214
- initialPos = e.clientX - parentRect.left;
121228
+ initialPosInOffsetParent = e.clientX - dragBarOffsetParentRect.left;
121215
121229
  dragBar.style.top = "0";
121216
- dragBar.style.left = `${initialPos}px`;
121230
+ dragBar.style.left = `${initialPosInOffsetParent}px`;
121217
121231
  dragBar.style.width = "1px";
121218
121232
  dragBar.style.height = "100%";
121219
121233
  } else {
121220
- initialPos = e.clientY - parentRect.top;
121234
+ initialPosInOffsetParent = e.clientY - dragBarOffsetParentRect.top;
121221
121235
  dragBar.style.left = "0";
121222
- dragBar.style.top = `${initialPos}px`;
121236
+ dragBar.style.top = `${initialPosInOffsetParent}px`;
121223
121237
  dragBar.style.height = "1px";
121224
121238
  dragBar.style.width = "100%";
121225
121239
  }
121226
121240
 
121227
- // Shadow DOM이 있다면 ShadowRoot에, 아니면 일반 DOM에 삽입
121228
- (parent.shadowRoot || parent).appendChild(dragBar);
121241
+ // 드래그 가능한 최소/최대 범위 (dragBarOffsetParent 기준으로 변환)
121242
+ const minLimit = isHorizontal
121243
+ ? prevRect.left - dragBarOffsetParentRect.left
121244
+ : prevRect.top - dragBarOffsetParentRect.top;
121245
+ const maxLimit = isHorizontal
121246
+ ? nextRect.right - dragBarOffsetParentRect.left
121247
+ : nextRect.bottom - dragBarOffsetParentRect.top;
121229
121248
 
121230
- // 드래그 가능한 범위 (부모 요소 내에서 이전/다음 엘리먼트의 실제 경계 기준)
121231
- const minLimit = isHorizontal ? prevRect.left : prevRect.top;
121232
- const maxLimit = isHorizontal ? nextRect.right : nextRect.bottom;
121233
121249
 
121234
121250
  const onMove = moveEvent => {
121235
121251
  const clientPos = isHorizontal ? moveEvent.clientX : moveEvent.clientY;
121236
- // 드래그 바가 부모 영역을 벗어나지 않도록 클램프
121237
- const clampedPos = Math.max(minLimit, Math.min(clientPos, maxLimit));
121252
+ // 뷰포트 기준 클릭 위치를 offsetParent 기준으로 변환
121253
+ const currentPosInOffsetParent = isHorizontal
121254
+ ? clientPos - dragBarOffsetParentRect.left
121255
+ : clientPos - dragBarOffsetParentRect.top;
121238
121256
 
121239
- // 부모 기준으로 드래그 바의 상대 위치
121240
- const relativePos = clampedPos - parentRect[isHorizontal ? "left" : "top"];
121257
+ // 드래그 바가 최소/최대 범위 내에 있도록 클램프
121258
+ const clampedPos = Math.max(minLimit, Math.min(currentPosInOffsetParent, maxLimit));
121241
121259
 
121242
121260
  if (isHorizontal) {
121243
- dragBar.style.left = `${relativePos}px`;
121261
+ dragBar.style.left = `${clampedPos}px`;
121244
121262
  } else {
121245
- dragBar.style.top = `${relativePos}px`;
121263
+ dragBar.style.top = `${clampedPos}px`;
121246
121264
  }
121247
121265
  };
121248
121266
 
121249
- const onUp = upEvent => {
121267
+ const onUp = (upEvent) => {
121250
121268
  window.removeEventListener("mousemove", onMove);
121251
121269
  window.removeEventListener("mouseup", onUp);
121252
121270
  dragBar.remove();
121253
121271
 
121254
- // 최종 드래그 바의 위치를 기준으로 새 크기 계산
121255
- const finalDragBarPos = isHorizontal
121272
+ // 최종 드래그 바의 위치를 offsetParent 기준으로 가져옴
121273
+ const finalDragBarPosInOffsetParent = isHorizontal
121256
121274
  ? parseFloat(dragBar.style.left)
121257
121275
  : parseFloat(dragBar.style.top);
121258
121276
 
121259
- // 이전 요소의 새로운 크기 (부모의 좌측/상단 경계부터 드래그 바까지)
121260
- const newPrevSize = finalDragBarPos;
121277
+ // 이전 요소의 새로운 크기 (offsetParent의 시작점부터 드래그 바까지)
121278
+ const newPrevSize = finalDragBarPosInOffsetParent;
121261
121279
 
121262
- // 다음 요소의 새로운 크기 (부모의 전체 크기에서 이전 요소 크기를 뺀 값)
121263
- const parentTotalSize = isHorizontal ? parentRect.width : parentRect.height;
121264
- const newNextSize = parentTotalSize - newPrevSize;
121280
+ // 다음 요소의 새로운 크기 (offsetParent의 전체 크기에서 이전 요소 크기를 뺀 값)
121281
+ const offsetParentTotalSize = isHorizontal
121282
+ ? dragBarOffsetParentRect.width
121283
+ : dragBarOffsetParentRect.height;
121284
+ const newNextSize = offsetParentTotalSize - newPrevSize;
121265
121285
 
121266
- // 최소/최대 크기 제약 (예: 1px 미만으로 작아지지 않도록)
121267
121286
  const MIN_PANEL_SIZE = 1; // 패널 최소 크기
121268
121287
  let finalPrevSize = Math.max(MIN_PANEL_SIZE, newPrevSize);
121269
121288
  let finalNextSize = Math.max(MIN_PANEL_SIZE, newNextSize);
121270
121289
 
121271
- // flex 레이아웃에 직접 width/height를 부여하는 대신 flex-basis를 사용하거나
121272
- // flex-grow 비율을 재조정하는 것이 일반적이나, 현재 flex: none; 으로 제어하는 방식을 유지한다면,
121273
- // 이와 같이 직접 style.width/height를 설정.
121274
- // 하지만 flex 컨테이너 내부에서는 flex-basis를 설정하는 것이 더 바람직합니다.
121275
- // 여기서는 기존 코드의 스타일 설정을 유지하면서 값을 정확히 계산.
121276
-
121277
- // flex-grow 비율로 제어하는 경우
121278
- // const currentTotalFlex = parseFloat(getComputedStyle(prev).flexGrow || 0) + parseFloat(getComputedStyle(next).flexGrow || 0);
121279
- // prev.style.flexGrow = (newPrevSize / parentTotalSize) * currentTotalFlex;
121280
- // next.style.flexGrow = (newNextSize / parentTotalSize) * currentTotalFlex;
121281
-
121282
121290
  // 기존 flex 값을 저장하고 복원
121283
121291
  const originalPrevFlex = prev.style.flex;
121284
121292
  const originalNextFlex = next.style.flex;
@@ -121296,8 +121304,8 @@ class nxSplitter extends HTMLElement {
121296
121304
  }
121297
121305
 
121298
121306
  // 작업 완료 후 원래 flex 값으로 복원
121299
- // 단, width/height가 설정된 경우 flex 속성이 다시 적용되면 겹칠 있으므로 주의 필요.
121300
- // 일반적으로 flex-basis 사용하거나, width/height 설정 후 flex-grow/shrink를 기본값으로 돌리는 것을 고려.
121307
+ // 주의: width/height가 설정된 상태에서 flex 복원하면 충돌할있음.
121308
+ // flex-basis flex-grow/shrink를 적절히 조절하는 것이 더 견고한 방법.
121301
121309
  prev.style.flex = originalPrevFlex;
121302
121310
  next.style.flex = originalNextFlex;
121303
121311
  };
@@ -121306,137 +121314,6 @@ class nxSplitter extends HTMLElement {
121306
121314
  window.addEventListener("mouseup", onUp);
121307
121315
  };
121308
121316
 
121309
- #startDrag = (e) => {
121310
-
121311
- e.preventDefault(); // 기본 drag/select 동작 제거
121312
- e.stopPropagation();
121313
-
121314
- const splitterRect = this.getBoundingClientRect();
121315
- const clickOffset = this.#mode === "h"
121316
- ? e.clientX - splitterRect.left
121317
- : e.clientY - splitterRect.top;
121318
-
121319
- //const mode = this.#mode;
121320
- const dragBar = document.createElement("div");
121321
- dragBar.className = `nx-splitter-drag-bar-${this.#mode}`;
121322
-
121323
- // 스타일 지정
121324
- Object.assign(dragBar.style, {
121325
- position: "absolute",
121326
- zIndex: "999",
121327
- background: "#666",
121328
- opacity: "0.6",
121329
- pointerEvents: "none"
121330
- });
121331
-
121332
- const root = this.getRootNode({ composed: true });
121333
- const parent = root instanceof ShadowRoot ? root.host : this.parentElement || document.body;
121334
-
121335
- //const parent = this.getRootNode().host || this.parentElement;
121336
- const prev = this.previousElementSibling;
121337
- const next = this.nextElementSibling;
121338
-
121339
- if (!parent || !prev || !next) return;
121340
-
121341
- const parentRect = parent.getBoundingClientRect();
121342
- const prevRect = prev.getBoundingClientRect();
121343
- const nextRect = next.getBoundingClientRect();
121344
-
121345
- /**
121346
- const clientPos = this.#mode === "h" ? e.clientX : e.clientY;
121347
- const position = Math.max(min, Math.min(clientPos, max));
121348
- const relative = position - parent.getBoundingClientRect()[this.#mode === "h" ? "left" : "top"];
121349
- */
121350
-
121351
- const left = e.clientX - parentRect.left;
121352
- const top = e.clientY - parentRect.top;
121353
-
121354
- console.log(left, top);
121355
-
121356
- // 방향별 위치 설정
121357
- if (this.#mode === "h") {
121358
- dragBar.style.top = "0";
121359
- dragBar.style.left = `${left}px`;
121360
- dragBar.style.width = "1px";
121361
- dragBar.style.height = "100%";
121362
- } else {
121363
- dragBar.style.left = "0";
121364
- dragBar.style.top = `${top}px`;
121365
- dragBar.style.height = "1px";
121366
- dragBar.style.width = "100%";
121367
- }
121368
-
121369
- // 👇 부모 노드 기준으로 삽입
121370
- (parent.shadowRoot || parent).appendChild(dragBar);
121371
-
121372
- const min = this.#mode === "h" ? prevRect.left : prevRect.top;
121373
- const max = this.#mode === "h" ? nextRect.right : nextRect.bottom;
121374
-
121375
- const onMove = e => {
121376
- const clientPos = this.#mode === "h" ? e.clientX : e.clientY;
121377
- const position = Math.max(min, Math.min(clientPos, max));
121378
-
121379
- const relative = position - parent.getBoundingClientRect()[this.#mode === "h" ? "left" : "top"];
121380
-
121381
- if (this.#mode === "h") {
121382
- dragBar.style.left = `${relative}px`;
121383
- } else {
121384
- dragBar.style.top = `${relative}px`;
121385
- }
121386
-
121387
- console.log(relative);
121388
- };
121389
-
121390
-
121391
-
121392
- const onUp = (e) => {
121393
-
121394
- window.removeEventListener("mousemove", onMove);
121395
- window.removeEventListener("mouseup", onUp);
121396
- dragBar.remove();
121397
-
121398
-
121399
- // 기준: prev + next 너비 합계
121400
- const totalSize = this.#mode === "h"
121401
- ? prev.offsetWidth + next.offsetWidth
121402
- : prev.offsetHeight + next.offsetHeight;
121403
-
121404
- // prev 기준 상대 거리 (드래그 거리)
121405
-
121406
- let delta = this.#mode === "h"
121407
- ? e.clientX - prev.getBoundingClientRect().left - clickOffset
121408
- : e.clientY - prev.getBoundingClientRect().top - clickOffset;
121409
- //let delta = dragStartPos - prev.getBoundingClientRect()[this.#mode === "h" ? "left" : "top"];
121410
-
121411
- const min = 1;
121412
- const max = totalSize - 1;
121413
- delta = Math.max(min, Math.min(delta, max));
121414
-
121415
-
121416
- const prev1 = prev.style.flex;
121417
- const prev2 = next.style.flex;
121418
- prev.style.flex = "none";
121419
- next.style.flex = "none";
121420
-
121421
- console.log(delta, totalSize);
121422
-
121423
- // 📌 사이즈 적용
121424
- if (this.#mode === "h") {
121425
- prev.style.width = `${delta}px`;
121426
- next.style.width = `${totalSize - delta}px`;
121427
- } else {
121428
- prev.style.height = `${delta}px`;
121429
- next.style.height = `${totalSize - delta}px`;
121430
- }
121431
-
121432
- prev.style.flex = prev1;
121433
- next.style.flex = prev2;
121434
- };
121435
-
121436
- window.addEventListener("mousemove", onMove);
121437
- window.addEventListener("mouseup", onUp);
121438
- };
121439
-
121440
121317
 
121441
121318
  #init = () => {
121442
121319
  this.#detectMode(this);
@@ -121450,13 +121327,13 @@ class nxSplitter extends HTMLElement {
121450
121327
  this.innerHTML = ""; // 기존 내부 HTML 제거
121451
121328
  const htmlTmpl = document.createElement("template");
121452
121329
  htmlTmpl.innerHTML = `
121453
- <style>
121454
- @import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxSplitter.css";
121455
- ${ninegrid.getCustomPath(this,"nxSplitter.css")}
121456
- </style>
121457
-
121458
- ${gripTmpl}
121459
- `;
121330
+ <style>
121331
+ @import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxSplitter.css";
121332
+ ${ninegrid.getCustomPath(this,"nxSplitter.css")}
121333
+ </style>
121334
+
121335
+ ${gripTmpl}
121336
+ `;
121460
121337
 
121461
121338
  this.shadowRoot.appendChild(htmlTmpl.content.cloneNode(true));
121462
121339
 
@@ -121163,20 +121163,25 @@ class nxSplitter extends HTMLElement {
121163
121163
  this.#mode = (!prevRect || !nextRect) || (Math.abs(prevRect.top - nextRect.top) < 5) ? "h" : "v";
121164
121164
  };
121165
121165
 
121166
- #startDrag_BAK = (e) => {
121167
- e.preventDefault();
121166
+ // 이전 #startDrag_BAK 함수는 삭제하거나 주석 처리합니다.
121167
+ // #startDrag_BAK = (...) => { ... }
121168
+
121169
+ #startDrag = (e) => {
121170
+ e.preventDefault(); // 기본 drag/select 동작 제거
121168
121171
  e.stopPropagation();
121169
121172
 
121170
121173
  const splitterRect = this.getBoundingClientRect();
121171
121174
  const isHorizontal = this.#mode === "h";
121172
121175
 
121173
- // 클릭 지점에서 스플리터 경계까지의 오프셋
121176
+ // 클릭 지점에서 스플리터 경계까지의 오프셋 (이것은 dragBar 초기 위치와는 별개로, 최종 패널 사이즈 계산에 사용됨)
121174
121177
  isHorizontal
121175
121178
  ? e.clientX - splitterRect.left
121176
121179
  : e.clientY - splitterRect.top;
121177
121180
 
121178
121181
  const dragBar = document.createElement("div");
121179
121182
  dragBar.className = `nx-splitter-drag-bar-${this.#mode}`;
121183
+
121184
+ // 스타일 지정
121180
121185
  Object.assign(dragBar.style, {
121181
121186
  position: "absolute",
121182
121187
  zIndex: "999",
@@ -121186,7 +121191,6 @@ class nxSplitter extends HTMLElement {
121186
121191
  });
121187
121192
 
121188
121193
  const root = this.getRootNode({ composed: true });
121189
- // parent는 스플리터의 직접적인 컨테이너 (flex 컨테이너 역할)
121190
121194
  const parent = root instanceof ShadowRoot ? root.host : this.parentElement;
121191
121195
 
121192
121196
  const prev = this.previousElementSibling;
@@ -121197,84 +121201,88 @@ class nxSplitter extends HTMLElement {
121197
121201
  return;
121198
121202
  }
121199
121203
 
121200
- const parentRect = parent.getBoundingClientRect();
121201
- const prevRect = prev.getBoundingClientRect();
121202
- const nextRect = next.getBoundingClientRect();
121204
+ // dragBar를 먼저 DOM에 추가하여 offsetParent를 확보합니다.
121205
+ (parent.shadowRoot || parent).appendChild(dragBar);
121206
+
121207
+ // dragBar의 실제 offsetParent (position: absolute의 기준이 되는 요소)
121208
+ const dragBarOffsetParent = dragBar.offsetParent;
121209
+
121210
+ if (!dragBarOffsetParent) {
121211
+ console.error("dragBar's offsetParent could not be determined. Ensure parent or an ancestor has a position property (e.g., relative).");
121212
+ dragBar.remove(); // 실패 시 dragBar 제거
121213
+ return;
121214
+ }
121215
+
121216
+ const dragBarOffsetParentRect = dragBarOffsetParent.getBoundingClientRect();
121217
+ const prevRect = prev.getBoundingClientRect(); // 뷰포트 기준
121218
+ const nextRect = next.getBoundingClientRect(); // 뷰포트 기준
121219
+
121203
121220
 
121204
- // dragBar의 초기 위치 설정 (parent 기준)
121205
- // padding을 고려하지 않고 parentRect를 기준으로 하는 것이 일반적이며,
121206
- // 스플리터 컨테이너의 flex-basis가 padding을 포함하는지 여부에 따라 조절.
121207
- // 여기서는 parent의 content-box 기준으로 relative 위치를 계산.
121208
- let initialPos;
121221
+ // 뷰포트 기준 클릭 위치를 dragBarOffsetParent 기준으로 변환하여 초기 dragBar 위치 설정
121222
+ let initialPosInOffsetParent;
121209
121223
  if (isHorizontal) {
121210
- initialPos = e.clientX - parentRect.left;
121224
+ initialPosInOffsetParent = e.clientX - dragBarOffsetParentRect.left;
121211
121225
  dragBar.style.top = "0";
121212
- dragBar.style.left = `${initialPos}px`;
121226
+ dragBar.style.left = `${initialPosInOffsetParent}px`;
121213
121227
  dragBar.style.width = "1px";
121214
121228
  dragBar.style.height = "100%";
121215
121229
  } else {
121216
- initialPos = e.clientY - parentRect.top;
121230
+ initialPosInOffsetParent = e.clientY - dragBarOffsetParentRect.top;
121217
121231
  dragBar.style.left = "0";
121218
- dragBar.style.top = `${initialPos}px`;
121232
+ dragBar.style.top = `${initialPosInOffsetParent}px`;
121219
121233
  dragBar.style.height = "1px";
121220
121234
  dragBar.style.width = "100%";
121221
121235
  }
121222
121236
 
121223
- // Shadow DOM이 있다면 ShadowRoot에, 아니면 일반 DOM에 삽입
121224
- (parent.shadowRoot || parent).appendChild(dragBar);
121237
+ // 드래그 가능한 최소/최대 범위 (dragBarOffsetParent 기준으로 변환)
121238
+ const minLimit = isHorizontal
121239
+ ? prevRect.left - dragBarOffsetParentRect.left
121240
+ : prevRect.top - dragBarOffsetParentRect.top;
121241
+ const maxLimit = isHorizontal
121242
+ ? nextRect.right - dragBarOffsetParentRect.left
121243
+ : nextRect.bottom - dragBarOffsetParentRect.top;
121225
121244
 
121226
- // 드래그 가능한 범위 (부모 요소 내에서 이전/다음 엘리먼트의 실제 경계 기준)
121227
- const minLimit = isHorizontal ? prevRect.left : prevRect.top;
121228
- const maxLimit = isHorizontal ? nextRect.right : nextRect.bottom;
121229
121245
 
121230
121246
  const onMove = moveEvent => {
121231
121247
  const clientPos = isHorizontal ? moveEvent.clientX : moveEvent.clientY;
121232
- // 드래그 바가 부모 영역을 벗어나지 않도록 클램프
121233
- const clampedPos = Math.max(minLimit, Math.min(clientPos, maxLimit));
121248
+ // 뷰포트 기준 클릭 위치를 offsetParent 기준으로 변환
121249
+ const currentPosInOffsetParent = isHorizontal
121250
+ ? clientPos - dragBarOffsetParentRect.left
121251
+ : clientPos - dragBarOffsetParentRect.top;
121234
121252
 
121235
- // 부모 기준으로 드래그 바의 상대 위치
121236
- const relativePos = clampedPos - parentRect[isHorizontal ? "left" : "top"];
121253
+ // 드래그 바가 최소/최대 범위 내에 있도록 클램프
121254
+ const clampedPos = Math.max(minLimit, Math.min(currentPosInOffsetParent, maxLimit));
121237
121255
 
121238
121256
  if (isHorizontal) {
121239
- dragBar.style.left = `${relativePos}px`;
121257
+ dragBar.style.left = `${clampedPos}px`;
121240
121258
  } else {
121241
- dragBar.style.top = `${relativePos}px`;
121259
+ dragBar.style.top = `${clampedPos}px`;
121242
121260
  }
121243
121261
  };
121244
121262
 
121245
- const onUp = upEvent => {
121263
+ const onUp = (upEvent) => {
121246
121264
  window.removeEventListener("mousemove", onMove);
121247
121265
  window.removeEventListener("mouseup", onUp);
121248
121266
  dragBar.remove();
121249
121267
 
121250
- // 최종 드래그 바의 위치를 기준으로 새 크기 계산
121251
- const finalDragBarPos = isHorizontal
121268
+ // 최종 드래그 바의 위치를 offsetParent 기준으로 가져옴
121269
+ const finalDragBarPosInOffsetParent = isHorizontal
121252
121270
  ? parseFloat(dragBar.style.left)
121253
121271
  : parseFloat(dragBar.style.top);
121254
121272
 
121255
- // 이전 요소의 새로운 크기 (부모의 좌측/상단 경계부터 드래그 바까지)
121256
- const newPrevSize = finalDragBarPos;
121273
+ // 이전 요소의 새로운 크기 (offsetParent의 시작점부터 드래그 바까지)
121274
+ const newPrevSize = finalDragBarPosInOffsetParent;
121257
121275
 
121258
- // 다음 요소의 새로운 크기 (부모의 전체 크기에서 이전 요소 크기를 뺀 값)
121259
- const parentTotalSize = isHorizontal ? parentRect.width : parentRect.height;
121260
- const newNextSize = parentTotalSize - newPrevSize;
121276
+ // 다음 요소의 새로운 크기 (offsetParent의 전체 크기에서 이전 요소 크기를 뺀 값)
121277
+ const offsetParentTotalSize = isHorizontal
121278
+ ? dragBarOffsetParentRect.width
121279
+ : dragBarOffsetParentRect.height;
121280
+ const newNextSize = offsetParentTotalSize - newPrevSize;
121261
121281
 
121262
- // 최소/최대 크기 제약 (예: 1px 미만으로 작아지지 않도록)
121263
121282
  const MIN_PANEL_SIZE = 1; // 패널 최소 크기
121264
121283
  let finalPrevSize = Math.max(MIN_PANEL_SIZE, newPrevSize);
121265
121284
  let finalNextSize = Math.max(MIN_PANEL_SIZE, newNextSize);
121266
121285
 
121267
- // flex 레이아웃에 직접 width/height를 부여하는 대신 flex-basis를 사용하거나
121268
- // flex-grow 비율을 재조정하는 것이 일반적이나, 현재 flex: none; 으로 제어하는 방식을 유지한다면,
121269
- // 이와 같이 직접 style.width/height를 설정.
121270
- // 하지만 flex 컨테이너 내부에서는 flex-basis를 설정하는 것이 더 바람직합니다.
121271
- // 여기서는 기존 코드의 스타일 설정을 유지하면서 값을 정확히 계산.
121272
-
121273
- // flex-grow 비율로 제어하는 경우
121274
- // const currentTotalFlex = parseFloat(getComputedStyle(prev).flexGrow || 0) + parseFloat(getComputedStyle(next).flexGrow || 0);
121275
- // prev.style.flexGrow = (newPrevSize / parentTotalSize) * currentTotalFlex;
121276
- // next.style.flexGrow = (newNextSize / parentTotalSize) * currentTotalFlex;
121277
-
121278
121286
  // 기존 flex 값을 저장하고 복원
121279
121287
  const originalPrevFlex = prev.style.flex;
121280
121288
  const originalNextFlex = next.style.flex;
@@ -121292,8 +121300,8 @@ class nxSplitter extends HTMLElement {
121292
121300
  }
121293
121301
 
121294
121302
  // 작업 완료 후 원래 flex 값으로 복원
121295
- // 단, width/height가 설정된 경우 flex 속성이 다시 적용되면 겹칠 있으므로 주의 필요.
121296
- // 일반적으로 flex-basis 사용하거나, width/height 설정 후 flex-grow/shrink를 기본값으로 돌리는 것을 고려.
121303
+ // 주의: width/height가 설정된 상태에서 flex 복원하면 충돌할있음.
121304
+ // flex-basis flex-grow/shrink를 적절히 조절하는 것이 더 견고한 방법.
121297
121305
  prev.style.flex = originalPrevFlex;
121298
121306
  next.style.flex = originalNextFlex;
121299
121307
  };
@@ -121302,137 +121310,6 @@ class nxSplitter extends HTMLElement {
121302
121310
  window.addEventListener("mouseup", onUp);
121303
121311
  };
121304
121312
 
121305
- #startDrag = (e) => {
121306
-
121307
- e.preventDefault(); // 기본 drag/select 동작 제거
121308
- e.stopPropagation();
121309
-
121310
- const splitterRect = this.getBoundingClientRect();
121311
- const clickOffset = this.#mode === "h"
121312
- ? e.clientX - splitterRect.left
121313
- : e.clientY - splitterRect.top;
121314
-
121315
- //const mode = this.#mode;
121316
- const dragBar = document.createElement("div");
121317
- dragBar.className = `nx-splitter-drag-bar-${this.#mode}`;
121318
-
121319
- // 스타일 지정
121320
- Object.assign(dragBar.style, {
121321
- position: "absolute",
121322
- zIndex: "999",
121323
- background: "#666",
121324
- opacity: "0.6",
121325
- pointerEvents: "none"
121326
- });
121327
-
121328
- const root = this.getRootNode({ composed: true });
121329
- const parent = root instanceof ShadowRoot ? root.host : this.parentElement || document.body;
121330
-
121331
- //const parent = this.getRootNode().host || this.parentElement;
121332
- const prev = this.previousElementSibling;
121333
- const next = this.nextElementSibling;
121334
-
121335
- if (!parent || !prev || !next) return;
121336
-
121337
- const parentRect = parent.getBoundingClientRect();
121338
- const prevRect = prev.getBoundingClientRect();
121339
- const nextRect = next.getBoundingClientRect();
121340
-
121341
- /**
121342
- const clientPos = this.#mode === "h" ? e.clientX : e.clientY;
121343
- const position = Math.max(min, Math.min(clientPos, max));
121344
- const relative = position - parent.getBoundingClientRect()[this.#mode === "h" ? "left" : "top"];
121345
- */
121346
-
121347
- const left = e.clientX - parentRect.left;
121348
- const top = e.clientY - parentRect.top;
121349
-
121350
- console.log(left, top);
121351
-
121352
- // 방향별 위치 설정
121353
- if (this.#mode === "h") {
121354
- dragBar.style.top = "0";
121355
- dragBar.style.left = `${left}px`;
121356
- dragBar.style.width = "1px";
121357
- dragBar.style.height = "100%";
121358
- } else {
121359
- dragBar.style.left = "0";
121360
- dragBar.style.top = `${top}px`;
121361
- dragBar.style.height = "1px";
121362
- dragBar.style.width = "100%";
121363
- }
121364
-
121365
- // 👇 부모 노드 기준으로 삽입
121366
- (parent.shadowRoot || parent).appendChild(dragBar);
121367
-
121368
- const min = this.#mode === "h" ? prevRect.left : prevRect.top;
121369
- const max = this.#mode === "h" ? nextRect.right : nextRect.bottom;
121370
-
121371
- const onMove = e => {
121372
- const clientPos = this.#mode === "h" ? e.clientX : e.clientY;
121373
- const position = Math.max(min, Math.min(clientPos, max));
121374
-
121375
- const relative = position - parent.getBoundingClientRect()[this.#mode === "h" ? "left" : "top"];
121376
-
121377
- if (this.#mode === "h") {
121378
- dragBar.style.left = `${relative}px`;
121379
- } else {
121380
- dragBar.style.top = `${relative}px`;
121381
- }
121382
-
121383
- console.log(relative);
121384
- };
121385
-
121386
-
121387
-
121388
- const onUp = (e) => {
121389
-
121390
- window.removeEventListener("mousemove", onMove);
121391
- window.removeEventListener("mouseup", onUp);
121392
- dragBar.remove();
121393
-
121394
-
121395
- // 기준: prev + next 너비 합계
121396
- const totalSize = this.#mode === "h"
121397
- ? prev.offsetWidth + next.offsetWidth
121398
- : prev.offsetHeight + next.offsetHeight;
121399
-
121400
- // prev 기준 상대 거리 (드래그 거리)
121401
-
121402
- let delta = this.#mode === "h"
121403
- ? e.clientX - prev.getBoundingClientRect().left - clickOffset
121404
- : e.clientY - prev.getBoundingClientRect().top - clickOffset;
121405
- //let delta = dragStartPos - prev.getBoundingClientRect()[this.#mode === "h" ? "left" : "top"];
121406
-
121407
- const min = 1;
121408
- const max = totalSize - 1;
121409
- delta = Math.max(min, Math.min(delta, max));
121410
-
121411
-
121412
- const prev1 = prev.style.flex;
121413
- const prev2 = next.style.flex;
121414
- prev.style.flex = "none";
121415
- next.style.flex = "none";
121416
-
121417
- console.log(delta, totalSize);
121418
-
121419
- // 📌 사이즈 적용
121420
- if (this.#mode === "h") {
121421
- prev.style.width = `${delta}px`;
121422
- next.style.width = `${totalSize - delta}px`;
121423
- } else {
121424
- prev.style.height = `${delta}px`;
121425
- next.style.height = `${totalSize - delta}px`;
121426
- }
121427
-
121428
- prev.style.flex = prev1;
121429
- next.style.flex = prev2;
121430
- };
121431
-
121432
- window.addEventListener("mousemove", onMove);
121433
- window.addEventListener("mouseup", onUp);
121434
- };
121435
-
121436
121313
 
121437
121314
  #init = () => {
121438
121315
  this.#detectMode(this);
@@ -121446,13 +121323,13 @@ class nxSplitter extends HTMLElement {
121446
121323
  this.innerHTML = ""; // 기존 내부 HTML 제거
121447
121324
  const htmlTmpl = document.createElement("template");
121448
121325
  htmlTmpl.innerHTML = `
121449
- <style>
121450
- @import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxSplitter.css";
121451
- ${ninegrid.getCustomPath(this,"nxSplitter.css")}
121452
- </style>
121453
-
121454
- ${gripTmpl}
121455
- `;
121326
+ <style>
121327
+ @import "https://cdn.jsdelivr.net/npm/ninegrid@${ninegrid.version}/dist/css/nxSplitter.css";
121328
+ ${ninegrid.getCustomPath(this,"nxSplitter.css")}
121329
+ </style>
121330
+
121331
+ ${gripTmpl}
121332
+ `;
121456
121333
 
121457
121334
  this.shadowRoot.appendChild(htmlTmpl.content.cloneNode(true));
121458
121335