105 lines
4.1 KiB
Plaintext
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}";
|
|
}
|
|
}
|
|
}
|