Files
Enciphered.Blazor.UIComponents/Enciphered.Blazor.UIComponents/Forms/DateTimeInput.razor
T

105 lines
4.1 KiB
Plaintext

@namespace Enciphered.Blazor.UIComponents
@inherits InputBase<DateTime?>
<input type="datetime-local"
id="@Id"
name="@Name"
value="@FormatValue()"
class="sr-only"
tabindex="-1"
aria-hidden="true"
disabled="@Disabled"
@attributes="MergedAttributes" />
<input type="hidden" id="@($"{Id}-date-part")"
value="@(SelectedDateOnly?.ToString("yyyy-MM-dd") ?? "")"
data-trigger-id="@($"trigger-{Id}-date")"
data-placeholder="@(Placeholder ?? "Select date")"
data-datetime-part="date"
data-datetime-input-id="@Id" />
<input type="hidden" id="@($"{Id}-time-part")"
value="@(SelectedTimeOnly.HasValue ? SelectedTimeOnly.Value.ToString("HH:mm") : "")"
data-trigger-id="@($"trigger-{Id}-time")"
data-placeholder="Select time"
data-datetime-part="time"
data-datetime-input-id="@Id" />
<div class="flex gap-2">
<Popover>
<Trigger>
<button type="button"
disabled="@Disabled"
data-testid="@($"trigger-{Id}-date")"
class="@TriggerClass">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="mr-2 shrink-0 text-muted-foreground">
<path d="M8 2v4" /><path d="M16 2v4" />
<rect width="18" height="18" x="3" y="4" rx="2" />
<path d="M3 10h18" />
</svg>
<span class="@(SelectedDateOnly.HasValue ? "" : "text-muted-foreground")">
@(SelectedDateOnly.HasValue ? SelectedDateOnly.Value.ToString("MMM d, yyyy") : (Placeholder ?? "Select date"))
</span>
</button>
</Trigger>
<Content>
<Calendar SelectedDate="@SelectedDateOnly" LinkedInputId="@($"{Id}-date-part")" />
</Content>
</Popover>
<Popover>
<Trigger>
<button type="button"
disabled="@Disabled"
data-testid="@($"trigger-{Id}-time")"
class="@TriggerClass">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="mr-2 shrink-0 text-muted-foreground">
<circle cx="12" cy="12" r="10" />
<polyline points="12 6 12 12 16 14" />
</svg>
<span class="@(SelectedTimeOnly.HasValue ? "" : "text-muted-foreground")">
@(SelectedTimeOnly.HasValue ? SelectedTimeOnly.Value.ToString("hh\\:mm tt") : "Select time")
</span>
</button>
</Trigger>
<Content>
<TimePicker SelectedTime="@SelectedTimeOnly" Use12Hour="true" LinkedInputId="@($"{Id}-time-part")" />
</Content>
</Popover>
</div>
@code {
[Parameter] public string? Min { get; set; }
[Parameter] public string? Max { get; set; }
[Parameter] public string? Step { get; set; }
private DateOnly? SelectedDateOnly =>
Value.HasValue ? DateOnly.FromDateTime(Value.Value) : null;
private TimeOnly? SelectedTimeOnly =>
Value.HasValue ? TimeOnly.FromDateTime(Value.Value) : null;
private string? FormatValue() =>
Value?.ToString("yyyy-MM-ddTHH:mm");
private string TriggerClass
{
get
{
const string baseClass =
"flex h-9 w-full items-center rounded-md border bg-transparent px-3 py-1 text-sm shadow-sm " +
"transition-colors cursor-pointer text-left " +
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring " +
"disabled:cursor-not-allowed disabled:opacity-50";
return string.IsNullOrEmpty(Class)
? $"{baseClass} border-input"
: $"{baseClass} border-input {Class}";
}
}
}