From 08382472f4a47e1ae9e5f07102a927605a7a0bed Mon Sep 17 00:00:00 2001 From: Steven RYDELL Date: Thu, 30 Jul 2026 20:08:10 +0200 Subject: [PATCH] fix(ui): theme date/time picker for dark mode --- CHANGELOG.md | 1 + src/components/forms/FieldWidget.tsx | 92 ++++++++++++++++++++++++---- src/i18n/en.json | 2 + src/index.css | 6 +- 4 files changed, 86 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 764e64e..ad3a837 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. This projec ### Fixed - Mobile admin shell and lists: wide tables no longer expand/clip the page. The shared ScrollArea constrains content width, tables scroll horizontally inside their card, and list Create / pagination actions stay visible in the mobile viewport. - Form and detail layouts wrap more cleanly on narrow screens (action bars, label/value rows). +- Date/time picker in dark mode: replaced the native time input (invisible clock icon + always-light popup) with themed hour/minute selects and a visible Clock icon; set `color-scheme` on light/dark themes so remaining native date controls follow the UI. ### Changed - Negative account disk-usage values (stale Stalwart quota counters) are shown in red with an info tooltip that explains how to recalculate usage via Tasks (Perform account maintenance operations → Recalculate storage quota usage, or store-wide Reset all user quotas). diff --git a/src/components/forms/FieldWidget.tsx b/src/components/forms/FieldWidget.tsx index 2bc1e9a..a0819b4 100644 --- a/src/components/forms/FieldWidget.tsx +++ b/src/components/forms/FieldWidget.tsx @@ -23,7 +23,7 @@ import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover import { Combobox, type ComboboxOption } from '@/components/ui/combobox'; import { Calendar } from '@/components/ui/calendar'; -import { Plus, X, Eye, EyeOff, Loader2, Search, Check, ChevronRight, Calendar as CalendarIcon } from 'lucide-react'; +import { Plus, X, Eye, EyeOff, Loader2, Search, Check, ChevronRight, Calendar as CalendarIcon, Clock } from 'lucide-react'; import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible'; @@ -839,6 +839,67 @@ interface DateTimeFieldProps { nullable?: boolean; } +const TIME_HOURS = Array.from({ length: 24 }, (_, i) => String(i).padStart(2, '0')); +const TIME_MINUTES = Array.from({ length: 60 }, (_, i) => String(i).padStart(2, '0')); + +/** Themed hour/minute selects — avoids the native time picker which ignores app dark/light tokens. */ +function DateTimeTimeSelect({ + value, + onChange, + disabled, +}: { + value: string; + onChange: (value: string) => void; + disabled?: boolean; +}) { + const { t } = useTranslation(); + const [hour = '00', minute = '00'] = value.split(':'); + + const update = (nextHour: string, nextMinute: string) => { + onChange(`${nextHour}:${nextMinute}`); + }; + + return ( +
+ + + +
+ ); +} + function DateTimeField({ value, onChange, readOnly, nullable }: DateTimeFieldProps) { const { t } = useTranslation(); const strValue = typeof value === 'string' ? value : ''; @@ -883,7 +944,7 @@ function DateTimeField({ value, onChange, readOnly, nullable }: DateTimeFieldPro return (
- +