@carto/ps-react-ui 4.4.3 → 4.5.1

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.
Files changed (116) hide show
  1. package/dist/{download-config-Dqu78h2a.js → download-config-DemuQ3Jm.js} +9 -10
  2. package/dist/{download-config-Dqu78h2a.js.map → download-config-DemuQ3Jm.js.map} +1 -1
  3. package/dist/error-Cj8eUMrl.js +40 -0
  4. package/dist/error-Cj8eUMrl.js.map +1 -0
  5. package/dist/no-data-DkIt7Qt1.js +61 -0
  6. package/dist/no-data-DkIt7Qt1.js.map +1 -0
  7. package/dist/row-D4VOhcNI.js +34 -0
  8. package/dist/row-D4VOhcNI.js.map +1 -0
  9. package/dist/series-Bola3CmD.js +90 -0
  10. package/dist/series-Bola3CmD.js.map +1 -0
  11. package/dist/types/widgets/category/style.d.ts +1 -0
  12. package/dist/types/widgets/echart/shared-resize-observer.d.ts +12 -0
  13. package/dist/types/widgets/stores/index.d.ts +2 -1
  14. package/dist/types/widgets/stores/use-widget-selector.d.ts +35 -0
  15. package/dist/types/widgets/stores/widget-store-performance.test.d.ts +1 -0
  16. package/dist/types/widgets/stores/widget-store.d.ts +49 -27
  17. package/dist/types/widgets/table/types.d.ts +1 -1
  18. package/dist/use-widget-ref-BFazQvJK.js +22 -0
  19. package/dist/use-widget-ref-BFazQvJK.js.map +1 -0
  20. package/dist/use-widget-selector-DqRmWQ1K.js +12 -0
  21. package/dist/use-widget-selector-DqRmWQ1K.js.map +1 -0
  22. package/dist/widget-store-CIrb9RKP.js +263 -0
  23. package/dist/widget-store-CIrb9RKP.js.map +1 -0
  24. package/dist/widgets/actions.js +783 -817
  25. package/dist/widgets/actions.js.map +1 -1
  26. package/dist/widgets/bar.js +2 -2
  27. package/dist/widgets/category.js +259 -258
  28. package/dist/widgets/category.js.map +1 -1
  29. package/dist/widgets/echart.js +109 -99
  30. package/dist/widgets/echart.js.map +1 -1
  31. package/dist/widgets/error.js +1 -1
  32. package/dist/widgets/formula.js +71 -63
  33. package/dist/widgets/formula.js.map +1 -1
  34. package/dist/widgets/histogram.js +7 -8
  35. package/dist/widgets/histogram.js.map +1 -1
  36. package/dist/widgets/loader.js +53 -60
  37. package/dist/widgets/loader.js.map +1 -1
  38. package/dist/widgets/markdown.js +51 -50
  39. package/dist/widgets/markdown.js.map +1 -1
  40. package/dist/widgets/no-data.js +1 -1
  41. package/dist/widgets/pie.js +2 -2
  42. package/dist/widgets/range.js +146 -144
  43. package/dist/widgets/range.js.map +1 -1
  44. package/dist/widgets/scatterplot.js +2 -2
  45. package/dist/widgets/skeleton-loader.js +18 -17
  46. package/dist/widgets/skeleton-loader.js.map +1 -1
  47. package/dist/widgets/spread.js +110 -94
  48. package/dist/widgets/spread.js.map +1 -1
  49. package/dist/widgets/stores.js +5 -2
  50. package/dist/widgets/stores.js.map +1 -1
  51. package/dist/widgets/subheader.js +29 -29
  52. package/dist/widgets/subheader.js.map +1 -1
  53. package/dist/widgets/table.js +422 -436
  54. package/dist/widgets/table.js.map +1 -1
  55. package/dist/widgets/timeseries.js +2 -2
  56. package/dist/widgets/utils.js +1 -1
  57. package/dist/widgets/wrapper.js +156 -158
  58. package/dist/widgets/wrapper.js.map +1 -1
  59. package/dist/widgets.js +4 -4
  60. package/package.json +1 -1
  61. package/src/hooks/use-widget-ref.ts +3 -4
  62. package/src/widgets/actions/brush-toggle/brush-toggle.tsx +18 -32
  63. package/src/widgets/actions/change-column/change-column.tsx +15 -15
  64. package/src/widgets/actions/change-column/sortable-column-item.tsx +3 -1
  65. package/src/widgets/actions/download/download.tsx +4 -3
  66. package/src/widgets/actions/fullscreen/fullscreen.tsx +7 -11
  67. package/src/widgets/actions/lock-selection/lock-selection.tsx +12 -15
  68. package/src/widgets/actions/relative-data/relative-data.tsx +22 -26
  69. package/src/widgets/actions/searcher/searcher-toggle.tsx +11 -12
  70. package/src/widgets/actions/searcher/searcher.tsx +20 -21
  71. package/src/widgets/actions/stack-toggle/stack-toggle.tsx +15 -21
  72. package/src/widgets/actions/zoom-toggle/zoom-toggle.tsx +27 -43
  73. package/src/widgets/category/category-ui.tsx +30 -31
  74. package/src/widgets/category/style.ts +1 -0
  75. package/src/widgets/echart/echart-ui.test.tsx +20 -16
  76. package/src/widgets/echart/echart-ui.tsx +6 -12
  77. package/src/widgets/echart/echart.tsx +13 -27
  78. package/src/widgets/echart/shared-resize-observer.ts +45 -0
  79. package/src/widgets/error/error.tsx +7 -9
  80. package/src/widgets/formula/components/prefix.tsx +4 -6
  81. package/src/widgets/formula/components/row.tsx +4 -4
  82. package/src/widgets/formula/components/series.tsx +4 -6
  83. package/src/widgets/formula/components/suffix.tsx +4 -6
  84. package/src/widgets/formula/components/value.tsx +9 -16
  85. package/src/widgets/loader/loader.tsx +31 -44
  86. package/src/widgets/markdown/markdown.tsx +4 -7
  87. package/src/widgets/no-data/no-data.tsx +7 -10
  88. package/src/widgets/range/components/range-item.tsx +20 -18
  89. package/src/widgets/skeleton-loader/skeleton-loader.tsx +2 -5
  90. package/src/widgets/spread/components/max-value.tsx +14 -16
  91. package/src/widgets/spread/components/min-value.tsx +14 -16
  92. package/src/widgets/stores/index.ts +2 -1
  93. package/src/widgets/stores/use-widget-selector.ts +47 -0
  94. package/src/widgets/stores/widget-store-performance.test.ts +750 -0
  95. package/src/widgets/stores/widget-store.test.ts +81 -0
  96. package/src/widgets/stores/widget-store.ts +225 -44
  97. package/src/widgets/subheader/subheader.tsx +11 -3
  98. package/src/widgets/table/config.ts +0 -1
  99. package/src/widgets/table/hooks/use-pagination.ts +28 -52
  100. package/src/widgets/table/hooks/use-selection.ts +20 -24
  101. package/src/widgets/table/hooks/use-sort.ts +22 -39
  102. package/src/widgets/table/types.ts +1 -1
  103. package/src/widgets/wrapper/wrapper-ui.tsx +12 -13
  104. package/src/widgets/wrapper/wrapper.tsx +4 -6
  105. package/dist/error-CEkRPccv.js +0 -39
  106. package/dist/error-CEkRPccv.js.map +0 -1
  107. package/dist/no-data-hR3KcJ-_.js +0 -60
  108. package/dist/no-data-hR3KcJ-_.js.map +0 -1
  109. package/dist/row-DTCV0Ocm.js +0 -35
  110. package/dist/row-DTCV0Ocm.js.map +0 -1
  111. package/dist/series-CYNOu2Ju.js +0 -91
  112. package/dist/series-CYNOu2Ju.js.map +0 -1
  113. package/dist/use-widget-ref-wtFLDFCD.js +0 -25
  114. package/dist/use-widget-ref-wtFLDFCD.js.map +0 -1
  115. package/dist/widget-store-CzDt8oSK.js +0 -163
  116. package/dist/widget-store-CzDt8oSK.js.map +0 -1
@@ -1,90 +1,98 @@
1
- import { I, S as W, P as D, a as P } from "../series-CYNOu2Ju.js";
2
- import { jsx as f, jsxs as k, Fragment as C } from "react/jsx-runtime";
3
- import { c as w } from "react/compiler-runtime";
4
- import { u as h } from "../widget-store-CzDt8oSK.js";
5
- import { useShallow as S } from "zustand/shallow";
6
- import { d as R } from "../formatter-B9Bxn1k7.js";
7
- import { R as T, s as $ } from "../row-DTCV0Ocm.js";
8
- import { Box as F, Skeleton as b } from "@mui/material";
1
+ import { I as y, S as F, P as I, a as D } from "../series-Bola3CmD.js";
2
+ import { jsx as f, jsxs as P, Fragment as k } from "react/jsx-runtime";
3
+ import { c as g } from "react/compiler-runtime";
4
+ import { d as C } from "../formatter-B9Bxn1k7.js";
5
+ import { u as R } from "../use-widget-selector-DqRmWQ1K.js";
6
+ import { R as T, s as $ } from "../row-D4VOhcNI.js";
7
+ import { Box as v, Skeleton as b } from "@mui/material";
8
+ import "../widget-store-CIrb9RKP.js";
9
+ import "zustand/shallow";
9
10
  import "@mui/icons-material";
10
11
  import "react";
11
- import "react-markdown";
12
- import { d as y, a as v } from "../exports-Cr43OCul.js";
12
+ import { d as h, a as S } from "../exports-Cr43OCul.js";
13
13
  import "../lasso-tool-BYbxrJ-7.js";
14
14
  import "../cjs-D4KH3azB.js";
15
15
  import "@dnd-kit/core";
16
16
  import "@dnd-kit/sortable";
17
17
  import "@dnd-kit/utilities";
18
- import { u as j } from "../use-widget-ref-wtFLDFCD.js";
18
+ import { u as j } from "../use-widget-ref-BFazQvJK.js";
19
19
  function z(t) {
20
- const e = w(19);
21
- let i, o, r;
20
+ const e = g(15);
21
+ let r, i, o;
22
22
  e[0] !== t ? ({
23
- id: i,
24
- index: r,
25
- ...o
26
- } = t, e[0] = t, e[1] = i, e[2] = o, e[3] = r) : (i = e[1], o = e[2], r = e[3]);
27
- const n = r === void 0 ? 0 : r;
23
+ id: r,
24
+ index: o,
25
+ ...i
26
+ } = t, e[0] = t, e[1] = r, e[2] = i, e[3] = o) : (r = e[1], i = e[2], o = e[3]);
27
+ const n = o === void 0 ? 0 : o;
28
28
  let a;
29
- e[4] !== i || e[5] !== n ? (a = (m) => m.getWidget(i)?.data?.[n]?.value, e[4] = i, e[5] = n, e[6] = a) : a = e[6];
30
- const l = h(S(a));
31
- let u;
32
- e[7] !== i || e[8] !== n ? (u = (m) => m.getWidget(i)?.data?.[n]?.color, e[7] = i, e[8] = n, e[9] = u) : u = e[9];
33
- const x = h(S(u)), g = h(S((m) => m.getWidget(i)?.formatter)) ?? R;
29
+ e[4] !== n ? (a = (w) => {
30
+ const p = w;
31
+ return {
32
+ value: p?.data?.[n]?.value,
33
+ color: p?.data?.[n]?.color,
34
+ formatter: p?.formatter ?? C
35
+ };
36
+ }, e[4] = n, e[5] = a) : a = e[5];
37
+ const {
38
+ value: l,
39
+ color: u,
40
+ formatter: c
41
+ } = R(r, a);
42
+ let m;
43
+ e[6] !== u ? (m = {
44
+ color: u
45
+ }, e[6] = u, e[7] = m) : m = e[7];
46
+ const x = l ?? 0;
34
47
  let s;
35
- e[10] !== x ? (s = {
36
- color: x
37
- }, e[10] = x, e[11] = s) : s = e[11];
38
- const p = l ?? 0;
48
+ e[8] !== c || e[9] !== x ? (s = c(x), e[8] = c, e[9] = x, e[10] = s) : s = e[10];
39
49
  let d;
40
- e[12] !== g || e[13] !== p ? (d = g(p), e[12] = g, e[13] = p, e[14] = d) : d = e[14];
41
- let c;
42
- return e[15] !== o || e[16] !== s || e[17] !== d ? (c = /* @__PURE__ */ f(I, { TypographyProps: s, ...o, children: d }), e[15] = o, e[16] = s, e[17] = d, e[18] = c) : c = e[18], c;
50
+ return e[11] !== i || e[12] !== m || e[13] !== s ? (d = /* @__PURE__ */ f(y, { TypographyProps: m, ...i, children: s }), e[11] = i, e[12] = m, e[13] = s, e[14] = d) : d = e[14], d;
43
51
  }
44
- function ee({
52
+ function Z({
45
53
  refUI: t
46
54
  }) {
47
55
  return [{
48
- ...y,
49
- modifier: () => y.modifier(t)
56
+ ...h,
57
+ modifier: () => h.modifier(t)
50
58
  }, {
51
- ...v,
59
+ ...S,
52
60
  modifier: async (e) => {
53
- const i = [e?.map((o) => o.value) ?? []];
54
- return v.modifier(i);
61
+ const r = [e?.map((i) => i.value) ?? []];
62
+ return S.modifier(r);
55
63
  }
56
64
  }];
57
65
  }
58
- function te() {
66
+ function ee() {
59
67
  return {
60
68
  series: []
61
69
  };
62
70
  }
63
- function ie(t) {
64
- const e = w(8), {
65
- ref: i
71
+ function te(t) {
72
+ const e = g(8), {
73
+ ref: r
66
74
  } = j(t.id);
67
- let o;
68
- e[0] !== t.id ? (o = (a) => {
75
+ let i;
76
+ e[0] !== t.id ? (i = (a) => {
69
77
  const {
70
78
  index: l
71
79
  } = a;
72
- return /* @__PURE__ */ k(C, { children: [
73
- /* @__PURE__ */ f(W, { id: t.id, index: l }),
74
- /* @__PURE__ */ f(D, { id: t.id, index: l }),
80
+ return /* @__PURE__ */ P(k, { children: [
81
+ /* @__PURE__ */ f(F, { id: t.id, index: l }),
82
+ /* @__PURE__ */ f(I, { id: t.id, index: l }),
75
83
  /* @__PURE__ */ f(z, { id: t.id, index: l }),
76
- /* @__PURE__ */ f(P, { id: t.id, index: l })
84
+ /* @__PURE__ */ f(D, { id: t.id, index: l })
77
85
  ] });
78
- }, e[0] = t.id, e[1] = o) : o = e[1];
79
- let r;
80
- e[2] !== t.id || e[3] !== o ? (r = /* @__PURE__ */ f(T, { id: t.id, children: o }), e[2] = t.id, e[3] = o, e[4] = r) : r = e[4];
86
+ }, e[0] = t.id, e[1] = i) : i = e[1];
87
+ let o;
88
+ e[2] !== t.id || e[3] !== i ? (o = /* @__PURE__ */ f(T, { id: t.id, children: i }), e[2] = t.id, e[3] = i, e[4] = o) : o = e[4];
81
89
  let n;
82
- return e[5] !== i || e[6] !== r ? (n = /* @__PURE__ */ f(F, { ref: i, children: r }), e[5] = i, e[6] = r, e[7] = n) : n = e[7], n;
90
+ return e[5] !== r || e[6] !== o ? (n = /* @__PURE__ */ f(v, { ref: r, children: o }), e[5] = r, e[6] = o, e[7] = n) : n = e[7], n;
83
91
  }
84
- function oe() {
85
- const t = w(1);
92
+ function ie() {
93
+ const t = g(1);
86
94
  let e;
87
- return t[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (e = /* @__PURE__ */ f(F, { sx: $.row, "aria-label": "Formula skeleton", children: /* @__PURE__ */ f(b, { width: 120, height: 32 }) }), t[0] = e) : e = t[0], e;
95
+ return t[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (e = /* @__PURE__ */ f(v, { sx: $.row, "aria-label": "Formula skeleton", children: /* @__PURE__ */ f(b, { width: 120, height: 32 }) }), t[0] = e) : e = t[0], e;
88
96
  }
89
97
  function V(t) {
90
98
  return {
@@ -93,21 +101,21 @@ function V(t) {
93
101
  suffix: typeof t.suffix == "string" ? t.suffix : void 0
94
102
  };
95
103
  }
96
- function re(t) {
104
+ function oe(t) {
97
105
  return t?.map(V);
98
106
  }
99
107
  export {
100
- oe as FormulaSkeleton,
101
- ie as FormulaUI,
102
- I as Item,
103
- D as Prefix,
108
+ ie as FormulaSkeleton,
109
+ te as FormulaUI,
110
+ y as Item,
111
+ I as Prefix,
104
112
  T as Row,
105
- W as Series,
106
- P as Suffix,
113
+ F as Series,
114
+ D as Suffix,
107
115
  z as Value,
108
- te as formulaConfig,
109
- ee as formulaDownloadConfig,
116
+ ee as formulaConfig,
117
+ Z as formulaDownloadConfig,
110
118
  V as sanitizeDataItem,
111
- re as sanitizeDataItems
119
+ oe as sanitizeDataItems
112
120
  };
113
121
  //# sourceMappingURL=formula.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"formula.js","sources":["../../src/widgets/formula/components/value.tsx","../../src/widgets/formula/config.ts","../../src/widgets/formula/formula-ui.tsx","../../src/widgets/formula/skeleton.tsx","../../src/widgets/formula/serializer.ts"],"sourcesContent":["import { type FormulaWidgetState, type ValueProps } from '../types'\nimport { useWidgetStore } from '../../stores/widget-store'\nimport { Item } from './item'\nimport { useShallow } from 'zustand/shallow'\nimport { defaultFormatter } from '../../utils/formatter'\n\n/**\n * Displays the formatted numeric value for a formula widget data item, applying the widget's formatter and color.\n */\nexport function Value({ id, index = 0, ...props }: ValueProps) {\n const value = useWidgetStore(\n useShallow(\n (state) => state.getWidget<FormulaWidgetState>(id)?.data?.[index]?.value,\n ),\n )\n const color = useWidgetStore(\n useShallow(\n (state) => state.getWidget<FormulaWidgetState>(id)?.data?.[index]?.color,\n ),\n )\n const formatter =\n useWidgetStore(\n useShallow((state) => state.getWidget<FormulaWidgetState>(id)?.formatter),\n ) ?? defaultFormatter\n\n return (\n <Item TypographyProps={{ color }} {...props}>\n {formatter(value ?? 0)}\n </Item>\n )\n}\n","import { downloadToCSV, downloadToPNG } from '../actions'\nimport type { ConfigProps } from '../loader/types'\nimport type { FormulaDownloadConfig, FormulaWidgetConfig } from './types'\n\n/**\n * Creates download configuration for formula widgets, supporting PNG (screenshot) and CSV (data) exports.\n *\n * @param props - Configuration with `refUI` reference for PNG export.\n * @returns Array of download items for use with the Download action.\n */\nexport function formulaDownloadConfig({\n refUI,\n}: ConfigProps): FormulaDownloadConfig {\n return [\n {\n ...downloadToPNG,\n modifier: () => downloadToPNG.modifier(refUI),\n },\n {\n ...downloadToCSV,\n modifier: async (data) => {\n const formulaData = [data?.map((item) => item.value) ?? []]\n return downloadToCSV.modifier(formulaData)\n },\n },\n ]\n}\n\n/**\n * Returns the default configuration for formula (single or multiple numeric value) widgets.\n *\n * @returns Default formula widget config with empty series.\n */\nexport function formulaConfig(): FormulaWidgetConfig {\n return {\n series: [],\n }\n}\n","import type { FormulaUIProps } from './types'\nimport { Row } from './components/row'\nimport { Value } from './components/value'\nimport { Prefix } from './components/prefix'\nimport { Suffix } from './components/suffix'\nimport { Series } from './components/series'\nimport { useWidgetRef } from '../../hooks'\nimport { Box } from '@mui/material'\n\n/**\n * Renders a formula widget displaying one or more KPI values with optional prefixes, suffixes, and series indicators.\n */\nexport function FormulaUI(props: FormulaUIProps) {\n const { ref } = useWidgetRef(props.id)\n\n return (\n <Box ref={ref}>\n <Row id={props.id}>\n {({ index }) => (\n <>\n <Series id={props.id} index={index} />\n <Prefix id={props.id} index={index} />\n <Value id={props.id} index={index} />\n <Suffix id={props.id} index={index} />\n </>\n )}\n </Row>\n </Box>\n )\n}\n","import { Box, Skeleton } from '@mui/material'\nimport { styles } from './style'\n\nexport function FormulaSkeleton() {\n return (\n <Box sx={styles.row} aria-label='Formula skeleton'>\n <Skeleton width={120} height={32} />\n </Box>\n )\n}\n","import type { DataItem } from './types'\n\n/**\n * Sanitizes DataItem by converting ReactNode prefix/suffix values to undefined.\n * This ensures only string values are stored in the widget state.\n *\n * @param item - The DataItem to sanitize\n * @returns A new DataItem with ReactNode prefix/suffix values converted to undefined\n */\nexport function sanitizeDataItem(item: DataItem): DataItem {\n return {\n ...item,\n prefix: typeof item.prefix === 'string' ? item.prefix : undefined,\n suffix: typeof item.suffix === 'string' ? item.suffix : undefined,\n }\n}\n\n/**\n * Sanitizes an array of DataItems by converting ReactNode prefix/suffix values to undefined.\n *\n * @param items - Array of DataItems to sanitize\n * @returns A new array with sanitized DataItems\n */\nexport function sanitizeDataItems(\n items: DataItem[] | undefined,\n): DataItem[] | undefined {\n return items?.map(sanitizeDataItem)\n}\n"],"names":["Value","t0","$","_c","id","props","t1","index","undefined","t2","state","getWidget","data","value","useWidgetStore","useShallow","t3","state_0","color","formatter","state_1","defaultFormatter","t4","t5","t6","t7","Item","formulaDownloadConfig","refUI","downloadToPNG","modifier","downloadToCSV","formulaData","map","item","formulaConfig","series","FormulaUI","ref","useWidgetRef","jsxs","Fragment","jsx","Series","Prefix","Suffix","Row","Box","FormulaSkeleton","Symbol","for","styles","row","Skeleton","sanitizeDataItem","prefix","suffix","sanitizeDataItems","items"],"mappings":"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"}
1
+ {"version":3,"file":"formula.js","sources":["../../src/widgets/formula/components/value.tsx","../../src/widgets/formula/config.ts","../../src/widgets/formula/formula-ui.tsx","../../src/widgets/formula/skeleton.tsx","../../src/widgets/formula/serializer.ts"],"sourcesContent":["import { type FormulaWidgetState, type ValueProps } from '../types'\nimport { Item } from './item'\nimport { defaultFormatter } from '../../utils/formatter'\nimport { useWidgetSelector } from '../../stores/use-widget-selector'\n\n/**\n * Displays the formatted numeric value for a formula widget data item, applying the widget's formatter and color.\n */\nexport function Value({ id, index = 0, ...props }: ValueProps) {\n const { value, color, formatter } = useWidgetSelector(id, (w) => {\n const widget = w as FormulaWidgetState | undefined\n return {\n value: widget?.data?.[index]?.value,\n color: widget?.data?.[index]?.color,\n formatter: widget?.formatter ?? defaultFormatter,\n }\n })\n\n return (\n <Item TypographyProps={{ color }} {...props}>\n {formatter(value ?? 0)}\n </Item>\n )\n}\n","import { downloadToCSV, downloadToPNG } from '../actions'\nimport type { ConfigProps } from '../loader/types'\nimport type { FormulaDownloadConfig, FormulaWidgetConfig } from './types'\n\n/**\n * Creates download configuration for formula widgets, supporting PNG (screenshot) and CSV (data) exports.\n *\n * @param props - Configuration with `refUI` reference for PNG export.\n * @returns Array of download items for use with the Download action.\n */\nexport function formulaDownloadConfig({\n refUI,\n}: ConfigProps): FormulaDownloadConfig {\n return [\n {\n ...downloadToPNG,\n modifier: () => downloadToPNG.modifier(refUI),\n },\n {\n ...downloadToCSV,\n modifier: async (data) => {\n const formulaData = [data?.map((item) => item.value) ?? []]\n return downloadToCSV.modifier(formulaData)\n },\n },\n ]\n}\n\n/**\n * Returns the default configuration for formula (single or multiple numeric value) widgets.\n *\n * @returns Default formula widget config with empty series.\n */\nexport function formulaConfig(): FormulaWidgetConfig {\n return {\n series: [],\n }\n}\n","import type { FormulaUIProps } from './types'\nimport { Row } from './components/row'\nimport { Value } from './components/value'\nimport { Prefix } from './components/prefix'\nimport { Suffix } from './components/suffix'\nimport { Series } from './components/series'\nimport { useWidgetRef } from '../../hooks'\nimport { Box } from '@mui/material'\n\n/**\n * Renders a formula widget displaying one or more KPI values with optional prefixes, suffixes, and series indicators.\n */\nexport function FormulaUI(props: FormulaUIProps) {\n const { ref } = useWidgetRef(props.id)\n\n return (\n <Box ref={ref}>\n <Row id={props.id}>\n {({ index }) => (\n <>\n <Series id={props.id} index={index} />\n <Prefix id={props.id} index={index} />\n <Value id={props.id} index={index} />\n <Suffix id={props.id} index={index} />\n </>\n )}\n </Row>\n </Box>\n )\n}\n","import { Box, Skeleton } from '@mui/material'\nimport { styles } from './style'\n\nexport function FormulaSkeleton() {\n return (\n <Box sx={styles.row} aria-label='Formula skeleton'>\n <Skeleton width={120} height={32} />\n </Box>\n )\n}\n","import type { DataItem } from './types'\n\n/**\n * Sanitizes DataItem by converting ReactNode prefix/suffix values to undefined.\n * This ensures only string values are stored in the widget state.\n *\n * @param item - The DataItem to sanitize\n * @returns A new DataItem with ReactNode prefix/suffix values converted to undefined\n */\nexport function sanitizeDataItem(item: DataItem): DataItem {\n return {\n ...item,\n prefix: typeof item.prefix === 'string' ? item.prefix : undefined,\n suffix: typeof item.suffix === 'string' ? item.suffix : undefined,\n }\n}\n\n/**\n * Sanitizes an array of DataItems by converting ReactNode prefix/suffix values to undefined.\n *\n * @param items - Array of DataItems to sanitize\n * @returns A new array with sanitized DataItems\n */\nexport function sanitizeDataItems(\n items: DataItem[] | undefined,\n): DataItem[] | undefined {\n return items?.map(sanitizeDataItem)\n}\n"],"names":["Value","t0","$","_c","id","props","t1","index","undefined","t2","w","widget","value","data","color","formatter","defaultFormatter","useWidgetSelector","t3","t4","t5","t6","Item","formulaDownloadConfig","refUI","downloadToPNG","modifier","downloadToCSV","formulaData","map","item","formulaConfig","series","FormulaUI","ref","useWidgetRef","jsxs","Fragment","jsx","Series","Prefix","Suffix","Row","Box","FormulaSkeleton","Symbol","for","styles","row","Skeleton","sanitizeDataItem","prefix","suffix","sanitizeDataItems","items"],"mappings":"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"}
@@ -2,14 +2,13 @@ import { jsx as m, jsxs as _ } from "react/jsx-runtime";
2
2
  import { c as L } from "react/compiler-runtime";
3
3
  import "react";
4
4
  import "echarts";
5
- import "../widget-store-CzDt8oSK.js";
5
+ import "../widget-store-CIrb9RKP.js";
6
6
  import "zustand/shallow";
7
7
  import { g as k } from "../options-D9wflre6.js";
8
8
  import { m as C } from "../utils-BOhInag6.js";
9
9
  import { g as $, h as A, n as u, d as M, e as v, c as T } from "../styles-Y8q7Jff3.js";
10
10
  import { Box as f, Skeleton as d } from "@mui/material";
11
11
  import "@mui/icons-material";
12
- import "react-markdown";
13
12
  import { d as h, a as y } from "../exports-Cr43OCul.js";
14
13
  import "../lasso-tool-BYbxrJ-7.js";
15
14
  import "../cjs-D4KH3azB.js";
@@ -23,7 +22,7 @@ function D(e, n, t) {
23
22
  length: o
24
23
  }, (c, s) => `Series ${s + 1}`)] : ["Bin", "Value"], ...a.map((c, s) => [c, ...e.map((i) => String(i[s] ?? 0))])];
25
24
  }
26
- function re({
25
+ function ie({
27
26
  refUI: e,
28
27
  ticks: n,
29
28
  labelFormatter: t
@@ -45,7 +44,7 @@ function x(e, n, t) {
45
44
  return l !== void 0 && isFinite(l) ? `${r(p)}-${r(l)}` : `${r(p)}+`;
46
45
  });
47
46
  }
48
- function oe(e) {
47
+ function re(e) {
49
48
  return {
50
49
  type: "histogram",
51
50
  option: C(k(e), I(e)),
@@ -148,7 +147,7 @@ const N = {
148
147
  graph: T.graph
149
148
  }
150
149
  };
151
- function ae() {
150
+ function oe() {
152
151
  const e = L(2);
153
152
  let n;
154
153
  e[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (n = /* @__PURE__ */ m(f, { sx: {
@@ -200,9 +199,9 @@ function V(e) {
200
199
  return n(0.5);
201
200
  }
202
201
  export {
203
- ae as HistogramSkeleton,
204
- oe as histogramConfig,
202
+ oe as HistogramSkeleton,
203
+ re as histogramConfig,
205
204
  D as histogramDataToCSV,
206
- re as histogramDownloadConfig
205
+ ie as histogramDownloadConfig
207
206
  };
208
207
  //# sourceMappingURL=histogram.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"histogram.js","sources":["../../src/widgets/histogram/config.ts","../../src/widgets/histogram/style.ts","../../src/widgets/histogram/skeleton.tsx"],"sourcesContent":["import {\n getCommonOptions,\n mergeEchartWidgetConfig,\n type EchartOptionsProps,\n} from '../echart'\nimport type { HistogramConfig, HistogramWidgetConfig } from './types'\nimport {\n buildLegendConfig,\n buildGridConfig,\n createTooltipPositioner,\n createTooltipFormatter,\n niceNum,\n} from '../utils/chart-config'\nimport { downloadToCSV, downloadToPNG, type DownloadItem } from '../actions'\nimport type { ConfigProps } from '../loader/types'\n\nexport interface HistogramDownloadConfigProps extends ConfigProps {\n ticks: number[]\n labelFormatter?: (value: string | number) => string | number\n}\n\nexport function histogramDataToCSV(\n data: number[][],\n ticks: number[],\n labelFormatter?: (value: string | number) => string | number,\n): string[][] {\n if (!data?.length || data[0]?.length === 0) return []\n\n const dataLength = data[0]?.length ?? 0\n const labels = createAxisLabels(dataLength, ticks, labelFormatter)\n const seriesCount = data.length\n const isMulti = seriesCount > 1\n\n const headers = isMulti\n ? [\n 'Bin',\n ...Array.from({ length: seriesCount }, (_, i) => `Series ${i + 1}`),\n ]\n : ['Bin', 'Value']\n\n return [\n headers,\n ...labels.map((label, i) => [\n label,\n ...data.map((series) => String(series[i] ?? 0)),\n ]),\n ]\n}\n\nexport function histogramDownloadConfig({\n refUI,\n ticks,\n labelFormatter,\n}: HistogramDownloadConfigProps): DownloadItem<number[][]>[] {\n return [\n {\n ...downloadToPNG,\n modifier: () => downloadToPNG.modifier(refUI),\n },\n {\n ...downloadToCSV,\n modifier: async (data) =>\n downloadToCSV.modifier(histogramDataToCSV(data, ticks, labelFormatter)),\n },\n ]\n}\n\n/**\n * Creates formatted axis labels from tick boundaries.\n *\n * @param dataLength - Number of data points (determines number of labels).\n * @param ticks - Bin boundaries. If `ticks.length === dataLength + 1`, all\n * bins are ranges. If `ticks.length === dataLength`, the last bin is\n * open-ended (`+`). A last tick of `Infinity` also produces `+`.\n * @param labelFormatter - Optional formatter applied to each individual tick\n * value when building the bin range label.\n */\nfunction createAxisLabels(\n dataLength: number,\n ticks: number[],\n labelFormatter?: (value: string | number) => string | number,\n): string[] {\n const fmt = (v: number) =>\n labelFormatter ? String(labelFormatter(v)) : String(v)\n\n return Array.from({ length: dataLength }, (_, i) => {\n const low = ticks[i] ?? i\n const high = ticks[i + 1]\n return high !== undefined && isFinite(high)\n ? `${fmt(low)}-${fmt(high)}`\n : `${fmt(low)}+`\n })\n}\n\n/**\n * Generates ECharts configuration for distribution histogram widgets with\n * adjacent bars (minimal gap) and axis formatting styled with the CARTO theme.\n *\n * Accepts raw `number[][]` data and `ticks` boundaries. The ticks and\n * `labelFormatter` are used to create the x-axis category labels; the raw\n * numeric data is embedded directly in each series.\n *\n * @param props - Histogram configuration including raw data, ticks, and theme.\n * @returns Widget config with ECharts option object.\n */\nexport function histogramConfig(props: HistogramConfig): HistogramWidgetConfig {\n return {\n type: 'histogram',\n option: mergeEchartWidgetConfig(getCommonOptions(props), getOption(props)),\n formatter: props.formatter,\n }\n}\n\nfunction getOption({\n data = [],\n ticks,\n theme,\n formatter,\n labelFormatter,\n}: HistogramConfig): EchartOptionsProps {\n const hasLegend = (data?.length ?? 0) > 1\n const dataLength = data[0]?.length ?? 0\n const axisLabels = createAxisLabels(dataLength, ticks, labelFormatter)\n\n let niceMin = 0\n let niceMax = 1\n\n return {\n legend: buildLegendConfig({ hasLegend }),\n grid: buildGridConfig(hasLegend, theme),\n xAxis: {\n type: 'category',\n data: axisLabels,\n axisLine: {\n show: false,\n },\n axisLabel: {\n fontSize: theme.typography.overlineDelicate.fontSize,\n fontFamily: theme.typography.overlineDelicate.fontFamily,\n showMinLabel: true,\n showMaxLabel: true,\n hideOverlap: true,\n margin: 0,\n padding: [\n parseInt(theme.spacing(0.5)),\n parseInt(theme.spacing(0.5)),\n 0,\n parseInt(theme.spacing(0.5)),\n ],\n color: theme.palette.black[60],\n },\n axisTick: {\n show: false,\n },\n splitLine: {\n show: true,\n lineStyle: {\n color: theme.palette.black[4],\n },\n },\n },\n yAxis: {\n type: 'value' as const,\n min: (extent: { min: number }) => {\n niceMin = extent.min < 0 ? niceNum(extent.min) : 0\n return niceMin\n },\n max: (extent: { min: number; max: number }) => {\n niceMax = extent.max <= 0 ? 1 : niceNum(extent.max)\n return niceMax\n },\n splitNumber: 1,\n axisLabel: {\n fontSize: theme.typography.overlineDelicate.fontSize,\n fontFamily: theme.typography.overlineDelicate.fontFamily,\n margin: parseInt(theme.spacing(1)),\n show: true,\n showMaxLabel: true,\n showMinLabel: true,\n verticalAlign: 'bottom' as const,\n formatter: (value: number) => {\n if (value !== niceMax && value !== niceMin) return ''\n if (value === 0) return ''\n return formatter ? formatter(value) : String(value)\n },\n },\n axisLine: {\n show: false,\n },\n axisTick: {\n show: false,\n },\n splitLine: {\n show: true,\n lineStyle: {\n color: theme.palette.black[4],\n },\n },\n },\n tooltip: {\n position: createTooltipPositioner(theme),\n formatter: createTooltipFormatter((item) => {\n const _value = item.value as number\n\n const formattedValue =\n typeof _value === 'number' && formatter\n ? formatter(_value)\n : String(_value ?? '')\n\n const marker = typeof item.marker === 'string' ? item.marker : ''\n const seriesName = item.seriesName ? `${item.seriesName}: ` : ''\n const name = item.name ?? ''\n\n return { name, seriesName, marker, value: formattedValue }\n }),\n },\n series: data.map((seriesData: number[]) => ({\n type: 'bar',\n data: seriesData,\n barGap: '1%',\n barCategoryGap: '1%',\n emphasis: {\n focus: 'series',\n },\n })),\n } as EchartOptionsProps\n}\n","import type { SxProps, Theme } from '@mui/material'\nimport { baseSkeletonStyles } from '../utils/skeleton'\n\nexport const styles = {\n skeleton: {\n graph: baseSkeletonStyles.graph,\n },\n} satisfies Record<string, SxProps<Theme>>\n","import { Box, Skeleton } from '@mui/material'\nimport { styles } from './style'\n\nexport function HistogramSkeleton() {\n return (\n <Box sx={styles.skeleton.graph.container}>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'flex-end',\n justifyContent: 'space-between',\n gap: ({ spacing }) => spacing(0.5),\n height: ({ spacing }) => spacing(30),\n width: '100%',\n }}\n >\n {Array(8)\n .fill(0)\n .map((_, i) => {\n // Create varying heights for histogram bars\n const heights = [60, 80, 95, 85, 70, 55, 40, 30]\n const height = `${heights[i]}%`\n return (\n <Skeleton\n key={`skeleton-bar-${i}`}\n variant='rectangular'\n sx={{\n flex: 1,\n height,\n }}\n />\n )\n })}\n </Box>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n mt: ({ spacing }) => spacing(1),\n }}\n >\n {Array(4)\n .fill(0)\n .map((_, i) => (\n <Skeleton key={`skeleton-label-${i}`} width={32} height={8} />\n ))}\n </Box>\n </Box>\n )\n}\n"],"names":["histogramDataToCSV","data","ticks","labelFormatter","length","dataLength","labels","createAxisLabels","seriesCount","Array","from","_","i","map","label","series","String","histogramDownloadConfig","refUI","downloadToPNG","modifier","downloadToCSV","fmt","v","low","high","undefined","isFinite","histogramConfig","props","type","option","mergeEchartWidgetConfig","getCommonOptions","getOption","formatter","theme","hasLegend","axisLabels","niceMin","niceMax","legend","buildLegendConfig","grid","buildGridConfig","xAxis","axisLine","show","axisLabel","fontSize","typography","overlineDelicate","fontFamily","showMinLabel","showMaxLabel","hideOverlap","margin","padding","parseInt","spacing","color","palette","black","axisTick","splitLine","lineStyle","yAxis","min","extent","niceNum","max","splitNumber","verticalAlign","value","tooltip","position","createTooltipPositioner","createTooltipFormatter","item","_value","formattedValue","marker","seriesName","name","seriesData","barGap","barCategoryGap","emphasis","focus","styles","skeleton","graph","baseSkeletonStyles","HistogramSkeleton","$","_c","t0","Symbol","for","jsx","Box","display","alignItems","justifyContent","gap","_temp","height","_temp2","width","fill","_temp3","t1","container","mt","_temp4","_temp5","__0","i_0","Skeleton","spacing_1","flex","spacing_0"],"mappings":"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"}
1
+ {"version":3,"file":"histogram.js","sources":["../../src/widgets/histogram/config.ts","../../src/widgets/histogram/style.ts","../../src/widgets/histogram/skeleton.tsx"],"sourcesContent":["import {\n getCommonOptions,\n mergeEchartWidgetConfig,\n type EchartOptionsProps,\n} from '../echart'\nimport type { HistogramConfig, HistogramWidgetConfig } from './types'\nimport {\n buildLegendConfig,\n buildGridConfig,\n createTooltipPositioner,\n createTooltipFormatter,\n niceNum,\n} from '../utils/chart-config'\nimport { downloadToCSV, downloadToPNG, type DownloadItem } from '../actions'\nimport type { ConfigProps } from '../loader/types'\n\nexport interface HistogramDownloadConfigProps extends ConfigProps {\n ticks: number[]\n labelFormatter?: (value: string | number) => string | number\n}\n\nexport function histogramDataToCSV(\n data: number[][],\n ticks: number[],\n labelFormatter?: (value: string | number) => string | number,\n): string[][] {\n if (!data?.length || data[0]?.length === 0) return []\n\n const dataLength = data[0]?.length ?? 0\n const labels = createAxisLabels(dataLength, ticks, labelFormatter)\n const seriesCount = data.length\n const isMulti = seriesCount > 1\n\n const headers = isMulti\n ? [\n 'Bin',\n ...Array.from({ length: seriesCount }, (_, i) => `Series ${i + 1}`),\n ]\n : ['Bin', 'Value']\n\n return [\n headers,\n ...labels.map((label, i) => [\n label,\n ...data.map((series) => String(series[i] ?? 0)),\n ]),\n ]\n}\n\nexport function histogramDownloadConfig({\n refUI,\n ticks,\n labelFormatter,\n}: HistogramDownloadConfigProps): DownloadItem<number[][]>[] {\n return [\n {\n ...downloadToPNG,\n modifier: () => downloadToPNG.modifier(refUI),\n },\n {\n ...downloadToCSV,\n modifier: async (data) =>\n downloadToCSV.modifier(histogramDataToCSV(data, ticks, labelFormatter)),\n },\n ]\n}\n\n/**\n * Creates formatted axis labels from tick boundaries.\n *\n * @param dataLength - Number of data points (determines number of labels).\n * @param ticks - Bin boundaries. If `ticks.length === dataLength + 1`, all\n * bins are ranges. If `ticks.length === dataLength`, the last bin is\n * open-ended (`+`). A last tick of `Infinity` also produces `+`.\n * @param labelFormatter - Optional formatter applied to each individual tick\n * value when building the bin range label.\n */\nfunction createAxisLabels(\n dataLength: number,\n ticks: number[],\n labelFormatter?: (value: string | number) => string | number,\n): string[] {\n const fmt = (v: number) =>\n labelFormatter ? String(labelFormatter(v)) : String(v)\n\n return Array.from({ length: dataLength }, (_, i) => {\n const low = ticks[i] ?? i\n const high = ticks[i + 1]\n return high !== undefined && isFinite(high)\n ? `${fmt(low)}-${fmt(high)}`\n : `${fmt(low)}+`\n })\n}\n\n/**\n * Generates ECharts configuration for distribution histogram widgets with\n * adjacent bars (minimal gap) and axis formatting styled with the CARTO theme.\n *\n * Accepts raw `number[][]` data and `ticks` boundaries. The ticks and\n * `labelFormatter` are used to create the x-axis category labels; the raw\n * numeric data is embedded directly in each series.\n *\n * @param props - Histogram configuration including raw data, ticks, and theme.\n * @returns Widget config with ECharts option object.\n */\nexport function histogramConfig(props: HistogramConfig): HistogramWidgetConfig {\n return {\n type: 'histogram',\n option: mergeEchartWidgetConfig(getCommonOptions(props), getOption(props)),\n formatter: props.formatter,\n }\n}\n\nfunction getOption({\n data = [],\n ticks,\n theme,\n formatter,\n labelFormatter,\n}: HistogramConfig): EchartOptionsProps {\n const hasLegend = (data?.length ?? 0) > 1\n const dataLength = data[0]?.length ?? 0\n const axisLabels = createAxisLabels(dataLength, ticks, labelFormatter)\n\n let niceMin = 0\n let niceMax = 1\n\n return {\n legend: buildLegendConfig({ hasLegend }),\n grid: buildGridConfig(hasLegend, theme),\n xAxis: {\n type: 'category',\n data: axisLabels,\n axisLine: {\n show: false,\n },\n axisLabel: {\n fontSize: theme.typography.overlineDelicate.fontSize,\n fontFamily: theme.typography.overlineDelicate.fontFamily,\n showMinLabel: true,\n showMaxLabel: true,\n hideOverlap: true,\n margin: 0,\n padding: [\n parseInt(theme.spacing(0.5)),\n parseInt(theme.spacing(0.5)),\n 0,\n parseInt(theme.spacing(0.5)),\n ],\n color: theme.palette.black[60],\n },\n axisTick: {\n show: false,\n },\n splitLine: {\n show: true,\n lineStyle: {\n color: theme.palette.black[4],\n },\n },\n },\n yAxis: {\n type: 'value' as const,\n min: (extent: { min: number }) => {\n niceMin = extent.min < 0 ? niceNum(extent.min) : 0\n return niceMin\n },\n max: (extent: { min: number; max: number }) => {\n niceMax = extent.max <= 0 ? 1 : niceNum(extent.max)\n return niceMax\n },\n splitNumber: 1,\n axisLabel: {\n fontSize: theme.typography.overlineDelicate.fontSize,\n fontFamily: theme.typography.overlineDelicate.fontFamily,\n margin: parseInt(theme.spacing(1)),\n show: true,\n showMaxLabel: true,\n showMinLabel: true,\n verticalAlign: 'bottom' as const,\n formatter: (value: number) => {\n if (value !== niceMax && value !== niceMin) return ''\n if (value === 0) return ''\n return formatter ? formatter(value) : String(value)\n },\n },\n axisLine: {\n show: false,\n },\n axisTick: {\n show: false,\n },\n splitLine: {\n show: true,\n lineStyle: {\n color: theme.palette.black[4],\n },\n },\n },\n tooltip: {\n position: createTooltipPositioner(theme),\n formatter: createTooltipFormatter((item) => {\n const _value = item.value as number\n\n const formattedValue =\n typeof _value === 'number' && formatter\n ? formatter(_value)\n : String(_value ?? '')\n\n const marker = typeof item.marker === 'string' ? item.marker : ''\n const seriesName = item.seriesName ? `${item.seriesName}: ` : ''\n const name = item.name ?? ''\n\n return { name, seriesName, marker, value: formattedValue }\n }),\n },\n series: data.map((seriesData: number[]) => ({\n type: 'bar',\n data: seriesData,\n barGap: '1%',\n barCategoryGap: '1%',\n emphasis: {\n focus: 'series',\n },\n })),\n } as EchartOptionsProps\n}\n","import type { SxProps, Theme } from '@mui/material'\nimport { baseSkeletonStyles } from '../utils/skeleton'\n\nexport const styles = {\n skeleton: {\n graph: baseSkeletonStyles.graph,\n },\n} satisfies Record<string, SxProps<Theme>>\n","import { Box, Skeleton } from '@mui/material'\nimport { styles } from './style'\n\nexport function HistogramSkeleton() {\n return (\n <Box sx={styles.skeleton.graph.container}>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'flex-end',\n justifyContent: 'space-between',\n gap: ({ spacing }) => spacing(0.5),\n height: ({ spacing }) => spacing(30),\n width: '100%',\n }}\n >\n {Array(8)\n .fill(0)\n .map((_, i) => {\n // Create varying heights for histogram bars\n const heights = [60, 80, 95, 85, 70, 55, 40, 30]\n const height = `${heights[i]}%`\n return (\n <Skeleton\n key={`skeleton-bar-${i}`}\n variant='rectangular'\n sx={{\n flex: 1,\n height,\n }}\n />\n )\n })}\n </Box>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n mt: ({ spacing }) => spacing(1),\n }}\n >\n {Array(4)\n .fill(0)\n .map((_, i) => (\n <Skeleton key={`skeleton-label-${i}`} width={32} height={8} />\n ))}\n </Box>\n </Box>\n )\n}\n"],"names":["histogramDataToCSV","data","ticks","labelFormatter","length","dataLength","labels","createAxisLabels","seriesCount","Array","from","_","i","map","label","series","String","histogramDownloadConfig","refUI","downloadToPNG","modifier","downloadToCSV","fmt","v","low","high","undefined","isFinite","histogramConfig","props","type","option","mergeEchartWidgetConfig","getCommonOptions","getOption","formatter","theme","hasLegend","axisLabels","niceMin","niceMax","legend","buildLegendConfig","grid","buildGridConfig","xAxis","axisLine","show","axisLabel","fontSize","typography","overlineDelicate","fontFamily","showMinLabel","showMaxLabel","hideOverlap","margin","padding","parseInt","spacing","color","palette","black","axisTick","splitLine","lineStyle","yAxis","min","extent","niceNum","max","splitNumber","verticalAlign","value","tooltip","position","createTooltipPositioner","createTooltipFormatter","item","_value","formattedValue","marker","seriesName","name","seriesData","barGap","barCategoryGap","emphasis","focus","styles","skeleton","graph","baseSkeletonStyles","HistogramSkeleton","$","_c","t0","Symbol","for","jsx","Box","display","alignItems","justifyContent","gap","_temp","height","_temp2","width","fill","_temp3","t1","container","mt","_temp4","_temp5","__0","i_0","Skeleton","spacing_1","flex","spacing_0"],"mappings":"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"}
@@ -1,71 +1,64 @@
1
- import { c as _ } from "react/compiler-runtime";
2
- import { useSyncExternalStore as b, useRef as R, useEffect as f } from "react";
3
- import { u as c } from "../widget-store-CzDt8oSK.js";
4
- import { d as E } from "../cjs-D4KH3azB.js";
5
- function z(t) {
6
- const e = _(36), i = c(w), n = c(v), d = c(M);
7
- let u;
8
- e[0] !== t.id ? (u = () => c.getState().widgets[t.id]?.registeredTools, e[0] = t.id, e[1] = u) : u = e[1];
9
- const C = b(c.subscribe, u), S = R(t.data), P = R(t.config), T = R(!1);
10
- let g;
11
- e[2] !== t.config || e[3] !== t.data ? (g = () => {
12
- S.current = t.data, P.current = t.config;
13
- }, e[2] = t.config, e[3] = t.data, e[4] = g) : g = e[4], f(g);
14
- let l, a;
15
- e[5] !== t.id || e[6] !== t.type || e[7] !== i ? (l = () => {
16
- i(t.id, {
17
- type: t.type
1
+ import { c as W } from "react/compiler-runtime";
2
+ import { useRef as x, useEffect as n } from "react";
3
+ import { u as w, w as y } from "../widget-store-CIrb9RKP.js";
4
+ import { d as A } from "../cjs-D4KH3azB.js";
5
+ function v(e) {
6
+ const i = W(25);
7
+ let t;
8
+ i[0] !== e.id ? (t = (L) => L.widgets[e.id]?.registeredTools, i[0] = e.id, i[1] = t) : t = i[1];
9
+ const F = w(t), C = x(e.data), h = x(e.config), P = x(!1);
10
+ let d;
11
+ i[2] !== e.config || i[3] !== e.data ? (d = () => {
12
+ C.current = e.data, h.current = e.config;
13
+ }, i[2] = e.config, i[3] = e.data, i[4] = d) : d = i[4], n(d);
14
+ let f, c;
15
+ i[5] !== e.error || i[6] !== e.id || i[7] !== e.isFetching || i[8] !== e.isLoading || i[9] !== e.type ? (f = () => {
16
+ y.setWidget(e.id, {
17
+ type: e.type,
18
+ isLoading: e.isLoading ?? !1,
19
+ isFetching: e.isFetching ?? !1,
20
+ error: e.error
18
21
  });
19
- }, a = [t.id, t.type, i], e[5] = t.id, e[6] = t.type, e[7] = i, e[8] = l, e[9] = a) : (l = e[8], a = e[9]), f(l, a);
20
- let r, m;
21
- e[10] !== t.error || e[11] !== t.id || e[12] !== t.isFetching || e[13] !== t.isLoading || e[14] !== i ? (r = () => {
22
- i(t.id, {
23
- isLoading: t.isLoading ?? !1,
24
- isFetching: t.isFetching ?? !1,
25
- error: t.error
26
- });
27
- }, m = [t.id, t.isLoading, t.isFetching, t.error, i], e[10] = t.error, e[11] = t.id, e[12] = t.isFetching, e[13] = t.isLoading, e[14] = i, e[15] = r, e[16] = m) : (r = e[15], m = e[16]), f(r, m);
28
- let y, h;
29
- e[17] !== d || e[18] !== t.config || e[19] !== t.id ? (y = () => {
30
- t.config && d(t.id, t.config);
31
- }, h = [t.id, t.config, d], e[17] = d, e[18] = t.config, e[19] = t.id, e[20] = y, e[21] = h) : (y = e[20], h = e[21]), f(y, h);
32
- let x, L;
33
- e[22] !== n || e[23] !== t.data || e[24] !== t.id ? (x = () => {
34
- n(t.id, t.data);
35
- }, L = [t.id, t.data, n], e[22] = n, e[23] = t.data, e[24] = t.id, e[25] = x, e[26] = L) : (x = e[25], L = e[26]), f(x, L);
36
- let F;
37
- e[27] !== d || e[28] !== n || e[29] !== t.id ? (F = () => {
38
- if (!T.current) {
39
- T.current = !0;
22
+ }, c = [e.id, e.type, e.isLoading, e.isFetching, e.error], i[5] = e.error, i[6] = e.id, i[7] = e.isFetching, i[8] = e.isLoading, i[9] = e.type, i[10] = f, i[11] = c) : (f = i[10], c = i[11]), n(f, c);
23
+ let a, g;
24
+ i[12] !== e.config || i[13] !== e.id ? (a = () => {
25
+ e.config && y.executeConfigPipeline(e.id, e.config);
26
+ }, g = [e.id, e.config], i[12] = e.config, i[13] = e.id, i[14] = a, i[15] = g) : (a = i[14], g = i[15]), n(a, g);
27
+ let l, u;
28
+ i[16] !== e.data || i[17] !== e.id ? (l = () => {
29
+ y.executeToolPipeline(e.id, e.data);
30
+ }, u = [e.id, e.data], i[16] = e.data, i[17] = e.id, i[18] = l, i[19] = u) : (l = i[18], u = i[19]), n(l, u);
31
+ let r;
32
+ i[20] !== e.id ? (r = () => {
33
+ if (!P.current) {
34
+ P.current = !0;
40
35
  return;
41
36
  }
42
- n(t.id, S.current), P.current && d(t.id, P.current);
43
- }, e[27] = d, e[28] = n, e[29] = t.id, e[30] = F) : F = e[30];
44
- let W;
45
- return e[31] !== d || e[32] !== n || e[33] !== t.id || e[34] !== C ? (W = [C, t.id, n, d], e[31] = d, e[32] = n, e[33] = t.id, e[34] = C, e[35] = W) : W = e[35], f(F, W), t.children;
46
- }
47
- function M(t) {
48
- return t.executeConfigPipeline;
49
- }
50
- function v(t) {
51
- return t.executeToolPipeline;
52
- }
53
- function w(t) {
54
- return t.setWidget;
37
+ const L = requestAnimationFrame(() => {
38
+ const {
39
+ executeToolPipeline: R,
40
+ executeConfigPipeline: T
41
+ } = y;
42
+ R(e.id, C.current), h.current && T(e.id, h.current);
43
+ });
44
+ return () => cancelAnimationFrame(L);
45
+ }, i[20] = e.id, i[21] = r) : r = i[21];
46
+ let m;
47
+ return i[22] !== e.id || i[23] !== F ? (m = [F, e.id], i[22] = e.id, i[23] = F, i[24] = m) : m = i[24], n(r, m), e.children;
55
48
  }
56
- function A(t, e, i) {
57
- return typeof t == "function" ? t(e, i) : t;
49
+ function E(e, i, t) {
50
+ return typeof e == "function" ? e(i, t) : e;
58
51
  }
59
- function B(...t) {
60
- return E(t[0] ?? {}, t[1] ?? {}, {
61
- arrayMerge(e, i) {
62
- return i;
52
+ function I(...e) {
53
+ return A(e[0] ?? {}, e[1] ?? {}, {
54
+ arrayMerge(i, t) {
55
+ return t;
63
56
  }
64
57
  });
65
58
  }
66
59
  export {
67
- z as WidgetLoader,
68
- B as mergeWidgetConfig,
69
- A as resolveConfig
60
+ v as WidgetLoader,
61
+ I as mergeWidgetConfig,
62
+ E as resolveConfig
70
63
  };
71
64
  //# sourceMappingURL=loader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sources":["../../src/widgets/loader/loader.tsx","../../src/widgets/loader/utils.ts"],"sourcesContent":["import { useEffect, useRef, useSyncExternalStore } from 'react'\nimport type { WidgetLoaderProps } from './types'\nimport { useWidgetStore } from '../stores/widget-store'\nimport type { WrapperState } from '../wrapper'\n\n/**\n * Foundation component for all widgets that manages state initialization, synchronization with the widget store, and data transformation pipeline execution.\n *\n * @remarks\n * The WidgetLoader is stateless -- it manages data flow but does not render any UI. Always wrap it with WidgetWrapper for consistent widget appearance.\n *\n * @example\n * ```tsx\n * <WidgetLoader\n * id=\"sales-chart\"\n * type=\"bar\"\n * data={data}\n * isLoading={false}\n * isFetching={false}\n * config={barConfig({ data })}\n * >\n * <WidgetWrapper id=\"sales-chart\" title=\"Sales\">\n * <Echart id=\"sales-chart\" />\n * </WidgetWrapper>\n * </WidgetLoader>\n * ```\n */\nexport function WidgetLoader<T extends object = Record<string, unknown>>(\n props: WidgetLoaderProps<T>,\n) {\n const setWidget = useWidgetStore((state) => state.setWidget)\n const executeToolPipeline = useWidgetStore(\n (state) => state.executeToolPipeline,\n )\n const executeConfigPipeline = useWidgetStore(\n (state) => state.executeConfigPipeline,\n )\n\n const registeredTools = useSyncExternalStore(\n useWidgetStore.subscribe,\n () => useWidgetStore.getState().widgets[props.id]?.registeredTools,\n )\n\n const dataRef = useRef(props.data)\n const configRef = useRef(props.config)\n const isMountedRef = useRef(false)\n\n useEffect(() => {\n dataRef.current = props.data\n configRef.current = props.config\n })\n\n // Split into 3 effects for metadata and 1 for data pipeline:\n // Each property that can be modified independently gets its own effect to avoid\n // accidentally resetting other properties.\n //\n // - Effect 1: Type (can be modified by tools that change visualization type)\n // - Effect 2: Loading/Error states (change during fetch lifecycle)\n // - Effect 3: Config (can be modified by tools that change widget configuration)\n // - Effect 4: Data pipeline execution (transforms data through registered tools)\n // - Effect 5: Re-execute pipeline when tool state changes\n\n // Effect 1: Type updates\n useEffect(() => {\n setWidget<WrapperState>(props.id, {\n type: props.type,\n })\n }, [props.id, props.type, setWidget])\n\n // Effect 2: Loading and error states\n useEffect(() => {\n setWidget<WrapperState>(props.id, {\n isLoading: props.isLoading ?? false,\n isFetching: props.isFetching ?? false,\n error: props.error,\n })\n }, [props.id, props.isLoading, props.isFetching, props.error, setWidget])\n\n // Effect 3: Config updates — run through config pipeline\n useEffect(() => {\n if (props.config) {\n void executeConfigPipeline(props.id, props.config)\n }\n }, [props.id, props.config, executeConfigPipeline])\n\n // Effect 4: Execute tool pipeline when props.data changes\n useEffect(() => {\n void executeToolPipeline(props.id, props.data)\n }, [props.id, props.data, executeToolPipeline])\n\n // Effect 5: Re-execute pipelines when registered tools change\n useEffect(() => {\n if (!isMountedRef.current) {\n isMountedRef.current = true\n return\n }\n\n void executeToolPipeline(props.id, dataRef.current)\n if (configRef.current) {\n void executeConfigPipeline(props.id, configRef.current)\n }\n }, [registeredTools, props.id, executeToolPipeline, executeConfigPipeline])\n\n return props.children\n}\n","import deepmerge from 'deepmerge'\n\n/**\n * Config can be either an object or a function that receives baseConfig and data\n * and returns a partial config to be merged with the base.\n */\nexport type ConfigOrFn<TConfig, TData = unknown> =\n | Partial<TConfig>\n | ((baseConfig: TConfig, data: TData) => Partial<TConfig>)\n\n/**\n * Resolves a widget config that may be either a partial object or a function receiving the computed base config and data. If it is a function, calls it with `baseConfig` and `data`; otherwise returns the value as-is.\n *\n * @param config - The config object or function to resolve.\n * @param baseConfig - The computed base configuration.\n * @param data - The widget data.\n * @returns Resolved partial config, or undefined.\n *\n * @example\n * ```tsx\n * const resolved = resolveConfig(\n * (base, data) => ({ maxItems: base.maxItems + 5 }),\n * baseConfig,\n * widgetData,\n * )\n * ```\n */\nexport function resolveConfig<TConfig, TData>(\n config: ConfigOrFn<TConfig, TData> | undefined,\n baseConfig: TConfig,\n data: TData,\n): Partial<TConfig> | undefined {\n if (typeof config === 'function') {\n return config(baseConfig, data)\n }\n return config\n}\n\n/**\n * Deep-merges two partial widget config objects using `deepmerge`, with arrays replaced rather than concatenated.\n *\n * @param options - A tuple of two partial configs to merge (base and override).\n * @returns The merged config object.\n *\n * @example\n * ```tsx\n * const finalConfig = mergeWidgetConfig(baseConfig, resolvedConfig)\n * ```\n */\nexport function mergeWidgetConfig<T>(\n ...options: [Partial<T> | undefined, Partial<T> | undefined]\n): T {\n return deepmerge(options[0] ?? {}, options[1] ?? {}, {\n arrayMerge(_, source) {\n return source as T[keyof T][]\n },\n })\n}\n"],"names":["WidgetLoader","props","$","_c","setWidget","useWidgetStore","_temp","executeToolPipeline","_temp2","executeConfigPipeline","_temp3","t0","id","getState","widgets","registeredTools","useSyncExternalStore","subscribe","dataRef","useRef","data","configRef","config","isMountedRef","t1","current","useEffect","t2","t3","type","t4","t5","error","isFetching","isLoading","t6","t7","t8","t9","t10","t11","children","state_1","state","state_0","resolveConfig","baseConfig","mergeWidgetConfig","options","deepmerge","arrayMerge","_","source"],"mappings":"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"}
1
+ {"version":3,"file":"loader.js","sources":["../../src/widgets/loader/loader.tsx","../../src/widgets/loader/utils.ts"],"sourcesContent":["import { useEffect, useRef } from 'react'\nimport type { WidgetLoaderProps } from './types'\nimport { useWidgetStore, widgetStoreActions } from '../stores/widget-store'\nimport type { WrapperState } from '../wrapper'\n\n/**\n * Foundation component for all widgets that manages state initialization, synchronization with the widget store, and data transformation pipeline execution.\n *\n * @remarks\n * The WidgetLoader is stateless -- it manages data flow but does not render any UI. Always wrap it with WidgetWrapper for consistent widget appearance.\n *\n * @example\n * ```tsx\n * <WidgetLoader\n * id=\"sales-chart\"\n * type=\"bar\"\n * data={data}\n * isLoading={false}\n * isFetching={false}\n * config={barConfig({ data })}\n * >\n * <WidgetWrapper id=\"sales-chart\" title=\"Sales\">\n * <Echart id=\"sales-chart\" />\n * </WidgetWrapper>\n * </WidgetLoader>\n * ```\n */\nexport function WidgetLoader<T extends object = Record<string, unknown>>(\n props: WidgetLoaderProps<T>,\n) {\n // Subscribe only to this widget's registeredTools via Zustand selector.\n // The selector returns a stable reference when other widgets change,\n // avoiding unnecessary re-evaluations of Effect 4.\n const registeredTools = useWidgetStore(\n (state) => state.widgets[props.id]?.registeredTools,\n )\n\n const dataRef = useRef(props.data)\n const configRef = useRef(props.config)\n const isMountedRef = useRef(false)\n\n useEffect(() => {\n dataRef.current = props.data\n configRef.current = props.config\n })\n\n // Effect 1: Metadata type, loading, and error states in a single setWidget call.\n // Merged to reduce store updates from 2 to 1 per widget during initialization.\n useEffect(() => {\n widgetStoreActions.setWidget<WrapperState>(props.id, {\n type: props.type,\n isLoading: props.isLoading ?? false,\n isFetching: props.isFetching ?? false,\n error: props.error,\n })\n }, [props.id, props.type, props.isLoading, props.isFetching, props.error])\n\n // Effect 2: Config updates — run through config pipeline\n useEffect(() => {\n if (props.config) {\n void widgetStoreActions.executeConfigPipeline(props.id, props.config)\n }\n }, [props.id, props.config])\n\n // Effect 3: Execute tool pipeline when props.data changes\n useEffect(() => {\n void widgetStoreActions.executeToolPipeline(props.id, props.data)\n }, [props.id, props.data])\n\n // Effect 4: Re-execute pipelines when registered tools change.\n // Uses requestAnimationFrame to coalesce rapid successive registeredTools\n // changes (e.g., 6 action components each calling registerTool on mount)\n // into a single pipeline execution instead of 6 pairs.\n useEffect(() => {\n if (!isMountedRef.current) {\n isMountedRef.current = true\n return\n }\n\n const rafId = requestAnimationFrame(() => {\n const { executeToolPipeline, executeConfigPipeline } = widgetStoreActions\n void executeToolPipeline(props.id, dataRef.current)\n if (configRef.current) {\n void executeConfigPipeline(props.id, configRef.current)\n }\n })\n\n return () => cancelAnimationFrame(rafId)\n }, [registeredTools, props.id])\n\n return props.children\n}\n","import deepmerge from 'deepmerge'\n\n/**\n * Config can be either an object or a function that receives baseConfig and data\n * and returns a partial config to be merged with the base.\n */\nexport type ConfigOrFn<TConfig, TData = unknown> =\n | Partial<TConfig>\n | ((baseConfig: TConfig, data: TData) => Partial<TConfig>)\n\n/**\n * Resolves a widget config that may be either a partial object or a function receiving the computed base config and data. If it is a function, calls it with `baseConfig` and `data`; otherwise returns the value as-is.\n *\n * @param config - The config object or function to resolve.\n * @param baseConfig - The computed base configuration.\n * @param data - The widget data.\n * @returns Resolved partial config, or undefined.\n *\n * @example\n * ```tsx\n * const resolved = resolveConfig(\n * (base, data) => ({ maxItems: base.maxItems + 5 }),\n * baseConfig,\n * widgetData,\n * )\n * ```\n */\nexport function resolveConfig<TConfig, TData>(\n config: ConfigOrFn<TConfig, TData> | undefined,\n baseConfig: TConfig,\n data: TData,\n): Partial<TConfig> | undefined {\n if (typeof config === 'function') {\n return config(baseConfig, data)\n }\n return config\n}\n\n/**\n * Deep-merges two partial widget config objects using `deepmerge`, with arrays replaced rather than concatenated.\n *\n * @param options - A tuple of two partial configs to merge (base and override).\n * @returns The merged config object.\n *\n * @example\n * ```tsx\n * const finalConfig = mergeWidgetConfig(baseConfig, resolvedConfig)\n * ```\n */\nexport function mergeWidgetConfig<T>(\n ...options: [Partial<T> | undefined, Partial<T> | undefined]\n): T {\n return deepmerge(options[0] ?? {}, options[1] ?? {}, {\n arrayMerge(_, source) {\n return source as T[keyof T][]\n },\n })\n}\n"],"names":["WidgetLoader","props","$","_c","t0","id","state","widgets","registeredTools","useWidgetStore","dataRef","useRef","data","configRef","config","isMountedRef","t1","current","useEffect","t2","t3","error","isFetching","isLoading","type","widgetStoreActions","setWidget","t4","t5","executeConfigPipeline","t6","t7","executeToolPipeline","t8","rafId","requestAnimationFrame","cancelAnimationFrame","t9","children","resolveConfig","baseConfig","mergeWidgetConfig","options","deepmerge","arrayMerge","_","source"],"mappings":"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"}