@candor-ui/react 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,21 +8,23 @@ export declare const relativeTimeStrings: {
8
8
  * "5 minutes ago", "in 6 days", in the locale (the runtime's own when left out). `bare` drops the direction for tight
9
9
  * spaces: "5 minutes".
10
10
  */
11
- export declare function formatRelative(date: Date, now?: Date, { locale, justNow, bare }?: {
11
+ export declare function formatRelative(date: Date, now?: Date, { locale, justNow, bare, numeric }?: {
12
12
  locale?: string | undefined;
13
13
  justNow?: string | undefined;
14
14
  bare?: boolean | undefined;
15
+ numeric?: "auto" | "always" | undefined;
15
16
  }): string;
16
17
  /** The current time in milliseconds, updated every 30 seconds; null while rendering on the server. */
17
18
  export declare function useNow(): number | null;
18
19
  /**
19
20
  * "3 minutes ago" / "in 6 days", kept fresh, with the exact time on hover. Shows the date until the clock is known.
21
+ * `bare` shows "3 minutes" and still names the whole phrase, "3 minutes ago", to a screen reader.
20
22
  * `format` shows an absolute time instead ("5 Nov 2026, 14:03"), in the locale, with the same server-safe gate.
21
23
  */
22
24
  declare function RelativeTime({ date, bare, format, className, }: {
23
25
  /** When it happened. Shown as "5 minutes ago", with the exact time on hover. */
24
26
  date: Date | string;
25
- /** Drop "ago" and "in", for tight spaces: "5 minutes". */
27
+ /** Drop "ago" and "in", for tight spaces: "5 minutes". Assistive technology still gets the direction. */
26
28
  bare?: boolean | undefined;
27
29
  /** "relative" (the default), or an absolute "date", "datetime" or "time" in the locale. */
28
30
  format?: "relative" | DateStyle | undefined;
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { useFormat, useStrings } from "./locale.js";
5
5
  /** RelativeTime's fixed words; override them under `relativeTime` in LocaleProvider's `strings`. */
@@ -19,7 +19,7 @@ const units = [
19
19
  * "5 minutes ago", "in 6 days", in the locale (the runtime's own when left out). `bare` drops the direction for tight
20
20
  * spaces: "5 minutes".
21
21
  */
22
- export function formatRelative(date, now = new Date(), { locale, justNow = relativeTimeStrings.justNow, bare = false } = {}) {
22
+ export function formatRelative(date, now = new Date(), { locale, justNow = relativeTimeStrings.justNow, bare = false, numeric = "auto" } = {}) {
23
23
  const seconds = Math.round((date.getTime() - now.getTime()) / 1000);
24
24
  if (Math.abs(seconds) < 10)
25
25
  return justNow;
@@ -28,7 +28,7 @@ export function formatRelative(date, now = new Date(), { locale, justNow = relat
28
28
  const n = Math.round(seconds / size);
29
29
  return bare
30
30
  ? new Intl.NumberFormat(locale, { style: "unit", unit, unitDisplay: "long" }).format(Math.abs(n))
31
- : new Intl.RelativeTimeFormat(locale, { numeric: "auto" }).format(n, unit);
31
+ : new Intl.RelativeTimeFormat(locale, { numeric }).format(n, unit);
32
32
  }
33
33
  }
34
34
  return "";
@@ -64,6 +64,7 @@ export function useNow() {
64
64
  }
65
65
  /**
66
66
  * "3 minutes ago" / "in 6 days", kept fresh, with the exact time on hover. Shows the date until the clock is known.
67
+ * `bare` shows "3 minutes" and still names the whole phrase, "3 minutes ago", to a screen reader.
67
68
  * `format` shows an absolute time instead ("5 Nov 2026, 14:03"), in the locale, with the same server-safe gate.
68
69
  */
69
70
  function RelativeTime({ date, bare = false, format = "relative", className, }) {
@@ -76,6 +77,9 @@ function RelativeTime({ date, bare = false, format = "relative", className, }) {
76
77
  : current === null
77
78
  ? d.toISOString().slice(0, 10)
78
79
  : formatRelative(d, new Date(current), { locale: fmt.tag, justNow: t("justNow"), bare });
79
- return (_jsx("time", { dateTime: d.toISOString(), title: current === null ? undefined : fmt.date(d, "datetime"), className: className, children: text }));
80
+ // A bare time ("2 days") is read aloud without its direction, so a screen reader hears the whole phrase ("2 days ago")
81
+ // while the page keeps the short one. "always" keeps the number ("1 day ago", not "yesterday"), so the spoken words match the shown ones.
82
+ const spoken = bare && format === "relative" && current !== null ? formatRelative(d, new Date(current), { locale: fmt.tag, justNow: t("justNow"), numeric: "always" }) : text;
83
+ return (_jsx("time", { dateTime: d.toISOString(), title: current === null ? undefined : fmt.date(d, "datetime"), className: className, children: spoken === text ? (text) : (_jsxs(_Fragment, { children: [_jsx("span", { "aria-hidden": true, children: text }), _jsx("span", { className: "sr-only", children: spoken })] })) }));
80
84
  }
81
85
  export { RelativeTime };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@candor-ui/react",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "description": "Candor UI's free tier as an npm package: React components for agents that do real work, on shadcn/ui and Tailwind 4.",
5
5
  "license": "MIT",
6
6
  "author": "Methodic LLC",