1- import { Fragment , useEffect , useState } from "react" ;
1+ import { GlobeAltIcon , GlobeAmericasIcon } from "@heroicons/react/20/solid" ;
2+ import { Laptop } from "lucide-react" ;
3+ import { Fragment , type ReactNode , useEffect , useState } from "react" ;
24import { useLocales } from "./LocaleProvider" ;
5+ import { Paragraph } from "./Paragraph" ;
6+ import { SimpleTooltip } from "./Tooltip" ;
37
48type DateTimeProps = {
59 date : Date | string ;
@@ -18,8 +22,9 @@ export const DateTime = ({
1822 showTimezone = false ,
1923} : DateTimeProps ) => {
2024 const locales = useLocales ( ) ;
21-
2225 const realDate = typeof date === "string" ? new Date ( date ) : date ;
26+ const resolvedOptions = Intl . DateTimeFormat ( ) . resolvedOptions ( ) ;
27+ const localTimeZone = resolvedOptions . timeZone ;
2328
2429 const initialFormattedDateTime = formatDateTime (
2530 realDate ,
@@ -32,8 +37,6 @@ export const DateTime = ({
3237 const [ formattedDateTime , setFormattedDateTime ] = useState < string > ( initialFormattedDateTime ) ;
3338
3439 useEffect ( ( ) => {
35- const resolvedOptions = Intl . DateTimeFormat ( ) . resolvedOptions ( ) ;
36-
3740 setFormattedDateTime (
3841 formatDateTime (
3942 realDate ,
@@ -45,11 +48,55 @@ export const DateTime = ({
4548 ) ;
4649 } , [ locales , includeSeconds , realDate ] ) ;
4750
51+ const tooltipContent = (
52+ < div className = "flex flex-col gap-1" >
53+ { ! timeZone || timeZone === "UTC" ? (
54+ < div className = "flex flex-col gap-3" >
55+ < DateTimeTooltipContent
56+ title = "UTC"
57+ dateTime = { formatDateTime ( realDate , "UTC" , locales , true , true ) }
58+ icon = { < GlobeAltIcon className = "size-4 text-blue-500" /> }
59+ />
60+ < DateTimeTooltipContent
61+ title = "Local"
62+ dateTime = { formatDateTime ( realDate , localTimeZone , locales , true , true ) }
63+ icon = { < Laptop className = "size-4 text-green-500" /> }
64+ />
65+ </ div >
66+ ) : (
67+ < div className = "flex flex-col gap-3" >
68+ < DateTimeTooltipContent
69+ title = { timeZone }
70+ dateTime = { formatDateTime ( realDate , timeZone , locales , true , true ) }
71+ icon = { < GlobeAmericasIcon className = "size-4 text-purple-500" /> }
72+ />
73+ < DateTimeTooltipContent
74+ title = "UTC"
75+ dateTime = { formatDateTime ( realDate , "UTC" , locales , true , true ) }
76+ icon = { < GlobeAltIcon className = "size-4 text-blue-500" /> }
77+ />
78+ < DateTimeTooltipContent
79+ title = "Local"
80+ dateTime = { formatDateTime ( realDate , localTimeZone , locales , true , true ) }
81+ icon = { < Laptop className = "size-4 text-green-500" /> }
82+ />
83+ </ div >
84+ ) }
85+ </ div >
86+ ) ;
87+
4888 return (
49- < Fragment >
50- { formattedDateTime . replace ( / \s / g, String . fromCharCode ( 32 ) ) }
51- { showTimezone ? ` (${ timeZone ?? "UTC" } )` : null }
52- </ Fragment >
89+ < SimpleTooltip
90+ button = {
91+ < Fragment >
92+ { formattedDateTime . replace ( / \s / g, String . fromCharCode ( 32 ) ) }
93+ { showTimezone ? ` (${ timeZone ?? "UTC" } )` : null }
94+ </ Fragment >
95+ }
96+ content = { tooltipContent }
97+ side = "right"
98+ // disableHoverableContent
99+ />
53100 ) ;
54101} ;
55102
@@ -226,3 +273,23 @@ function formatDateTimeShort(date: Date, timeZone: string, locales: string[]): s
226273
227274 return formattedDateTime ;
228275}
276+
277+ type DateTimeTooltipContentProps = {
278+ title : string ;
279+ dateTime : string ;
280+ icon : ReactNode ;
281+ } ;
282+
283+ function DateTimeTooltipContent ( { title, dateTime, icon } : DateTimeTooltipContentProps ) {
284+ return (
285+ < div className = "flex flex-col gap-1" >
286+ < div className = "flex items-center gap-1 text-sm" >
287+ { icon }
288+ < span className = "font-medium" > { title } </ span >
289+ </ div >
290+ < Paragraph variant = "extra-small" className = "text-text-dimmed" >
291+ { dateTime }
292+ </ Paragraph >
293+ </ div >
294+ ) ;
295+ }
0 commit comments