react-semaphor 0.1.514 → 0.1.515

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.
Files changed (65) hide show
  1. package/dist/brand-studio/index.cjs +1 -1
  2. package/dist/brand-studio/index.js +1 -1
  3. package/dist/briefings/index.cjs +1 -1
  4. package/dist/briefings/index.js +3 -3
  5. package/dist/chunks/{dashboard-briefing-launcher-BzPD50QD.cjs → dashboard-briefing-launcher-B7zqm8P1.cjs} +1 -1
  6. package/dist/chunks/{dashboard-briefing-launcher-e3s3MuSs.js → dashboard-briefing-launcher-BA_bl05p.js} +5 -5
  7. package/dist/chunks/{dashboard-controls-DAOABnks.js → dashboard-controls-QMW17RKx.js} +6 -6
  8. package/dist/chunks/{dashboard-controls-DQBfOqmC.cjs → dashboard-controls-x_v9wLOU.cjs} +1 -1
  9. package/dist/chunks/{dashboard-json-1jZycd5h.cjs → dashboard-json-0ZLLBlHj.cjs} +1 -1
  10. package/dist/chunks/{dashboard-json-S5Eq2GAg.js → dashboard-json-DRnpkNwO.js} +3 -3
  11. package/dist/chunks/{edit-dashboard-visual-Bkm0ciHG.js → edit-dashboard-visual-1ISjhwry.js} +1377 -1380
  12. package/dist/chunks/{edit-dashboard-visual-BwJ2Eljw.cjs → edit-dashboard-visual-CI0EqzKj.cjs} +2 -2
  13. package/dist/chunks/{editor-action-buttons-Bvv16QA-.js → editor-action-buttons-BTCKZERI.js} +3 -3
  14. package/dist/chunks/{editor-action-buttons-B2NCSsDw.cjs → editor-action-buttons-Czq5SnA9.cjs} +1 -1
  15. package/dist/chunks/{index-DhlVxvyI.cjs → index-BMMXKK3G.cjs} +1 -1
  16. package/dist/chunks/{index-DrOFJOCq.cjs → index-C6_xef4P.cjs} +147 -147
  17. package/dist/chunks/{index-CACdoqu3.js → index-C8w91oj4.js} +61 -51
  18. package/dist/chunks/index-Cw2ypaFl.cjs +1 -0
  19. package/dist/chunks/{index-nhUr9xBz.js → index-Dlic9KZs.js} +31494 -31379
  20. package/dist/chunks/{index-CnGVjyF8.js → index-v1OE4-eA.js} +2 -2
  21. package/dist/chunks/matrix-formatter-BdIsE7Qu.js +341 -0
  22. package/dist/chunks/matrix-formatter-Dajj91Ni.cjs +1 -0
  23. package/dist/chunks/{pivot-header-presentation-Dm9dUQsl.js → pivot-header-presentation-BIf4HW3L.js} +35 -36
  24. package/dist/chunks/{pivot-header-presentation-Cxz8-06f.cjs → pivot-header-presentation-B_N11CgN.cjs} +3 -3
  25. package/dist/chunks/{pivot-result-lifecycle-BeOpjAhg.js → pivot-result-lifecycle-CEmyU2At.js} +207 -148
  26. package/dist/chunks/pivot-result-lifecycle-vg_suUNb.cjs +1 -0
  27. package/dist/chunks/{raw-temporal-DrmCX9Wq.js → raw-temporal-Bj6_w9cG.js} +471 -361
  28. package/dist/chunks/raw-temporal-CeblVJbu.cjs +1 -0
  29. package/dist/chunks/{report-preferences-dialog-DcLkVqni.cjs → report-preferences-dialog-Dr1BYwuf.cjs} +1 -1
  30. package/dist/chunks/{report-preferences-dialog-B2fzQH1T.js → report-preferences-dialog-b8J6KjSy.js} +2 -2
  31. package/dist/chunks/semantic-format-DFI1iszk.cjs +1 -0
  32. package/dist/chunks/{semantic-format-BZxJLKvw.js → semantic-format-Dt-nUxFB.js} +23 -29
  33. package/dist/chunks/switch-Ced9ZZwI.cjs +134 -0
  34. package/dist/chunks/{switch-QfKb0Iwe.js → switch-D5_tjsIS.js} +3139 -3087
  35. package/dist/dashboard/index.cjs +1 -1
  36. package/dist/dashboard/index.js +1 -1
  37. package/dist/data-app-builder/index.cjs +1 -1
  38. package/dist/data-app-builder/index.js +2 -2
  39. package/dist/data-app-sdk/index.cjs +1 -1
  40. package/dist/data-app-sdk/index.js +1 -1
  41. package/dist/format-utils/index.cjs +3 -3
  42. package/dist/format-utils/index.js +131 -126
  43. package/dist/index.cjs +1 -1
  44. package/dist/index.js +7 -7
  45. package/dist/surfboard/index.cjs +1 -1
  46. package/dist/surfboard/index.js +2 -2
  47. package/dist/types/components/visual/aggregated-table/utils/metric-format-resolver.d.ts +3 -3
  48. package/dist/types/components/visual/data-table/types/data-table.d.ts +4 -1
  49. package/dist/types/components/visual/pivot-table/utils/pivot-metric-formatting.d.ts +2 -2
  50. package/dist/types/lib/formatters/metric-formatting.d.ts +3 -3
  51. package/dist/types/lib/table-formatting/table-presentation-fields.d.ts +1 -0
  52. package/dist/types/lib/utils/date-timezone-utils.d.ts +26 -4
  53. package/dist/types/shared/format-utils/formatters/duration-formatter.d.ts +4 -1
  54. package/dist/types/shared/format-utils/formatters/index.d.ts +2 -2
  55. package/dist/types/shared/format-utils/formatters/number-formatter.d.ts +8 -2
  56. package/dist/types/shared/format-utils/presentation-execution.d.ts +17 -2
  57. package/dist/types/shared/format-utils/types/format-types.d.ts +16 -1
  58. package/package.json +1 -1
  59. package/dist/chunks/index-F25jnH0p.cjs +0 -1
  60. package/dist/chunks/matrix-formatter-BLunke3R.js +0 -424
  61. package/dist/chunks/matrix-formatter-CveLJo6S.cjs +0 -1
  62. package/dist/chunks/pivot-result-lifecycle-BiERyXnS.cjs +0 -1
  63. package/dist/chunks/raw-temporal-BUeTpG76.cjs +0 -1
  64. package/dist/chunks/semantic-format-BzH69TRq.cjs +0 -1
  65. package/dist/chunks/switch--Re1K566.cjs +0 -134
package/dist/index.js CHANGED
@@ -1,15 +1,15 @@
1
- import { E as x, F as B, S, c as N, U as _, d as P, C as w, V as F, e as R, f as L, g as I, h as M, I as k, R as U, i as O, j as V, k as q, l as z } from "./chunks/index-nhUr9xBz.js";
2
- import { al as Ta, am as va, an as Aa, ao as Ba, W as Sa, G as Na, D as _a, A as Pa, z as wa, w as Fa, b as Ra, av as La, M as Ia, n as Ma, q as ka, q as Ua, r as Oa, B as Va, a as qa, ag as za, ai as ja, aj as Wa, ah as Qa, a7 as Ha, aa as Ka, au as Ga, _ as Ya, af as Xa, aq as $a, a2 as Ja, ab as Za, y as ae, x as ee, ay as se, Z as re, ac as oe, ad as ie, a6 as te, a9 as ne, at as le, as as de, ar as ue, ax as ce, aw as pe, a8 as fe, Y as me, X as he, a0 as Ce, ae as ge, a4 as De, a1 as Ee, a3 as xe, a5 as be, $ as ye, P as Te, L as ve, ap as Ae, v as Be, J as Se, t as Ne, m as _e, H as Pe, K as we, o as Fe, T as Re, O as Le, N as Ie, Q as Me, u as ke, s as Ue, p as Oe, ak as Ve } from "./chunks/index-nhUr9xBz.js";
1
+ import { E as x, F as B, S, c as N, U as _, d as P, C as w, V as F, e as R, f as L, g as I, h as M, I as k, R as U, i as O, j as V, k as q, l as z } from "./chunks/index-Dlic9KZs.js";
2
+ import { al as Ta, am as va, an as Aa, ao as Ba, W as Sa, G as Na, D as _a, A as Pa, z as wa, w as Fa, b as Ra, av as La, M as Ia, n as Ma, q as ka, q as Ua, r as Oa, B as Va, a as qa, ag as za, ai as ja, aj as Wa, ah as Qa, a7 as Ha, aa as Ka, au as Ga, _ as Ya, af as Xa, aq as $a, a2 as Ja, ab as Za, y as ae, x as ee, ay as se, Z as re, ac as oe, ad as ie, a6 as te, a9 as ne, at as le, as as de, ar as ue, ax as ce, aw as pe, a8 as fe, Y as me, X as he, a0 as Ce, ae as ge, a4 as De, a1 as Ee, a3 as xe, a5 as be, $ as ye, P as Te, L as ve, ap as Ae, v as Be, J as Se, t as Ne, m as _e, H as Pe, K as we, o as Fe, T as Re, O as Le, N as Ie, Q as Me, u as ke, s as Ue, p as Oe, ak as Ve } from "./chunks/index-Dlic9KZs.js";
3
3
  import { C as ze, E as je } from "./chunks/common-types-C6cAQgyh.js";
4
- import { R as Qe } from "./chunks/report-preferences-dialog-B2fzQH1T.js";
4
+ import { R as Qe } from "./chunks/report-preferences-dialog-b8J6KjSy.js";
5
5
  import { jsx as a, jsxs as l } from "react/jsx-runtime";
6
- import { u as j, P as W, a as Q, B as H, c as g, b as K, d as G } from "./chunks/switch-QfKb0Iwe.js";
7
- import { A as Ke, n as Ge, e as Ye, f as Xe, g as $e, p as Je, o as Ze, s as as, t as es, m as ss, i as rs, l as os, q as is, k as ts, j as ns, h as ls, v as ds, r as us, w as cs, y as ps, x as fs, z as ms, E as hs, D as Cs } from "./chunks/switch-QfKb0Iwe.js";
6
+ import { u as j, P as W, a as Q, B as H, c as g, b as K, d as G } from "./chunks/switch-D5_tjsIS.js";
7
+ import { A as Ke, n as Ge, e as Ye, f as Xe, g as $e, p as Je, o as Ze, s as as, t as es, m as ss, i as rs, l as os, q as is, k as ts, j as ns, h as ls, v as ds, r as us, w as cs, y as ps, x as fs, z as ms, E as hs, D as Cs } from "./chunks/switch-D5_tjsIS.js";
8
8
  import * as f from "react";
9
9
  import { useMemo as Y, useEffect as b } from "react";
10
10
  import { D as Ds } from "./chunks/token-types-Dl0hcKBX.js";
11
11
  import { C as xs, D as bs, L as ys, P as Ts, f as vs, g as As, k as Bs, j as Ss, l as Ns, e as _s, c as Ps, b as ws, d as Fs, n as Rs, h as Ls } from "./chunks/validators-CkHsAvwB.js";
12
- import { A as Ms, h as ks, D as Us, f as Os, g as Vs, e as qs, b as zs, E as js, N as Ws, U as Qs, a as Hs, V as Ks, W as Gs, u as Ys, c as Xs, d as $s } from "./chunks/dashboard-briefing-launcher-e3s3MuSs.js";
12
+ import { A as Ms, h as ks, D as Us, f as Os, g as Vs, e as qs, b as zs, E as js, N as Ws, U as Qs, a as Hs, V as Ks, W as Gs, u as Ys, c as Xs, d as $s } from "./chunks/dashboard-briefing-launcher-BA_bl05p.js";
13
13
  import { u as Zs } from "./chunks/use-debounced-dirty-check-BwAbnX_5.js";
14
14
  import "./chunks/matrix-operation-contract-D0HfzwZg.js";
15
15
  import "./chunks/matrix-continuation-C4sRcjZU.js";
@@ -21,7 +21,7 @@ import { c as X } from "./chunks/calculated-field-identity-DnRd4YIY.js";
21
21
  import "zod";
22
22
  import "./chunks/card-config-utils-B2cDWQqB.js";
23
23
  import "react-dom";
24
- import "./chunks/index-CnGVjyF8.js";
24
+ import "./chunks/index-v1OE4-eA.js";
25
25
  import "./chunks/appearance-context-VJdrKi7r.js";
26
26
  import "./chunks/color-CJvdlFM_.js";
27
27
  import "./chunks/index-CLIro-EG.js";
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../chunks/index-DrOFJOCq.cjs"),r=require("../chunks/common-types-nBuCd3u2.cjs"),o=require("../chunks/report-preferences-dialog-DcLkVqni.cjs");exports.DisplayFormatPreferencesFields=e.DisplayFormatPreferencesFields;exports.Surfboard=e.DashboardPlus;exports.CONTROL_CARD_DEFAULT_VALUE=r.CONTROL_CARD_DEFAULT_VALUE;exports.EMPTY_SELECTION=r.EMPTY_SELECTION;exports.ReportPreferencesDialog=o.ReportPreferencesDialog;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../chunks/index-C6_xef4P.cjs"),r=require("../chunks/common-types-nBuCd3u2.cjs"),o=require("../chunks/report-preferences-dialog-Dr1BYwuf.cjs");exports.DisplayFormatPreferencesFields=e.DisplayFormatPreferencesFields;exports.Surfboard=e.DashboardPlus;exports.CONTROL_CARD_DEFAULT_VALUE=r.CONTROL_CARD_DEFAULT_VALUE;exports.EMPTY_SELECTION=r.EMPTY_SELECTION;exports.ReportPreferencesDialog=o.ReportPreferencesDialog;
@@ -1,6 +1,6 @@
1
- import { b as a, a as o } from "../chunks/index-nhUr9xBz.js";
1
+ import { b as a, a as o } from "../chunks/index-Dlic9KZs.js";
2
2
  import { C as f, E } from "../chunks/common-types-C6cAQgyh.js";
3
- import { R as t } from "../chunks/report-preferences-dialog-B2fzQH1T.js";
3
+ import { R as t } from "../chunks/report-preferences-dialog-b8J6KjSy.js";
4
4
  export {
5
5
  f as CONTROL_CARD_DEFAULT_VALUE,
6
6
  a as DisplayFormatPreferencesFields,
@@ -4,7 +4,7 @@ import { ColumnSettings, ColumnSettingsMap } from '../../data-table/types/data-t
4
4
  import { PresentationFormatField } from '../../../../lib/formatters/metric-formatting.js';
5
5
  import { ResolvedValueFormatPreferences } from '../../../../shared/value-format-preferences/index.js';
6
6
  import { CardNumericPresentationContext } from '../../../../lib/formatters/numeric-presentation.js';
7
- import { NumericCanonicalFormat } from '../../../../shared/format-utils/types/index.js';
7
+ import { MeasureCanonicalFormat } from '../../../../shared/format-utils/types/index.js';
8
8
  import { coerceNumericValue } from '../../../../lib/formatters/numeric-value-coercion.js';
9
9
  export { hasNumericFieldFormat } from '../../../../lib/table-formatting/table-presentation-fields.js';
10
10
  export { coerceNumericValue };
@@ -58,9 +58,9 @@ export declare function resolveAggregateMetricCanonicalPresentation(params: {
58
58
  groupByColumnCount: number;
59
59
  columnSettingsMap?: ColumnSettingsMap;
60
60
  presentation?: CardNumericPresentationContext;
61
- }): NumericCanonicalFormat | undefined;
61
+ }): MeasureCanonicalFormat | undefined;
62
62
  export declare function formatNumericWithSettings(value: unknown, settings?: ColumnSettings): string | null;
63
63
  export declare function formatAggregateMetricValue(value: unknown, presentation?: {
64
64
  settings?: ColumnSettings;
65
- canonical?: NumericCanonicalFormat;
65
+ canonical?: MeasureCanonicalFormat;
66
66
  }): string;
@@ -6,6 +6,7 @@ import { Interaction } from '../../../../lib/types/interaction-types.js';
6
6
  import { ClickContextResult } from '../../../../lib/interactions/get-click-context-from-chartjs.js';
7
7
  import { ComparisonMetadataMap } from '../../../../lib/types/query-types.js';
8
8
  import { ColumnReorderRequest } from '../../shared/utils/table-column-order.js';
9
+ import { ColumnDurationFormat, ColumnNumberStyle } from '../../../../shared/format-utils/types/index.js';
9
10
  import { ConditionalFormattingRenderContext, TableBaseFormatting, TableBaseStyle } from '../../../../lib/table-formatting/table-formatting-types.js';
10
11
  import { ColumnTextWrap } from '../../../../lib/table-formatting/table-text-flow.js';
11
12
  import { RawTemporalValueKind, SemaphorResultColumn } from '../../../../shared/analytics-protocol/index.js';
@@ -38,7 +39,7 @@ export interface ColumnSettings {
38
39
  totalsBehavior?: TotalsBehavior;
39
40
  totalsLabel?: string;
40
41
  numberFormat: {
41
- style: 'decimal' | 'currency' | 'percent' | 'scientific';
42
+ style: ColumnNumberStyle;
42
43
  currency?: string;
43
44
  locale?: string;
44
45
  minimumFractionDigits?: number;
@@ -50,6 +51,8 @@ export interface ColumnSettings {
50
51
  negativeStyle?: 'minus' | 'parentheses';
51
52
  prefix?: string;
52
53
  suffix?: string;
54
+ /** Duration options; read only when `style` is `duration`. */
55
+ duration?: ColumnDurationFormat;
53
56
  showDataBar: boolean;
54
57
  dataBarColor: string;
55
58
  dataBarMinValue?: number;
@@ -1,7 +1,7 @@
1
1
  import { CurrencyPresentationTarget, TCard } from '../../../../lib/types/common-types.js';
2
2
  import { ResolvedValueFormatPreferences } from '../../../../shared/value-format-preferences/index.js';
3
3
  import { ColumnSettings, ColumnSettingsMap } from '../../data-table/types/data-table.js';
4
- import { NumericCanonicalFormat } from '../../../../shared/format-utils/types/index.js';
4
+ import { MeasureCanonicalFormat } from '../../../../shared/format-utils/types/index.js';
5
5
  type PivotColumnMetadata = Record<string, {
6
6
  metricId?: string;
7
7
  metricAlias?: string;
@@ -14,5 +14,5 @@ export declare function resolvePivotRowTotalSettings(params: {
14
14
  valueFormatPreferences: ResolvedValueFormatPreferences | null;
15
15
  resolveBoundCurrency: (target: CurrencyPresentationTarget) => string | undefined;
16
16
  }): ColumnSettings | undefined;
17
- export declare function resolvePivotRowTotalCanonicalFormat(params: Parameters<typeof resolvePivotRowTotalSettings>[0]): NumericCanonicalFormat | undefined;
17
+ export declare function resolvePivotRowTotalCanonicalFormat(params: Parameters<typeof resolvePivotRowTotalSettings>[0]): MeasureCanonicalFormat | undefined;
18
18
  export {};
@@ -6,7 +6,7 @@ import { CardNumericPresentationContext } from './numeric-presentation.js';
6
6
  import { RawTemporalValueKind } from '../../shared/format-utils/index.js';
7
7
  import { ResolvedValueFormatPreferences } from '../../shared/value-format-preferences/index.js';
8
8
  import { MatrixCardCatalog } from '../matrix-table/matrix-card-adapter.js';
9
- import { NumericCanonicalFormat } from '../../shared/format-utils/types/index.js';
9
+ import { MeasureCanonicalFormat, NumericCanonicalFormat } from '../../shared/format-utils/types/index.js';
10
10
  import { ChartNumericPresentationContext } from './chart-numeric-presentation.js';
11
11
  type MetricLookup = TableFieldLookup;
12
12
  export type PresentationFormatField = Pick<MetricField | DetailField | GroupByField, 'id' | 'name' | 'alias' | 'format' | 'dataType'>;
@@ -154,7 +154,7 @@ export declare function resolveMetricCanonicalFormat(params: {
154
154
  columnKeyMap?: QueryColumnKeyMap;
155
155
  valueFormatPreferences?: ResolvedValueFormatPreferences | null;
156
156
  boundCurrency?: string;
157
- }): NumericCanonicalFormat | undefined;
157
+ }): MeasureCanonicalFormat | undefined;
158
158
  export declare function resolveTableColumnCanonicalPresentation(params: {
159
159
  card: TCard;
160
160
  columnId: string;
@@ -167,7 +167,7 @@ export declare function resolveTableColumnCanonicalPresentation(params: {
167
167
  comparisonValueKind?: 'comparison' | 'delta' | 'percent_change' | 'ratio';
168
168
  comparisonPrecision?: number;
169
169
  presentation: CardNumericPresentationContext;
170
- }): NumericCanonicalFormat | undefined;
170
+ }): MeasureCanonicalFormat | undefined;
171
171
  export declare function resolveCurrencyPresentationTargetFormat(params: {
172
172
  matrixCatalog?: MatrixCardCatalog;
173
173
  card: TCard;
@@ -10,6 +10,7 @@ export type TableFieldLookup = {
10
10
  fieldRole?: QueryColumnKeyRole;
11
11
  columnKeyMap?: QueryColumnKeyMap;
12
12
  };
13
+ /** True when the field authors a format for numeric values (numeric or duration). */
13
14
  export declare function hasNumericFieldFormat(field: Pick<PresentationField, 'format'> | undefined): boolean;
14
15
  /** Resolve identity before presentation. A supplied map is authoritative; names
15
16
  * and labels are only a unique-match adapter for results without bindings. */
@@ -8,9 +8,13 @@ import { CalendarContext, WeekStart } from '../types/token-types.js';
8
8
  * @returns A Date object representing midnight in the specified timezone
9
9
  *
10
10
  * @example
11
- * // User in PST selects Nov 18, 2025
12
- * startOfDayInTimezone(new Date('2025-11-18'), 'America/Los_Angeles')
11
+ * // Nov 18, 2025 14:30 PST
12
+ * startOfDayInTimezone(new Date('2025-11-18T22:30:00Z'), 'America/Los_Angeles')
13
13
  * // Returns a Date that serializes to: 2025-11-18T08:00:00.000Z (Nov 18 00:00 PST)
14
+ *
15
+ * Do not pass `new Date('YYYY-MM-DD')`: that is UTC midnight, which is the
16
+ * previous day in zones west of UTC. Use `parseFilterDateValue` for
17
+ * date-only strings.
14
18
  */
15
19
  export declare const startOfDayInTimezone: (date: Date, timezone: string) => Date;
16
20
  /**
@@ -22,11 +26,29 @@ export declare const startOfDayInTimezone: (date: Date, timezone: string) => Dat
22
26
  * @returns A Date object representing 23:59:59.999 in the specified timezone
23
27
  *
24
28
  * @example
25
- * // User in PST selects Nov 20, 2025
26
- * endOfDayInTimezone(new Date('2025-11-20'), 'America/Los_Angeles')
29
+ * // Nov 20, 2025 14:30 PST
30
+ * endOfDayInTimezone(new Date('2025-11-20T22:30:00Z'), 'America/Los_Angeles')
27
31
  * // Returns a Date that serializes to: 2025-11-21T07:59:59.999Z (Nov 20 23:59:59 PST)
28
32
  */
29
33
  export declare const endOfDayInTimezone: (date: Date, timezone: string) => Date;
34
+ /**
35
+ * Parses a stored date filter value into the instant the date pickers would
36
+ * have written for it.
37
+ *
38
+ * Filter values are usually instants, but date-only strings (`YYYY-MM-DD`)
39
+ * also arrive from SDK/embed defaults, generated dashboards and inputs. A
40
+ * date-only string names a calendar day, not an instant: it maps to the start
41
+ * (or, for an upper bound, the end) of that day in `timezone`, exactly as
42
+ * `startOfDayInTimezone` / `endOfDayInTimezone` produce for a picked day.
43
+ * `new Date('YYYY-MM-DD')` would instead give UTC midnight, which displays as
44
+ * the previous day in zones west of UTC.
45
+ *
46
+ * Everything else parses as an instant. Returns undefined for empty or
47
+ * unparseable values, including `YYYY-MM-DD` strings that name no calendar
48
+ * day (which `new Date` would silently roll into the next month). A missing timezone falls back to the browser zone, as
49
+ * `getEffectiveTimezone` does.
50
+ */
51
+ export declare const parseFilterDateValue: (value: unknown, timezone: string | null | undefined, bound?: "start" | "end") => Date | undefined;
30
52
  /**
31
53
  * Gets the start of week (midnight) for a date in the specified timezone.
32
54
  *
@@ -1,2 +1,5 @@
1
- import { DurationFormatOptions } from '../types/index.js';
1
+ import { DurationCanonicalFormat, DurationFormatOptions } from '../types/index.js';
2
+ import { ExactNumericValue } from '../../analytics-protocol/scalar-value.js';
2
3
  export declare function formatDuration(value: number | string | null | undefined, options?: DurationFormatOptions): string;
4
+ /** Formats a value with a canonical duration format. */
5
+ export declare function formatDurationCanonical(value: number | ExactNumericValue | string | null | undefined, format: DurationCanonicalFormat): string;
@@ -1,5 +1,5 @@
1
- export { formatNumber, formatCurrency, formatPercent, formatScientific, formatNumericCanonical, formatNumberWithColumnSettings, formatNumberCustom, } from './number-formatter.js';
2
- export { formatDuration } from './duration-formatter.js';
1
+ export { formatNumber, formatCurrency, formatPercent, formatScientific, formatNumericCanonical, formatMeasureCanonical, formatNumberWithColumnSettings, formatNumberCustom, } from './number-formatter.js';
2
+ export { formatDuration, formatDurationCanonical } from './duration-formatter.js';
3
3
  export { formatMetricComparison, type FormattedMetricComparison, type FormattedMetricComparisonPart, type FormatMetricComparisonOptions, type MetricComparisonDisplayMode, } from './metric-comparison-formatter.js';
4
4
  export { formatDate, formatRelativeTime, resolveTimezone, getTimezoneAbbreviation, getTimezoneName, parseWithSourceTimezone, } from './date-formatter.js';
5
5
  export { formatCellValue, formatRowForExport } from './cell-formatter.js';
@@ -1,4 +1,4 @@
1
- import { FormatOptions, NumberFormatOptions, NumericCanonicalFormat } from '../types/index.js';
1
+ import { ColumnDurationFormat, ColumnNumberStyle, FormatOptions, MeasureCanonicalFormat, NumberFormatOptions, NumericCanonicalFormat } from '../types/index.js';
2
2
  import { ExactNumericValue } from '../../analytics-protocol/scalar-value.js';
3
3
  type NumericValue = number | ExactNumericValue;
4
4
  /**
@@ -21,12 +21,17 @@ export declare function formatPercent(value: NumericValue | null | undefined, op
21
21
  */
22
22
  export declare function formatScientific(value: NumericValue | null | undefined, options?: NumberFormatOptions): string;
23
23
  export declare function formatNumericCanonical(value: number | ExactNumericValue | null | undefined, format: NumericCanonicalFormat): string;
24
+ /**
25
+ * Formats a table measure value with its resolved format: numeric styles go
26
+ * through `formatNumericCanonical`, durations through the duration formatter.
27
+ */
28
+ export declare function formatMeasureCanonical(value: number | ExactNumericValue | null | undefined, format: MeasureCanonicalFormat): string;
24
29
  /**
25
30
  * Format a number value based on ColumnSettings.numberFormat
26
31
  * Used for export formatting
27
32
  */
28
33
  export declare function formatNumberWithColumnSettings(value: number | ExactNumericValue | null | undefined, numberFormat: {
29
- style?: 'decimal' | 'currency' | 'percent' | 'scientific';
34
+ style?: ColumnNumberStyle;
30
35
  currency?: string;
31
36
  locale?: string;
32
37
  minimumFractionDigits?: number;
@@ -38,6 +43,7 @@ export declare function formatNumberWithColumnSettings(value: number | ExactNume
38
43
  negativeStyle?: 'minus' | 'parentheses';
39
44
  prefix?: string;
40
45
  suffix?: string;
46
+ duration?: ColumnDurationFormat;
41
47
  } | undefined, defaultLocale?: string): string;
42
48
  /**
43
49
  * Legacy wrapper for backward compatibility with existing code
@@ -2,7 +2,7 @@ import { ResolvedRawTemporalFormat } from './raw-temporal.js';
2
2
  import { ReportRuntimeContext } from '../report-runtime-context/index.js';
3
3
  import { NumericPresentationTarget } from './numeric-presentation.js';
4
4
  import { ResolvedTemporalBucketFormat } from './temporal-bucket.js';
5
- import { NumericCanonicalFormat } from './types/index.js';
5
+ import { DurationCanonicalFormat, MeasureCanonicalFormat, NumericCanonicalFormat } from './types/index.js';
6
6
  export type PresentationScope = {
7
7
  dashboardId: string;
8
8
  cardId?: string;
@@ -25,6 +25,11 @@ export type ResolvedNumericPresentationEntry = {
25
25
  target: NumericPresentationTarget;
26
26
  format: NumericCanonicalFormat;
27
27
  };
28
+ export type ResolvedDurationPresentationEntry = {
29
+ scope: PresentationScope;
30
+ target: NumericPresentationTarget;
31
+ format: DurationCanonicalFormat;
32
+ };
28
33
  export type ResolvedTemporalBucketPresentationEntry = {
29
34
  scope: PresentationScope;
30
35
  target: TemporalBucketPresentationTarget;
@@ -39,7 +44,7 @@ export type ResolvedRawTemporalPresentationEntry = {
39
44
  target: RawTemporalPresentationTarget;
40
45
  format: ResolvedRawTemporalFormat;
41
46
  };
42
- export type ResolvedPresentationEntry = ResolvedNumericPresentationEntry | ResolvedTemporalBucketPresentationEntry | ResolvedRawTemporalPresentationEntry;
47
+ export type ResolvedPresentationEntry = ResolvedNumericPresentationEntry | ResolvedDurationPresentationEntry | ResolvedTemporalBucketPresentationEntry | ResolvedRawTemporalPresentationEntry;
43
48
  export type PresentationExecutionSnapshot = {
44
49
  version: 1;
45
50
  reportContext: ReportRuntimeContext;
@@ -67,6 +72,16 @@ export declare function findResolvedNumericFormat(input: {
67
72
  scope: PresentationScope;
68
73
  target: NumericPresentationTarget;
69
74
  }): NumericCanonicalFormat | undefined;
75
+ /**
76
+ * Finds the resolved numeric or duration format for a measure target. Value
77
+ * formatters use this; `findResolvedNumericFormat` is for numeric-only
78
+ * consumers such as precision and currency lookups.
79
+ */
80
+ export declare function findResolvedMeasureFormat(input: {
81
+ snapshot: PresentationExecutionSnapshot;
82
+ scope: PresentationScope;
83
+ target: NumericPresentationTarget;
84
+ }): MeasureCanonicalFormat | undefined;
70
85
  export declare function findResolvedRawTemporalFormat(input: {
71
86
  snapshot: PresentationExecutionSnapshot;
72
87
  scope: PresentationScope;
@@ -51,6 +51,12 @@ export type DurationCanonicalFormat = {
51
51
  suffix?: string;
52
52
  negativeStyle?: 'minus' | 'parentheses';
53
53
  };
54
+ /**
55
+ * Formats a table measure value can resolve to: a numeric style, or a
56
+ * duration rendered from a numeric amount of `inputUnit`. Every surface that
57
+ * renders a measure value (table cells, totals, exports) must accept both.
58
+ */
59
+ export type MeasureCanonicalFormat = NumericCanonicalFormat | DurationCanonicalFormat;
54
60
  export type StringCanonicalFormat = {
55
61
  type: 'string';
56
62
  prefix?: string;
@@ -58,6 +64,7 @@ export type StringCanonicalFormat = {
58
64
  };
59
65
  export type CanonicalFormatSpec = NumericCanonicalFormat | DateCanonicalFormat | RawTemporalFormat | DurationCanonicalFormat | StringCanonicalFormat | TemporalBucketFormat;
60
66
  export declare function isNumericCanonicalFormat(format: unknown): format is NumericCanonicalFormat;
67
+ export declare function isMeasureCanonicalFormat(format: unknown): format is MeasureCanonicalFormat;
61
68
  export interface NumberFormatOptions {
62
69
  style: 'decimal' | 'currency' | 'percent' | 'scientific';
63
70
  locale?: string;
@@ -113,18 +120,26 @@ export interface DateFormatOptions {
113
120
  /** Locale for date formatting */
114
121
  locale?: string;
115
122
  }
123
+ export type ColumnNumberStyle = 'decimal' | 'currency' | 'percent' | 'scientific' | 'duration';
124
+ /** Duration options on a table column (`numberFormat.style: 'duration'`). */
125
+ export type ColumnDurationFormat = Pick<DurationCanonicalFormat, 'inputUnit' | 'outputStyle' | 'largestUnit' | 'smallestUnit' | 'maxUnits'>;
116
126
  export interface ColumnSettings {
117
127
  type: 'none' | 'text' | 'number' | 'date' | 'badge' | 'link' | 'progress';
118
128
  textAlign?: 'left' | 'center' | 'right';
119
129
  width?: number;
120
130
  numberFormat?: {
121
- style: 'decimal' | 'currency' | 'percent' | 'scientific';
131
+ style: ColumnNumberStyle;
122
132
  currency?: string;
123
133
  locale?: string;
124
134
  minimumFractionDigits?: number;
125
135
  maximumFractionDigits?: number;
126
136
  useGrouping?: boolean;
127
137
  percentValueMode?: 'fraction' | 'whole';
138
+ prefix?: string;
139
+ suffix?: string;
140
+ negativeStyle?: 'minus' | 'parentheses';
141
+ /** Duration options; read only when `style` is `duration`. */
142
+ duration?: ColumnDurationFormat;
128
143
  showDataBar?: boolean;
129
144
  dataBarColor?: string;
130
145
  dataBarMinValue?: number;
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "email": "support@semaphor.cloud"
6
6
  },
7
7
  "license": "MIT",
8
- "version": "0.1.514",
8
+ "version": "0.1.515",
9
9
  "description": "Fully interactive and customizable dashboards for your apps.",
10
10
  "keywords": [
11
11
  "react",
@@ -1 +0,0 @@
1
- "use strict";function F(e,t){const n=b(t);return"formatToParts"in n?$(n,e):A(n,e)}const _={year:0,month:1,day:2,hour:3,minute:4,second:5};function $(e,t){try{const n=e.formatToParts(t),r=[];for(let i=0;i<n.length;i++){const a=_[n[i].type];a!==void 0&&(r[a]=parseInt(n[i].value,10))}return r}catch(n){if(n instanceof RangeError)return[NaN];throw n}}function A(e,t){const n=e.format(t),r=/(\d+)\/(\d+)\/(\d+),? (\d+):(\d+):(\d+)/.exec(n);return[parseInt(r[3],10),parseInt(r[1],10),parseInt(r[2],10),parseInt(r[4],10),parseInt(r[5],10),parseInt(r[6],10)]}const f={},I=new Intl.DateTimeFormat("en-US",{hourCycle:"h23",timeZone:"America/New_York",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"}).format(new Date("2014-06-25T04:00:00.123Z")),S=I==="06/25/2014, 00:00:00"||I==="‎06‎/‎25‎/‎2014‎ ‎00‎:‎00‎:‎00";function b(e){return f[e]||(f[e]=S?new Intl.DateTimeFormat("en-US",{hourCycle:"h23",timeZone:e,year:"numeric",month:"numeric",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"}):new Intl.DateTimeFormat("en-US",{hour12:!1,timeZone:e,year:"numeric",month:"numeric",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"})),f[e]}function T(e,t,n,r,i,a,o){const u=new Date(0);return u.setUTCFullYear(e,t,n),u.setUTCHours(r,i,a,o),u}const w=36e5,L=6e4,D={timezoneZ:/^(Z)$/,timezoneHH:/^([+-]\d{2})$/,timezoneHHMM:/^([+-])(\d{2}):?(\d{2})$/};function Y(e,t,n){if(!e)return 0;let r=D.timezoneZ.exec(e);if(r)return 0;let i,a;if(r=D.timezoneHH.exec(e),r)return i=parseInt(r[1],10),g(i)?-(i*w):NaN;if(r=D.timezoneHHMM.exec(e),r){i=parseInt(r[2],10);const o=parseInt(r[3],10);return g(i,o)?(a=Math.abs(i)*w+o*L,r[1]==="+"?-a:a):NaN}if(E(e)){t=new Date(t||Date.now());const o=n?t:Z(t),u=m(o,e);return-(n?u:z(t,u,e))}return NaN}function Z(e){return T(e.getFullYear(),e.getMonth(),e.getDate(),e.getHours(),e.getMinutes(),e.getSeconds(),e.getMilliseconds())}function m(e,t){const n=F(e,t),r=T(n[0],n[1]-1,n[2],n[3]%24,n[4],n[5],0).getTime();let i=e.getTime();const a=i%1e3;return i-=a>=0?a:1e3+a,r-i}function z(e,t,n){let i=e.getTime()-t;const a=m(new Date(i),n);if(t===a)return t;i-=a-t;const o=m(new Date(i),n);return a===o?a:Math.max(a,o)}function g(e,t){return-23<=e&&e<=23&&(t==null||0<=t&&t<=59)}const M={};function E(e){if(M[e])return!0;try{return new Intl.DateTimeFormat(void 0,{timeZone:e}),M[e]=!0,!0}catch{return!1}}function h(e){const t=new Date(Date.UTC(e.getFullYear(),e.getMonth(),e.getDate(),e.getHours(),e.getMinutes(),e.getSeconds(),e.getMilliseconds()));return t.setUTCFullYear(e.getFullYear()),+e-+t}const U=/(Z|[+-]\d{2}(?::?\d{2})?| UTC| [a-zA-Z]+\/[a-zA-Z_]+(?:\/[a-zA-Z_]+)?)$/,N=36e5,H=6e4,P=2,s={dateTimePattern:/^([0-9W+-]+)(T| )(.*)/,datePattern:/^([0-9W+-]+)(.*)/,YY:/^(\d{2})$/,YYY:[/^([+-]\d{2})$/,/^([+-]\d{3})$/,/^([+-]\d{4})$/],YYYY:/^(\d{4})/,YYYYY:[/^([+-]\d{4})/,/^([+-]\d{5})/,/^([+-]\d{6})/],MM:/^-(\d{2})$/,DDD:/^-?(\d{3})$/,MMDD:/^-?(\d{2})-?(\d{2})$/,Www:/^-?W(\d{2})$/,WwwD:/^-?W(\d{2})-?(\d{1})$/,HH:/^(\d{2}([.,]\d*)?)$/,HHMM:/^(\d{2}):?(\d{2}([.,]\d*)?)$/,HHMMSS:/^(\d{2}):?(\d{2}):?(\d{2}([.,]\d*)?)$/,timeZone:U};function p(e,t={}){if(arguments.length<1)throw new TypeError("1 argument required, but only "+arguments.length+" present");if(e===null)return new Date(NaN);const n=t.additionalDigits==null?P:Number(t.additionalDigits);if(n!==2&&n!==1&&n!==0)throw new RangeError("additionalDigits must be 0, 1 or 2");if(e instanceof Date||typeof e=="object"&&Object.prototype.toString.call(e)==="[object Date]")return new Date(e.getTime());if(typeof e=="number"||Object.prototype.toString.call(e)==="[object Number]")return new Date(e);if(Object.prototype.toString.call(e)!=="[object String]")return new Date(NaN);const r=W(e),{year:i,restDateString:a}=k(r.date,n),o=v(a,i);if(o===null||isNaN(o.getTime()))return new Date(NaN);if(o){const u=o.getTime();let c=0,l;if(r.time&&(c=j(r.time),c===null||isNaN(c)))return new Date(NaN);if(r.timeZone||t.timeZone){if(l=Y(r.timeZone||t.timeZone,new Date(u+c)),isNaN(l))return new Date(NaN)}else l=h(new Date(u+c)),l=h(new Date(u+c+l));return new Date(u+c+l)}else return new Date(NaN)}function W(e){const t={};let n=s.dateTimePattern.exec(e),r;if(n?(t.date=n[1],r=n[3]):(n=s.datePattern.exec(e),n?(t.date=n[1],r=n[2]):(t.date=null,r=e)),r){const i=s.timeZone.exec(r);i?(t.time=r.replace(i[1],""),t.timeZone=i[1].trim()):t.time=r}return t}function k(e,t){if(e){const n=s.YYY[t],r=s.YYYYY[t];let i=s.YYYY.exec(e)||r.exec(e);if(i){const a=i[1];return{year:parseInt(a,10),restDateString:e.slice(a.length)}}if(i=s.YY.exec(e)||n.exec(e),i){const a=i[1];return{year:parseInt(a,10)*100,restDateString:e.slice(a.length)}}}return{year:null}}function v(e,t){if(t===null)return null;let n,r,i;if(!e||!e.length)return n=new Date(0),n.setUTCFullYear(t),n;let a=s.MM.exec(e);if(a)return n=new Date(0),r=parseInt(a[1],10)-1,C(t,r)?(n.setUTCFullYear(t,r),n):new Date(NaN);if(a=s.DDD.exec(e),a){n=new Date(0);const o=parseInt(a[1],10);return q(t,o)?(n.setUTCFullYear(t,0,o),n):new Date(NaN)}if(a=s.MMDD.exec(e),a){n=new Date(0),r=parseInt(a[1],10)-1;const o=parseInt(a[2],10);return C(t,r,o)?(n.setUTCFullYear(t,r,o),n):new Date(NaN)}if(a=s.Www.exec(e),a)return i=parseInt(a[1],10)-1,O(i)?x(t,i):new Date(NaN);if(a=s.WwwD.exec(e),a){i=parseInt(a[1],10)-1;const o=parseInt(a[2],10)-1;return O(i,o)?x(t,i,o):new Date(NaN)}return null}function j(e){let t,n,r=s.HH.exec(e);if(r)return t=parseFloat(r[1].replace(",",".")),d(t)?t%24*N:NaN;if(r=s.HHMM.exec(e),r)return t=parseInt(r[1],10),n=parseFloat(r[2].replace(",",".")),d(t,n)?t%24*N+n*H:NaN;if(r=s.HHMMSS.exec(e),r){t=parseInt(r[1],10),n=parseInt(r[2],10);const i=parseFloat(r[3].replace(",","."));return d(t,n,i)?t%24*N+n*H+i*1e3:NaN}return null}function x(e,t,n){t=t||0,n=n||0;const r=new Date(0);r.setUTCFullYear(e,0,4);const i=r.getUTCDay()||7,a=t*7+n+1-i;return r.setUTCDate(r.getUTCDate()+a),r}const R=[31,28,31,30,31,30,31,31,30,31,30,31],G=[31,29,31,30,31,30,31,31,30,31,30,31];function y(e){return e%400===0||e%4===0&&e%100!==0}function C(e,t,n){if(t<0||t>11)return!1;if(n!=null){if(n<1)return!1;const r=y(e);if(r&&n>G[t]||!r&&n>R[t])return!1}return!0}function q(e,t){if(t<1)return!1;const n=y(e);return!(n&&t>366||!n&&t>365)}function O(e,t){return!(e<0||e>52||t!=null&&(t<0||t>6))}function d(e,t,n){return!(e<0||e>=25||t!=null&&(t<0||t>=60)||n!=null&&(n<0||n>=60))}function J(e,t,n){if(typeof e=="string"&&!e.match(U))return p(e,{...n,timeZone:t});e=p(e,n);const r=T(e.getFullYear(),e.getMonth(),e.getDate(),e.getHours(),e.getMinutes(),e.getSeconds(),e.getMilliseconds()).getTime(),i=Y(t,new Date(r));return new Date(r+i)}exports.fromZonedTime=J;exports.toDate=p;exports.tzParseTimezone=Y;