From 178b046137cd20d73db211c3529fcdbd4c6877fb Mon Sep 17 00:00:00 2001 From: chenxi Date: Wed, 28 Oct 2026 14:21:17 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=9B=BA=E5=AE=9A=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E5=8C=96=E5=BE=85=E5=8A=9E=E6=97=A5=E6=9C=9F=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E4=BD=8D=E7=BD=AE=20(#732)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/systemization-todos.blade.php | 51 +++++++++++++++---- .../Business/SystemizationTodosTest.php | 3 ++ 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/resources/views/business/pages/systemization-todos.blade.php b/resources/views/business/pages/systemization-todos.blade.php index 7d4dfdbc..00687d2f 100644 --- a/resources/views/business/pages/systemization-todos.blade.php +++ b/resources/views/business/pages/systemization-todos.blade.php @@ -73,12 +73,11 @@ .sys-todo-grid-value:hover { border-color:#ded4c3; background:#fffdf8; } .sys-todo-grid-value:focus-visible, .sys-todo-grid-value.is-selected { border-color:var(--sys-gold); background:var(--sys-gold-soft); box-shadow:0 0 0 2px rgba(133,102,50,.16); } .sys-todo-grid-value.is-editing { position:relative; padding:0; border-color:var(--sys-gold); background:#fff; box-shadow:0 0 0 3px rgba(133,102,50,.18); } + .sys-todo-grid-value.is-date-anchor { border-color:var(--sys-gold); background:#fff; box-shadow:0 0 0 3px rgba(133,102,50,.18); } .sys-todo-grid-value.is-dirty { background:#fff8e8; } .sys-todo-grid-editor { display:block; box-sizing:border-box; width:100%; min-height:1.9rem; padding:.3rem .4rem; border:0; border-radius:.28rem; background:#fff; color:#171717; font:inherit; font-size:.78rem; line-height:1.5; outline:none; resize:vertical; } textarea.sys-todo-grid-editor { min-height:4rem; } - .sys-todo-table-wrap.is-date-picking { overflow:visible; } - .sys-todo-grid-date-editor { position:absolute; top:0; left:0; z-index:45; display:grid; width:18rem; padding:.55rem; border:1px solid var(--sys-border); border-radius:.55rem; background:#fff; box-shadow:0 6px 18px rgba(23,23,23,.16); gap:.45rem; } - .sys-todo-grid-date-editor.is-align-right { right:0; left:auto; } + .sys-todo-grid-date-editor { position:fixed; top:0; left:0; z-index:45; display:grid; box-sizing:border-box; width:min(18rem,calc(100vw - 1rem)); padding:.55rem; border:1px solid var(--sys-border); border-radius:.55rem; background:#fff; box-shadow:0 6px 18px rgba(23,23,23,.16); gap:.45rem; } .sys-todo-grid-date-editor .upstream-data-date { width:100%; } .sys-todo-grid-date-editor .upstream-data-date input { height:2rem; font-size:.75rem; } .sys-todo-grid-date-editor .upstream-data-date__pick { height:2rem; } @@ -2691,9 +2690,6 @@ var pending = note === '待定'; var wrapper = document.createElement('div'); wrapper.className = 'sys-todo-grid-date-editor'; - if (cell.getBoundingClientRect().left > window.innerWidth * .62) { - wrapper.classList.add('is-align-right'); - } wrapper.innerHTML = '' + '
' + '' @@ -2719,6 +2715,7 @@ activeEditor = { cell: cell, editor: hiddenValue, + wrapper: wrapper, original: original, scope: scope, getValue: function () { @@ -2729,9 +2726,31 @@ return wrapper.contains(element); } }; - cell.classList.add('is-editing'); - cell.replaceChildren(wrapper); - tableWrap.classList.add('is-date-picking'); + cell.classList.add('is-date-anchor'); + wrapper.style.visibility = 'hidden'; + document.body.appendChild(wrapper); + + function positionFloatingEditor() { + if (!wrapper.isConnected) return; + var anchor = cell.getBoundingClientRect(); + var viewportWidth = document.documentElement.clientWidth || window.innerWidth; + var viewportHeight = document.documentElement.clientHeight || window.innerHeight; + var width = wrapper.offsetWidth; + var height = wrapper.offsetHeight; + var left = Math.max(8, Math.min( + anchor.left + anchor.width / 2 - width / 2, + viewportWidth - width - 8 + )); + var below = anchor.bottom + 4; + var above = anchor.top - height - 4; + var top = below + height <= viewportHeight - 8 ? below : above; + top = Math.max(8, Math.min(top, viewportHeight - height - 8)); + wrapper.style.left = Math.round(left) + 'px'; + wrapper.style.top = Math.round(top) + 'px'; + } + activeEditor.reposition = positionFloatingEditor; + window.addEventListener('scroll', positionFloatingEditor, true); + window.addEventListener('resize', positionFloatingEditor); if (window.CaiWuDatePicker) window.CaiWuDatePicker.setup(wrapper); function closeAfterChoice() { @@ -2797,6 +2816,10 @@ window.setTimeout(function () { dateInput.focus({ preventScroll: true }); dateToggle.click(); + window.requestAnimationFrame(function () { + positionFloatingEditor(); + wrapper.style.visibility = ''; + }); }, 0); } @@ -2805,8 +2828,14 @@ var current = activeEditor; activeEditor = null; var value = current.getValue ? current.getValue() : current.editor.value; - current.cell.classList.remove('is-editing'); - tableWrap.classList.remove('is-date-picking'); + current.cell.classList.remove('is-editing', 'is-date-anchor'); + if (current.reposition) { + window.removeEventListener('scroll', current.reposition, true); + window.removeEventListener('resize', current.reposition); + } + if (current.wrapper) { + current.wrapper.remove(); + } if (!commit || !commitCellValue(current.cell, value, current.scope)) { renderCell(current.cell, current.original); return commit === false; diff --git a/tests/Feature/Business/SystemizationTodosTest.php b/tests/Feature/Business/SystemizationTodosTest.php index 290e48b9..671f7123 100644 --- a/tests/Feature/Business/SystemizationTodosTest.php +++ b/tests/Feature/Business/SystemizationTodosTest.php @@ -89,6 +89,9 @@ class SystemizationTodosTest extends FeatureTestCase ->assertSee("if (field === 'start_date' || field === 'due_date')", false) ->assertSee('sys-todo-grid-date-editor__pending', false) ->assertSee('window.CaiWuDatePicker.setup(wrapper)', false) + ->assertSee('document.body.appendChild(wrapper)', false) + ->assertSee('anchor.left + anchor.width / 2 - width / 2', false) + ->assertDontSee('cell.replaceChildren(wrapper)', false) ->assertSee("if (pendingInput.checked) return '待定'", false) ->assertSee('data-sys-todo-image-prev', false) ->assertSee('data-sys-todo-image-next', false)