@liiift-studio/sanity-visitor-insights 0.75.0 → 0.76.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.
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as sanity from 'sanity';
2
2
  import React from 'react';
3
- import { R as ReportEnvelope, a as ReportName, b as RangeKey, M as MetricValue, A as AcquisitionData, c as MeasurementHealthData, D as DiagnosticReport, J as JourneyData, T as TypefaceInterestData } from './ranges-DfjCK0XY.mjs';
4
- export { C as CaptureBasis, d as CaptureEstimate, e as CaptureModel, f as CheckStatus, g as Coverage, h as CrossSourceDay, i as DateRange, j as DiagnosticCheck, E as EmailCampaign, k as EventCutover, l as JourneyOutcome, m as JourneySegment, n as JourneyStep, L as LandingPage, o as LicenceTierRow, P as PREEXISTING, p as REPORT_NAMES, q as ReportError, S as SiteAnalyticsConfig, r as SourceName, s as SourceRow, t as SourceStatus, u as TimelineEvent, v as TypefaceInterestRow, U as UnavailableReason, w as coverageForRange, x as estimated, y as isReportName, z as ok, B as partial, F as previousRange, G as resolveRange, H as unavailable, I as validateSiteConfig, K as valueOrNull } from './ranges-DfjCK0XY.mjs';
3
+ import { R as ReportEnvelope, a as ReportName, b as RangeKey, M as MetricValue, A as AcquisitionData, c as MeasurementHealthData, D as DiagnosticReport, J as JourneyData, T as TypefaceInterestData } from './ranges-B2W_3Z0t.mjs';
4
+ export { C as CaptureBasis, d as CaptureEstimate, e as CaptureModel, f as CheckStatus, g as Coverage, h as CrossSourceDay, i as DateRange, j as DiagnosticCheck, E as EmailCampaign, k as EventCutover, l as JourneyOutcome, m as JourneySegment, n as JourneyStep, L as LandingPage, o as LicenceTierRow, P as PREEXISTING, p as REPORT_NAMES, q as ReportError, S as SiteAnalyticsConfig, r as SourceName, s as SourceRow, t as SourceStatus, u as TimelineEvent, v as TypefaceInterestRow, U as UnavailableReason, w as coverageForRange, x as estimated, y as isReportName, z as ok, B as partial, F as previousRange, G as resolveRange, H as unavailable, I as validateSiteConfig, K as valueOrNull } from './ranges-B2W_3Z0t.mjs';
5
5
 
6
6
  /**
7
7
  * Data hook for the Studio panels.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as sanity from 'sanity';
2
2
  import React from 'react';
3
- import { R as ReportEnvelope, a as ReportName, b as RangeKey, M as MetricValue, A as AcquisitionData, c as MeasurementHealthData, D as DiagnosticReport, J as JourneyData, T as TypefaceInterestData } from './ranges-DfjCK0XY.js';
4
- export { C as CaptureBasis, d as CaptureEstimate, e as CaptureModel, f as CheckStatus, g as Coverage, h as CrossSourceDay, i as DateRange, j as DiagnosticCheck, E as EmailCampaign, k as EventCutover, l as JourneyOutcome, m as JourneySegment, n as JourneyStep, L as LandingPage, o as LicenceTierRow, P as PREEXISTING, p as REPORT_NAMES, q as ReportError, S as SiteAnalyticsConfig, r as SourceName, s as SourceRow, t as SourceStatus, u as TimelineEvent, v as TypefaceInterestRow, U as UnavailableReason, w as coverageForRange, x as estimated, y as isReportName, z as ok, B as partial, F as previousRange, G as resolveRange, H as unavailable, I as validateSiteConfig, K as valueOrNull } from './ranges-DfjCK0XY.js';
3
+ import { R as ReportEnvelope, a as ReportName, b as RangeKey, M as MetricValue, A as AcquisitionData, c as MeasurementHealthData, D as DiagnosticReport, J as JourneyData, T as TypefaceInterestData } from './ranges-B2W_3Z0t.js';
4
+ export { C as CaptureBasis, d as CaptureEstimate, e as CaptureModel, f as CheckStatus, g as Coverage, h as CrossSourceDay, i as DateRange, j as DiagnosticCheck, E as EmailCampaign, k as EventCutover, l as JourneyOutcome, m as JourneySegment, n as JourneyStep, L as LandingPage, o as LicenceTierRow, P as PREEXISTING, p as REPORT_NAMES, q as ReportError, S as SiteAnalyticsConfig, r as SourceName, s as SourceRow, t as SourceStatus, u as TimelineEvent, v as TypefaceInterestRow, U as UnavailableReason, w as coverageForRange, x as estimated, y as isReportName, z as ok, B as partial, F as previousRange, G as resolveRange, H as unavailable, I as validateSiteConfig, K as valueOrNull } from './ranges-B2W_3Z0t.js';
5
5
 
6
6
  /**
7
7
  * Data hook for the Studio panels.
package/dist/index.js CHANGED
@@ -165,7 +165,7 @@ function useReport({ apiBaseUrl, report, range, custom, compare, enabled = true
165
165
  }
166
166
  void run();
167
167
  return () => controller.abort();
168
- }, [client, apiBaseUrl, report, range, custom?.start, custom?.end, nonce, enabled]);
168
+ }, [client, apiBaseUrl, report, range, custom?.start, custom?.end, compare, nonce, enabled]);
169
169
  return { state, reload };
170
170
  }
171
171
 
@@ -814,6 +814,21 @@ function gapLabel(delta, measurement, entry = 0) {
814
814
  }
815
815
  var partialSlot = { height: 10 };
816
816
  var funnelSegmentKey = { display: "flex", gap: 14, flexWrap: "wrap", paddingTop: 4 };
817
+ var ladderRow = {
818
+ display: "grid",
819
+ gridTemplateColumns: "minmax(80px, 1.1fr) minmax(60px, 0.8fr) minmax(60px, 2fr) auto",
820
+ gap: 10,
821
+ alignItems: "center"
822
+ };
823
+ var ladderTrack = {
824
+ position: "relative",
825
+ height: 8,
826
+ borderRadius: 4,
827
+ overflow: "hidden",
828
+ background: mark("bar.track")
829
+ };
830
+ var ladderValue = { textAlign: "right", fontVariantNumeric: "tabular-nums", whiteSpace: "nowrap" };
831
+ var ladderMoney = { opacity: 0.7 };
817
832
  var funnelList = { listStyle: "none", margin: 0, padding: 0 };
818
833
  var funnelItem = { display: "grid", gap: 4 };
819
834
  function funnelGapStyle(hasBar) {
@@ -1039,6 +1054,34 @@ function EstimateDotPlot({
1039
1054
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_sanity_ui_compat.Text, { size: 0, muted: true, children: "The rule marks 100%." })
1040
1055
  ] });
1041
1056
  }
1057
+ function LicenceLadder({ rows, currency }) {
1058
+ if (rows.length === 0) return null;
1059
+ const peak = Math.max(1, ...rows.map((row) => row.orders));
1060
+ const types = [];
1061
+ for (const row of rows) {
1062
+ const facet = types.find((t) => t.type === row.type);
1063
+ if (facet) facet.rungs.push(row);
1064
+ else types.push({ type: row.type, rungs: [row] });
1065
+ }
1066
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_sanity_ui_compat.Stack, { space: 4, children: types.map((facet) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_sanity_ui_compat.Stack, { space: 2, children: [
1067
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_sanity_ui_compat.Text, { size: 1, weight: "semibold", children: facet.type }),
1068
+ facet.rungs.map((row, index) => {
1069
+ const sameTierAsAbove = index > 0 && facet.rungs[index - 1]?.tier === row.tier;
1070
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: ladderRow, children: [
1071
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_sanity_ui_compat.Text, { size: 0, muted: true, children: sameTierAsAbove ? "" : row.tier }),
1072
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_sanity_ui_compat.Text, { size: 0, muted: true, children: row.term }),
1073
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { "aria-hidden": "true", style: ladderTrack, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { ...barFill, width: `${Math.max(2, row.orders / peak * 100)}%` } }) }),
1074
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_sanity_ui_compat.Text, { size: 0, style: ladderValue, children: [
1075
+ formatCount(row.orders),
1076
+ row.revenue !== null && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: ladderMoney, children: [
1077
+ " \xB7 ",
1078
+ formatMoney(row.revenue, currency)
1079
+ ] })
1080
+ ] })
1081
+ ] }, `${row.tier}\0${row.term}`);
1082
+ })
1083
+ ] }, facet.type)) });
1084
+ }
1042
1085
  function RatioFigure({
1043
1086
  value,
1044
1087
  format,
@@ -3291,22 +3334,8 @@ function TypefaceInterestPanel({ data }) {
3291
3334
  ] }),
3292
3335
  (data.licences?.length ?? 0) > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_sanity_ui_compat3.Stack, { space: 3, children: [
3293
3336
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SectionTitle, { title: "How licences sell" }),
3294
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_sanity_ui_compat3.Text, { size: 1, muted: true, children: "From your orders, so exact. Tier and term are separate rows, because they are the two variables in the pricing question and a tier that sells well at one year may not at perpetual." }),
3295
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3296
- ProportionChart,
3297
- {
3298
- bars: (data.licences ?? []).map((row) => ({
3299
- key: `${row.type}-${row.tier}-${row.term}`,
3300
- label: `${row.type} \xB7 ${row.tier}`,
3301
- sublabel: row.term,
3302
- // Ranked by revenue where it is known, by orders where it is not — a
3303
- // count would put a cheap tier above one worth ten times as much.
3304
- value: row.revenue ?? row.orders
3305
- })),
3306
- format: (value) => (data.licences ?? []).some((r) => r.revenue !== null) ? formatMoney(value, data.currency ?? null) : `${formatCount(value)} orders`,
3307
- totalLabel: (data.licences ?? []).some((r) => r.revenue !== null) ? "Total across licences" : "Total licence lines"
3308
- }
3309
- )
3337
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_sanity_ui_compat3.Text, { size: 1, muted: true, children: "From your orders, so exact. Bars are orders; the money beside them is that order total split evenly across the licences on it, so it is a share rather than a price." }),
3338
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LicenceLadder, { rows: data.licences ?? [], currency: data.currency ?? null })
3310
3339
  ] }),
3311
3340
  data.revenueIsApportioned && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_sanity_ui_compat3.Text, { size: 0, muted: true, children: "An order covering several families is split evenly between them, because the order documents carry no per-line value." }),
3312
3341
  finiteOrNull(data.unattributedRevenue) !== null && data.unattributedRevenue > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_sanity_ui_compat3.Text, { size: 0, muted: true, children: [