UNPKG

javascript-time-ago

Version:

Localized relative date/time formatting

189 lines (158 loc) 6.31 kB
export type DateInput = Date | number; export type Locale = string; // Users can add custom styles via `TimeAgo.addLabels(locale, styleName, labels)`. export type CustomLabelStyleName = string; // There're also "legacy" label styles like "time" or "long-time" that have been deprecated. // Users can still use those by adding them manually via `TimeAgo.addLabels()`. export type LabelStyleName = 'long' | 'short' | 'narrow' | 'mini' | 'now' | CustomLabelStyleName; export type Rounding = 'round' | 'floor'; // https://github.com/eemeli/make-plural/blob/master/packages/compiler/src/compile-range.js#L1 export type Count = 'zero' | 'one' | 'two' | 'few' | 'many' | 'other'; export type CommonUnit = 'year' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second'; export type Unit = CommonUnit | 'quarter' | 'now'; export type CountLabels = { [count in Count]?: string; } export interface PastAndFutureLabels { past: string | CountLabels; future: string | CountLabels; previous?: string; current?: string; next?: string; } export interface PastAndFutureNowLabels { past: string; future: string; current: string; } export type UnitLabels = string | CountLabels | PastAndFutureLabels export type Labels = { year: UnitLabels; quarter?: UnitLabels; month: UnitLabels; week: UnitLabels; day: UnitLabels; hour: UnitLabels; minute: UnitLabels; second: UnitLabels; } export type UnitLabelsMini = string | CountLabels; export type MiniLabels = { year: UnitLabelsMini; quarter?: UnitLabelsMini; month: UnitLabelsMini; week: UnitLabelsMini; day: UnitLabelsMini; hour: UnitLabelsMini; minute: UnitLabelsMini; second: UnitLabelsMini; } export type NowLabels = { now: string | PastAndFutureNowLabels; } export type LocaleData = { locale: Locale; short: Labels; narrow: Labels; long: Labels; mini?: MiniLabels; now?: NowLabels; } export type FormatStyleName = 'round' | 'round-minute' | 'mini' | 'mini-now' | 'mini-minute' | 'mini-minute-now' | 'twitter' | 'twitter-now' | 'twitter-minute' | 'twitter-minute-now' | 'twitter-first-minute'; export type MinTimeFunction = (date: number, options: { future: boolean, getMinTimeForUnit: (unit: Unit, prevUnit?: Unit) => number | void }) => number; export interface Step { formatAs?: Unit; minTime?: number | MinTimeFunction; format?(date: DateInput, locale: Locale, options: { formatAs: (unit: Unit, amount: number) => string, now: number, future: boolean }): string | void; getTimeToNextUpdate?(date: DateInput, options: { getTimeToNextUpdateForUnit: (unit: Unit) => number | void, now: number, future: boolean }): number | void; } export interface Style { steps: Step[]; labels: LabelStyleName | LabelStyleName[]; round?: Rounding; } interface FormatOptions { now?: number; future?: boolean; round?: Rounding; } interface FormatOptionsWithGetTimeToNextUpdate extends FormatOptions { getTimeToNextUpdate: boolean; // `setTimeout()` function has a bug when it fires immediately // when the delay is longer than about `24.85` days. // https://stackoverflow.com/questions/3468607/why-does-settimeout-break-for-large-millisecond-delay-values // // In order to not burden the end users of this library with manually working around that bug, // this library automatically caps the returned delay to a maximum value of about `24.85` days // which still works correctly with `setTimeout()` function and doesn't break it. // // The end user of this library could still disable this automatic workaround // by passing a `getTimeToNextUpdateUncapped: true` parameter. // In that case, it will return the original non-modified uncapped delay // which can be longer than `24.85` days and should be manually capped // by the developer if it's going to be used in a `setTimeout()` call. // getTimeToNextUpdateUncapped?: boolean; } interface FormatOptionsWithRefresh extends FormatOptions { refresh: (text: string) => void; } export default class TimeAgo { // Creates a `TimeAgo` instance. constructor(locale: Locale | Locale[], options?: { polyfill?: boolean }); // Calling `.format()` function normally. format(date: DateInput, style?: FormatStyleName | Style, options?: FormatOptions): string; // Calling `.format()` with `getTimeToNextUpdate: true` parameter. // // When `.format()` is called with `getTimeToNextUpdate: true` parameter, // it returns an array containing the formatted time and the "time to next update" delay. // // Perhaps returning an array is not the best solution, and it would've been better // to introduce a new function called `.formatAndGetTimeToNextUpdate()` or something like that. // But at this stage it already returns an array and changing that would require // a "major" version number update, and I would prefer not doing that for such an insignificant change. // format(date: DateInput, options: FormatOptionsWithGetTimeToNextUpdate): [string, number?]; format(date: DateInput, style: FormatStyleName | Style, options: FormatOptionsWithGetTimeToNextUpdate): [string, number?]; // Calling `.format()` with a `refresh()` parameter. // // When `.format()` is called with a `refresh()` parameter, // it returns an array containing the formatted time and the "stop refreshing" function. // // I.e. it mimicks the return value of already-existing `getTimeToNextUpdate: true` parameter. // format(date: DateInput, options: FormatOptionsWithRefresh): [string, () => void]; format(date: DateInput, style: FormatStyleName | Style, options: FormatOptionsWithRefresh): [string, () => void]; // `getLabels()` function seems to be unused and is not documented. // Perhaps it even wasn't ever declared as part of the public API // and got in this TypeScript definition by accident. // // getLabels(labelsType: LabelStyleName | LabelStyleName[]): Labels; static addLocale(localeData: LocaleData): void; static addDefaultLocale(localeData: LocaleData): void; static getDefaultLocale(): Locale; static setDefaultLocale(locale: Locale): void; static addLabels(locale: Locale, name: LabelStyleName, labels: Labels): void; }