@verifiedinc-public/shared-ui-elements 9.15.1 → 10.0.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.
@@ -3,11 +3,32 @@ import { SxProps } from '@mui/material';
3
3
  import { AreaSeriesChartData } from '../AreaChart';
4
4
  import { BrandFilter } from '../../BrandFilterInput';
5
5
  export type { AreaSeriesChartData } from '../AreaChart';
6
+ type ViewMode = 'absolute' | 'percent';
6
7
  export interface BrandIntervalData {
7
8
  brandUuid: string;
8
9
  brandName: string;
9
10
  interval?: Array<Record<string, number | string>>;
10
11
  }
12
+ /**
13
+ * A single entry in the chart's toggle button group. Selecting it swaps the
14
+ * data, series, and display configuration the chart renders.
15
+ */
16
+ export interface ConversionOverTimeChartView {
17
+ key: string;
18
+ label: string;
19
+ /** Raw bucketed data; will be mapped via {@link mapBrandIntervalData}. */
20
+ chartData?: BrandIntervalData[];
21
+ /** Pre-mapped data points (alternative to `chartData`). */
22
+ data?: Array<Record<string, number | string>>;
23
+ /** Series definitions for pre-mapped `data`. */
24
+ series?: AreaSeriesChartData[];
25
+ /** Series config used to map `chartData`. */
26
+ seriesConfig?: AreaSeriesChartData[];
27
+ /** Display mode for this view. Defaults to 'absolute'. */
28
+ mode?: ViewMode;
29
+ /** Stacking mode for this view. Defaults to the top-level `stackMode`. */
30
+ stackMode?: 'stack' | 'none';
31
+ }
11
32
  export interface ConversionOverTimeChartLegendBrand {
12
33
  uuid: string;
13
34
  value: string;
@@ -37,5 +58,17 @@ export interface ConversionOverTimeChartProps {
37
58
  legendBrand?: ConversionOverTimeChartLegendBrand;
38
59
  /** Whether the legend displays the copyable UUID. Defaults to true. */
39
60
  showLegendUuid?: boolean;
61
+ /**
62
+ * Configurable toggle button group. Each view defines its own data, series,
63
+ * and display mode. Consumers control the order — including inserting custom
64
+ * views (e.g. 'Data Providers') between the built-in Numbers / Percentages.
65
+ *
66
+ * When omitted, the chart falls back to the built-in
67
+ * `[Numbers, Percentages]` toggles driven by the top-level
68
+ * `chartData`/`seriesConfig`.
69
+ */
70
+ views?: ConversionOverTimeChartView[];
71
+ /** Key of the initially selected view. Defaults to the first view. */
72
+ defaultViewKey?: string;
40
73
  }
41
- export declare function ConversionOverTimeChart({ data, series, chartData, seriesConfig, stackMode: stackModeProp, isLoading, isFetching, isSuccess, filter, sx, legendBrand, showLegendUuid, }: Readonly<ConversionOverTimeChartProps>): React.ReactNode;
74
+ export declare function ConversionOverTimeChart({ data, series, chartData, seriesConfig, stackMode: stackModeProp, isLoading, isFetching, isSuccess, filter, sx, legendBrand, showLegendUuid, views, defaultViewKey, }: Readonly<ConversionOverTimeChartProps>): React.ReactNode;
@@ -1 +1 @@
1
- "use strict";import{useState as T}from"react";import{Stack as A,Box as v,ToggleButtonGroup as E,ToggleButton as N}from"@mui/material";import{EmptyChartSection as U}from"../EmptyChartSection.mjs";import{LoadingChartSection as B}from"../LoadingChartSection.mjs";import{AreaChart as j}from"../AreaChart/index.mjs";import{SeriesPercentageChartLegend as Z}from"../SeriesPercentageChartLegend/index.mjs";import{useStyle as $}from"../styles.mjs";import{formatExtendedDate as z,formatDateMMYY as O}from"../../../utils/date.mjs";import{DEFAULT_TIMEZONE as W}from"../../form/TimezoneInput/timezones.mjs";import{jsx as n,jsxs as b}from"react/jsx-runtime";function _({brands:g,data:y,seriesConfig:d}){const c=new Map,u=g?new Set(g.map(a=>a._raw.brandUuid)):null;for(const a of y)if(!(u&&!u.has(a.brandUuid)))for(const l of a.interval??[]){const f=+new Date(l.date);let t=c.get(f);if(!t){t={date:f};for(const i of d)t[i.dataKey]=0;c.set(f,t)}for(const i of d)t[i.dataKey]=t[i.dataKey]+Number(l[i.dataKey]||0)}return{series:d,data:Array.from(c.values()).sort((a,l)=>a.date-l.date)}}function I({data:g,series:y,chartData:d,seriesConfig:c,stackMode:u="stack",isLoading:a,isFetching:l,isSuccess:f,filter:t,sx:i,legendBrand:r,showLegendUuid:K=!0}){const x=$(),C=t.timezone??W,[p,k]=T("absolute"),o=d!==void 0?a?{series:[],data:[]}:_({brands:t.brands,data:d,seriesConfig:c??[]}):{series:y??[],data:g??[]};if(!o.data.length&&a)return n(B,{});if(!o.data.length||!f)return n(U,{});const S=u==="none"&&p==="percent"?o.data.map(e=>{const m=Math.max(0,...o.series.map(s=>Number(e[s.dataKey])||0)),h={date:e.date};for(const s of o.series)h[s.dataKey]=m===0?0:(Number(e[s.dataKey])||0)/m;return h}):null,F=u==="stack"?p==="absolute"?"stack":"expand":"none",D=p==="absolute"?{tickFormatter:e=>Number(e).toLocaleString(),allowDecimals:!1}:{tickFormatter:e=>`${(e*100).toFixed(0)}%`,domain:[0,1]},M=p==="absolute"?e=>Number(e).toLocaleString():u==="stack"?(e,m,h)=>{const s=o.series.reduce((w,L)=>w+(Number(h.payload[L.dataKey])||0),0);return s===0?"0.0%":`${(Number(e)/s*100).toFixed(1)}%`}:e=>`${(Number(e)*100).toFixed(1)}%`;return b(A,{children:[b(v,{sx:{display:"flex",flexDirection:"column",gap:1,height:x.regularChartWrapper.height},children:[n(v,{sx:{display:"flex",justifyContent:"flex-end"},children:b(E,{value:p,exclusive:!0,onChange:(e,m)=>{m!==null&&k(m)},size:"small",children:[n(N,{value:"absolute",children:"Numbers"}),n(N,{value:"percent",children:"Percentages"})]})}),n(j,{data:S??o.data,series:o.series,stackMode:F,isAnimationActive:!0,xAxis:{dataKey:"date",type:"number",domain:["dataMin","dataMax"],tickFormatter:e=>O(e,{timeZone:C,hour12:!1,hour:"numeric"}),allowDuplicatedCategory:!1},yAxis:D,tooltip:{formatter:M,labelFormatter:e=>z(e,{timeZone:C,hour12:!1})},sx:{...x.regularChartWrapper,height:"unset",flex:1,minHeight:0,opacity:l?.4:1,...i}})]}),r&&n(Z,{payload:[{uuid:r.uuid,value:r.value,color:r.color,dataKey:r.dataKey??r.uuid,brandName:r.brandName,integrationType:r.integrationType}],showUuid:K})]})}export{I as ConversionOverTimeChart};
1
+ "use strict";import{useState as I}from"react";import{Stack as V,Box as M,ToggleButtonGroup as Y,ToggleButton as q}from"@mui/material";import{EmptyChartSection as A}from"../EmptyChartSection.mjs";import{LoadingChartSection as T}from"../LoadingChartSection.mjs";import{AreaChart as G}from"../AreaChart/index.mjs";import{SeriesPercentageChartLegend as J}from"../SeriesPercentageChartLegend/index.mjs";import{useStyle as Q}from"../styles.mjs";import{formatExtendedDate as R,formatDateMMYY as X}from"../../../utils/date.mjs";import{DEFAULT_TIMEZONE as ee}from"../../form/TimezoneInput/timezones.mjs";import{jsx as o,jsxs as L}from"react/jsx-runtime";function ae({brands:p,data:x,seriesConfig:m}){const c=new Map,g=p?new Set(p.map(t=>t._raw.brandUuid)):null;for(const t of x)if(!(g&&!g.has(t.brandUuid)))for(const l of t.interval??[]){const f=+new Date(l.date);let r=c.get(f);if(!r){r={date:f};for(const s of m)r[s.dataKey]=0;c.set(f,r)}for(const s of m)r[s.dataKey]=r[s.dataKey]+Number(l[s.dataKey]||0)}return{series:m,data:Array.from(c.values()).sort((t,l)=>t.date-l.date)}}function te({data:p,series:x,chartData:m,seriesConfig:c,stackMode:g="stack",isLoading:t,isFetching:l,isSuccess:f,filter:r,sx:s,legendBrand:i,showLegendUuid:E=!0,views:k,defaultViewKey:B}){var C;const K=Q(),N=r.timezone??ee,h=k??[{key:"absolute",label:"Numbers",mode:"absolute"},{key:"percent",label:"Percentages",mode:"percent"}],[w,U]=I(B??((C=h[0])==null?void 0:C.key)??"absolute"),a=h.find(e=>e.key===w)??h[0],y=a?.mode??"absolute",v=a?.stackMode??g,S=a?.chartData??m,j=a?.seriesConfig??c,Z=a?.data??p,$=a?.series??x,n=S!==void 0?t?{series:[],data:[]}:ae({brands:r.brands,data:S,seriesConfig:j??[]}):{series:$??[],data:Z??[]},D=!n.data.length||!f,F=!n.data.length&&t;if(!k){if(F)return o(T,{});if(D)return o(A,{})}const z=v==="none"&&y==="percent"?n.data.map(e=>{const u=Math.max(0,...n.series.map(d=>Number(e[d.dataKey])||0)),b={date:e.date};for(const d of n.series)b[d.dataKey]=u===0?0:(Number(e[d.dataKey])||0)/u;return b}):null,O=v==="stack"?y==="absolute"?"stack":"expand":"none",P=y==="absolute"?{tickFormatter:e=>Number(e).toLocaleString(),allowDecimals:!1}:{tickFormatter:e=>`${(e*100).toFixed(0)}%`,domain:[0,1]},W=y==="absolute"?e=>Number(e).toLocaleString():v==="stack"?(e,u,b)=>{const d=n.series.reduce((_,H)=>_+(Number(b.payload[H.dataKey])||0),0);return d===0?"0.0%":`${(Number(e)/d*100).toFixed(1)}%`}:e=>`${(Number(e)*100).toFixed(1)}%`;return L(V,{children:[L(M,{sx:{display:"flex",flexDirection:"column",gap:1,height:K.regularChartWrapper.height},children:[o(M,{sx:{display:"flex",justifyContent:"flex-end"},children:o(Y,{value:w,exclusive:!0,onChange:(e,u)=>{u!==null&&U(u)},size:"small",children:h.map(e=>o(q,{value:e.key,children:e.label},e.key))})}),F?o(T,{}):D?o(A,{}):o(G,{data:z??n.data,series:n.series,stackMode:O,isAnimationActive:!0,xAxis:{dataKey:"date",type:"number",domain:["dataMin","dataMax"],tickFormatter:e=>X(e,{timeZone:N,hour12:!1,hour:"numeric"}),allowDuplicatedCategory:!1},yAxis:P,tooltip:{formatter:W,labelFormatter:e=>R(e,{timeZone:N,hour12:!1})},sx:{...K.regularChartWrapper,height:"unset",flex:1,minHeight:0,opacity:l?.4:1,...s}})]}),i&&o(J,{payload:[{uuid:i.uuid,value:i.value,color:i.color,dataKey:i.dataKey??i.uuid,brandName:i.brandName,integrationType:i.integrationType}],showUuid:E})]})}export{te as ConversionOverTimeChart};
@@ -0,0 +1 @@
1
+ export * from './formatters';
@@ -0,0 +1 @@
1
+ "use strict";import{formatCurrency as r,formatNumberRounded as a,formatPercentage as e}from"./formatters.mjs";export{r as formatCurrency,a as formatNumberRounded,e as formatPercentage};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verifiedinc-public/shared-ui-elements",
3
- "version": "9.15.1",
3
+ "version": "10.0.0",
4
4
  "description": "A set of UI components, utilities that is shareable with the core apps.",
5
5
  "private": false,
6
6
  "sideEffects": false,