Skip to content

Commit 4009956

Browse files
committed
fix floating toolbar linux anchoring
1 parent fa08067 commit 4009956

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

ci-workflows-release-pr-validation.plan.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,10 @@ Root-cause note:
226226
- `PrompterLive.App.UITests.EditorFloatingToolbarLayoutTests.EditorScreen_FloatingToolbarStaysPinnedAfterFloatingFormatAction`
227227
- Root cause note: the test asserted `getBoundingClientRect().x/y` drift after the format action even though the production floating-toolbar contract preserves the inline/computed anchor (`left` and `top`) and the element itself is centered with `transform: translate(-50%, ...)`. Linux font/layout differences moved the rendered box without breaking the preserved anchor.
228228
- Intended fix path: assert the preserved computed anchor coordinates instead of bounding-box drift, and keep the visibility check after the floating action.
229+
- GitHub runs `23815986364` and `23815989928` showed the browser failures were not purely test-level:
230+
- `EditorScreen_FloatingToolbarStaysPinnedAfterFloatingFormatAction` still failed because a late textarea `select` event could request a fresh floating-bar re-anchor after toolbar formatting on Linux.
231+
- `EditorScreen_FloatingToolbarStaysAboveMultiLineSelection` failed because the visual floating-toolbar gap above the selected segment line was too tight for Linux font metrics.
232+
- Intended fix path: preserve the existing floating-bar anchor when the refreshed DOM selection matches the already-tracked range, and increase the runtime floating-toolbar gap so the toolbar body clears multi-line selections consistently across platforms.
229233
- Local validation after the browser-suite stability fixes passed:
230234
- `dotnet build /Users/ksemenenko/Developer/PrompterLive/PrompterLive.slnx -warnaserror`
231235
- `dotnet test /Users/ksemenenko/Developer/PrompterLive/tests/PrompterLive.Core.Tests/PrompterLive.Core.Tests.csproj --no-build`
@@ -235,6 +239,11 @@ Root-cause note:
235239
- `dotnet build /Users/ksemenenko/Developer/PrompterLive/PrompterLive.slnx -warnaserror`
236240
- `dotnet test /Users/ksemenenko/Developer/PrompterLive/tests/PrompterLive.App.UITests/PrompterLive.App.UITests.csproj --no-build`
237241
- `dotnet format /Users/ksemenenko/Developer/PrompterLive/PrompterLive.slnx`
242+
- Local validation after the runtime floating-toolbar fixes passed:
243+
- `dotnet build /Users/ksemenenko/Developer/PrompterLive/PrompterLive.slnx -warnaserror`
244+
- `dotnet test /Users/ksemenenko/Developer/PrompterLive/tests/PrompterLive.App.Tests/PrompterLive.App.Tests.csproj --no-build`
245+
- `dotnet test /Users/ksemenenko/Developer/PrompterLive/tests/PrompterLive.App.UITests/PrompterLive.App.UITests.csproj --no-build`
246+
- `dotnet format /Users/ksemenenko/Developer/PrompterLive/PrompterLive.slnx`
238247

239248
## Final Validation Skills And Commands
240249

src/PrompterLive.Shared/Editor/Components/EditorSourcePanel.razor.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,25 @@ private async Task OnSelectionInteractionAsync()
170170

171171
// A late textarea select event can arrive after a toolbar click and should
172172
// refresh selection state without dismissing the menu the user just opened.
173-
private Task OnSourceSelectAsync()
173+
private async Task OnSourceSelectAsync()
174174
{
175-
RequestFloatingBarReanchor();
176-
return RefreshSelectionAsync();
175+
var selection = await RunSelectionInteropAsync(
176+
() => Interop.GetSelectionAsync(_textareaRef),
177+
RefreshSelectionFailureMessage);
178+
179+
if (selection is null)
180+
{
181+
return;
182+
}
183+
184+
if (!_floatingBarAnchor.HasSelection || selection.Range != Selection.Range)
185+
{
186+
RequestFloatingBarReanchor();
187+
}
188+
189+
await OnSelectionChanged.InvokeAsync(selection);
190+
_syncScrollAfterRender = Selection.HasSelection || selection.HasSelection;
191+
StateHasChanged();
177192
}
178193

179194
private async Task OnSourceInputAsync(ChangeEventArgs args)

src/PrompterLive.Shared/Editor/Components/EditorSourcePanel.razor.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
.ed-source-error{margin:0 48px 24px;padding:12px 16px;border-radius:10px;border:1px solid rgba(255,138,138,.22);background:rgba(255,96,96,.08);color:#FFB3B3;font-size:13px;line-height:1.5;}
4242
.ed-statusbar{display:flex;gap:24px;padding:8px 28px;background:transparent;border-top:1px solid var(--gold-06);font-size:13px;color:#7A8E88;flex-shrink:0;font-family:var(--mono);border-radius:0 0 var(--r2) var(--r2);}
4343

44-
.ed-float-bar{--ed-floatbar-gap:8px;position:absolute;left:50%;top:0;bottom:auto;transform:translate(-50%,calc(-100% - var(--ed-floatbar-gap)));z-index:300;display:inline-flex;align-items:center;gap:3px;background:rgba(12,16,28,.72);backdrop-filter:blur(24px) saturate(1.4);-webkit-backdrop-filter:blur(24px) saturate(1.4);border:1px solid rgba(212,176,112,.22);border-top:1px solid rgba(212,176,112,.30);border-radius:12px;padding:5px 8px;width:max-content;box-shadow:0 8px 32px rgba(0,0,0,.45),0 0 0 1px rgba(0,0,0,.3),inset 0 1px 0 rgba(255,255,255,.06),0 0 20px rgba(212,176,112,.06);white-space:nowrap;animation:floatBarIn .18s ease-out;}
44+
.ed-float-bar{--ed-floatbar-gap:14px;position:absolute;left:50%;top:0;bottom:auto;transform:translate(-50%,calc(-100% - var(--ed-floatbar-gap)));z-index:300;display:inline-flex;align-items:center;gap:3px;background:rgba(12,16,28,.72);backdrop-filter:blur(24px) saturate(1.4);-webkit-backdrop-filter:blur(24px) saturate(1.4);border:1px solid rgba(212,176,112,.22);border-top:1px solid rgba(212,176,112,.30);border-radius:12px;padding:5px 8px;width:max-content;box-shadow:0 8px 32px rgba(0,0,0,.45),0 0 0 1px rgba(0,0,0,.3),inset 0 1px 0 rgba(255,255,255,.06),0 0 20px rgba(212,176,112,.06);white-space:nowrap;animation:floatBarIn .18s ease-out;}
4545
.ed-float-bar::after{content:"";position:absolute;bottom:-5px;left:50%;width:10px;height:10px;background:rgba(12,16,28,.72);border-right:1px solid rgba(212,176,112,.18);border-bottom:1px solid rgba(212,176,112,.18);transform:translateX(-50%) rotate(45deg);}
4646
.efb-btn{display:inline-flex;align-items:center;gap:4px;padding:5px 10px;font-size:13px;font-weight:500;color:#9AABA4;background:transparent;border-radius:7px;font-family:var(--font);height:30px;}
4747
.efb-btn:hover{background:var(--gold-09);color:#ECF0EE;}

0 commit comments

Comments
 (0)