@liiift-studio/sanity-visitor-insights 0.47.0 → 0.49.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
@@ -363,6 +363,13 @@ interface SortColumn<Row> {
363
363
  * currency, and a column with a fallback displays something `sortValue` returns null for.
364
364
  */
365
365
  exportValue?: (row: Row) => number | string | null;
366
+ /**
367
+ * Keep this column even when every value in it is blank or zero.
368
+ *
369
+ * For the column that identifies the row — a table whose first column collapsed would be a list
370
+ * of numbers belonging to nothing — and for any column whose emptiness is itself the finding.
371
+ */
372
+ alwaysShow?: boolean;
366
373
  render: (row: Row) => React.ReactNode;
367
374
  }
368
375
  /** Props for SortableTable. */
@@ -403,6 +410,34 @@ interface SortableTableProps<Row> {
403
410
  */
404
411
  declare function SortableTable<Row>({ caption, columns, rows, rowKey, initialSort, filterPlaceholder, filterOn, exportName, truncatedNote, onExclude, }: SortableTableProps<Row>): React.ReactElement;
405
412
 
413
+ /**
414
+ * The series palette, and the rules that keep it honest.
415
+ *
416
+ * Every chart in this package was drawn in `currentColor` at varying alpha, so five series on one
417
+ * chart were five greys separated by dash pattern alone. That is legible in a screenshot and not
418
+ * in use: a reader tracking co-movement between GA4 and Vercel had to keep which-line-is-which in
419
+ * their head while looking at the shape.
420
+ *
421
+ * Three constraints decided these values, and all three are enforced by tests rather than asserted
422
+ * here:
423
+ *
424
+ * 1. ONE SET FOR BOTH THEMES. The Studio ships light and dark and this component is not told which
425
+ * it is in. Rather than swap palettes at a breakpoint we cannot observe, every colour clears
426
+ * 3:1 — the WCAG floor for a graphical object — against BOTH a white card and Sanity's dark
427
+ * card. That is what pins them to mid-lightness.
428
+ *
429
+ * 2. HUE FAMILY MEANS SOURCE. The two GA4 series are deliberately neighbours in the warm range,
430
+ * because they are the same instrument measuring two things; Vercel, orders and revenue each
431
+ * get their own family. So the palette carries a fact rather than just distinguishing rows.
432
+ *
433
+ * 3. COLOUR IS NEVER THE ONLY CHANNEL. Completeness stays encoded as a dash pattern and every
434
+ * value stays readable in the tooltip. The two GA4 hues are close enough to converge for a
435
+ * deuteranope — which is acceptable precisely because dash and label still separate them, and
436
+ * unacceptable for any pair that does not have that second channel.
437
+ */
438
+ /** One series colour. The key names what it measures, not what it looks like. */
439
+ type SeriesKey = 'vercel' | 'ga4Pageviews' | 'ga4Sessions' | 'orders' | 'revenue';
440
+
406
441
  /**
407
442
  * One time axis, every source stacked against it.
408
443
  *
@@ -433,15 +468,6 @@ interface SeriesPoint {
433
468
  }
434
469
  /** How a value should be written out. */
435
470
  type SeriesUnit = 'count' | 'money' | 'percent';
436
- /**
437
- * One row of the chart: one answer, with what a lossier source saw underneath it.
438
- *
439
- * A row shows a SINGLE line by default. Two peer lines make the reader reconcile before they get
440
- * an answer, and at a glance a foundry owner wants "how much", not "here are two measurements that
441
- * disagree". The disagreement is still drawn — as a filled region, and in full on hover — because
442
- * hiding it entirely would switch off the alarm: the 24 August collapse was visible precisely
443
- * because two lines came apart.
444
- */
445
471
  interface Series {
446
472
  key: string;
447
473
  label: string;
@@ -449,6 +475,15 @@ interface Series {
449
475
  source: 'GA4' | 'Vercel' | 'Sanity' | 'Mailchimp';
450
476
  /** Whether the line's source sees everything. Drives the stroke and the wording. */
451
477
  complete: boolean;
478
+ /**
479
+ * Which series colour this row draws in.
480
+ *
481
+ * Optional, and falling back to the row's `source`, so a caller that adds a row gets a colour
482
+ * consistent with every other row from the same upstream rather than an uncoloured one. Set it
483
+ * explicitly only where the source does not decide the meaning — coverage is computed FROM GA4
484
+ * and Vercel and belongs to neither.
485
+ */
486
+ color?: SeriesKey;
452
487
  unit: SeriesUnit;
453
488
  /**
454
489
  * How the row is drawn. Defaults to `line`.
@@ -494,6 +529,8 @@ interface Series {
494
529
  */
495
530
  shortfall?: {
496
531
  label: string;
532
+ /** The lossier source's colour. Falls back to its `source`, as the row's own does. */
533
+ color?: SeriesKey;
497
534
  source: Series['source'];
498
535
  points: SeriesPoint[];
499
536
  };
package/dist/index.d.ts CHANGED
@@ -363,6 +363,13 @@ interface SortColumn<Row> {
363
363
  * currency, and a column with a fallback displays something `sortValue` returns null for.
364
364
  */
365
365
  exportValue?: (row: Row) => number | string | null;
366
+ /**
367
+ * Keep this column even when every value in it is blank or zero.
368
+ *
369
+ * For the column that identifies the row — a table whose first column collapsed would be a list
370
+ * of numbers belonging to nothing — and for any column whose emptiness is itself the finding.
371
+ */
372
+ alwaysShow?: boolean;
366
373
  render: (row: Row) => React.ReactNode;
367
374
  }
368
375
  /** Props for SortableTable. */
@@ -403,6 +410,34 @@ interface SortableTableProps<Row> {
403
410
  */
404
411
  declare function SortableTable<Row>({ caption, columns, rows, rowKey, initialSort, filterPlaceholder, filterOn, exportName, truncatedNote, onExclude, }: SortableTableProps<Row>): React.ReactElement;
405
412
 
413
+ /**
414
+ * The series palette, and the rules that keep it honest.
415
+ *
416
+ * Every chart in this package was drawn in `currentColor` at varying alpha, so five series on one
417
+ * chart were five greys separated by dash pattern alone. That is legible in a screenshot and not
418
+ * in use: a reader tracking co-movement between GA4 and Vercel had to keep which-line-is-which in
419
+ * their head while looking at the shape.
420
+ *
421
+ * Three constraints decided these values, and all three are enforced by tests rather than asserted
422
+ * here:
423
+ *
424
+ * 1. ONE SET FOR BOTH THEMES. The Studio ships light and dark and this component is not told which
425
+ * it is in. Rather than swap palettes at a breakpoint we cannot observe, every colour clears
426
+ * 3:1 — the WCAG floor for a graphical object — against BOTH a white card and Sanity's dark
427
+ * card. That is what pins them to mid-lightness.
428
+ *
429
+ * 2. HUE FAMILY MEANS SOURCE. The two GA4 series are deliberately neighbours in the warm range,
430
+ * because they are the same instrument measuring two things; Vercel, orders and revenue each
431
+ * get their own family. So the palette carries a fact rather than just distinguishing rows.
432
+ *
433
+ * 3. COLOUR IS NEVER THE ONLY CHANNEL. Completeness stays encoded as a dash pattern and every
434
+ * value stays readable in the tooltip. The two GA4 hues are close enough to converge for a
435
+ * deuteranope — which is acceptable precisely because dash and label still separate them, and
436
+ * unacceptable for any pair that does not have that second channel.
437
+ */
438
+ /** One series colour. The key names what it measures, not what it looks like. */
439
+ type SeriesKey = 'vercel' | 'ga4Pageviews' | 'ga4Sessions' | 'orders' | 'revenue';
440
+
406
441
  /**
407
442
  * One time axis, every source stacked against it.
408
443
  *
@@ -433,15 +468,6 @@ interface SeriesPoint {
433
468
  }
434
469
  /** How a value should be written out. */
435
470
  type SeriesUnit = 'count' | 'money' | 'percent';
436
- /**
437
- * One row of the chart: one answer, with what a lossier source saw underneath it.
438
- *
439
- * A row shows a SINGLE line by default. Two peer lines make the reader reconcile before they get
440
- * an answer, and at a glance a foundry owner wants "how much", not "here are two measurements that
441
- * disagree". The disagreement is still drawn — as a filled region, and in full on hover — because
442
- * hiding it entirely would switch off the alarm: the 24 August collapse was visible precisely
443
- * because two lines came apart.
444
- */
445
471
  interface Series {
446
472
  key: string;
447
473
  label: string;
@@ -449,6 +475,15 @@ interface Series {
449
475
  source: 'GA4' | 'Vercel' | 'Sanity' | 'Mailchimp';
450
476
  /** Whether the line's source sees everything. Drives the stroke and the wording. */
451
477
  complete: boolean;
478
+ /**
479
+ * Which series colour this row draws in.
480
+ *
481
+ * Optional, and falling back to the row's `source`, so a caller that adds a row gets a colour
482
+ * consistent with every other row from the same upstream rather than an uncoloured one. Set it
483
+ * explicitly only where the source does not decide the meaning — coverage is computed FROM GA4
484
+ * and Vercel and belongs to neither.
485
+ */
486
+ color?: SeriesKey;
452
487
  unit: SeriesUnit;
453
488
  /**
454
489
  * How the row is drawn. Defaults to `line`.
@@ -494,6 +529,8 @@ interface Series {
494
529
  */
495
530
  shortfall?: {
496
531
  label: string;
532
+ /** The lossier source's colour. Falls back to its `source`, as the row's own does. */
533
+ color?: SeriesKey;
497
534
  source: Series['source'];
498
535
  points: SeriesPoint[];
499
536
  };