Files
decePubClient/Components/PhoneSheet.razor
T

59 lines
2.1 KiB
Plaintext
Raw Permalink Normal View History

@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; }
2026-10-06 23:49:49 +02:00
[Inject] OverlayService Overlays { get; set; }
IDisposable overlay;
protected override void OnInitialized() => IsLoading = false;
2026-10-06 23:49:49 +02:00
// open, the Back button closes it
protected override void OnParametersSet()
{
if (IsOpen && overlay is null)
overlay = Overlays.Open(() => InvokeAsync(Close));
else if (!IsOpen && overlay is not null)
{
overlay.Dispose();
overlay = null;
}
}
public override async ValueTask DisposeAsync()
{
overlay?.Dispose();
await base.DisposeAsync();
}
Task Close() => OnClose.InvokeAsync();
Task OnKeyDown(KeyboardEventArgs e) => e.Key == "Escape" ? Close() : Task.CompletedTask;
}