@carto/ps-react-ui 4.5.0 → 4.6.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.
Files changed (99) hide show
  1. package/dist/{download-config-DemuQ3Jm.js → download-config-C3I0jWIL.js} +2 -2
  2. package/dist/{download-config-DemuQ3Jm.js.map → download-config-C3I0jWIL.js.map} +1 -1
  3. package/dist/{row-D4VOhcNI.js → row-DZSP99LW.js} +2 -2
  4. package/dist/{row-D4VOhcNI.js.map → row-DZSP99LW.js.map} +1 -1
  5. package/dist/{series-Bola3CmD.js → series-DLNHDWs0.js} +3 -3
  6. package/dist/{series-Bola3CmD.js.map → series-DLNHDWs0.js.map} +1 -1
  7. package/dist/types/hooks/index.d.ts +0 -1
  8. package/dist/types/widgets/actions/brush-toggle/brush-toggle.d.ts +3 -0
  9. package/dist/types/widgets/actions/index.d.ts +4 -4
  10. package/dist/types/widgets/actions/lock-selection/types.d.ts +2 -0
  11. package/dist/types/widgets/actions/relative-data/relative-data.d.ts +7 -2
  12. package/dist/types/widgets/actions/relative-data/types.d.ts +2 -0
  13. package/dist/types/widgets/actions/zoom-toggle/zoom-toggle.d.ts +4 -0
  14. package/dist/types/widgets/category/index.d.ts +10 -2
  15. package/dist/types/widgets/category/style.d.ts +1 -0
  16. package/dist/types/widgets/no-data/no-data.d.ts +3 -2
  17. package/dist/types/widgets/no-data/types.d.ts +5 -1
  18. package/dist/types/widgets/stores/index.d.ts +1 -1
  19. package/dist/types/widgets/stores/types.d.ts +10 -10
  20. package/dist/types/widgets/stores/widget-store.d.ts +2 -3
  21. package/dist/types/widgets/table/index.d.ts +6 -2
  22. package/dist/{use-widget-ref-BFazQvJK.js → use-widget-ref-Ddr_SlJJ.js} +2 -2
  23. package/dist/{use-widget-ref-BFazQvJK.js.map → use-widget-ref-Ddr_SlJJ.js.map} +1 -1
  24. package/dist/{use-widget-selector-DqRmWQ1K.js → use-widget-selector-DFl2hW0R.js} +2 -2
  25. package/dist/{use-widget-selector-DqRmWQ1K.js.map → use-widget-selector-DFl2hW0R.js.map} +1 -1
  26. package/dist/{widget-store-CIrb9RKP.js → widget-store-Bw5zRUGg.js} +93 -95
  27. package/dist/widget-store-Bw5zRUGg.js.map +1 -0
  28. package/dist/widgets/actions.js +770 -755
  29. package/dist/widgets/actions.js.map +1 -1
  30. package/dist/widgets/bar.js +2 -2
  31. package/dist/widgets/category.js +187 -183
  32. package/dist/widgets/category.js.map +1 -1
  33. package/dist/widgets/echart.js +2 -2
  34. package/dist/widgets/error.js +37 -2
  35. package/dist/widgets/error.js.map +1 -1
  36. package/dist/widgets/formula.js +5 -5
  37. package/dist/widgets/histogram.js +1 -1
  38. package/dist/widgets/loader.js +1 -1
  39. package/dist/widgets/markdown.js +2 -2
  40. package/dist/widgets/no-data.js +58 -2
  41. package/dist/widgets/no-data.js.map +1 -1
  42. package/dist/widgets/note.js +121 -2
  43. package/dist/widgets/note.js.map +1 -1
  44. package/dist/widgets/pie.js +2 -2
  45. package/dist/widgets/range.js +3 -3
  46. package/dist/widgets/scatterplot.js +2 -2
  47. package/dist/widgets/skeleton-loader.js +1 -1
  48. package/dist/widgets/spread.js +5 -5
  49. package/dist/widgets/stores.js +2 -2
  50. package/dist/widgets/subheader.js +29 -29
  51. package/dist/widgets/subheader.js.map +1 -1
  52. package/dist/widgets/table.js +3 -3
  53. package/dist/widgets/timeseries.js +2 -2
  54. package/dist/widgets/utils.js +1 -1
  55. package/dist/widgets/wrapper.js +2 -2
  56. package/package.json +1 -5
  57. package/src/hooks/index.ts +0 -1
  58. package/src/widgets/actions/brush-toggle/brush-toggle.tsx +18 -22
  59. package/src/widgets/actions/change-column/change-column.test.tsx +1 -1
  60. package/src/widgets/actions/download/download.test.tsx +1 -1
  61. package/src/widgets/actions/index.ts +11 -2
  62. package/src/widgets/actions/lock-selection/lock-selection.test.tsx +14 -0
  63. package/src/widgets/actions/lock-selection/lock-selection.tsx +18 -11
  64. package/src/widgets/actions/lock-selection/types.ts +2 -0
  65. package/src/widgets/actions/relative-data/relative-data.test.tsx +211 -20
  66. package/src/widgets/actions/relative-data/relative-data.tsx +65 -34
  67. package/src/widgets/actions/relative-data/types.ts +2 -0
  68. package/src/widgets/actions/searcher/searcher.tsx +28 -30
  69. package/src/widgets/actions/stack-toggle/stack-toggle.tsx +11 -2
  70. package/src/widgets/actions/zoom-toggle/zoom-toggle.tsx +53 -45
  71. package/src/widgets/category/category-ui.tsx +7 -6
  72. package/src/widgets/category/index.ts +13 -14
  73. package/src/widgets/category/style.ts +1 -0
  74. package/src/widgets/no-data/no-data.test.tsx +90 -40
  75. package/src/widgets/no-data/no-data.tsx +7 -5
  76. package/src/widgets/no-data/types.ts +5 -1
  77. package/src/widgets/stores/index.ts +2 -0
  78. package/src/widgets/stores/types.ts +10 -18
  79. package/src/widgets/stores/widget-store.test.ts +132 -13
  80. package/src/widgets/stores/widget-store.ts +29 -35
  81. package/src/widgets/subheader/subheader.tsx +11 -3
  82. package/src/widgets/table/index.ts +6 -4
  83. package/dist/error-Cj8eUMrl.js +0 -40
  84. package/dist/error-Cj8eUMrl.js.map +0 -1
  85. package/dist/no-data-DkIt7Qt1.js +0 -61
  86. package/dist/no-data-DkIt7Qt1.js.map +0 -1
  87. package/dist/note-t51drNe0.js +0 -124
  88. package/dist/note-t51drNe0.js.map +0 -1
  89. package/dist/types/hooks/use-debounce.d.ts +0 -19
  90. package/dist/types/widgets/category/components/index.d.ts +0 -10
  91. package/dist/types/widgets/index.d.ts +0 -9
  92. package/dist/types/widgets/table/hooks/index.d.ts +0 -6
  93. package/dist/widget-store-CIrb9RKP.js.map +0 -1
  94. package/dist/widgets.js +0 -13
  95. package/dist/widgets.js.map +0 -1
  96. package/src/hooks/use-debounce.ts +0 -55
  97. package/src/widgets/category/components/index.ts +0 -14
  98. package/src/widgets/index.ts +0 -25
  99. package/src/widgets/table/hooks/index.ts +0 -7
@@ -1,5 +1,5 @@
1
- import { u as o, w as r } from "../widget-store-CIrb9RKP.js";
2
- import { u as i } from "../use-widget-selector-DqRmWQ1K.js";
1
+ import { u as o, w as r } from "../widget-store-Bw5zRUGg.js";
2
+ import { u as i } from "../use-widget-selector-DFl2hW0R.js";
3
3
  export {
4
4
  i as useWidgetSelector,
5
5
  o as useWidgetStore,
@@ -1,16 +1,16 @@
1
- import { jsx as g, jsxs as m } from "react/jsx-runtime";
2
- import { c as d } from "react/compiler-runtime";
3
- import { Box as x } from "@mui/material";
4
- const c = {
1
+ import { jsx as c, jsxs as g } from "react/jsx-runtime";
2
+ import { c as x } from "react/compiler-runtime";
3
+ import { Box as a } from "@mui/material";
4
+ const d = {
5
5
  root: {
6
6
  display: "flex",
7
7
  alignItems: "center",
8
8
  gap: ({
9
- spacing: e
10
- }) => e(1),
9
+ spacing: t
10
+ }) => t(1),
11
11
  minHeight: ({
12
- spacing: e
13
- }) => e(3)
12
+ spacing: t
13
+ }) => t(3)
14
14
  },
15
15
  slotLeft: {
16
16
  flexShrink: 0
@@ -21,30 +21,30 @@ const c = {
21
21
  justifyContent: "flex-end",
22
22
  alignItems: "center",
23
23
  gap: ({
24
- spacing: e
25
- }) => e(1)
24
+ spacing: t
25
+ }) => t(1)
26
26
  }
27
27
  };
28
- function u(e) {
29
- const t = d(10), {
30
- slotLeft: i,
31
- slotRight: n,
32
- sx: f
33
- } = e;
34
- let l;
35
- t[0] !== f ? (l = {
36
- ...c.root,
37
- ...f
38
- }, t[0] = f, t[1] = l) : l = t[1];
28
+ function u(t) {
29
+ const e = x(10), {
30
+ slotLeft: o,
31
+ slotRight: r,
32
+ sx: n
33
+ } = t;
39
34
  let s;
40
- t[2] !== i ? (s = i && /* @__PURE__ */ g(x, { sx: c.slotLeft, children: i }), t[2] = i, t[3] = s) : s = t[3];
41
- let o;
42
- t[4] !== n ? (o = /* @__PURE__ */ g(x, { sx: c.slotRight, children: n }), t[4] = n, t[5] = o) : o = t[5];
43
- let r;
44
- return t[6] !== l || t[7] !== s || t[8] !== o ? (r = /* @__PURE__ */ m(x, { sx: l, children: [
45
- s,
46
- o
47
- ] }), t[6] = l, t[7] = s, t[8] = o, t[9] = r) : r = t[9], r;
35
+ e[0] !== n ? (s = {
36
+ ...d.root,
37
+ ...n
38
+ }, e[0] = n, e[1] = s) : s = e[1];
39
+ let l;
40
+ e[2] !== o ? (l = o && /* @__PURE__ */ c(a, { sx: d.slotLeft, className: "widget-subheader-slot-left", children: o }), e[2] = o, e[3] = l) : l = e[3];
41
+ let i;
42
+ e[4] !== r ? (i = r && /* @__PURE__ */ c(a, { sx: d.slotRight, className: "widget-subheader-slot-right", children: r }), e[4] = r, e[5] = i) : i = e[5];
43
+ let f;
44
+ return e[6] !== s || e[7] !== l || e[8] !== i ? (f = /* @__PURE__ */ g(a, { sx: s, className: "widget-subheader", children: [
45
+ l,
46
+ i
47
+ ] }), e[6] = s, e[7] = l, e[8] = i, e[9] = f) : f = e[9], f;
48
48
  }
49
49
  export {
50
50
  u as WidgetSubHeader
@@ -1 +1 @@
1
- {"version":3,"file":"subheader.js","sources":["../../src/widgets/subheader/style.ts","../../src/widgets/subheader/subheader.tsx"],"sourcesContent":["import type { SxProps, Theme } from '@mui/material'\n\nexport const styles = {\n root: {\n display: 'flex',\n alignItems: 'center',\n gap: ({ spacing }) => spacing(1),\n minHeight: ({ spacing }) => spacing(3),\n },\n slotLeft: {\n flexShrink: 0,\n },\n slotRight: {\n flexGrow: 1,\n display: 'flex',\n justifyContent: 'flex-end',\n alignItems: 'center',\n gap: ({ spacing }) => spacing(1),\n },\n} satisfies Record<string, SxProps<Theme>>\n","import { Box } from '@mui/material'\nimport { styles } from './style'\nimport type { WidgetSubHeaderProps } from './types'\n\n/**\n * Flexible two-slot layout for displaying supplementary widget information such as totals, timestamps, or controls. Uses flexbox with space-between justification.\n *\n * @example\n * ```tsx\n * <WidgetSubHeader\n * slotLeft={<Typography variant=\"caption\">Total: 1,234</Typography>}\n * slotRight={<Typography variant=\"caption\">Updated: 2m ago</Typography>}\n * />\n * ```\n */\nexport function WidgetSubHeader({\n slotLeft,\n slotRight,\n sx,\n}: WidgetSubHeaderProps) {\n return (\n <Box sx={{ ...styles.root, ...sx }}>\n {slotLeft && <Box sx={styles.slotLeft}>{slotLeft}</Box>}\n <Box sx={styles.slotRight}>{slotRight}</Box>\n </Box>\n )\n}\n"],"names":["styles","root","display","alignItems","gap","spacing","minHeight","slotLeft","flexShrink","slotRight","flexGrow","justifyContent","WidgetSubHeader","t0","$","_c","sx","t1","t2","jsx","Box","t3","t4"],"mappings":";;;AAEO,MAAMA,IAAS;AAAA,EACpBC,MAAM;AAAA,IACJC,SAAS;AAAA,IACTC,YAAY;AAAA,IACZC,KAAKA,CAAC;AAAA,MAAEC,SAAAA;AAAAA,IAAAA,MAAcA,EAAQ,CAAC;AAAA,IAC/BC,WAAWA,CAAC;AAAA,MAAED,SAAAA;AAAAA,IAAAA,MAAcA,EAAQ,CAAC;AAAA,EAAA;AAAA,EAEvCE,UAAU;AAAA,IACRC,YAAY;AAAA,EAAA;AAAA,EAEdC,WAAW;AAAA,IACTC,UAAU;AAAA,IACVR,SAAS;AAAA,IACTS,gBAAgB;AAAA,IAChBR,YAAY;AAAA,IACZC,KAAKA,CAAC;AAAA,MAAEC,SAAAA;AAAAA,IAAAA,MAAcA,EAAQ,CAAC;AAAA,EAAA;AAEnC;ACJO,SAAAO,EAAAC,GAAA;AAAA,QAAAC,IAAAC,EAAA,EAAA,GAAyB;AAAA,IAAAR,UAAAA;AAAAA,IAAAE,WAAAA;AAAAA,IAAAO,IAAAA;AAAAA,EAAAA,IAAAH;AAIT,MAAAI;AAAA,EAAAH,SAAAE,KAEVC,IAAA;AAAA,IAAA,GAAKjB,EAAMC;AAAAA,IAAK,GAAKe;AAAAA,EAAAA,GAAIF,OAAAE,GAAAF,OAAAG,KAAAA,IAAAH,EAAA,CAAA;AAAA,MAAAI;AAAA,EAAAJ,SAAAP,KAC/BW,IAAAX,KAAY,gBAAAY,EAACC,GAAA,EAAQ,IAAApB,EAAMO,uBAAqB,GAAMO,OAAAP,GAAAO,OAAAI,KAAAA,IAAAJ,EAAA,CAAA;AAAA,MAAAO;AAAA,EAAAP,SAAAL,KACvDY,IAAA,gBAAAF,EAACC,GAAA,EAAQ,IAAApB,EAAMS,WAAaA,UAAAA,GAAU,GAAMK,OAAAL,GAAAK,OAAAO,KAAAA,IAAAP,EAAA,CAAA;AAAA,MAAAQ;AAAA,SAAAR,EAAA,CAAA,MAAAG,KAAAH,SAAAI,KAAAJ,EAAA,CAAA,MAAAO,KAF9CC,sBAACF,GAAA,EAAQ,IAAAH,GACNC,UAAAA;AAAAA,IAAAA;AAAAA,IACDG;AAAAA,EAAAA,GACF,GAAMP,OAAAG,GAAAH,OAAAI,GAAAJ,OAAAO,GAAAP,OAAAQ,KAAAA,IAAAR,EAAA,CAAA,GAHNQ;AAGM;"}
1
+ {"version":3,"file":"subheader.js","sources":["../../src/widgets/subheader/style.ts","../../src/widgets/subheader/subheader.tsx"],"sourcesContent":["import type { SxProps, Theme } from '@mui/material'\n\nexport const styles = {\n root: {\n display: 'flex',\n alignItems: 'center',\n gap: ({ spacing }) => spacing(1),\n minHeight: ({ spacing }) => spacing(3),\n },\n slotLeft: {\n flexShrink: 0,\n },\n slotRight: {\n flexGrow: 1,\n display: 'flex',\n justifyContent: 'flex-end',\n alignItems: 'center',\n gap: ({ spacing }) => spacing(1),\n },\n} satisfies Record<string, SxProps<Theme>>\n","import { Box } from '@mui/material'\nimport { styles } from './style'\nimport type { WidgetSubHeaderProps } from './types'\n\n/**\n * Flexible two-slot layout for displaying supplementary widget information such as totals, timestamps, or controls. Uses flexbox with space-between justification.\n *\n * @example\n * ```tsx\n * <WidgetSubHeader\n * slotLeft={<Typography variant=\"caption\">Total: 1,234</Typography>}\n * slotRight={<Typography variant=\"caption\">Updated: 2m ago</Typography>}\n * />\n * ```\n */\nexport function WidgetSubHeader({\n slotLeft,\n slotRight,\n sx,\n}: WidgetSubHeaderProps) {\n return (\n <Box sx={{ ...styles.root, ...sx }} className='widget-subheader'>\n {slotLeft && (\n <Box sx={styles.slotLeft} className='widget-subheader-slot-left'>\n {slotLeft}\n </Box>\n )}\n {slotRight && (\n <Box sx={styles.slotRight} className='widget-subheader-slot-right'>\n {slotRight}\n </Box>\n )}\n </Box>\n )\n}\n"],"names":["styles","root","display","alignItems","gap","spacing","minHeight","slotLeft","flexShrink","slotRight","flexGrow","justifyContent","WidgetSubHeader","t0","$","_c","sx","t1","t2","Box","t3","t4","jsxs"],"mappings":";;;AAEO,MAAMA,IAAS;AAAA,EACpBC,MAAM;AAAA,IACJC,SAAS;AAAA,IACTC,YAAY;AAAA,IACZC,KAAKA,CAAC;AAAA,MAAEC,SAAAA;AAAAA,IAAAA,MAAcA,EAAQ,CAAC;AAAA,IAC/BC,WAAWA,CAAC;AAAA,MAAED,SAAAA;AAAAA,IAAAA,MAAcA,EAAQ,CAAC;AAAA,EAAA;AAAA,EAEvCE,UAAU;AAAA,IACRC,YAAY;AAAA,EAAA;AAAA,EAEdC,WAAW;AAAA,IACTC,UAAU;AAAA,IACVR,SAAS;AAAA,IACTS,gBAAgB;AAAA,IAChBR,YAAY;AAAA,IACZC,KAAKA,CAAC;AAAA,MAAEC,SAAAA;AAAAA,IAAAA,MAAcA,EAAQ,CAAC;AAAA,EAAA;AAEnC;ACJO,SAAAO,EAAAC,GAAA;AAAA,QAAAC,IAAAC,EAAA,EAAA,GAAyB;AAAA,IAAAR,UAAAA;AAAAA,IAAAE,WAAAA;AAAAA,IAAAO,IAAAA;AAAAA,EAAAA,IAAAH;AAIT,MAAAI;AAAA,EAAAH,SAAAE,KAEVC,IAAA;AAAA,IAAA,GAAKjB,EAAMC;AAAAA,IAAK,GAAKe;AAAAA,EAAAA,GAAIF,OAAAE,GAAAF,OAAAG,KAAAA,IAAAH,EAAA,CAAA;AAAA,MAAAI;AAAA,EAAAJ,SAAAP,KAC/BW,IAAAX,uBACEY,GAAA,EAAQ,IAAAnB,EAAMO,UAAqB,WAAA,8BACjCA,UAAAA,EAAAA,CACH,GACDO,OAAAP,GAAAO,OAAAI,KAAAA,IAAAJ,EAAA,CAAA;AAAA,MAAAM;AAAA,EAAAN,SAAAL,KACAW,IAAAX,uBACEU,GAAA,EAAQ,IAAAnB,EAAMS,WAAsB,WAAA,+BAClCA,UAAAA,EAAAA,CACH,GACDK,OAAAL,GAAAK,OAAAM,KAAAA,IAAAN,EAAA,CAAA;AAAA,MAAAO;AAAA,SAAAP,EAAA,CAAA,MAAAG,KAAAH,SAAAI,KAAAJ,EAAA,CAAA,MAAAM,KAVHC,IAAA,gBAAAC,EAACH,GAAA,EAAQ,IAAAF,GAAqC,WAAA,oBAC3CC,UAAAA;AAAAA,IAAAA;AAAAA,IAKAE;AAAAA,EAAAA,GAKH,GAAMN,OAAAG,GAAAH,OAAAI,GAAAJ,OAAAM,GAAAN,OAAAO,KAAAA,IAAAP,EAAA,CAAA,GAXNO;AAWM;"}
@@ -6,10 +6,10 @@ import se from "@mui/icons-material/FirstPage";
6
6
  import ce from "@mui/icons-material/KeyboardArrowLeft";
7
7
  import ae from "@mui/icons-material/KeyboardArrowRight";
8
8
  import fe from "@mui/icons-material/LastPage";
9
+ import { u as de } from "../use-widget-ref-Ddr_SlJJ.js";
9
10
  import "react";
10
- import { u as de } from "../use-widget-ref-BFazQvJK.js";
11
- import { w as x } from "../widget-store-CIrb9RKP.js";
12
- import { u as B } from "../use-widget-selector-DqRmWQ1K.js";
11
+ import { w as x } from "../widget-store-Bw5zRUGg.js";
12
+ import { u as B } from "../use-widget-selector-DFl2hW0R.js";
13
13
  import "zustand/shallow";
14
14
  import "@mui/icons-material";
15
15
  import { d as J, a as F } from "../exports-Cr43OCul.js";
@@ -2,11 +2,11 @@ import { jsxs as m, jsx as r } from "react/jsx-runtime";
2
2
  import { c as y } from "react/compiler-runtime";
3
3
  import "react";
4
4
  import "echarts";
5
- import "../widget-store-CIrb9RKP.js";
5
+ import "../widget-store-Bw5zRUGg.js";
6
6
  import "zustand/shallow";
7
7
  import { g as b } from "../options-D9wflre6.js";
8
8
  import { m as k } from "../utils-BOhInag6.js";
9
- import { c as v, f as w } from "../download-config-DemuQ3Jm.js";
9
+ import { c as v, f as w } from "../download-config-C3I0jWIL.js";
10
10
  import { g as L, b as C, a as I, d as S, e as _, c as A } from "../styles-Y8q7Jff3.js";
11
11
  import { Box as l, Skeleton as s } from "@mui/material";
12
12
  const Y = v(w);
@@ -1,5 +1,5 @@
1
1
  import { d as i, a as n } from "../formatter-B9Bxn1k7.js";
2
- import { c as f, f as p, s as c } from "../download-config-DemuQ3Jm.js";
2
+ import { c as f, f as p, s as c } from "../download-config-C3I0jWIL.js";
3
3
  import { a as m, b as u, c as C, d as b, e as x, f as g, g as F, h as y, n as A } from "../styles-Y8q7Jff3.js";
4
4
  function r({
5
5
  type: a,
@@ -6,8 +6,8 @@ import { useState as H, useLayoutEffect as G } from "react";
6
6
  import "../lasso-tool-BYbxrJ-7.js";
7
7
  import "../cjs-D4KH3azB.js";
8
8
  import { S as U } from "../smart-tooltip-D4vwQpFf.js";
9
- import { u as V } from "../use-widget-selector-DqRmWQ1K.js";
10
- import { w as M } from "../widget-store-CIrb9RKP.js";
9
+ import { u as V } from "../use-widget-selector-DFl2hW0R.js";
10
+ import { w as M } from "../widget-store-Bw5zRUGg.js";
11
11
  const k = {
12
12
  root: {
13
13
  ".Mui-disabled .MuiAccordionSummary-expandIconWrapper": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carto/ps-react-ui",
3
- "version": "4.5.0",
3
+ "version": "4.6.0",
4
4
  "description": "CARTO's Professional Service React Material library",
5
5
  "type": "module",
6
6
  "devDependencies": {
@@ -38,10 +38,6 @@
38
38
  "import": "./dist/components.js",
39
39
  "types": "./dist/types/components/index.d.ts"
40
40
  },
41
- "./widgets": {
42
- "import": "./dist/widgets.js",
43
- "types": "./dist/types/widgets/index.d.ts"
44
- },
45
41
  "./widgets/actions": {
46
42
  "import": "./dist/widgets/actions.js",
47
43
  "types": "./dist/types/widgets/actions/index.d.ts"
@@ -1,2 +1 @@
1
- export { useDebounce } from './use-debounce'
2
1
  export { useWidgetRef } from './use-widget-ref'
@@ -2,7 +2,7 @@ import { Box, IconButton } from '@mui/material'
2
2
  import { HighlightAltOutlined } from '@mui/icons-material'
3
3
  import { useEffect, useCallback, useRef } from 'react'
4
4
  import { widgetStoreActions } from '../../stores/widget-store'
5
- import type { BrushSelectedItems, BrushToggleProps } from './types'
5
+ import type { BrushSelectedItems, BrushToggleProps, BrushState } from './types'
6
6
  import { styles } from './style'
7
7
  import { Tooltip } from '../../../components'
8
8
  import { getEChartBrushConfig } from '../../echart/utils'
@@ -17,6 +17,9 @@ export const BRUSH_TOGGLE_TOOL_ID = 'brush-toggle'
17
17
  * Registers as a config pipeline tool so that brush configuration is automatically
18
18
  * re-applied when the base config is updated (e.g., by WidgetLoader).
19
19
  *
20
+ * Brush state is stored in the widget store root, and the tool derives its
21
+ * `enabled` flag from the store. This keeps state accessible across component instances.
22
+ *
20
23
  * When brush is active, users can drag across bars to select a range.
21
24
  * Selection clearing is handled via the chart's brush interactions/toolbox configuration.
22
25
  * Only intended for use in fullscreen ToolbarActions for bar and histogram widgets.
@@ -38,26 +41,19 @@ export function BrushToggle({
38
41
  }: BrushToggleProps) {
39
42
  const selected = useRef<BrushSelectedItems>({ dataIndex: [], seriesIndex: 0 })
40
43
 
44
+ // Read brush state from widget store root — single source of truth
41
45
  const { brush } = useWidgetSelector(id, (w) => ({
42
- brush: w?.registeredTools?.find((tool) => tool.id === BRUSH_TOGGLE_TOOL_ID)
43
- ?.enabled,
46
+ brush: (w as BrushState | undefined)?.brush ?? false,
44
47
  }))
45
48
 
46
- const toggleTool = useCallback(
47
- (value: boolean) => {
48
- widgetStoreActions.setToolEnabled(id, BRUSH_TOGGLE_TOOL_ID, value)
49
- },
50
- [id],
51
- )
52
-
53
49
  const handleToggle = useCallback(() => {
54
50
  const newBrush = !brush
55
- toggleTool(newBrush)
51
+ widgetStoreActions.setWidget(id, { brush: newBrush })
56
52
 
57
53
  if (newBrush) {
58
54
  onBrushSelected?.({ dataIndex: [], seriesIndex: 0 }) // Clear selection when enabling brush
59
55
  }
60
- }, [brush, onBrushSelected, toggleTool])
56
+ }, [brush, id, onBrushSelected])
61
57
 
62
58
  // Re-dispatch brush action after every ECharts render while brush is active
63
59
  useEffect(() => {
@@ -135,22 +131,17 @@ export function BrushToggle({
135
131
 
136
132
  const handleBrushEnd = useCallback(() => {
137
133
  onBrushSelected?.(selected.current)
138
- toggleTool(false) // Disable brush after selection is made
139
- }, [onBrushSelected, toggleTool])
134
+ widgetStoreActions.setWidget(id, { brush: false }) // Disable brush after selection is made
135
+ }, [onBrushSelected, id])
140
136
 
141
- // Register config tool with all reactive deps store's no-op detection handles performance
137
+ // Register config tool once fn closure depends on event handlers.
138
+ // Enabled is synced separately to avoid full re-registration on toggle.
142
139
  useEffect(() => {
143
- const existingTool = widgetStoreActions
144
- .getWidget(id)
145
- ?.registeredTools?.find((tool) => tool.id === BRUSH_TOGGLE_TOOL_ID)
146
-
147
- const initialEnabled = existingTool?.enabled ?? false
148
-
149
140
  widgetStoreActions.registerTool(id, {
150
141
  id: BRUSH_TOGGLE_TOOL_ID,
151
142
  type: 'config',
152
143
  order: 25,
153
- enabled: initialEnabled,
144
+ enabled: false,
154
145
  fn: (currentConfig) => {
155
146
  const config = currentConfig as Record<string, unknown>
156
147
  const option = config.option as EchartOptionsProps | undefined
@@ -178,6 +169,11 @@ export function BrushToggle({
178
169
  return () => widgetStoreActions.unregisterTool(id, BRUSH_TOGGLE_TOOL_ID)
179
170
  }, [id, handleBrushSelected, handleBrushEnd])
180
171
 
172
+ // Sync enabled from store — lightweight, no re-registration
173
+ useEffect(() => {
174
+ widgetStoreActions.setToolEnabled(id, BRUSH_TOGGLE_TOOL_ID, brush)
175
+ }, [id, brush])
176
+
181
177
  const enableLabel = labels?.enable ?? 'Enable brush selection'
182
178
  const disableLabel = labels?.disable ?? 'Disable brush selection'
183
179
  const tooltipLabel = brush ? disableLabel : enableLabel
@@ -217,7 +217,7 @@ describe('ChangeColumn', () => {
217
217
 
218
218
  // When config columns match widget columns, fn returns the same reference
219
219
  const input = { columns: mockColumns }
220
- const result = tool?.fn(input, tool.config)
220
+ const result = tool?.fn(input)
221
221
  expect(result).toBe(input)
222
222
  })
223
223
 
@@ -1,7 +1,7 @@
1
1
  import { describe, test, expect, beforeEach, vi } from 'vitest'
2
2
  import { render, screen, fireEvent, waitFor } from '@testing-library/react'
3
3
  import { Download } from './download'
4
- import { useWidgetStore } from '../../../widgets'
4
+ import { useWidgetStore } from '../../../widgets/stores'
5
5
  import type { DownloadItem } from './types'
6
6
 
7
7
  describe('Download', () => {
@@ -1,6 +1,10 @@
1
1
  /* Fullscreen Widget */
2
2
  export { FullScreen } from './fullscreen/fullscreen'
3
- export type { FullScreenState, FullScreenConfig } from './fullscreen/types'
3
+ export type {
4
+ FullScreenState,
5
+ FullScreenConfig,
6
+ FullScreenProps,
7
+ } from './fullscreen/types'
4
8
 
5
9
  /* Download Widget */
6
10
  export { Download } from './download/download'
@@ -13,7 +17,10 @@ export {
13
17
  RELATIVE_DATA_TOOL_ID,
14
18
  RELATIVE_DATA_CONFIG_TOOL_ID,
15
19
  } from './relative-data/relative-data'
16
- export type { RelativeDataProps } from './relative-data/types'
20
+ export type {
21
+ RelativeDataProps,
22
+ RelativeDataState,
23
+ } from './relative-data/types'
17
24
 
18
25
  /* Zoom Toggle Widget */
19
26
  export { ZoomToggle, ZOOM_TOGGLE_TOOL_ID } from './zoom-toggle/zoom-toggle'
@@ -35,6 +42,7 @@ export type {
35
42
  SearcherProps,
36
43
  SearcherFilterFn,
37
44
  SearcherState,
45
+ SearcherStateProps,
38
46
  } from './searcher/types'
39
47
 
40
48
  /* Change Column Widget */
@@ -52,6 +60,7 @@ export {
52
60
  export type {
53
61
  LockSelectionProps,
54
62
  LockSelectionState,
63
+ LockSelectionStateProps,
55
64
  } from './lock-selection/types'
56
65
 
57
66
  /* Brush Toggle Widget */
@@ -3,6 +3,7 @@ import { render, screen, fireEvent } from '@testing-library/react'
3
3
  import { LockSelection, LOCK_SELECTION_TOOL_ID } from './lock-selection'
4
4
  import { useWidgetStore } from '../../stores/widget-store'
5
5
  import type { EchartWidgetData } from '../../echart/types'
6
+ import type { LockSelectionState } from './types'
6
7
  import { WidgetLoader } from '../../loader/loader'
7
8
 
8
9
  // Test data
@@ -110,6 +111,19 @@ describe('LockSelection', () => {
110
111
  expect(tool?.enabled).toBe(false)
111
112
  })
112
113
 
114
+ test('clears lock state when selectedItems becomes empty while locked', () => {
115
+ // Simulate remount: isLocked persists in store but selectedItems is now empty
116
+ useWidgetStore
117
+ .getState()
118
+ .setWidget(widgetId, { isLocked: true, lockedItems: ['Electronics'] })
119
+
120
+ render(<LockSelection id={widgetId} selectedItems={[]} />)
121
+
122
+ const widget = useWidgetStore.getState().getWidget(widgetId)
123
+ expect((widget as LockSelectionState | undefined)?.isLocked).toBe(false)
124
+ expect((widget as LockSelectionState | undefined)?.lockedItems).toEqual([])
125
+ })
126
+
113
127
  test('has active state when locked', () => {
114
128
  render(<LockSelection id={widgetId} selectedItems={['Electronics']} />)
115
129
 
@@ -1,6 +1,6 @@
1
1
  import { IconButton } from '@mui/material'
2
2
  import { CheckBoxOutlined } from '@mui/icons-material'
3
- import { useCallback, useEffect, useMemo } from 'react'
3
+ import { useCallback, useEffect } from 'react'
4
4
  import type { LockSelectionProps, LockSelectionState } from './types'
5
5
  import { actionButtonStyles } from '../shared/styles'
6
6
  import { Tooltip } from '../../../components'
@@ -39,28 +39,35 @@ export function LockSelection({
39
39
  }))
40
40
 
41
41
  const isLocked = storeIsLocked ?? false
42
- const lockedItems = useMemo(
43
- () => (isLocked ? selectedItems : []),
44
- [isLocked, selectedItems],
45
- )
46
42
 
47
- // Register tool with all reactive deps store's no-op detection handles performance
43
+ // Register tool once fn reads lockedItems from the store at execution time
48
44
  useEffect(() => {
49
45
  widgetStoreActions.registerTool(id, {
50
46
  id: LOCK_SELECTION_TOOL_ID,
51
47
  order,
52
- enabled: isLocked,
53
- fn: (data, config) => {
54
- const items = (config?.lockedItems as string[]) || []
48
+ enabled: false,
49
+ fn: (data) => {
50
+ const widget = widgetStoreActions.getWidget<LockSelectionState>(id)
51
+ const items = widget?.lockedItems ?? []
55
52
  if (items.length === 0) return data
56
53
 
57
54
  return filterDataByLockedItems(data as EchartWidgetData, items)
58
55
  },
59
- config: { lockedItems },
60
56
  })
61
57
 
62
58
  return () => widgetStoreActions.unregisterTool(id, LOCK_SELECTION_TOOL_ID)
63
- }, [id, order, isLocked, lockedItems])
59
+ }, [id, order])
60
+
61
+ // Sync enabled from store — lightweight, no re-registration.
62
+ // When selectedItems is empty (e.g., remount with no active selection),
63
+ // disable the tool and clear stale lock state.
64
+ useEffect(() => {
65
+ if (isLocked && selectedItems.length === 0) {
66
+ widgetStoreActions.setWidget(id, { isLocked: false, lockedItems: [] })
67
+ return
68
+ }
69
+ widgetStoreActions.setToolEnabled(id, LOCK_SELECTION_TOOL_ID, isLocked)
70
+ }, [id, isLocked, selectedItems.length])
64
71
 
65
72
  const handleToggle = useCallback(() => {
66
73
  if (isLocked) {
@@ -38,4 +38,6 @@ export interface LockSelectionProps {
38
38
  export interface LockSelectionStateProps {
39
39
  /** Whether the selection is currently locked */
40
40
  isLocked?: boolean
41
+ /** Items locked for filtering */
42
+ lockedItems?: string[]
41
43
  }