mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-10-01 23:58:36 -05:00
Move app to apps/web-react in pnpm workspace layout
This commit is contained in:
56
apps/web-react/app/components/LocaleTimeRange.tsx
Normal file
56
apps/web-react/app/components/LocaleTimeRange.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import clsx from "clsx";
|
||||
import { useDateTimeFormat } from "~/hooks/intl/useDateTimeFormat";
|
||||
import { databaseTimestampToDate } from "~/utils/dates";
|
||||
|
||||
interface LocaleTimeRangeProps {
|
||||
/** Start of the range. Accepts a `Date` or a database timestamp (number), which is converted via `databaseTimestampToDate`. */
|
||||
from: Date | number;
|
||||
/** End of the range. Accepts a `Date` or a database timestamp (number), which is converted via `databaseTimestampToDate`. */
|
||||
to: Date | number;
|
||||
/** Formatting options forwarded to `Intl.DateTimeFormat`. Combined with the user's locale and hour cycle preferences. */
|
||||
options: Intl.DateTimeFormatOptions;
|
||||
/** Optional extra class names appended to the rendered element. */
|
||||
className?: string;
|
||||
/** When `true`, renders inline; otherwise the element is displayed as a block. Defaults to block. */
|
||||
inline?: boolean;
|
||||
/** Optional test id forwarded to the rendered element. */
|
||||
"data-testid"?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the given date range formatted according to the user's locale preferences,
|
||||
* using `Intl.DateTimeFormat.prototype.formatRange` for locale-aware separators and
|
||||
* collapsing of shared parts (e.g. the year when both bounds share it).
|
||||
*
|
||||
* During SSR and before the user's locale preference has loaded the formatted text is hidden
|
||||
* (via `invisible`) while still reserving one line of height to avoid layout shift on hydration.
|
||||
*/
|
||||
export function LocaleTimeRange({
|
||||
from,
|
||||
to,
|
||||
options,
|
||||
className,
|
||||
inline,
|
||||
"data-testid": testId,
|
||||
}: LocaleTimeRangeProps) {
|
||||
const { formatter, isLoaded } = useDateTimeFormat(options);
|
||||
|
||||
const fromDate =
|
||||
typeof from === "number" ? databaseTimestampToDate(from) : from;
|
||||
const toDate = typeof to === "number" ? databaseTimestampToDate(to) : to;
|
||||
|
||||
return (
|
||||
<span
|
||||
data-testid={testId}
|
||||
className={clsx(
|
||||
{
|
||||
block: !inline,
|
||||
invisible: !isLoaded,
|
||||
},
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{formatter.formatRange(fromDate, toDate)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user