@liiift-studio/sanity-visitor-insights 0.19.0 → 0.21.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.
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
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, D as DiagnosticReport, J as JourneyData, c as MeasurementHealthData, T as TypefaceInterestData } from './ranges-BUZuS1c-.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-BUZuS1c-.mjs';
4
4
  export { C as CaptureBasis, d as CaptureEstimate, e as CaptureModel, f as CheckStatus, g as Coverage, h as CrossSourceDay, i as DailyPoint, j as DateRange, k as DiagnosticCheck, E as EmailCampaign, l as EventCutover, m as JourneyOutcome, 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-BUZuS1c-.mjs';
5
5
 
6
6
  /**
@@ -51,6 +51,7 @@ type ReportState<T> = {
51
51
  } | {
52
52
  status: 'ready';
53
53
  envelope: ReportEnvelope<T>;
54
+ stale?: boolean;
54
55
  } | {
55
56
  status: 'error';
56
57
  message: string;
@@ -67,13 +68,20 @@ interface UseReportOptions {
67
68
  apiBaseUrl: string;
68
69
  report: ReportName;
69
70
  range: RangeKey;
71
+ /**
72
+ * Whether to fetch at all. Defaults to true.
73
+ *
74
+ * Lets a panel declare a secondary report it only needs on one tab, without the other four
75
+ * paying a request for data they will not draw.
76
+ */
77
+ enabled?: boolean;
70
78
  }
71
79
  /**
72
80
  * Fetch a report, re-fetching when the range changes.
73
81
  *
74
82
  * @returns the current state plus a `reload` for manual refresh
75
83
  */
76
- declare function useReport<T>({ apiBaseUrl, report, range, custom }: UseReportOptions): {
84
+ declare function useReport<T>({ apiBaseUrl, report, range, custom, enabled }: UseReportOptions): {
77
85
  state: ReportState<T>;
78
86
  reload: () => void;
79
87
  };
@@ -162,6 +170,28 @@ interface ComparisonBarProps {
162
170
  * Studio bundle and the theme-token bridging that a chart library would need for light and dark.
163
171
  */
164
172
  declare function ComparisonBar({ label, metric, max, tone }: ComparisonBarProps): React.ReactElement;
173
+ /** Props for ChartData. */
174
+ interface ChartDataProps<Row> {
175
+ /** What the disclosure is called. Names the chart it belongs to. */
176
+ label: string;
177
+ rows: Row[];
178
+ columns: Array<SortColumn<Row>>;
179
+ rowKey: (row: Row) => string;
180
+ exportName?: string;
181
+ }
182
+ /**
183
+ * The figures behind a chart, as a table, collapsed by default.
184
+ *
185
+ * A chart is a picture of the data and not the data. Every other panel here renders a table for
186
+ * exactly that reason — the file header used to say so, and it stopped being true the moment the
187
+ * charts landed, leaving two time series with no equivalent anywhere in the tool.
188
+ *
189
+ * One disclosure serves four readers at once: someone using a screen reader, for whom an SVG under
190
+ * `role="img"` is a single opaque node; someone navigating by keyboard; someone who cannot resolve
191
+ * axis type at any size; and anyone who wants these numbers in a spreadsheet, since the table
192
+ * brings sorting and CSV copy with it. Collapsed, so it costs a sighted reader one line.
193
+ */
194
+ declare function ChartData<Row>({ label, rows, columns, rowKey, exportName }: ChartDataProps<Row>): React.ReactElement | null;
165
195
  /** One bar of a proportion chart. */
166
196
  interface ProportionBar {
167
197
  key: string;
@@ -386,6 +416,17 @@ interface CrossSourceTimelineProps {
386
416
  markers?: TimelineMarker[];
387
417
  /** ISO 4217 code for any `money` series. */
388
418
  currency?: string | null;
419
+ /**
420
+ * Called when the reader drags across a span, with inclusive ISO dates.
421
+ *
422
+ * Time is the only dimension all four sources genuinely share, which makes it the only thing
423
+ * worth linking on — a referrer row carries no date and a funnel step carries no source, so
424
+ * value-based cross-filtering would need dimensions the reports do not request and could not
425
+ * afford. Dragging a span and having every panel reflow to it is the whole of the cross-filter
426
+ * this data model supports, and it costs one callback: the range state already drives
427
+ * everything.
428
+ */
429
+ onBrush?: (start: string, end: string) => void;
389
430
  }
390
431
  /**
391
432
  * The cross-source timeline.
@@ -393,7 +434,7 @@ interface CrossSourceTimelineProps {
393
434
  * Renders nothing rather than an empty frame when there is not enough to plot — two points cannot
394
435
  * show a shape, and an axis with one dot on it invites a reading it cannot support.
395
436
  */
396
- declare function CrossSourceTimeline({ series, markers, currency }: CrossSourceTimelineProps): React.ReactElement | null;
437
+ declare function CrossSourceTimeline({ series, markers, currency, onBrush }: CrossSourceTimelineProps): React.ReactElement | null;
397
438
 
398
439
  /**
399
440
  * The four report panels.
@@ -415,9 +456,30 @@ declare function CrossSourceTimeline({ series, markers, currency }: CrossSourceT
415
456
  * Compares pageviews to pageviews. Sessions and orders sit alongside as context and are never
416
457
  * subtracted from a pageview count.
417
458
  */
418
- declare function MeasurementHealthPanel({ data, previous }: {
459
+ /**
460
+ * Overview — the five-minute read.
461
+ *
462
+ * Revenue, orders, the mailing list, the cross-source timeline and the campaign table all used to
463
+ * live on a tab called "Measurement health", whose own blurb announced it was about how much of
464
+ * reality each source sees. Four of the five questions a foundry owner opens this for were filed
465
+ * under plumbing, on tab four, behind a door labelled for the instrument. This is the same data,
466
+ * first, under a heading that says what it is.
467
+ */
468
+ declare function OverviewPanel({ data, previous, onBrush }: {
419
469
  data: MeasurementHealthData;
420
470
  previous?: MeasurementHealthData;
471
+ /** Narrow every panel to a span dragged on the timeline. */
472
+ onBrush?: (start: string, end: string) => void;
473
+ }): React.ReactElement;
474
+ /**
475
+ * Data health — the instrument, deliberately last.
476
+ *
477
+ * Everything here answers one question: can I trust the numbers on the other tabs. It was two
478
+ * separate tabs answering that question, which is one more than it deserves out of five.
479
+ */
480
+ declare function DataHealthPanel({ data, diagnostics }: {
481
+ data: MeasurementHealthData;
482
+ diagnostics?: DiagnosticReport;
421
483
  }): React.ReactElement;
422
484
  /** Acquisition — where visitors came from, with design-industry referrers called out. */
423
485
  declare function AcquisitionPanel({ data, previous }: {
@@ -485,4 +547,4 @@ interface VisitorInsightsPluginOptions {
485
547
  */
486
548
  declare const visitorInsights: sanity.Plugin<VisitorInsightsPluginOptions>;
487
549
 
488
- export { AcquisitionData, AcquisitionPanel, ComparisonBar, CrossSourceTimeline, type CrossSourceTimelineProps, Delta, type DeltaProps, DiagnosticReport, DiagnosticsPanel, FunnelChart, JourneyData, JourneyPanel, MeasurementHealthData, MeasurementHealthPanel, MetricFigure, MetricValue, NoticeList, type ProportionBar, ProportionChart, type ProportionChartProps, RangeKey, ReportEnvelope, ReportName, type ReportState, type Series, type SeriesPoint, type SortColumn, SortableTable, type SortableTableProps, type TimelineMarker, TrendChart, TypefaceInterestData, TypefaceInterestPanel, type UseReportOptions, type VisitorInsightsPluginOptions, VisitorInsightsTool, type VisitorInsightsToolProps, visitorInsights as default, formatCount, formatMoney, formatPercent, useReport, visitorInsights };
550
+ export { AcquisitionData, AcquisitionPanel, ChartData, type ChartDataProps, ComparisonBar, CrossSourceTimeline, type CrossSourceTimelineProps, DataHealthPanel, Delta, type DeltaProps, DiagnosticReport, DiagnosticsPanel, FunnelChart, JourneyData, JourneyPanel, MeasurementHealthData, MetricFigure, MetricValue, NoticeList, OverviewPanel, type ProportionBar, ProportionChart, type ProportionChartProps, RangeKey, ReportEnvelope, ReportName, type ReportState, type Series, type SeriesPoint, type SortColumn, SortableTable, type SortableTableProps, type TimelineMarker, TrendChart, TypefaceInterestData, TypefaceInterestPanel, type UseReportOptions, type VisitorInsightsPluginOptions, VisitorInsightsTool, type VisitorInsightsToolProps, visitorInsights as default, formatCount, formatMoney, formatPercent, useReport, visitorInsights };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
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, D as DiagnosticReport, J as JourneyData, c as MeasurementHealthData, T as TypefaceInterestData } from './ranges-BUZuS1c-.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-BUZuS1c-.js';
4
4
  export { C as CaptureBasis, d as CaptureEstimate, e as CaptureModel, f as CheckStatus, g as Coverage, h as CrossSourceDay, i as DailyPoint, j as DateRange, k as DiagnosticCheck, E as EmailCampaign, l as EventCutover, m as JourneyOutcome, 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-BUZuS1c-.js';
5
5
 
6
6
  /**
@@ -51,6 +51,7 @@ type ReportState<T> = {
51
51
  } | {
52
52
  status: 'ready';
53
53
  envelope: ReportEnvelope<T>;
54
+ stale?: boolean;
54
55
  } | {
55
56
  status: 'error';
56
57
  message: string;
@@ -67,13 +68,20 @@ interface UseReportOptions {
67
68
  apiBaseUrl: string;
68
69
  report: ReportName;
69
70
  range: RangeKey;
71
+ /**
72
+ * Whether to fetch at all. Defaults to true.
73
+ *
74
+ * Lets a panel declare a secondary report it only needs on one tab, without the other four
75
+ * paying a request for data they will not draw.
76
+ */
77
+ enabled?: boolean;
70
78
  }
71
79
  /**
72
80
  * Fetch a report, re-fetching when the range changes.
73
81
  *
74
82
  * @returns the current state plus a `reload` for manual refresh
75
83
  */
76
- declare function useReport<T>({ apiBaseUrl, report, range, custom }: UseReportOptions): {
84
+ declare function useReport<T>({ apiBaseUrl, report, range, custom, enabled }: UseReportOptions): {
77
85
  state: ReportState<T>;
78
86
  reload: () => void;
79
87
  };
@@ -162,6 +170,28 @@ interface ComparisonBarProps {
162
170
  * Studio bundle and the theme-token bridging that a chart library would need for light and dark.
163
171
  */
164
172
  declare function ComparisonBar({ label, metric, max, tone }: ComparisonBarProps): React.ReactElement;
173
+ /** Props for ChartData. */
174
+ interface ChartDataProps<Row> {
175
+ /** What the disclosure is called. Names the chart it belongs to. */
176
+ label: string;
177
+ rows: Row[];
178
+ columns: Array<SortColumn<Row>>;
179
+ rowKey: (row: Row) => string;
180
+ exportName?: string;
181
+ }
182
+ /**
183
+ * The figures behind a chart, as a table, collapsed by default.
184
+ *
185
+ * A chart is a picture of the data and not the data. Every other panel here renders a table for
186
+ * exactly that reason — the file header used to say so, and it stopped being true the moment the
187
+ * charts landed, leaving two time series with no equivalent anywhere in the tool.
188
+ *
189
+ * One disclosure serves four readers at once: someone using a screen reader, for whom an SVG under
190
+ * `role="img"` is a single opaque node; someone navigating by keyboard; someone who cannot resolve
191
+ * axis type at any size; and anyone who wants these numbers in a spreadsheet, since the table
192
+ * brings sorting and CSV copy with it. Collapsed, so it costs a sighted reader one line.
193
+ */
194
+ declare function ChartData<Row>({ label, rows, columns, rowKey, exportName }: ChartDataProps<Row>): React.ReactElement | null;
165
195
  /** One bar of a proportion chart. */
166
196
  interface ProportionBar {
167
197
  key: string;
@@ -386,6 +416,17 @@ interface CrossSourceTimelineProps {
386
416
  markers?: TimelineMarker[];
387
417
  /** ISO 4217 code for any `money` series. */
388
418
  currency?: string | null;
419
+ /**
420
+ * Called when the reader drags across a span, with inclusive ISO dates.
421
+ *
422
+ * Time is the only dimension all four sources genuinely share, which makes it the only thing
423
+ * worth linking on — a referrer row carries no date and a funnel step carries no source, so
424
+ * value-based cross-filtering would need dimensions the reports do not request and could not
425
+ * afford. Dragging a span and having every panel reflow to it is the whole of the cross-filter
426
+ * this data model supports, and it costs one callback: the range state already drives
427
+ * everything.
428
+ */
429
+ onBrush?: (start: string, end: string) => void;
389
430
  }
390
431
  /**
391
432
  * The cross-source timeline.
@@ -393,7 +434,7 @@ interface CrossSourceTimelineProps {
393
434
  * Renders nothing rather than an empty frame when there is not enough to plot — two points cannot
394
435
  * show a shape, and an axis with one dot on it invites a reading it cannot support.
395
436
  */
396
- declare function CrossSourceTimeline({ series, markers, currency }: CrossSourceTimelineProps): React.ReactElement | null;
437
+ declare function CrossSourceTimeline({ series, markers, currency, onBrush }: CrossSourceTimelineProps): React.ReactElement | null;
397
438
 
398
439
  /**
399
440
  * The four report panels.
@@ -415,9 +456,30 @@ declare function CrossSourceTimeline({ series, markers, currency }: CrossSourceT
415
456
  * Compares pageviews to pageviews. Sessions and orders sit alongside as context and are never
416
457
  * subtracted from a pageview count.
417
458
  */
418
- declare function MeasurementHealthPanel({ data, previous }: {
459
+ /**
460
+ * Overview — the five-minute read.
461
+ *
462
+ * Revenue, orders, the mailing list, the cross-source timeline and the campaign table all used to
463
+ * live on a tab called "Measurement health", whose own blurb announced it was about how much of
464
+ * reality each source sees. Four of the five questions a foundry owner opens this for were filed
465
+ * under plumbing, on tab four, behind a door labelled for the instrument. This is the same data,
466
+ * first, under a heading that says what it is.
467
+ */
468
+ declare function OverviewPanel({ data, previous, onBrush }: {
419
469
  data: MeasurementHealthData;
420
470
  previous?: MeasurementHealthData;
471
+ /** Narrow every panel to a span dragged on the timeline. */
472
+ onBrush?: (start: string, end: string) => void;
473
+ }): React.ReactElement;
474
+ /**
475
+ * Data health — the instrument, deliberately last.
476
+ *
477
+ * Everything here answers one question: can I trust the numbers on the other tabs. It was two
478
+ * separate tabs answering that question, which is one more than it deserves out of five.
479
+ */
480
+ declare function DataHealthPanel({ data, diagnostics }: {
481
+ data: MeasurementHealthData;
482
+ diagnostics?: DiagnosticReport;
421
483
  }): React.ReactElement;
422
484
  /** Acquisition — where visitors came from, with design-industry referrers called out. */
423
485
  declare function AcquisitionPanel({ data, previous }: {
@@ -485,4 +547,4 @@ interface VisitorInsightsPluginOptions {
485
547
  */
486
548
  declare const visitorInsights: sanity.Plugin<VisitorInsightsPluginOptions>;
487
549
 
488
- export { AcquisitionData, AcquisitionPanel, ComparisonBar, CrossSourceTimeline, type CrossSourceTimelineProps, Delta, type DeltaProps, DiagnosticReport, DiagnosticsPanel, FunnelChart, JourneyData, JourneyPanel, MeasurementHealthData, MeasurementHealthPanel, MetricFigure, MetricValue, NoticeList, type ProportionBar, ProportionChart, type ProportionChartProps, RangeKey, ReportEnvelope, ReportName, type ReportState, type Series, type SeriesPoint, type SortColumn, SortableTable, type SortableTableProps, type TimelineMarker, TrendChart, TypefaceInterestData, TypefaceInterestPanel, type UseReportOptions, type VisitorInsightsPluginOptions, VisitorInsightsTool, type VisitorInsightsToolProps, visitorInsights as default, formatCount, formatMoney, formatPercent, useReport, visitorInsights };
550
+ export { AcquisitionData, AcquisitionPanel, ChartData, type ChartDataProps, ComparisonBar, CrossSourceTimeline, type CrossSourceTimelineProps, DataHealthPanel, Delta, type DeltaProps, DiagnosticReport, DiagnosticsPanel, FunnelChart, JourneyData, JourneyPanel, MeasurementHealthData, MetricFigure, MetricValue, NoticeList, OverviewPanel, type ProportionBar, ProportionChart, type ProportionChartProps, RangeKey, ReportEnvelope, ReportName, type ReportState, type Series, type SeriesPoint, type SortColumn, SortableTable, type SortableTableProps, type TimelineMarker, TrendChart, TypefaceInterestData, TypefaceInterestPanel, type UseReportOptions, type VisitorInsightsPluginOptions, VisitorInsightsTool, type VisitorInsightsToolProps, visitorInsights as default, formatCount, formatMoney, formatPercent, useReport, visitorInsights };