@danxbot/ui 5.1.1 → 5.2.1

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,48 @@
1
+ export interface FormatDateTimeOptions {
2
+ /**
3
+ * IANA zone to render in, e.g. `"America/New_York"`. Omit to use the
4
+ * reader's own zone — the right default for an instant, and the reason
5
+ * this is a parameter at all rather than always-local: a report emailed to
6
+ * someone in a different zone, or a server rendering a PDF, needs to say
7
+ * WHOSE clock the printed time is on.
8
+ */
9
+ zone?: string;
10
+ }
11
+ /**
12
+ * A stored instant → `"09/11/2026, 1:18 PM"` in `options.zone` (default: the
13
+ * reader's own).
14
+ *
15
+ * `null` / `undefined` / `""` render as the em dash. A non-empty value that
16
+ * does not parse as an instant is returned UNCHANGED — see `date.ts`'s
17
+ * docblock for why absence and corruption get different treatment.
18
+ */
19
+ export declare function formatDateTime(value: string | number | null | undefined, options?: FormatDateTimeOptions): string;
20
+ export interface ParseDateTimeOptions {
21
+ /**
22
+ * The zone a bare (no AM/PM-less midnight, no offset) typed value's
23
+ * wall-clock reading is IN. Omit to use the reader's own zone — matching
24
+ * `formatDateTime`'s default, so parsing a value typed against that display
25
+ * uses the same zone it was rendered in.
26
+ */
27
+ zone?: string;
28
+ }
29
+ /**
30
+ * A human-typed date-time → the stored ISO instant, or `null`.
31
+ *
32
+ * TWO PATHS, DELIBERATELY NOT ONE. An ISO string carrying its own offset or
33
+ * `Z` is unambiguous — `Date.parse` resolves it correctly regardless of what
34
+ * zone this function is running in, and is used directly. Everything else is
35
+ * a WALL-CLOCK reading with no zone of its own (`"09/11/2026, 1:18 PM"`), and
36
+ * `Date.parse`'s native handling of that shape resolves it against the
37
+ * HOST's zone — which is wrong the instant `options.zone` names a different
38
+ * one, e.g. a server in UTC parsing a value entered by a reader in
39
+ * `America/New_York`. So the wall-clock path is hand-parsed into fields and
40
+ * handed to `plainDateTimeToInstant`, which resolves it against the
41
+ * REQUESTED zone rather than whatever zone the code happens to be running in.
42
+ *
43
+ * A wall-clock reading that lands in a DST gap or overlap does not throw —
44
+ * `plainDateTimeToInstant`'s default (`"compatible"`) disambiguation applies,
45
+ * matching every other date library's default and `Temporal`'s own. See
46
+ * `time-dst.test.ts` for what that resolves to at a transition.
47
+ */
48
+ export declare function parseDateTime(input: string, options?: ParseDateTimeOptions): string | null;
@@ -0,0 +1,6 @@
1
+ export { formatDate, parseDate } from "./date";
2
+ export { formatDateTime, parseDateTime, type FormatDateTimeOptions, type ParseDateTimeOptions } from "./datetime";
3
+ export { formatCurrency, parseCurrency } from "./currency";
4
+ export { formatPhone, parsePhone } from "./phone";
5
+ export { formatNumber, parseNumber, type FormatNumberOptions } from "./number";
6
+ export { formatBoolean, parseBoolean, type FormatBooleanOptions } from "./boolean";
@@ -0,0 +1,27 @@
1
+ export interface FormatNumberOptions {
2
+ /**
3
+ * Fixed fraction digits, e.g. `1` for a percentage rendered as `"42.0"`.
4
+ * Omit to show the value's own precision, up to 6 fraction digits, with no
5
+ * trailing zeros invented.
6
+ */
7
+ decimals?: number;
8
+ }
9
+ /**
10
+ * `1234.5` → `"1,234.5"`. `null` / `undefined` → `"—"`.
11
+ *
12
+ * `NaN` / `Infinity` render as the em dash too, for the same reason
13
+ * `formatCurrency` groups them with absence rather than showing them back:
14
+ * the caller holds a `number`, not a string a person typed, so there is no
15
+ * original text to preserve.
16
+ */
17
+ export declare function formatNumber(value: number | null | undefined, options?: FormatNumberOptions): string;
18
+ /**
19
+ * A human-typed number → a `number`, or `null`.
20
+ *
21
+ * Strips thousands-separator commas (`"1,234.5"` → `1234.5`) before parsing,
22
+ * and accepts a leading `-` for a negative value. Rejects, rather than
23
+ * silently truncating, anything `parseFloat` would otherwise accept a PREFIX
24
+ * of — `"12abc"` is not twelve, it is a typo, and `parseFloat` alone would
25
+ * return `12` and hide that.
26
+ */
27
+ export declare function parseNumber(input: string): number | null;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Ten stored digits → `"(555) 123-4567"`. `null` / `undefined` / `""` → `"—"`.
3
+ *
4
+ * A non-empty value that is not exactly ten digits after parsing is returned
5
+ * UNCHANGED — the same "show the corruption, don't hide it behind absence"
6
+ * rule `formatDate` documents. A stored value should already be `parsePhone`'s
7
+ * output; if it is not, that is a data problem worth seeing in the row, not
8
+ * a blank field that looks like nobody ever entered a number.
9
+ */
10
+ export declare function formatPhone(value: string | null | undefined): string;
11
+ /**
12
+ * A human-typed phone number → ten stored digits, or `null`.
13
+ *
14
+ * Strips everything but digits, so `"(555) 123-4567"`, `"555.123.4567"`,
15
+ * `"555-123-4567 "` and `"5551234567"` all normalise the same way. A leading
16
+ * US country code (`"1"`, making 11 digits total) is dropped — `"+1 (555)
17
+ * 123-4567"` is the same number as `"(555) 123-4567"` and should be stored
18
+ * identically. Anything that is not exactly 10 digits after that — too few,
19
+ * too many, or an 11-digit number NOT starting with `1` (a foreign number
20
+ * mis-typed into a US field, not a US number with an extra digit) — returns
21
+ * `null` rather than truncating or padding a guess into place.
22
+ */
23
+ export declare function parsePhone(input: string): string | null;
@@ -24,13 +24,19 @@
24
24
  *
25
25
  * WHAT BELONGS HERE. Decisions about how a value READS, with no dependencies:
26
26
  * precision, units, the point at which a rounded figure stops telling the
27
- * truth. Deliberately NOT the calendar and time layers — `formatDateRange`,
28
- * `hoursInDay` and the rest are equally pure and would drag the whole `Intl`
29
- * time layer behind them, which is a bigger entry answering a question nobody
30
- * has asked yet. That is a separate decision, to be made when a consumer needs
31
- * it and not before.
27
+ * truth. Deliberately NOT the whole calendar layer — `formatDateRange`,
28
+ * `hoursInDay`, `monthGridDays` and the rest of `lib/time`'s CALENDAR-UI
29
+ * surface are equally pure but answer a question this entry's consumers do
30
+ * not have: they are grid-layout and scheduling math, not "turn a stored
31
+ * value into a string." `lib/values/date.ts` and `datetime.ts` are the
32
+ * question that WAS asked (a consumer's data grid duplicating this exact
33
+ * display/parse logic locally, instead of sourcing it from one place) and are
34
+ * exported below. They reuse `lib/time`'s zone arithmetic internally — that
35
+ * module has no React in it either, so pulling it in transitively costs real
36
+ * bytes but not the one thing this entry actually guards against.
32
37
  *
33
38
  * Everything exported here is ALSO exported from the main entry, so nothing
34
39
  * about this is a migration and no existing import has to change.
35
40
  */
36
- export { formatBytes, formatTokens } from "./lib/format";
41
+ export { formatBytes, formatTokens, formatCompactNumber } from "./lib/format";
42
+ export { formatDate, parseDate, formatDateTime, parseDateTime, type FormatDateTimeOptions, type ParseDateTimeOptions, formatCurrency, parseCurrency, formatPhone, parsePhone, formatNumber, parseNumber, type FormatNumberOptions, formatBoolean, parseBoolean, type FormatBooleanOptions, } from "./lib/values";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danxbot/ui",
3
- "version": "5.1.1",
3
+ "version": "5.2.1",
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",