@carto/ps-react-ui 5.0.0-widgets.2 → 5.0.0-widgets.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{error-zHOU_QIB.js → error-DGzuzmn1.js} +3 -3
- package/dist/error-DGzuzmn1.js.map +1 -0
- package/dist/{no-data-Cz80hEWj.js → no-data-BBAoT1vK.js} +16 -16
- package/dist/no-data-BBAoT1vK.js.map +1 -0
- package/dist/types/widgets/error/error.d.ts +2 -2
- package/dist/types/widgets/error/index.d.ts +2 -2
- package/dist/types/widgets/error/types.d.ts +1 -1
- package/dist/types/widgets/index.d.ts +4 -4
- package/dist/types/widgets/no-data/index.d.ts +2 -2
- package/dist/types/widgets/no-data/no-data.d.ts +2 -2
- package/dist/types/widgets/no-data/types.d.ts +8 -8
- package/dist/types/widgets/root/index.d.ts +2 -2
- package/dist/types/widgets/root/root.d.ts +2 -2
- package/dist/types/widgets/root/types.d.ts +1 -1
- package/dist/widgets/error.js +2 -2
- package/dist/widgets/no-data.js +2 -2
- package/dist/widgets/root.js +6 -6
- package/dist/widgets/root.js.map +1 -1
- package/dist/widgets.js +4 -4
- package/package.json +1 -1
- package/dist/error-zHOU_QIB.js.map +0 -1
- package/dist/no-data-Cz80hEWj.js.map +0 -1
|
@@ -3,7 +3,7 @@ import { c as f } from "react/compiler-runtime";
|
|
|
3
3
|
import { AlertTitle as m, Alert as h } from "@mui/material";
|
|
4
4
|
import { u } from "./widget-store-DNyVElxd.js";
|
|
5
5
|
import { useShallow as p } from "zustand/shallow";
|
|
6
|
-
function
|
|
6
|
+
function W(g) {
|
|
7
7
|
const r = f(7), {
|
|
8
8
|
id: l,
|
|
9
9
|
children: c
|
|
@@ -33,6 +33,6 @@ function L(g) {
|
|
|
33
33
|
return c;
|
|
34
34
|
}
|
|
35
35
|
export {
|
|
36
|
-
|
|
36
|
+
W
|
|
37
37
|
};
|
|
38
|
-
//# sourceMappingURL=error-
|
|
38
|
+
//# sourceMappingURL=error-DGzuzmn1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-DGzuzmn1.js","sources":["../src/widgets/error/error.tsx"],"sourcesContent":["import { Alert, AlertTitle } from '@mui/material'\nimport { useWidgetStore } from '../stores/widget-store'\nimport { useShallow } from 'zustand/shallow'\nimport type { WidgetErrorProps } from './types'\n\nexport function WidgetError({ id, children }: WidgetErrorProps) {\n const widget = useWidgetStore(\n useShallow((state) => {\n const w = state.widgets[id]\n return {\n isLoading: w?.isLoading,\n isFetching: w?.isFetching,\n error: w?.error,\n }\n }),\n )\n\n // Don't show error during loading/fetching states\n if (widget?.isLoading || widget?.isFetching) {\n return children\n }\n\n // Show error UI if error exists\n if (widget?.error) {\n const errorTitle = widget.error.title ?? 'Error'\n const errorMessage =\n widget.error.message ??\n 'An error occurred while loading the widget. Please try again.'\n\n return (\n <Alert severity='error'>\n <AlertTitle>{errorTitle}</AlertTitle>\n {errorMessage}\n </Alert>\n )\n }\n\n // No error, render children\n return children\n}\n"],"names":["WidgetError","t0","$","_c","id","children","t1","state","w","widgets","isLoading","isFetching","error","widget","useWidgetStore","useShallow","errorTitle","title","errorMessage","message","t2","AlertTitle","t3","jsxs","Alert"],"mappings":";;;;;AAKO,SAAAA,EAAAC,GAAA;AAAA,QAAAC,IAAAC,EAAA,CAAA,GAAqB;AAAA,IAAAC,IAAAA;AAAAA,IAAAC,UAAAA;AAAAA,EAAAA,IAAAJ;AAAkC,MAAAK;AAAA,EAAAJ,SAAAE,KAE/CE,IAAAC,CAAAA,MAAA;AACT,UAAAC,IAAUD,EAAKE,QAASL,CAAE;AAAC,WACpB;AAAA,MAAAM,WACMF,GAACE;AAAAA,MAAWC,YACXH,GAACG;AAAAA,MAAYC,OAClBJ,GAACI;AAAAA,IAAAA;AAAAA,EACT,GACFV,OAAAE,GAAAF,OAAAI,KAAAA,IAAAJ,EAAA,CAAA;AARH,QAAAW,IAAeC,EACbC,EAAWT,CAOV,CACH;AAGA,MAAIO,GAAMH,aAAeG,GAAMF;AAAY,WAClCN;AAIT,MAAIQ,GAAMD,OAAO;AACf,UAAAI,IAAmBH,EAAMD,MAAMK,SAAZ,SACnBC,IACEL,EAAMD,MAAMO,WAAZ;AAC+D,QAAAC;AAAA,IAAAlB,SAAAc,KAI7DI,sBAACC,kBAAuB,GAAanB,OAAAc,GAAAd,OAAAkB,KAAAA,IAAAlB,EAAA,CAAA;AAAA,QAAAoB;AAAA,WAAApB,EAAA,CAAA,MAAAgB,KAAAhB,SAAAkB,KADvCE,IAAA,gBAAAC,EAACC,GAAA,EAAe,UAAA,SACdJ,UAAAA;AAAAA,MAAAA;AAAAA,MACCF;AAAAA,IAAAA,GACH,GAAQhB,OAAAgB,GAAAhB,OAAAkB,GAAAlB,OAAAoB,KAAAA,IAAApB,EAAA,CAAA,GAHRoB;AAAAA,EAGQ;AAEX,SAGMjB;AAAQ;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { jsx as
|
|
1
|
+
import { jsx as g, jsxs as h } from "react/jsx-runtime";
|
|
2
2
|
import { c as x } from "react/compiler-runtime";
|
|
3
|
-
import { Typography as
|
|
3
|
+
import { Typography as y, Box as v } from "@mui/material";
|
|
4
4
|
import { useShallow as w } from "zustand/shallow";
|
|
5
5
|
import { u as b } from "./widget-store-DNyVElxd.js";
|
|
6
6
|
const j = {
|
|
@@ -19,17 +19,17 @@ const j = {
|
|
|
19
19
|
minHeight: "100%"
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
|
-
function k(
|
|
22
|
+
function k(i) {
|
|
23
23
|
const t = x(9), {
|
|
24
24
|
id: s,
|
|
25
25
|
children: c,
|
|
26
26
|
title: f,
|
|
27
27
|
description: p,
|
|
28
28
|
isEmpty: u
|
|
29
|
-
} =
|
|
29
|
+
} = i, a = f === void 0 ? "No data available" : f, l = p === void 0 ? "There are no results for the combination of filters applied to your data. Try tweaking your filters, or zoom and pan the map to adjust filters" : p, m = u === void 0 ? A : u;
|
|
30
30
|
let o;
|
|
31
|
-
t[0] !== s ? (o = (
|
|
32
|
-
const e =
|
|
31
|
+
t[0] !== s ? (o = (r) => {
|
|
32
|
+
const e = r.widgets[s];
|
|
33
33
|
return {
|
|
34
34
|
isLoading: e?.isLoading,
|
|
35
35
|
isFetching: e?.isFetching,
|
|
@@ -40,22 +40,22 @@ function k(r) {
|
|
|
40
40
|
if (d?.isLoading || d?.isFetching)
|
|
41
41
|
return c;
|
|
42
42
|
if (m(d?.data)) {
|
|
43
|
-
let
|
|
44
|
-
t[2] !== a ? (
|
|
43
|
+
let r;
|
|
44
|
+
t[2] !== a ? (r = /* @__PURE__ */ g(y, { variant: "body2", color: "text.primary", children: a }), t[2] = a, t[3] = r) : r = t[3];
|
|
45
45
|
let e;
|
|
46
|
-
t[4] !== l ? (e = /* @__PURE__ */ y
|
|
46
|
+
t[4] !== l ? (e = /* @__PURE__ */ g(y, { variant: "caption", color: "text.secondary", children: l }), t[4] = l, t[5] = e) : e = t[5];
|
|
47
47
|
let n;
|
|
48
|
-
return t[6] !==
|
|
49
|
-
|
|
48
|
+
return t[6] !== r || t[7] !== e ? (n = /* @__PURE__ */ h(v, { sx: j.root, children: [
|
|
49
|
+
r,
|
|
50
50
|
e
|
|
51
|
-
] }), t[6] =
|
|
51
|
+
] }), t[6] = r, t[7] = e, t[8] = n) : n = t[8], n;
|
|
52
52
|
}
|
|
53
53
|
return c;
|
|
54
54
|
}
|
|
55
|
-
function A(
|
|
56
|
-
return
|
|
55
|
+
function A(i) {
|
|
56
|
+
return i == null ? !0 : Array.isArray(i) ? !!(i.length === 0 || i.every((t) => Array.isArray(t) && t.length === 0)) : typeof i == "object" ? Object.keys(i).length === 0 : !1;
|
|
57
57
|
}
|
|
58
58
|
export {
|
|
59
|
-
k as
|
|
59
|
+
k as W
|
|
60
60
|
};
|
|
61
|
-
//# sourceMappingURL=no-data-
|
|
61
|
+
//# sourceMappingURL=no-data-BBAoT1vK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-data-BBAoT1vK.js","sources":["../src/widgets/no-data/style.ts","../src/widgets/no-data/no-data.tsx"],"sourcesContent":["import type { SxProps, Theme } from '@mui/material'\n\n/**\n * Styles for NoData component matching Figma design specifications\n * Design reference: node 5781-11028\n */\nexport const styles: Record<string, SxProps<Theme>> = {\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: 1, // 8px\n paddingTop: 1, // 8px\n paddingBottom: 2, // 16px\n paddingX: 2, // 16px\n width: '100%',\n minHeight: '100%',\n },\n}\n","import { Box, Typography } from '@mui/material'\nimport { useShallow } from 'zustand/shallow'\nimport { useWidgetStore } from '../stores/widget-store'\nimport type { WidgetNoDataProps } from './types'\nimport { styles } from './style'\n\n/**\n * NoData wrapper component that displays empty state UI when widget has no data\n *\n * Integrates with widget store to check loading/fetching state and data availability.\n * Works in conjunction with SkeletonLoader for complete loading/empty state handling.\n *\n * @example Basic usage\n * ```tsx\n * <NoData id=\"my-widget\">\n * <WidgetContent id=\"my-widget\" />\n * </NoData>\n * ```\n *\n * @example With SkeletonLoader\n * ```tsx\n * <SkeletonLoader id=\"my-widget\" Skeleton={MySkeleton}>\n * <NoData id=\"my-widget\">\n * <WidgetContent id=\"my-widget\" />\n * </NoData>\n * </SkeletonLoader>\n * ```\n *\n * @example With custom messages\n * ```tsx\n * <NoData\n * id=\"my-widget\"\n * title=\"No results found\"\n * description=\"Try adjusting your filters\"\n * >\n * <WidgetContent id=\"my-widget\" />\n * </NoData>\n * ```\n */\nexport function WidgetNoData({\n id,\n children,\n title = 'No data available',\n description = 'There are no results for the combination of filters applied to your data. Try tweaking your filters, or zoom and pan the map to adjust filters',\n isEmpty = defaultIsEmpty,\n}: WidgetNoDataProps) {\n // Subscribe to widget store with selective subscription for optimal performance\n const widget = useWidgetStore(\n useShallow((state) => {\n const w = state.widgets[id]\n return {\n isLoading: w?.isLoading,\n isFetching: w?.isFetching,\n data: w?.data,\n }\n }),\n )\n\n // If loading or fetching, show children\n // SkeletonLoader handles loading state, this allows proper composition\n if (widget?.isLoading || widget?.isFetching) {\n return children\n }\n\n // Check if data is empty\n if (isEmpty(widget?.data)) {\n return (\n <Box sx={styles.root}>\n <Typography variant='body2' color='text.primary'>\n {title}\n </Typography>\n <Typography variant='caption' color='text.secondary'>\n {description}\n </Typography>\n </Box>\n )\n }\n\n // Data exists, render children\n return children\n}\n\n/**\n * Default function to determine if data is empty\n * Handles various data structures commonly used in widgets\n */\nfunction defaultIsEmpty(data: unknown): boolean {\n // Null or undefined\n if (data == null) {\n return true\n }\n\n // Arrays (most common case)\n if (Array.isArray(data)) {\n // Empty array\n if (data.length === 0) {\n return true\n }\n\n // Array of arrays (CategoryWidget pattern: [[],[]])\n // Check if all inner arrays are empty\n if (data.every((item) => Array.isArray(item) && item.length === 0)) {\n return true\n }\n\n return false\n }\n\n // Objects\n if (typeof data === 'object') {\n return Object.keys(data).length === 0\n }\n\n // Primitives (numbers, strings, booleans) are considered valid data\n return false\n}\n"],"names":["styles","root","display","flexDirection","gap","paddingTop","paddingBottom","paddingX","width","minHeight","WidgetNoData","t0","$","_c","id","children","title","t1","description","t2","isEmpty","t3","undefined","defaultIsEmpty","t4","state","w","widgets","isLoading","isFetching","data","widget","useWidgetStore","useShallow","t5","Typography","t6","t7","Box","Array","isArray","length","every","item","Object","keys"],"mappings":";;;;;AAMO,MAAMA,IAAyC;AAAA,EACpDC,MAAM;AAAA,IACJC,SAAS;AAAA,IACTC,eAAe;AAAA,IACfC,KAAK;AAAA;AAAA,IACLC,YAAY;AAAA;AAAA,IACZC,eAAe;AAAA;AAAA,IACfC,UAAU;AAAA;AAAA,IACVC,OAAO;AAAA,IACPC,WAAW;AAAA,EAAA;AAEf;ACsBO,SAAAC,EAAAC,GAAA;AAAA,QAAAC,IAAAC,EAAA,CAAA,GAAsB;AAAA,IAAAC,IAAAA;AAAAA,IAAAC,UAAAA;AAAAA,IAAAC,OAAAC;AAAAA,IAAAC,aAAAC;AAAAA,IAAAC,SAAAC;AAAAA,EAAAA,IAAAV,GAG3BK,IAAAC,MAAAK,SAAA,sBAAAL,GACAC,IAAAC,MAAAG,SAAA,mJAAAH,GACAC,IAAAC,MAAAC,SAAAC,IAAAF;AAAwB,MAAAG;AAAA,EAAAZ,SAAAE,KAIXU,IAAAC,CAAAA,MAAA;AACT,UAAAC,IAAUD,EAAKE,QAASb,CAAE;AAAC,WACpB;AAAA,MAAAc,WACMF,GAACE;AAAAA,MAAWC,YACXH,GAACG;AAAAA,MAAYC,MACnBJ,GAACI;AAAAA,IAAAA;AAAAA,EACR,GACFlB,OAAAE,GAAAF,OAAAY,KAAAA,IAAAZ,EAAA,CAAA;AARH,QAAAmB,IAAeC,EACbC,EAAWT,CAOV,CACH;AAIA,MAAIO,GAAMH,aAAeG,GAAMF;AAAY,WAClCd;AAIT,MAAIK,EAAQW,GAAMD,IAAM,GAAC;AAAA,QAAAI;AAAA,IAAAtB,SAAAI,KAGnBkB,sBAACC,GAAA,EAAmB,SAAA,SAAc,OAAA,gBAC/BnB,UAAAA,GACH,GAAaJ,OAAAI,GAAAJ,OAAAsB,KAAAA,IAAAtB,EAAA,CAAA;AAAA,QAAAwB;AAAA,IAAAxB,SAAAM,KACbkB,sBAACD,GAAA,EAAmB,SAAA,WAAgB,OAAA,kBACjCjB,UAAAA,GACH,GAAaN,OAAAM,GAAAN,OAAAwB,KAAAA,IAAAxB,EAAA,CAAA;AAAA,QAAAyB;AAAA,WAAAzB,EAAA,CAAA,MAAAsB,KAAAtB,SAAAwB,KANfC,sBAACC,GAAA,EAAQ,IAAAtC,EAAMC,MACbiC,UAAAA;AAAAA,MAAAA;AAAAA,MAGAE;AAAAA,IAAAA,GAGF,GAAMxB,OAAAsB,GAAAtB,OAAAwB,GAAAxB,OAAAyB,KAAAA,IAAAzB,EAAA,CAAA,GAPNyB;AAAAA,EAOM;AAET,SAGMtB;AAAQ;AAOjB,SAASQ,EAAeO,GAAwB;AAE9C,SAAIA,KAAQ,OACH,KAILS,MAAMC,QAAQV,CAAI,IAEhBA,GAAAA,EAAKW,WAAW,KAMhBX,EAAKY,MAAOC,CAAAA,MAASJ,MAAMC,QAAQG,CAAI,KAAKA,EAAKF,WAAW,CAAC,KAQ/D,OAAOX,KAAS,WACXc,OAAOC,KAAKf,CAAI,EAAEW,WAAW,IAI/B;AACT;"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function
|
|
1
|
+
import { WidgetErrorProps } from './types';
|
|
2
|
+
export declare function WidgetError({ id, children }: WidgetErrorProps): string | number | bigint | boolean | Iterable<import('react').ReactNode> | Promise<string | number | bigint | boolean | import('react').ReactPortal | import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>> | Iterable<import('react').ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export type {
|
|
1
|
+
export { WidgetError } from './error';
|
|
2
|
+
export type { WidgetErrorProps } from './types';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { useWidgetStore } from './stores/widget-store';
|
|
2
2
|
export type { BaseWidgetState, WidgetsStoreProps, WidgetState, WidgetStore, WidgetStoreActions, WidgetStoreState, } from './stores/types';
|
|
3
|
-
export {
|
|
4
|
-
export type {
|
|
5
|
-
export {
|
|
6
|
-
export type {
|
|
3
|
+
export { WidgetNoData } from './no-data';
|
|
4
|
+
export type { WidgetNoDataProps } from './no-data';
|
|
5
|
+
export { WidgetError } from './error';
|
|
6
|
+
export type { WidgetErrorProps } from './error';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export type {
|
|
1
|
+
export { WidgetNoData } from './no-data';
|
|
2
|
+
export type { WidgetNoDataProps } from './types';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { WidgetNoDataProps } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* NoData wrapper component that displays empty state UI when widget has no data
|
|
4
4
|
*
|
|
@@ -32,4 +32,4 @@ import { NoDataProps } from './types';
|
|
|
32
32
|
* </NoData>
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
35
|
-
export declare function
|
|
35
|
+
export declare function WidgetNoData({ id, children, title, description, isEmpty, }: WidgetNoDataProps): string | number | bigint | boolean | Iterable<import('react').ReactNode> | Promise<string | number | bigint | boolean | import('react').ReactPortal | import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>> | Iterable<import('react').ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import { WidgetState } from '../stores/types';
|
|
3
3
|
/**
|
|
4
|
-
* Props for the
|
|
4
|
+
* Props for the WidgetNoData wrapper component
|
|
5
5
|
*
|
|
6
6
|
* @example Basic usage
|
|
7
7
|
* ```tsx
|
|
8
|
-
* <
|
|
8
|
+
* <WidgetNoData id="my-widget">
|
|
9
9
|
* <WidgetContent id="my-widget" />
|
|
10
|
-
* </
|
|
10
|
+
* </WidgetNoData>
|
|
11
11
|
* ```
|
|
12
12
|
*
|
|
13
13
|
* @example With custom messages
|
|
14
14
|
* ```tsx
|
|
15
|
-
* <
|
|
15
|
+
* <WidgetNoData
|
|
16
16
|
* id="my-widget"
|
|
17
17
|
* title="No results found"
|
|
18
18
|
* description="Try adjusting your filters"
|
|
19
19
|
* >
|
|
20
20
|
* <WidgetContent id="my-widget" />
|
|
21
|
-
* </
|
|
21
|
+
* </WidgetNoData>
|
|
22
22
|
* ```
|
|
23
23
|
*
|
|
24
24
|
* @example With custom isEmpty logic
|
|
25
25
|
* ```tsx
|
|
26
|
-
* <
|
|
26
|
+
* <WidgetNoData
|
|
27
27
|
* id="my-widget"
|
|
28
28
|
* isEmpty={(data) => {
|
|
29
29
|
* const d = data as CustomData
|
|
@@ -31,10 +31,10 @@ import { WidgetState } from '../stores/types';
|
|
|
31
31
|
* }}
|
|
32
32
|
* >
|
|
33
33
|
* <WidgetContent id="my-widget" />
|
|
34
|
-
* </
|
|
34
|
+
* </WidgetNoData>
|
|
35
35
|
* ```
|
|
36
36
|
*/
|
|
37
|
-
export interface
|
|
37
|
+
export interface WidgetNoDataProps {
|
|
38
38
|
/**
|
|
39
39
|
* Widget ID to fetch state from store
|
|
40
40
|
*/
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { WidgetRoot } from './root';
|
|
2
2
|
export { mergeWidgetConfig } from './utils';
|
|
3
|
-
export type {
|
|
3
|
+
export type { WidgetRootProps, ConfigProps } from './types';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function
|
|
1
|
+
import { WidgetRootProps } from './types';
|
|
2
|
+
export declare function WidgetRoot<T>(props: WidgetRootProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import { WidgetsStoreProps, WidgetState } from '../stores/types';
|
|
3
|
-
export interface
|
|
3
|
+
export interface WidgetRootProps<T> extends WidgetsStoreProps {
|
|
4
4
|
children: ReactNode;
|
|
5
5
|
config?: T;
|
|
6
6
|
}
|
package/dist/widgets/error.js
CHANGED
package/dist/widgets/no-data.js
CHANGED
package/dist/widgets/root.js
CHANGED
|
@@ -19,20 +19,20 @@ function $(e) {
|
|
|
19
19
|
type: e.type
|
|
20
20
|
});
|
|
21
21
|
}, c = [e.id, e.type, t], i[0] = e.id, i[1] = e.type, i[2] = t, i[3] = l, i[4] = c) : (l = i[3], c = i[4]), n(l, c);
|
|
22
|
-
let a,
|
|
22
|
+
let a, g;
|
|
23
23
|
i[5] !== e.error || i[6] !== e.id || i[7] !== e.isFetching || i[8] !== e.isLoading || i[9] !== t ? (a = () => {
|
|
24
24
|
t(e.id, {
|
|
25
25
|
isLoading: e.isLoading ?? !1,
|
|
26
26
|
isFetching: e.isFetching ?? !1,
|
|
27
27
|
error: e.error
|
|
28
28
|
});
|
|
29
|
-
},
|
|
30
|
-
let
|
|
31
|
-
i[12] !== e.config || i[13] !== e.id || i[14] !== t ? (
|
|
29
|
+
}, g = [e.id, e.isLoading, e.isFetching, e.error, t], i[5] = e.error, i[6] = e.id, i[7] = e.isFetching, i[8] = e.isLoading, i[9] = t, i[10] = a, i[11] = g) : (a = i[10], g = i[11]), n(a, g);
|
|
30
|
+
let f, u;
|
|
31
|
+
i[12] !== e.config || i[13] !== e.id || i[14] !== t ? (f = () => {
|
|
32
32
|
e.config && t(e.id, {
|
|
33
33
|
...e.config
|
|
34
34
|
});
|
|
35
|
-
}, u = [e.id, e.config, t], i[12] = e.config, i[13] = e.id, i[14] = t, i[15] =
|
|
35
|
+
}, u = [e.id, e.config, t], i[12] = e.config, i[13] = e.id, i[14] = t, i[15] = f, i[16] = u) : (f = i[15], u = i[16]), n(f, u);
|
|
36
36
|
let m, r;
|
|
37
37
|
i[17] !== d || i[18] !== e.data || i[19] !== e.id ? (m = () => {
|
|
38
38
|
d(e.id, e.data);
|
|
@@ -62,7 +62,7 @@ function k(...e) {
|
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
64
|
export {
|
|
65
|
-
$ as
|
|
65
|
+
$ as WidgetRoot,
|
|
66
66
|
k as mergeWidgetConfig
|
|
67
67
|
};
|
|
68
68
|
//# sourceMappingURL=root.js.map
|
package/dist/widgets/root.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"root.js","sources":["../../src/widgets/root/style.ts","../../src/widgets/root/root.tsx","../../src/widgets/root/utils.ts"],"sourcesContent":["import type { SxProps, Theme } from '@mui/material'\n\nexport const styles = {\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: (theme: Theme) => theme.spacing(2),\n },\n} satisfies Record<string, SxProps<Theme>>\n","import { Box } from '@mui/material'\nimport { styles } from './style'\nimport { useEffect } from 'react'\nimport type {
|
|
1
|
+
{"version":3,"file":"root.js","sources":["../../src/widgets/root/style.ts","../../src/widgets/root/root.tsx","../../src/widgets/root/utils.ts"],"sourcesContent":["import type { SxProps, Theme } from '@mui/material'\n\nexport const styles = {\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: (theme: Theme) => theme.spacing(2),\n },\n} satisfies Record<string, SxProps<Theme>>\n","import { Box } from '@mui/material'\nimport { styles } from './style'\nimport { useEffect } from 'react'\nimport type { WidgetRootProps } from './types'\nimport { useWidgetStore } from '../stores/widget-store'\nimport type { WrapperState } from '../wrapper'\n\nexport function WidgetRoot<T>(props: WidgetRootProps<T>) {\n const setWidget = useWidgetStore((state) => state.setWidget)\n const executeToolPipeline = useWidgetStore(\n (state) => state.executeToolPipeline,\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\n useEffect(() => {\n if (props.config) {\n setWidget<WrapperState>(props.id, {\n ...props.config,\n })\n }\n }, [props.id, props.config, setWidget])\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 pipeline when tool state changes (enabled/config)\n useEffect(() => {\n let prevTools = useWidgetStore.getState().widgets[props.id]?.registeredTools\n\n const unsubscribe = useWidgetStore.subscribe((state) => {\n const currentTools = state.widgets[props.id]?.registeredTools\n\n // Only re-execute if tools array changed\n if (currentTools !== prevTools) {\n prevTools = currentTools\n void executeToolPipeline(props.id, props.data)\n }\n })\n\n return unsubscribe\n }, [props.id, props.data, executeToolPipeline])\n\n return <Box sx={styles.root}>{props.children}</Box>\n}\n","import deepmerge from 'deepmerge'\n\nexport function mergeWidgetConfig<T>(\n ...options: [T | undefined, T | undefined]\n): T {\n return deepmerge(options[0] ?? {}, options[1] ?? {}, {\n arrayMerge(_, source) {\n return source as T[keyof T][]\n },\n }) as T\n}\n"],"names":["styles","root","display","flexDirection","gap","theme","spacing","WidgetRoot","props","$","_c","setWidget","useWidgetStore","_temp","executeToolPipeline","_temp2","t0","t1","id","type","useEffect","t2","t3","error","isFetching","isLoading","t4","t5","config","t6","t7","data","t8","t9","prevTools","getState","widgets","registeredTools","subscribe","state_1","currentTools","state","t10","children","Box","state_0","mergeWidgetConfig","options","deepmerge","arrayMerge","_","source"],"mappings":"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"}
|
package/dist/widgets.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { u as e } from "./widget-store-DNyVElxd.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { W as a } from "./no-data-BBAoT1vK.js";
|
|
3
|
+
import { W as s } from "./error-DGzuzmn1.js";
|
|
4
4
|
export {
|
|
5
|
-
|
|
6
|
-
a as
|
|
5
|
+
s as WidgetError,
|
|
6
|
+
a as WidgetNoData,
|
|
7
7
|
e as useWidgetStore
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=widgets.js.map
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"error-zHOU_QIB.js","sources":["../src/widgets/error/error.tsx"],"sourcesContent":["import { Alert, AlertTitle } from '@mui/material'\nimport { useWidgetStore } from '../stores/widget-store'\nimport { useShallow } from 'zustand/shallow'\nimport type { ErrorProps } from './types'\n\nexport function Error({ id, children }: ErrorProps) {\n const widget = useWidgetStore(\n useShallow((state) => {\n const w = state.widgets[id]\n return {\n isLoading: w?.isLoading,\n isFetching: w?.isFetching,\n error: w?.error,\n }\n }),\n )\n\n // Don't show error during loading/fetching states\n if (widget?.isLoading || widget?.isFetching) {\n return children\n }\n\n // Show error UI if error exists\n if (widget?.error) {\n const errorTitle = widget.error.title ?? 'Error'\n const errorMessage =\n widget.error.message ??\n 'An error occurred while loading the widget. Please try again.'\n\n return (\n <Alert severity='error'>\n <AlertTitle>{errorTitle}</AlertTitle>\n {errorMessage}\n </Alert>\n )\n }\n\n // No error, render children\n return children\n}\n"],"names":["Error","t0","$","_c","id","children","t1","state","w","widgets","isLoading","isFetching","error","widget","useWidgetStore","useShallow","errorTitle","title","errorMessage","message","t2","AlertTitle","t3","jsxs","Alert"],"mappings":";;;;;AAKO,SAAAA,EAAAC,GAAA;AAAA,QAAAC,IAAAC,EAAA,CAAA,GAAe;AAAA,IAAAC,IAAAA;AAAAA,IAAAC,UAAAA;AAAAA,EAAAA,IAAAJ;AAA4B,MAAAK;AAAA,EAAAJ,SAAAE,KAEnCE,IAAAC,CAAAA,MAAA;AACT,UAAAC,IAAUD,EAAKE,QAASL,CAAE;AAAC,WACpB;AAAA,MAAAM,WACMF,GAACE;AAAAA,MAAWC,YACXH,GAACG;AAAAA,MAAYC,OAClBJ,GAACI;AAAAA,IAAAA;AAAAA,EACT,GACFV,OAAAE,GAAAF,OAAAI,KAAAA,IAAAJ,EAAA,CAAA;AARH,QAAAW,IAAeC,EACbC,EAAWT,CAOV,CACH;AAGA,MAAIO,GAAMH,aAAeG,GAAMF;AAAY,WAClCN;AAIT,MAAIQ,GAAMD,OAAO;AACf,UAAAI,IAAmBH,EAAMD,MAAMK,SAAZ,SACnBC,IACEL,EAAMD,MAAMO,WAAZ;AAC+D,QAAAC;AAAA,IAAAlB,SAAAc,KAI7DI,sBAACC,kBAAuB,GAAanB,OAAAc,GAAAd,OAAAkB,KAAAA,IAAAlB,EAAA,CAAA;AAAA,QAAAoB;AAAA,WAAApB,EAAA,CAAA,MAAAgB,KAAAhB,SAAAkB,KADvCE,IAAA,gBAAAC,EAACC,GAAA,EAAe,UAAA,SACdJ,UAAAA;AAAAA,MAAAA;AAAAA,MACCF;AAAAA,IAAAA,GACH,GAAQhB,OAAAgB,GAAAhB,OAAAkB,GAAAlB,OAAAoB,KAAAA,IAAApB,EAAA,CAAA,GAHRoB;AAAAA,EAGQ;AAEX,SAGMjB;AAAQ;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"no-data-Cz80hEWj.js","sources":["../src/widgets/no-data/style.ts","../src/widgets/no-data/no-data.tsx"],"sourcesContent":["import type { SxProps, Theme } from '@mui/material'\n\n/**\n * Styles for NoData component matching Figma design specifications\n * Design reference: node 5781-11028\n */\nexport const styles: Record<string, SxProps<Theme>> = {\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: 1, // 8px\n paddingTop: 1, // 8px\n paddingBottom: 2, // 16px\n paddingX: 2, // 16px\n width: '100%',\n minHeight: '100%',\n },\n}\n","import { Box, Typography } from '@mui/material'\nimport { useShallow } from 'zustand/shallow'\nimport { useWidgetStore } from '../stores/widget-store'\nimport type { NoDataProps } from './types'\nimport { styles } from './style'\n\n/**\n * NoData wrapper component that displays empty state UI when widget has no data\n *\n * Integrates with widget store to check loading/fetching state and data availability.\n * Works in conjunction with SkeletonLoader for complete loading/empty state handling.\n *\n * @example Basic usage\n * ```tsx\n * <NoData id=\"my-widget\">\n * <WidgetContent id=\"my-widget\" />\n * </NoData>\n * ```\n *\n * @example With SkeletonLoader\n * ```tsx\n * <SkeletonLoader id=\"my-widget\" Skeleton={MySkeleton}>\n * <NoData id=\"my-widget\">\n * <WidgetContent id=\"my-widget\" />\n * </NoData>\n * </SkeletonLoader>\n * ```\n *\n * @example With custom messages\n * ```tsx\n * <NoData\n * id=\"my-widget\"\n * title=\"No results found\"\n * description=\"Try adjusting your filters\"\n * >\n * <WidgetContent id=\"my-widget\" />\n * </NoData>\n * ```\n */\nexport function NoData({\n id,\n children,\n title = 'No data available',\n description = 'There are no results for the combination of filters applied to your data. Try tweaking your filters, or zoom and pan the map to adjust filters',\n isEmpty = defaultIsEmpty,\n}: NoDataProps) {\n // Subscribe to widget store with selective subscription for optimal performance\n const widget = useWidgetStore(\n useShallow((state) => {\n const w = state.widgets[id]\n return {\n isLoading: w?.isLoading,\n isFetching: w?.isFetching,\n data: w?.data,\n }\n }),\n )\n\n // If loading or fetching, show children\n // SkeletonLoader handles loading state, this allows proper composition\n if (widget?.isLoading || widget?.isFetching) {\n return children\n }\n\n // Check if data is empty\n if (isEmpty(widget?.data)) {\n return (\n <Box sx={styles.root}>\n <Typography variant='body2' color='text.primary'>\n {title}\n </Typography>\n <Typography variant='caption' color='text.secondary'>\n {description}\n </Typography>\n </Box>\n )\n }\n\n // Data exists, render children\n return children\n}\n\n/**\n * Default function to determine if data is empty\n * Handles various data structures commonly used in widgets\n */\nfunction defaultIsEmpty(data: unknown): boolean {\n // Null or undefined\n if (data == null) {\n return true\n }\n\n // Arrays (most common case)\n if (Array.isArray(data)) {\n // Empty array\n if (data.length === 0) {\n return true\n }\n\n // Array of arrays (CategoryWidget pattern: [[],[]])\n // Check if all inner arrays are empty\n if (data.every((item) => Array.isArray(item) && item.length === 0)) {\n return true\n }\n\n return false\n }\n\n // Objects\n if (typeof data === 'object') {\n return Object.keys(data).length === 0\n }\n\n // Primitives (numbers, strings, booleans) are considered valid data\n return false\n}\n"],"names":["styles","root","display","flexDirection","gap","paddingTop","paddingBottom","paddingX","width","minHeight","NoData","t0","$","_c","id","children","title","t1","description","t2","isEmpty","t3","undefined","defaultIsEmpty","t4","state","w","widgets","isLoading","isFetching","data","widget","useWidgetStore","useShallow","t5","Typography","t6","t7","Box","Array","isArray","length","every","item","Object","keys"],"mappings":";;;;;AAMO,MAAMA,IAAyC;AAAA,EACpDC,MAAM;AAAA,IACJC,SAAS;AAAA,IACTC,eAAe;AAAA,IACfC,KAAK;AAAA;AAAA,IACLC,YAAY;AAAA;AAAA,IACZC,eAAe;AAAA;AAAA,IACfC,UAAU;AAAA;AAAA,IACVC,OAAO;AAAA,IACPC,WAAW;AAAA,EAAA;AAEf;ACsBO,SAAAC,EAAAC,GAAA;AAAA,QAAAC,IAAAC,EAAA,CAAA,GAAgB;AAAA,IAAAC,IAAAA;AAAAA,IAAAC,UAAAA;AAAAA,IAAAC,OAAAC;AAAAA,IAAAC,aAAAC;AAAAA,IAAAC,SAAAC;AAAAA,EAAAA,IAAAV,GAGrBK,IAAAC,MAAAK,SAAA,sBAAAL,GACAC,IAAAC,MAAAG,SAAA,mJAAAH,GACAC,IAAAC,MAAAC,SAAAC,IAAAF;AAAwB,MAAAG;AAAA,EAAAZ,SAAAE,KAIXU,IAAAC,CAAAA,MAAA;AACT,UAAAC,IAAUD,EAAKE,QAASb,CAAE;AAAC,WACpB;AAAA,MAAAc,WACMF,GAACE;AAAAA,MAAWC,YACXH,GAACG;AAAAA,MAAYC,MACnBJ,GAACI;AAAAA,IAAAA;AAAAA,EACR,GACFlB,OAAAE,GAAAF,OAAAY,KAAAA,IAAAZ,EAAA,CAAA;AARH,QAAAmB,IAAeC,EACbC,EAAWT,CAOV,CACH;AAIA,MAAIO,GAAMH,aAAeG,GAAMF;AAAY,WAClCd;AAIT,MAAIK,EAAQW,GAAMD,IAAM,GAAC;AAAA,QAAAI;AAAA,IAAAtB,SAAAI,KAGnBkB,sBAACC,GAAA,EAAmB,SAAA,SAAc,OAAA,gBAC/BnB,UAAAA,GACH,GAAaJ,OAAAI,GAAAJ,OAAAsB,KAAAA,IAAAtB,EAAA,CAAA;AAAA,QAAAwB;AAAA,IAAAxB,SAAAM,KACbkB,sBAACD,GAAA,EAAmB,SAAA,WAAgB,OAAA,kBACjCjB,UAAAA,GACH,GAAaN,OAAAM,GAAAN,OAAAwB,KAAAA,IAAAxB,EAAA,CAAA;AAAA,QAAAyB;AAAA,WAAAzB,EAAA,CAAA,MAAAsB,KAAAtB,SAAAwB,KANfC,sBAACC,GAAA,EAAQ,IAAAtC,EAAMC,MACbiC,UAAAA;AAAAA,MAAAA;AAAAA,MAGAE;AAAAA,IAAAA,GAGF,GAAMxB,OAAAsB,GAAAtB,OAAAwB,GAAAxB,OAAAyB,KAAAA,IAAAzB,EAAA,CAAA,GAPNyB;AAAAA,EAOM;AAET,SAGMtB;AAAQ;AAOjB,SAASQ,EAAeO,GAAwB;AAE9C,SAAIA,KAAQ,OACH,KAILS,MAAMC,QAAQV,CAAI,IAEhBA,GAAAA,EAAKW,WAAW,KAMhBX,EAAKY,MAAOC,CAAAA,MAASJ,MAAMC,QAAQG,CAAI,KAAKA,EAAKF,WAAW,CAAC,KAQ/D,OAAOX,KAAS,WACXc,OAAOC,KAAKf,CAAI,EAAEW,WAAW,IAI/B;AACT;"}
|