From 1ef514e38245dd6c236c12b959d9881a0b1f3077 Mon Sep 17 00:00:00 2001 From: Wilbert Mui Date: Sat, 23 Sep 2023 22:37:40 -0700 Subject: [PATCH] feat: use Intl.RelativeTimeFormat() constructor --- packages/timestamp/src/Timestamp.js | 31 +++++++++++++++++-- .../src/__stories__/Timestamp.story.js | 12 ++++++- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/packages/timestamp/src/Timestamp.js b/packages/timestamp/src/Timestamp.js index ce9f56b1cb..53de4e1317 100644 --- a/packages/timestamp/src/Timestamp.js +++ b/packages/timestamp/src/Timestamp.js @@ -48,9 +48,14 @@ const Timestamp = (props) => { }; const humanizeTimestamp = () => { - const { plural, timeDescriptors, timestamp } = props; + const { plural, relativeTimeFormatOptions, timeDescriptors, timestamp } = + props; const asSeconds = Date.parse(timestamp) / 1000; // TODO: handle future timestamps, or bad input? const nowAsSeconds = new Date().valueOf() / 1000; + const rtf = new Intl.RelativeTimeFormat( + relativeTimeFormatOptions?.locales, + relativeTimeFormatOptions?.options + ); const timeDifference = nowAsSeconds - asSeconds; let distance; @@ -99,7 +104,9 @@ const Timestamp = (props) => { : timeDescriptors.year; } - return getTimestampSequence(distance, ellapsedDescriptor); + return relativeTimeFormatOptions + ? rtf.format(-distance, ellapsedDescriptor) + : getTimestampSequence(distance, ellapsedDescriptor); }; return ( @@ -126,15 +133,33 @@ Timestamp.displayName = "Timestamp"; Timestamp.propTypes = { /** + * DEPRECATED - use relativeTimeFormatOptions prop * If you want to pluralize the elapsed time unit * If "true" then it adds an "s" to the end of the time unit */ plural: PropTypes.bool, + /** + * These are the options passed to the + * Intl.RelativeTimeFormat() constructor + * If this prop is used then the following props + * will be ignored: plural, timestampSequence, + * timeDescriptors, wordspace + */ + relativeTimeFormatOptions: PropTypes.shape({ + locales: PropTypes.string, + options: PropTypes.shape({ + localeMatcher: PropTypes.string, + numberingSystem: PropTypes.string, + style: PropTypes.string, + numeric: PropTypes.string, + }), + }), /** * Adds custom/overriding styles */ stylesheet: PropTypes.func, /** + * DEPRECATED - use relativeTimeFormatOptions prop * An object that allows for localization of all the time words used * By default the object property name is the same as the property value * Property names: second, minute, hour, day, week, month, year, ago @@ -154,11 +179,13 @@ Timestamp.propTypes = { */ timestamp: PropTypes.string, /** + * DEPRECATED - use relativeTimeFormatOptions prop * The sequence in which the timestamp is displayed * ie. 4 seconds ago (abc) */ timestampSequence: PropTypes.oneOf(availableSequences), /** + * DEPRECATED - use relativeTimeFormatOptions prop * If you want a space between words */ wordSpace: PropTypes.bool, diff --git a/packages/timestamp/src/__stories__/Timestamp.story.js b/packages/timestamp/src/__stories__/Timestamp.story.js index 79220e4a1d..a8f1680e1d 100644 --- a/packages/timestamp/src/__stories__/Timestamp.story.js +++ b/packages/timestamp/src/__stories__/Timestamp.story.js @@ -1,5 +1,5 @@ import React from "react"; -import { ArgsTable, Primary } from "@storybook/addon-docs"; +import { ArgsTable, Primary, Stories } from "@storybook/addon-docs"; import Timestamp from "../index"; import Readme from "../../README.md"; @@ -19,6 +19,7 @@ export default { page: () => ( <> + @@ -39,3 +40,12 @@ const Template = (args) => { }; export const Default = Template.bind({}); + +export const RelativeTimeFormat = Template.bind({}); + +RelativeTimeFormat.args = { + relativeTimeFormatOptions: { + locales: "es", + }, +}; +RelativeTimeFormat.storyName = "Relative time format";