/** * Kit semantics core — the Intl formatters the KIT ITSELF still needs. * * The value-formatting tier is gone: a screen formats its own figures with * `Intl`, which the VM bridges (`genui/component/vm-program.ts`), so nothing here * is model-facing any more — the charts were the last holdout, and their `format` * tokens are now the screen's own per-row functions (`charts/sanitize.tsx`). * What is left serves the three places a displayed value never passes through the * model's code at all: the chrome's own rendering of tool arguments, the digit * grouping a chart falls back to on an axis the screen cannot reach, one form * control's own affordance (DateRange) — plus the total text coercion every * container uses to turn an absent field into a designed placeholder. * * Every formatter is still total: bad data (NaN, Infinity, unparseable dates) * returns `null`, never `$NaN` on an axis. */ /** A finite, real JS number — the only thing the numeric tier will format. */ export declare function isRenderableNumber(value: unknown): value is number; /** The host's display currency + locale for every Kit formatter. */ export interface KitIntl { /** ISO 4217 code, e.g. "PKR". */ currency: string; /** BCP-47 locale, e.g. "en-PK". */ locale: string; } /** * Install the ambient currency/locale. Unspecified fields RESET to the * built-in default rather than merging with whatever ran before, so the same * input always produces the same state regardless of call order. * * A currency/locale Intl rejects is dropped for the default: a typo in host * config costs the "$" it would have fixed, never a screen of placeholders. */ export declare function setKitIntl(next: Partial | undefined): void; /** The currency/locale every formatter falls back to. */ export declare function getKitIntl(): KitIntl; export interface MoneyOptions { /** ISO 4217 code; defaults to the ambient currency (USD until set). */ currency?: string; /** BCP-47 locale; defaults to the ambient locale (en-US until set). */ locale?: string; } /** How many minor units make one major unit of `currency`. */ export declare function currencyMinorUnits(currency: string): number; /** * Pretty-print an amount that is ALREADY in major units: `1234.56` → `"$1,234.56"`. * * Formatters never convert units. Callers pass major units, so a host field in * minor units (cents) is divided by 100 where it is READ, never here. The ISO * minor unit still decides how many decimals SHOW — none for JPY, three for KWD. * Returns `null` for any non-finite or absent input so `$NaN` can never ship. */ export declare function formatMoney(amount: number | undefined, options?: MoneyOptions): string | null; export interface NumOptions { maximumFractionDigits?: number; minimumFractionDigits?: number; notation?: "standard" | "compact"; /** A unit written after the figure — "ms", "min", "h", "GB". Not `Intl`'s * `style: "unit"`: that takes a fixed vocabulary ("millisecond"), and the * short word a host actually uses is not always in it. */ unit?: string; locale?: string; } /** * Format a plain number with thousands grouping. Returns `null` if non-finite. * * A CHART AXIS is what this is left for inside the Kit, and it is the one figure * a screen's own formatter cannot reach: recharts invents an axis tick off the * scale, so it is a number the screen never held a row of. Grouping is all the * Kit will do to one — 285000 reads "285,000" and never "$285,000", because what * the number MEANS is the screen's to say and the chart is not told. */ export declare function formatNum(value: number | undefined, options?: NumOptions): string | null; export type DateInput = string | number | Date; export interface DateTimeOptions { /** date = calendar day · time = clock · datetime = both · relative = "3 days ago". */ mode?: "date" | "time" | "datetime" | "relative"; /** Drop the year ("Aug 12"), for somewhere narrow like a table cell. */ compact?: boolean; locale?: string; timeZone?: string; } /** * Format a date/time. Accepts ISO strings, epoch millis, or `Date` — and ONLY * those. Returns `null` for anything else, including a stamp that is already * written for a reader ("Aug 15, 7:42 AM"), which the caller shows as it stands. * * KNOWN COST of the value tier's removal: this totality now covers only the * places the KIT still formats — the chrome, and DateRange's own range. A screen writes * `new Date(row.due).toLocaleDateString(…)` in its own code, and an unparseable * stamp there renders the literal "Invalid Date" where the tier used to paint a * muted dash. Accepted: the dash was worth less than one road for every figure. */ export declare function formatDateTime(value: DateInput | undefined, options?: DateTimeOptions): string | null; /** * What is left of the format union: `text`, and the one control that still reads * a `date` for itself. * * There is NO model-facing token any more. The chart tokens were the last of them * — `money`, `number`, `duration`, `datetime`, `time` all died with the charts' * own `format`, which is a function the screen writes now — so this union is * purely internal, and nothing outside `@vendoai/vendo/ui` names a member of it. * `text` is its floor: the total coercion the containers read through it, which is * what turns an absent field into a designed placeholder. `date` is `DateRange`'s * own affordance — a date picker draws the range it holds, and the range is the * control's state rather than a figure the screen handed it. */ export type ValueFormat = "date" | "text"; /** Apply a `ValueFormat` token to a raw value, returning `null` when unrenderable. */ export declare function applyFormat(value: unknown, format?: ValueFormat): string | null;