On a phone the composer opened at the top of the feed whether or not the feed was scrolled there, and a reply, quote or edit opened inside its card's 228px column. New PhoneSheet shows them as a sheet from the bottom of the screen below md, over a dimmed page, with a heading and a close button (a tap outside or Escape closes it too); from md they stay in place as before. On a phone a new post starts from a round button under the thumb (the feed keeps room for it at the bottom), and the tabs' Post button shows from md. Opening the composer scrolls the feed to its top, and the composer's words take the focus (DTextarea.Element). Picking a suggested mention or hashtag keeps the focus, and the phone's keyboard, in the words (DButton.KeepFocus, and the words are focused again). The character count sits under the words instead of over their last line, and the visibility menu names each choice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
38 lines
1.7 KiB
Plaintext
38 lines
1.7 KiB
Plaintext
@inherits LocalizableComponentBase
|
|
|
|
@* What opens in place on a desktop (the composer at the top of the feed, a reply under its post) and as a sheet from the
|
|
bottom of a phone's screen (below md), over a dimmed page, with its heading and a close button; a tap outside it or
|
|
Escape closes it too. Class is the inline look from md (padding, a raised panel). *@
|
|
@if (IsOpen)
|
|
{
|
|
<div class="max-md:fixed max-md:inset-0 max-md:z-[60] max-md:flex max-md:flex-col max-md:justify-end" @onkeydown="OnKeyDown">
|
|
<div class="md:hidden absolute inset-0 bg-black/40" aria-hidden="true" @onclick="Close"></div>
|
|
<div class="@($"relative max-md:max-h-[85dvh] max-md:overflow-y-auto max-md:overscroll-contain max-md:rounded-t-box max-md:bg-base-100 max-md:p-4 max-md:pb-[max(1rem,env(safe-area-inset-bottom))] {Class}")"
|
|
data-sheet>
|
|
<div class="md:hidden flex items-center gap-3 mb-3">
|
|
<b class="flex-1 min-w-0 truncate">@Heading</b>
|
|
<button type="button" class="btn btn-sm btn-circle btn-ghost flex-none" aria-label="@Localizer["Close"]" title="@Localizer["Close"]"
|
|
@onclick="Close" data-sheet-close>
|
|
<i class="ion-md-close" aria-hidden="true"></i>
|
|
</button>
|
|
</div>
|
|
@ChildContent
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
@code {
|
|
[Parameter] public bool IsOpen { get; set; }
|
|
[Parameter] public EventCallback OnClose { get; set; }
|
|
/// <summary>The sheet's heading on a phone.</summary>
|
|
[Parameter] public string Heading { get; set; }
|
|
[Parameter] public RenderFragment ChildContent { get; set; }
|
|
[Parameter] public string Class { get; set; }
|
|
|
|
protected override void OnInitialized() => IsLoading = false;
|
|
|
|
Task Close() => OnClose.InvokeAsync();
|
|
|
|
Task OnKeyDown(KeyboardEventArgs e) => e.Key == "Escape" ? Close() : Task.CompletedTask;
|
|
}
|