@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 +67 -5
- package/dist/index.d.ts +67 -5
- package/dist/index.js +400 -175
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +397 -174
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +3 -3
- package/src/studio/CrossSourceTimeline.tsx +98 -13
- package/src/studio/Figure.tsx +69 -7
- package/src/studio/VisitorInsightsTool.tsx +113 -30
- package/src/studio/panels.test.tsx +160 -28
- package/src/studio/panels.tsx +234 -158
- package/src/studio/useReport.ts +46 -4
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,
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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 };
|