@intility/bifrost-react
Version:
React library for Intility's design system, Bifrost.
62 lines (60 loc) • 2.15 kB
JavaScript
"use client";
import { c as _c } from "react-compiler-runtime";
import { useMemo } from "react";
import useLocale from "./useLocale.js";
import getDuration from "../utils/getDuration.js";
// cache each formatter as it is created
const relativeFormattersCache = {};
function getRelativeTimeFormatter(locale, options) {
// todo: figure out if this is actually less expensive than creating a new formatter
const key = JSON.stringify({
locale,
options
});
let formatter = relativeFormattersCache[key];
if (!formatter || typeof formatter.format !== "function") {
formatter = new Intl.RelativeTimeFormat(locale, options);
relativeFormattersCache[key] = formatter;
}
return formatter;
}
/**
* Relative time formatter using locale and options from the current Bifrost
* context (can be overridden).
*
* @param date - The date to format relative to now
* @param options - Optional Configuration options
* @param options.locale - Optional locale override (defaults to current Bifrost locale, e.g. "en-us" or "nb-no")
* @param options.options - Optional Intl.RelativeTimeFormatOptions override (default `{ numeric: "auto", style: "long" }`)
* @returns {string} A formatted relative time string (e.g. "5 minutes ago" or "in 2 hours")
*
* @see https://bifrost.intility.com/react/useRelativeTime
*
* @example
* // e.g. "5 minutes ago" or "in 2 hours" depending on the date provided
* const relativeTime = useRelativeTime(dateObjectOrISOString);
*/
export default function useRelativeTime(date, t0) {
const $ = _c(2);
const {
locale: localeOverride,
options: optionsOverride
} = t0 === undefined ? {} : t0;
const {
dateOptions
} = useLocale();
let t1;
if ($[0] !== date) {
t1 = typeof date === "string" ? new Date(date) : date;
$[0] = date;
$[1] = t1;
} else {
t1 = $[1];
}
const dateObj = t1;
const locale = localeOverride ?? dateOptions.locale;
const options = optionsOverride ?? dateOptions.relativeTime;
const now = new Date();
const [unit, duration] = getDuration(now, dateObj);
return getRelativeTimeFormatter(locale, options).format(duration, unit);
}