@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 +53 -13
- package/dist/index.d.ts +53 -13
- package/dist/index.js +415 -119
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +417 -123
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +11 -3
- package/src/studio/CrossSourceTimeline.tsx +162 -19
- package/src/studio/Figure.tsx +85 -14
- package/src/studio/VisitorInsightsTool.tsx +166 -31
- package/src/studio/panels.test.tsx +161 -4
- package/src/studio/panels.tsx +124 -31
- package/src/studio/useReport.ts +67 -3
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
|
-
/**
|
|
163
|
-
|
|
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,
|
|
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
|
|
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
|
-
/**
|
|
163
|
-
|
|
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,
|
|
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
|
|
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 };
|