@danxbot/ui 21.1.0 → 22.0.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.
@@ -0,0 +1,17 @@
1
+ import { type ReactNode } from "react";
2
+ import { type RelativeFormat } from "../lib/time/relativeClock";
3
+ export interface RelativeTimeProps {
4
+ /** The moment: an ISO string, epoch millis or a `Date`. */
5
+ at: string | number | Date;
6
+ /** Words for the moment as of `now`. Default: `relativeAge` in the provider's words and locale. A pure function of `(at, now)`, and a STABLE one (memoize it; a new `format` re-reads when the text next changes). */
7
+ format?: RelativeFormat;
8
+ /** The tooltip content. Default: the absolute moment, in the provider's locale. `false` for none (the caller wraps its own). */
9
+ tooltip?: ReactNode | false;
10
+ className?: string;
11
+ }
12
+ /**
13
+ * The text of a moment, re-read whenever it changes: what `RelativeTime` draws, for a caller that needs the words themselves
14
+ * (a sentence built around them, a layout key that must move when the shown age does). Same `format` rules as `RelativeTimeProps`.
15
+ */
16
+ export declare function useRelativeText(at: string | number | Date, format?: RelativeFormat): string;
17
+ export declare function RelativeTime({ at, format, tooltip, className }: RelativeTimeProps): import("react").JSX.Element;
@@ -134,6 +134,9 @@ export { ContextMeter, ChatStatus, type ContextMeterProps, type ContextSegment,
134
134
  export { cn } from "./lib/cn";
135
135
  export { formatBytes, formatTokens, formatCompactNumber } from "./lib/format";
136
136
  export { copyText } from "./lib/clipboard";
137
+ export { RelativeTime, useRelativeText, type RelativeTimeProps } from "./components/RelativeTime";
138
+ export type { RelativeFormat } from "./lib/time/relativeClock";
139
+ export { toEpochMs } from "./lib/time/instant";
137
140
  export { CopyValue, type CopyValueProps } from "./components/CopyValue";
138
141
  export { formatDate, parseDate, formatDateTime, parseDateTime, type FormatDateTimeOptions, type ParseDateTimeOptions, formatCurrency, parseCurrency, formatNumber, parseNumber, type FormatNumberOptions, formatBoolean, parseBoolean, type FormatBooleanOptions, } from "./lib/values";
139
142
  export { COMPONENT_GUIDANCE, type ComponentGuidanceRule } from "./lib/component-guidance";
@@ -168,5 +171,5 @@ export { OpenApiViewer, type OpenApiViewerProps, OperationCard, type OperationCa
168
171
  export { defineRecordType, resetRecordTypes, useRecord, useRecords, useStaleness, write, writeAll, peekRecord, readState, readStaleness, subscribeToKey, subscribeToStaleness, retainKeys, sweepRecords, setRecordStoreTenant, getRecordStoreTenant, flushRecordNotifications, resetRecordStore, recordStoreStats, UNKNOWN_STATE, normalizeTypeName, normalizeTimestamp, recordKey, isRecordRef, type RecordRef, type ReadOptions, type RecordPayload, type RecordState, type RecordTypeOptions, type RecordTypeToken, type StalenessEntry, type WriteAllResult, type WriteOptions, type WriteResult, type WriteSource, type WriteVerdict, } from "./lib/records";
169
172
  export { RealtimeProvider, useRealtime, useRealtimeEpoch, useRealtimeHealth, useRealtimeRegistry, SubscriptionRegistry, normalizeScope, scopeKey, subscriptionKey, readRealtimeEpoch, subscribeToRealtimeEpoch, subscribeToRealtimeEvents, resetRealtimeSignals, type RealtimeChannel, type RealtimeConnectionState, type RealtimeDiagnostic, type RealtimeEvent, type RealtimeHealth, type RealtimeProviderProps, type RealtimeScope, type RealtimeScopeInput, type RealtimeStatus, type RealtimeTransport, type RegistryOptions, type SubscriptionHealth, type SubscriptionLease, type SubscriptionRequest, } from "./lib/realtime";
170
173
  export { useRecordRead, useRecordListRead, useRecordStoreSweep, applyMutationResult, optimisticWrite, beginOptimisticWrite, resetOptimisticWrites, type OptimisticHandle, type OptimisticWriteOptions, type OptimisticWriteSpec, type SlotDescriptor, acquireSlot, appendCreated, emptySlotSnapshot, readSlot, resetSlots, slotKeys, subscribeToSlot, writeSlot, RefetchRunner, registerActiveRead, resetActiveReads, type ActiveRead, type ListFetch, type ListFetchResult, type ListReadOptions, type ListReadResult, type ReadError, type RecordFetch, type RecordReadOptions, type RecordReadResult, type RunnerOptions, type SlotSnapshot, } from "./lib/reads";
171
- export { ENGLISH_UI_STRINGS, UiLocaleProvider, useUiLocale, useUiStrings, type UiLocaleProviderProps, type UiLocaleValue, type UiStrings, } from "./lib/i18n";
174
+ export { chordLabel, ENGLISH_UI_STRINGS, UiLocaleProvider, useUiLocale, useUiStrings, type KeyId, type UiLocaleProviderProps, type UiLocaleValue, type UiStrings, } from "./lib/i18n";
172
175
  export type { BooleanStrings, FormatsStrings, ReadErrorStrings, RelativeAgeStrings } from "./lib/i18n/areas/formats";
@@ -63,6 +63,8 @@ export interface FeedbackStrings {
63
63
  toast: {
64
64
  /** Accessible name of a toast's close button. */
65
65
  dismiss: string;
66
+ /** Accessible name of the region that holds the toasts. */
67
+ viewport: string;
66
68
  };
67
69
  legalDocument: {
68
70
  /** Default accessible name of the table of contents. */
@@ -17,6 +17,8 @@ export interface FormsStrings {
17
17
  open: string;
18
18
  /** Name of a selected chip's remove button. */
19
19
  remove: string;
20
+ /** Name of the screen-reader buttons that close the open list. */
21
+ dismiss: string;
20
22
  };
21
23
  select: {
22
24
  /** Trigger text while nothing is selected and the caller gave no `placeholder`. */
@@ -99,8 +101,8 @@ export interface FormsStrings {
99
101
  empty: string;
100
102
  /** Screen-reader announcement while an autosave is in flight. */
101
103
  saving: string;
102
- /** Message under a field whose save failed, naming the key that retries it. */
103
- failure: (retryKey: "Enter" | "Ctrl+Enter") => string;
104
+ /** Message under a field whose save failed; `retryChord` is the chord that retries it, in the catalog's key names ("Ctrl+Enter"). */
105
+ failure: (retryChord: string) => string;
104
106
  };
105
107
  inlineMarkdownEdit: {
106
108
  /** Resting text of an empty InlineMarkdownEdit. */
@@ -0,0 +1,14 @@
1
+ /** The keys the library prints the name of: modifiers and the named keys a chord can contain. */
2
+ export declare const KEY_IDS: readonly ["ctrl", "alt", "shift", "tab", "enter", "backspace"];
3
+ export type KeyId = (typeof KEY_IDS)[number];
4
+ export interface KeysStrings {
5
+ /** The name printed on the key cap, by key id ("Shift", or "Mayús" on a Spanish keyboard). */
6
+ keyNames: Record<KeyId, string>;
7
+ }
8
+ export declare const keysStrings: KeysStrings;
9
+ /**
10
+ * A chord as a person reads it: `ctrl+shift+bracketleft` -> `Ctrl+Shift+[`, each named key in
11
+ * the catalog's words. A part that is neither a named key, a symbol nor a single character is a
12
+ * chord the table never declared, so it throws rather than print a made-up name.
13
+ */
14
+ export declare function chordLabel(chord: string, keyNames: KeysStrings["keyNames"]): string;
@@ -6,3 +6,5 @@ export type { UiStrings } from "./strings";
6
6
  export { useNumberFormat } from "./number-format";
7
7
  export { plural } from "./plural";
8
8
  export type { PluralForms } from "./plural";
9
+ export { chordLabel } from "./areas/keys";
10
+ export type { KeyId } from "./areas/keys";
@@ -7,9 +7,10 @@ import { type DocsViewsStrings } from "./areas/docs-views";
7
7
  import { type FeedbackStrings } from "./areas/feedback";
8
8
  import { type FormsStrings } from "./areas/forms";
9
9
  import { type FormatsStrings } from "./areas/formats";
10
+ import { type KeysStrings } from "./areas/keys";
10
11
  import { type MarkdownStrings } from "./areas/markdown";
11
12
  import { type MoveRejectedStrings } from "./areas/move-rejected";
12
13
  import { type NavigationStrings } from "./areas/navigation";
13
14
  import { type RbacStrings } from "./areas/rbac";
14
- export type UiStrings = AuthProvenanceFlowsStrings & BoardStrings & ChatChartStrings & CodeEditorStrings & DatesStrings & DocsViewsStrings & FeedbackStrings & FormsStrings & FormatsStrings & MarkdownStrings & MoveRejectedStrings & NavigationStrings & RbacStrings;
15
+ export type UiStrings = AuthProvenanceFlowsStrings & BoardStrings & ChatChartStrings & CodeEditorStrings & DatesStrings & DocsViewsStrings & FeedbackStrings & FormsStrings & FormatsStrings & KeysStrings & MarkdownStrings & MoveRejectedStrings & NavigationStrings & RbacStrings;
15
16
  export declare const ENGLISH_UI_STRINGS: UiStrings;
@@ -30,8 +30,6 @@ interface HotkeyBase {
30
30
  * which character the modifier produced.
31
31
  */
32
32
  key: string;
33
- /** What the help surface shows, which is the chord as a person types it ("Ctrl+Shift+["), derived from `key`. */
34
- label: string;
35
33
  group: HotkeyGroup;
36
34
  }
37
35
  /** A chord, and EITHER the pure edit it makes OR the editor request it raises. */
@@ -0,0 +1,2 @@
1
+ /** A moment as epoch millis, from the three shapes a caller holds (ISO string, epoch millis, `Date`). `NaN` when it does not parse. The one parser the time layer shares. DX-4797. */
2
+ export declare function toEpochMs(when: string | number | Date): number;
@@ -11,5 +11,8 @@ import type { RelativeAgeStrings } from "../i18n/areas/formats";
11
11
  * every sibling formatter in this codebase — nobody needs "9d ago" instead
12
12
  * of "1w 2d ago", and nobody needs either instead of a calendar date, but a
13
13
  * chat message's hover row has no room for a calendar date, so weeks it is.
14
+ *
15
+ * `now` is the instant to measure against (default: the clock). `RelativeTime`'s shared ticker passes later instants to find
16
+ * when this text next changes.
14
17
  */
15
- export declare function relativeAge(when: string | number | Date, strings: RelativeAgeStrings, locale: string): string;
18
+ export declare function relativeAge(when: string | number | Date, strings: RelativeAgeStrings, locale: string, now?: number): string;
@@ -0,0 +1,8 @@
1
+ /** The text of a moment as of `now` (epoch ms). `relativeAge` is one. */
2
+ export type RelativeFormat = (at: string | number | Date, now?: number) => string;
3
+ /** The first instant after `now` at which `format(at, instant)` differs from `format(at, now)`, within `HORIZON_MS`. */
4
+ export declare function nextTextChangeAt(at: number, format: RelativeFormat, now: number): number;
5
+ /** Calls `onChange` whenever `format(at)` may now read differently. Returns the unsubscribe. The last unsubscribe stops the timer. */
6
+ export declare function subscribeRelativeClock(at: number, format: RelativeFormat, onChange: () => void): () => void;
7
+ /** Mounted subscribers right now; the tests pin that it returns to zero. */
8
+ export declare function relativeClockSubscriberCount(): number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danxbot/ui",
3
- "version": "21.1.0",
3
+ "version": "22.0.0",
4
4
  "type": "module",
5
5
  "description": "Danxbot — a domain-agnostic React design system with motion as a first-class primitive.",
6
6
  "license": "MIT",