@liiift-studio/sanity-visitor-insights 0.20.0 → 0.22.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
@@ -52,6 +52,7 @@ type ReportState<T> = {
52
52
  status: 'ready';
53
53
  envelope: ReportEnvelope<T>;
54
54
  stale?: boolean;
55
+ revalidationError?: string;
55
56
  } | {
56
57
  status: 'error';
57
58
  message: string;
@@ -159,8 +160,15 @@ interface ComparisonBarProps {
159
160
  metric: MetricValue;
160
161
  /** Largest value across the sibling bars, used to scale width. */
161
162
  max: number;
162
- /** Tone conveys category, but never carries meaning on its own. */
163
- tone?: 'primary' | 'positive' | 'caution' | 'default';
163
+ /**
164
+ * What full width means, named.
165
+ *
166
+ * A ComparisonBar scales to the largest sibling, so a full bar means only "biggest of these" —
167
+ * and unlike the other two bar idioms, which print their share and their total, this one said
168
+ * nothing at all. There was a `tone` prop instead, which both call sites passed different
169
+ * values to and which the component destructured and never used.
170
+ */
171
+ outOf?: string;
164
172
  }
165
173
  /**
166
174
  * A horizontal bar with its value printed alongside.
@@ -169,7 +177,29 @@ interface ComparisonBarProps {
169
177
  * values, which a labelled bar does as well as a chart while avoiding a large dependency in the
170
178
  * Studio bundle and the theme-token bridging that a chart library would need for light and dark.
171
179
  */
172
- declare function ComparisonBar({ label, metric, max, tone }: ComparisonBarProps): React.ReactElement;
180
+ declare function ComparisonBar({ label, metric, max, outOf }: ComparisonBarProps): React.ReactElement;
181
+ /** Props for ChartData. */
182
+ interface ChartDataProps<Row> {
183
+ /** What the disclosure is called. Names the chart it belongs to. */
184
+ label: string;
185
+ rows: Row[];
186
+ columns: Array<SortColumn<Row>>;
187
+ rowKey: (row: Row) => string;
188
+ exportName?: string;
189
+ }
190
+ /**
191
+ * The figures behind a chart, as a table, collapsed by default.
192
+ *
193
+ * A chart is a picture of the data and not the data. Every other panel here renders a table for
194
+ * exactly that reason — the file header used to say so, and it stopped being true the moment the
195
+ * charts landed, leaving two time series with no equivalent anywhere in the tool.
196
+ *
197
+ * One disclosure serves four readers at once: someone using a screen reader, for whom an SVG under
198
+ * `role="img"` is a single opaque node; someone navigating by keyboard; someone who cannot resolve
199
+ * axis type at any size; and anyone who wants these numbers in a spreadsheet, since the table
200
+ * brings sorting and CSV copy with it. Collapsed, so it costs a sighted reader one line.
201
+ */
202
+ declare function ChartData<Row>({ label, rows, columns, rowKey, exportName }: ChartDataProps<Row>): React.ReactElement | null;
173
203
  /** One bar of a proportion chart. */
174
204
  interface ProportionBar {
175
205
  key: string;
@@ -305,6 +335,8 @@ interface SortableTableProps<Row> {
305
335
  exportName?: string;
306
336
  /** Shown under the table when the server truncated the row set. */
307
337
  truncatedNote?: string;
338
+ /** Allow per-row exclusion even without a filter box. */
339
+ onExclude?: boolean;
308
340
  }
309
341
  /**
310
342
  * A table whose columns sort.
@@ -318,7 +350,7 @@ interface SortableTableProps<Row> {
318
350
  * unavailable metric is not a zero, and letting it lead an ascending sort would restate exactly the
319
351
  * confusion the MetricValue type exists to prevent.
320
352
  */
321
- declare function SortableTable<Row>({ caption, columns, rows, rowKey, initialSort, filterPlaceholder, filterOn, exportName, truncatedNote, }: SortableTableProps<Row>): React.ReactElement;
353
+ declare function SortableTable<Row>({ caption, columns, rows, rowKey, initialSort, filterPlaceholder, filterOn, exportName, truncatedNote, onExclude, }: SortableTableProps<Row>): React.ReactElement;
322
354
 
323
355
  /**
324
356
  * One time axis, every source stacked against it.
@@ -394,6 +426,17 @@ interface CrossSourceTimelineProps {
394
426
  markers?: TimelineMarker[];
395
427
  /** ISO 4217 code for any `money` series. */
396
428
  currency?: string | null;
429
+ /**
430
+ * Called when the reader drags across a span, with inclusive ISO dates.
431
+ *
432
+ * Time is the only dimension all four sources genuinely share, which makes it the only thing
433
+ * worth linking on — a referrer row carries no date and a funnel step carries no source, so
434
+ * value-based cross-filtering would need dimensions the reports do not request and could not
435
+ * afford. Dragging a span and having every panel reflow to it is the whole of the cross-filter
436
+ * this data model supports, and it costs one callback: the range state already drives
437
+ * everything.
438
+ */
439
+ onBrush?: (start: string, end: string) => void;
397
440
  }
398
441
  /**
399
442
  * The cross-source timeline.
@@ -401,10 +444,10 @@ interface CrossSourceTimelineProps {
401
444
  * Renders nothing rather than an empty frame when there is not enough to plot — two points cannot
402
445
  * show a shape, and an axis with one dot on it invites a reading it cannot support.
403
446
  */
404
- declare function CrossSourceTimeline({ series, markers, currency }: CrossSourceTimelineProps): React.ReactElement | null;
447
+ declare function CrossSourceTimeline({ series, markers, currency, onBrush }: CrossSourceTimelineProps): React.ReactElement | null;
405
448
 
406
449
  /**
407
- * The four report panels.
450
+ * The report panels.
408
451
  *
409
452
  * Every panel renders a table or labelled bars rather than a chart, and every one surfaces its own
410
453
  * caveats inline. Tables are the accessible representation as well as the visual one, so there is
@@ -418,11 +461,6 @@ declare function CrossSourceTimeline({ series, markers, currency }: CrossSourceT
418
461
  * undefined". A panel must degrade to showing less, never to a stack trace.
419
462
  */
420
463
 
421
- /**
422
- * Measurement Health — how much of reality each source sees.
423
- * Compares pageviews to pageviews. Sessions and orders sit alongside as context and are never
424
- * subtracted from a pageview count.
425
- */
426
464
  /**
427
465
  * Overview — the five-minute read.
428
466
  *
@@ -432,9 +470,11 @@ declare function CrossSourceTimeline({ series, markers, currency }: CrossSourceT
432
470
  * under plumbing, on tab four, behind a door labelled for the instrument. This is the same data,
433
471
  * first, under a heading that says what it is.
434
472
  */
435
- declare function OverviewPanel({ data, previous }: {
473
+ declare function OverviewPanel({ data, previous, onBrush }: {
436
474
  data: MeasurementHealthData;
437
475
  previous?: MeasurementHealthData;
476
+ /** Narrow every panel to a span dragged on the timeline. */
477
+ onBrush?: (start: string, end: string) => void;
438
478
  }): React.ReactElement;
439
479
  /**
440
480
  * Data health — the instrument, deliberately last.
@@ -512,4 +552,4 @@ interface VisitorInsightsPluginOptions {
512
552
  */
513
553
  declare const visitorInsights: sanity.Plugin<VisitorInsightsPluginOptions>;
514
554
 
515
- export { AcquisitionData, AcquisitionPanel, 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 };
555
+ export { AcquisitionData, AcquisitionPanel, ChartData, type ChartDataProps, ComparisonBar, CrossSourceTimeline, type CrossSourceTimelineProps, DataHealthPanel, Delta, type DeltaProps, DiagnosticReport, DiagnosticsPanel, FunnelChart, JourneyData, JourneyPanel, MeasurementHealthData, DataHealthPanel as MeasurementHealthPanel, 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
@@ -52,6 +52,7 @@ type ReportState<T> = {
52
52
  status: 'ready';
53
53
  envelope: ReportEnvelope<T>;
54
54
  stale?: boolean;
55
+ revalidationError?: string;
55
56
  } | {
56
57
  status: 'error';
57
58
  message: string;
@@ -159,8 +160,15 @@ interface ComparisonBarProps {
159
160
  metric: MetricValue;
160
161
  /** Largest value across the sibling bars, used to scale width. */
161
162
  max: number;
162
- /** Tone conveys category, but never carries meaning on its own. */
163
- tone?: 'primary' | 'positive' | 'caution' | 'default';
163
+ /**
164
+ * What full width means, named.
165
+ *
166
+ * A ComparisonBar scales to the largest sibling, so a full bar means only "biggest of these" —
167
+ * and unlike the other two bar idioms, which print their share and their total, this one said
168
+ * nothing at all. There was a `tone` prop instead, which both call sites passed different
169
+ * values to and which the component destructured and never used.
170
+ */
171
+ outOf?: string;
164
172
  }
165
173
  /**
166
174
  * A horizontal bar with its value printed alongside.
@@ -169,7 +177,29 @@ interface ComparisonBarProps {
169
177
  * values, which a labelled bar does as well as a chart while avoiding a large dependency in the
170
178
  * Studio bundle and the theme-token bridging that a chart library would need for light and dark.
171
179
  */
172
- declare function ComparisonBar({ label, metric, max, tone }: ComparisonBarProps): React.ReactElement;
180
+ declare function ComparisonBar({ label, metric, max, outOf }: ComparisonBarProps): React.ReactElement;
181
+ /** Props for ChartData. */
182
+ interface ChartDataProps<Row> {
183
+ /** What the disclosure is called. Names the chart it belongs to. */
184
+ label: string;
185
+ rows: Row[];
186
+ columns: Array<SortColumn<Row>>;
187
+ rowKey: (row: Row) => string;
188
+ exportName?: string;
189
+ }
190
+ /**
191
+ * The figures behind a chart, as a table, collapsed by default.
192
+ *
193
+ * A chart is a picture of the data and not the data. Every other panel here renders a table for
194
+ * exactly that reason — the file header used to say so, and it stopped being true the moment the
195
+ * charts landed, leaving two time series with no equivalent anywhere in the tool.
196
+ *
197
+ * One disclosure serves four readers at once: someone using a screen reader, for whom an SVG under
198
+ * `role="img"` is a single opaque node; someone navigating by keyboard; someone who cannot resolve
199
+ * axis type at any size; and anyone who wants these numbers in a spreadsheet, since the table
200
+ * brings sorting and CSV copy with it. Collapsed, so it costs a sighted reader one line.
201
+ */
202
+ declare function ChartData<Row>({ label, rows, columns, rowKey, exportName }: ChartDataProps<Row>): React.ReactElement | null;
173
203
  /** One bar of a proportion chart. */
174
204
  interface ProportionBar {
175
205
  key: string;
@@ -305,6 +335,8 @@ interface SortableTableProps<Row> {
305
335
  exportName?: string;
306
336
  /** Shown under the table when the server truncated the row set. */
307
337
  truncatedNote?: string;
338
+ /** Allow per-row exclusion even without a filter box. */
339
+ onExclude?: boolean;
308
340
  }
309
341
  /**
310
342
  * A table whose columns sort.
@@ -318,7 +350,7 @@ interface SortableTableProps<Row> {
318
350
  * unavailable metric is not a zero, and letting it lead an ascending sort would restate exactly the
319
351
  * confusion the MetricValue type exists to prevent.
320
352
  */
321
- declare function SortableTable<Row>({ caption, columns, rows, rowKey, initialSort, filterPlaceholder, filterOn, exportName, truncatedNote, }: SortableTableProps<Row>): React.ReactElement;
353
+ declare function SortableTable<Row>({ caption, columns, rows, rowKey, initialSort, filterPlaceholder, filterOn, exportName, truncatedNote, onExclude, }: SortableTableProps<Row>): React.ReactElement;
322
354
 
323
355
  /**
324
356
  * One time axis, every source stacked against it.
@@ -394,6 +426,17 @@ interface CrossSourceTimelineProps {
394
426
  markers?: TimelineMarker[];
395
427
  /** ISO 4217 code for any `money` series. */
396
428
  currency?: string | null;
429
+ /**
430
+ * Called when the reader drags across a span, with inclusive ISO dates.
431
+ *
432
+ * Time is the only dimension all four sources genuinely share, which makes it the only thing
433
+ * worth linking on — a referrer row carries no date and a funnel step carries no source, so
434
+ * value-based cross-filtering would need dimensions the reports do not request and could not
435
+ * afford. Dragging a span and having every panel reflow to it is the whole of the cross-filter
436
+ * this data model supports, and it costs one callback: the range state already drives
437
+ * everything.
438
+ */
439
+ onBrush?: (start: string, end: string) => void;
397
440
  }
398
441
  /**
399
442
  * The cross-source timeline.
@@ -401,10 +444,10 @@ interface CrossSourceTimelineProps {
401
444
  * Renders nothing rather than an empty frame when there is not enough to plot — two points cannot
402
445
  * show a shape, and an axis with one dot on it invites a reading it cannot support.
403
446
  */
404
- declare function CrossSourceTimeline({ series, markers, currency }: CrossSourceTimelineProps): React.ReactElement | null;
447
+ declare function CrossSourceTimeline({ series, markers, currency, onBrush }: CrossSourceTimelineProps): React.ReactElement | null;
405
448
 
406
449
  /**
407
- * The four report panels.
450
+ * The report panels.
408
451
  *
409
452
  * Every panel renders a table or labelled bars rather than a chart, and every one surfaces its own
410
453
  * caveats inline. Tables are the accessible representation as well as the visual one, so there is
@@ -418,11 +461,6 @@ declare function CrossSourceTimeline({ series, markers, currency }: CrossSourceT
418
461
  * undefined". A panel must degrade to showing less, never to a stack trace.
419
462
  */
420
463
 
421
- /**
422
- * Measurement Health — how much of reality each source sees.
423
- * Compares pageviews to pageviews. Sessions and orders sit alongside as context and are never
424
- * subtracted from a pageview count.
425
- */
426
464
  /**
427
465
  * Overview — the five-minute read.
428
466
  *
@@ -432,9 +470,11 @@ declare function CrossSourceTimeline({ series, markers, currency }: CrossSourceT
432
470
  * under plumbing, on tab four, behind a door labelled for the instrument. This is the same data,
433
471
  * first, under a heading that says what it is.
434
472
  */
435
- declare function OverviewPanel({ data, previous }: {
473
+ declare function OverviewPanel({ data, previous, onBrush }: {
436
474
  data: MeasurementHealthData;
437
475
  previous?: MeasurementHealthData;
476
+ /** Narrow every panel to a span dragged on the timeline. */
477
+ onBrush?: (start: string, end: string) => void;
438
478
  }): React.ReactElement;
439
479
  /**
440
480
  * Data health — the instrument, deliberately last.
@@ -512,4 +552,4 @@ interface VisitorInsightsPluginOptions {
512
552
  */
513
553
  declare const visitorInsights: sanity.Plugin<VisitorInsightsPluginOptions>;
514
554
 
515
- export { AcquisitionData, AcquisitionPanel, 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 };
555
+ export { AcquisitionData, AcquisitionPanel, ChartData, type ChartDataProps, ComparisonBar, CrossSourceTimeline, type CrossSourceTimelineProps, DataHealthPanel, Delta, type DeltaProps, DiagnosticReport, DiagnosticsPanel, FunnelChart, JourneyData, JourneyPanel, MeasurementHealthData, DataHealthPanel as MeasurementHealthPanel, 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 };