@datawheel/data-explorer 1.1.17 → 1.2.0-rc.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.
package/dist/main.d.mts CHANGED
@@ -782,6 +782,12 @@ declare const defaultTranslation: {
782
782
  time_range: string;
783
783
  total: string;
784
784
  };
785
+ transient: {
786
+ title_one_row: string;
787
+ title_loading: string;
788
+ title_empty: string;
789
+ description_empty: string;
790
+ };
785
791
  }>;
786
792
  action_copy: string;
787
793
  action_copy_done: string;
package/dist/main.mjs CHANGED
@@ -1,10 +1,10 @@
1
1
  import { createStyles, keyframes, Select, Center, Text, rem, Input, Box, Stack, Group, Button, SimpleGrid, Flex, ScrollArea, LoadingOverlay as LoadingOverlay$1, Table, MultiSelect, NumberInput, Menu, ActionIcon, UnstyledButton, Loader, Container, Title, useMantineTheme, TextInput, CopyButton, MantineProvider, Space, Modal, Alert, Paper, Tooltip, useComponentDefaultProps, Skeleton, Anchor, packSx, CloseButton, Tabs, ThemeIcon, Drawer, Switch, Divider, Accordion, Popover, Checkbox } from '@mantine/core';
2
2
  import { useClipboard, useDebouncedState, useMediaQuery, useFullscreen, useDisclosure } from '@mantine/hooks';
3
- import { IconWorld, IconExternalLink, IconClipboard, IconSettings, IconMathGreater, IconMathLower, IconArrowsLeftRight, IconWorldWww, IconClipboardCheck, IconCircleOff, IconAlertCircle, IconAlertTriangle, IconVectorTriangle, IconPhotoDown, IconDownload, IconArrowsMinimize, IconArrowsMaximize, IconCheck, IconShare, IconLanguage, IconCopy, IconBrandGithub, IconArrowLeft, IconArrowRight, IconX, IconChevronLeft, IconChevronRight, IconSearch, IconBox, IconDotsVertical, IconTrash, IconPlus, IconStack3, IconInfoCircleFilled, IconArrowsSort, IconSortDescendingNumbers, IconSortDescendingLetters, IconSortAscendingNumbers, IconSortAscendingLetters, IconHelpCircle, IconFilterOff, IconFilter, IconClock, IconAdjustments } from '@tabler/icons-react';
3
+ import { IconWorld, IconExternalLink, IconClipboard, IconSettings, IconMathGreater, IconMathLower, IconArrowsLeftRight, IconWorldWww, IconClipboardCheck, IconCircleOff, IconAlertCircle, IconAlertTriangle, IconBrandGithub, IconVectorTriangle, IconPhotoDown, IconDownload, IconArrowsMinimize, IconArrowsMaximize, IconCheck, IconShare, IconLanguage, IconCopy, IconArrowLeft, IconArrowRight, IconX, IconChevronLeft, IconChevronRight, IconSearch, IconBox, IconDotsVertical, IconTrash, IconPlus, IconStack3, IconInfoCircleFilled, IconArrowsSort, IconSortDescendingNumbers, IconSortDescendingLetters, IconSortAscendingNumbers, IconSortAscendingLetters, IconHelpCircle, IconFilterOff, IconFilter, IconClock, IconAdjustments } from '@tabler/icons-react';
4
4
  import * as React21 from 'react';
5
- import React21__default, { createContext, forwardRef, useMemo, useCallback, useContext, useRef, useEffect, useState, Component, Suspense, useLayoutEffect } from 'react';
5
+ import React21__default, { createContext, forwardRef, useMemo, useCallback, useContext, useRef, useEffect, useState, Suspense, useLayoutEffect } from 'react';
6
6
  import { translationFactory } from '@datawheel/use-translation';
7
- import { VizbuilderProvider, useVizbuilderContext, d3plusConfigBuilder } from '@datawheel/vizbuilder/react';
7
+ import { VizbuilderProvider, useVizbuilderContext, ErrorBoundary, d3plusConfigBuilder } from '@datawheel/vizbuilder/react';
8
8
  import { createSlice, createSelector, combineReducers, configureStore, bindActionCreators } from '@reduxjs/toolkit';
9
9
  import { assign } from 'd3plus-common';
10
10
  import identity2 from 'lodash-es/identity';
@@ -2234,7 +2234,7 @@ function ChartCard(props) {
2234
2234
  const { chart, isFullMode, onFocus, height } = props;
2235
2235
  const { dataset } = chart.datagroup;
2236
2236
  const { translate } = useVizbuilderTranslation();
2237
- const { downloadFormats, ErrorBoundary: ErrorBoundary2, showConfidenceInt } = useVizbuilderContext();
2237
+ const { downloadFormats, showConfidenceInt, CardErrorComponent } = useVizbuilderContext();
2238
2238
  const nodeRef = useRef(null);
2239
2239
  const { ref: inViewRef, inView } = useInView({ triggerOnce: false, threshold: 0 });
2240
2240
  const [hasBeenInView, setHasBeenInView] = useState(false);
@@ -2253,6 +2253,7 @@ function ChartCard(props) {
2253
2253
  t: translate
2254
2254
  });
2255
2255
  const downloadButtons = useMemo(() => {
2256
+ if (!config) return null;
2256
2257
  const filename = (typeof config.title === "function" ? config.title(dataset) : config.title || "").replace(/[^\w]/g, "_").replace(/[_]+/g, "_");
2257
2258
  return downloadFormats.map((format2) => {
2258
2259
  const formatLower = format2.toLowerCase();
@@ -2309,24 +2310,16 @@ function ChartCard(props) {
2309
2310
  ));
2310
2311
  }, [translate]);
2311
2312
  const resolvedHeight = height ? height : isFullMode ? "calc(100vh - 3rem)" : 400;
2312
- if (!ChartComponent) return null;
2313
- return /* @__PURE__ */ React21__default.createElement(
2313
+ if (!ChartComponent || !config) return null;
2314
+ return /* @__PURE__ */ React21__default.createElement(ErrorBoundary, { ErrorContent: CardErrorComponent }, /* @__PURE__ */ React21__default.createElement(
2314
2315
  Paper,
2315
2316
  {
2316
2317
  className: props.className,
2317
2318
  w: "100%",
2318
2319
  style: { overflow: "hidden", height: resolvedHeight, ...props.style }
2319
2320
  },
2320
- /* @__PURE__ */ React21__default.createElement(ErrorBoundary2, null, /* @__PURE__ */ React21__default.createElement(Stack, { spacing: "xs", p: "xs", style: { position: "relative" }, h: "100%", w: "100%" }, /* @__PURE__ */ React21__default.createElement(Group, { position: "center", spacing: "xs", align: "center" }, isFullMode && shareButton, downloadButtons, onFocus && focusButton), /* @__PURE__ */ React21__default.createElement(
2321
- Box,
2322
- {
2323
- style: { flex: "1 1 auto" },
2324
- ref: setRefs,
2325
- sx: { "& > .viz": { height: "100%" } }
2326
- },
2327
- ChartComponent && (inView || hasBeenInView) ? /* @__PURE__ */ React21__default.createElement(ChartComponent, { config }) : /* @__PURE__ */ React21__default.createElement("div", { style: { height: "100%", width: "100%" } })
2328
- )))
2329
- );
2321
+ /* @__PURE__ */ React21__default.createElement(Stack, { spacing: "xs", p: "xs", style: { position: "relative" }, h: "100%", w: "100%" }, /* @__PURE__ */ React21__default.createElement(Group, { position: "center", spacing: "xs", align: "center" }, isFullMode && shareButton, downloadButtons, onFocus && focusButton), /* @__PURE__ */ React21__default.createElement(Box, { style: { flex: "1 1 auto" }, ref: setRefs, sx: { "& > .viz": { height: "100%" } } }, ChartComponent && (inView || hasBeenInView) ? /* @__PURE__ */ React21__default.createElement(ChartComponent, { config }) : /* @__PURE__ */ React21__default.createElement("div", { style: { height: "100%", width: "100%" } })))
2322
+ ));
2330
2323
  }
2331
2324
  var getBackground = (node) => {
2332
2325
  if (node.nodeType !== Node.ELEMENT_NODE) return "white";
@@ -2377,14 +2370,7 @@ var useStyles = createStyles((theme) => ({
2377
2370
  function Vizbuilder(props) {
2378
2371
  const datasets = useMemo(() => asArray(props.datasets), [props.datasets]);
2379
2372
  const { t } = useVizbuilderTranslation();
2380
- const {
2381
- chartLimits,
2382
- chartTypes,
2383
- datacap,
2384
- getTopojsonConfig,
2385
- ErrorBoundary: ErrorBoundary2,
2386
- NonIdealState: NonIdealState3
2387
- } = useVizbuilderContext();
2373
+ const { chartLimits, chartTypes, datacap, getTopojsonConfig, NonIdealState: NonIdealState3 } = useVizbuilderContext();
2388
2374
  const { actions: actions2 } = useSettings();
2389
2375
  const queryItem = useSelector$1(selectCurrentQueryItem);
2390
2376
  const { classes, cx } = useStyles();
@@ -2412,14 +2398,10 @@ function Vizbuilder(props) {
2412
2398
  return /* @__PURE__ */ React21__default.createElement(Flex, { justify: "center", align: "center", direction: "column", w: "50%" }, /* @__PURE__ */ React21__default.createElement(IconCircleOff, { size: 92 }), /* @__PURE__ */ React21__default.createElement(Title, { mt: "md", mb: "md", order: 4 }, t("vizbuilder.transient.title_empty")), /* @__PURE__ */ React21__default.createElement(Text, null, t("transient.description_empty")));
2413
2399
  }
2414
2400
  const isSingleChart = chartList.length === 1;
2415
- return /* @__PURE__ */ React21__default.createElement(ErrorBoundary2, null, /* @__PURE__ */ React21__default.createElement("div", { className: cx(classes.grid, { [classes.fill]: isSingleChart }) }, chartList.map((chart2, idx) => {
2401
+ return /* @__PURE__ */ React21__default.createElement("div", { className: cx(classes.grid, { [classes.fill]: isSingleChart }) }, chartList.map((chart2, idx) => {
2416
2402
  let className = classes.fill;
2417
2403
  if (!isSingleChart) {
2418
- const names = [
2419
- classes.itemLarge,
2420
- classes.itemSmallTop,
2421
- classes.itemSmallBottom
2422
- ];
2404
+ const names = [classes.itemLarge, classes.itemSmallTop, classes.itemSmallBottom];
2423
2405
  className = names[idx % 3];
2424
2406
  }
2425
2407
  return /* @__PURE__ */ React21__default.createElement(
@@ -2432,8 +2414,8 @@ function Vizbuilder(props) {
2432
2414
  className
2433
2415
  }
2434
2416
  );
2435
- })));
2436
- }, [charts, classes, datasets, t, cx, ErrorBoundary2]);
2417
+ }));
2418
+ }, [charts, classes, datasets, t, cx]);
2437
2419
  const currentChart = (queryItem == null ? void 0 : queryItem.chart) || "";
2438
2420
  const chart = charts[currentChart];
2439
2421
  return /* @__PURE__ */ React21__default.createElement("div", { className: cls("vb-wrapper", classes.wrapper, props.className) }, props.customHeader, content, props.customFooter, /* @__PURE__ */ React21__default.createElement(
@@ -2505,72 +2487,6 @@ function VizbuilderView(props) {
2505
2487
  };
2506
2488
  return /* @__PURE__ */ React21__default.createElement(Vizbuilder, { datasets: dataset });
2507
2489
  }
2508
- var ErrorBoundary = class extends Component {
2509
- constructor() {
2510
- super(...arguments);
2511
- this.state = {
2512
- message: "",
2513
- name: ""
2514
- };
2515
- this.clearError = () => this.setState({ message: "", name: "" });
2516
- }
2517
- static getDerivedStateFromError(error) {
2518
- return { message: error.message, name: error.name };
2519
- }
2520
- render() {
2521
- const { message, name: name4 } = this.state;
2522
- if (!message) {
2523
- return this.props.children;
2524
- }
2525
- return /* @__PURE__ */ React21__default.createElement(TranslationConsumer, null, ({ translate: t }) => {
2526
- const detailText = t("vizbuilder.error.detail");
2527
- return /* @__PURE__ */ React21__default.createElement(
2528
- Flex,
2529
- {
2530
- p: "xl",
2531
- align: "center",
2532
- justify: "center",
2533
- direction: "column",
2534
- className: "chart-card error"
2535
- },
2536
- /* @__PURE__ */ React21__default.createElement(Title, { order: 3 }, t("vizbuilder.error.title")),
2537
- detailText.length ? /* @__PURE__ */ React21__default.createElement(Text, null, detailText) : null,
2538
- /* @__PURE__ */ React21__default.createElement(Text, null, t("vizbuilder.error.message", { message })),
2539
- /* @__PURE__ */ React21__default.createElement(Group, { spacing: "xs", my: "sm" }, /* @__PURE__ */ React21__default.createElement(Button, { onClick: this.clearError, size: "xs", variant: "light" }, t("vizbuilder.action_retry")), /* @__PURE__ */ React21__default.createElement(IssueButton, { error: name4, message }))
2540
- );
2541
- });
2542
- }
2543
- };
2544
- function IssueButton(props) {
2545
- const { error, message } = props;
2546
- const { t } = useVizbuilderTranslation();
2547
- const location2 = typeof window === "object" ? window.location : { href: "<SSR>" };
2548
- const issueParams = new URLSearchParams({
2549
- title: `[report/vizbuilder] ${error}`,
2550
- body: [
2551
- `**URL**: ${location2.href}`,
2552
- `**Error**: ${error}`,
2553
- message ? `**Error details:** ${message}
2554
- ` : "",
2555
- "**Detail of the issue:**\n"
2556
- ].join("\n")
2557
- });
2558
- return /* @__PURE__ */ React21__default.createElement(
2559
- Button,
2560
- {
2561
- component: "a",
2562
- href: `https://github.com/Datawheel/vizbuilder/issues/new?${issueParams}`,
2563
- leftIcon: /* @__PURE__ */ React21__default.createElement(IconBrandGithub, { size: "1rem" }),
2564
- rel: "noopener noreferrer",
2565
- role: "button",
2566
- size: "xs",
2567
- tabIndex: 0,
2568
- target: "_blank",
2569
- variant: "subtle"
2570
- },
2571
- t("action_fileissue")
2572
- );
2573
- }
2574
2490
  function NonIdealState(props) {
2575
2491
  const { status } = props;
2576
2492
  const { translate: t } = useTranslation();
@@ -6798,6 +6714,51 @@ function ExplorerTour({ children, tourConfig }) {
6798
6714
  children
6799
6715
  );
6800
6716
  }
6717
+ function ReportIssueCard(props) {
6718
+ const { errorMessage, errorClass, onClear: clearHandler } = props;
6719
+ const location2 = typeof window === "object" ? window.location : { href: "<SSR>" };
6720
+ const issueParams = new URLSearchParams({
6721
+ title: `[report/vizbuilder] ${errorClass}`,
6722
+ body: [
6723
+ `**URL**: ${location2.href}`,
6724
+ `**Error**: ${errorClass}`,
6725
+ errorMessage ? `**Error details:** ${errorMessage}
6726
+ ` : "",
6727
+ "**Detail of the issue:**\n"
6728
+ ].join("\n")
6729
+ });
6730
+ return /* @__PURE__ */ React21__default.createElement(TranslationConsumer, null, ({ translate: t }) => {
6731
+ const detailText = t("vizbuilder.error.detail");
6732
+ return /* @__PURE__ */ React21__default.createElement(Paper, { w: "100%" }, /* @__PURE__ */ React21__default.createElement(
6733
+ Flex,
6734
+ {
6735
+ p: "xl",
6736
+ align: "center",
6737
+ justify: "center",
6738
+ direction: "column",
6739
+ className: "chart-card error"
6740
+ },
6741
+ /* @__PURE__ */ React21__default.createElement(Title, { order: 3 }, t("vizbuilder.error.title")),
6742
+ detailText.length ? /* @__PURE__ */ React21__default.createElement(Text, null, detailText) : null,
6743
+ /* @__PURE__ */ React21__default.createElement(Text, null, t("vizbuilder.error.message", { message: errorMessage })),
6744
+ /* @__PURE__ */ React21__default.createElement(Group, { spacing: "xs", my: "sm" }, /* @__PURE__ */ React21__default.createElement(Button, { onClick: clearHandler, size: "xs", variant: "light" }, t("vizbuilder.action_retry")), /* @__PURE__ */ React21__default.createElement(
6745
+ Button,
6746
+ {
6747
+ component: "a",
6748
+ href: `https://github.com/Datawheel/vizbuilder/issues/new?${issueParams}`,
6749
+ leftIcon: /* @__PURE__ */ React21__default.createElement(IconBrandGithub, { size: "1rem" }),
6750
+ rel: "noopener noreferrer",
6751
+ role: "button",
6752
+ size: "xs",
6753
+ tabIndex: 0,
6754
+ target: "_blank",
6755
+ variant: "subtle"
6756
+ },
6757
+ t("vizbuilder.action_fileissue")
6758
+ ))
6759
+ ));
6760
+ });
6761
+ }
6801
6762
 
6802
6763
  // src/components/Explorer.tsx
6803
6764
  var defaultVizbuilderConfig = {
@@ -6815,7 +6776,7 @@ var defaultVizbuilderConfig = {
6815
6776
  TREE_MAP_SHAPE_MAX: 1e3
6816
6777
  },
6817
6778
  downloadFormats: ["SVG", "PNG"],
6818
- ErrorBoundary,
6779
+ CardErrorComponent: ReportIssueCard,
6819
6780
  NonIdealState
6820
6781
  };
6821
6782
  var defaultTourConfig = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datawheel/data-explorer",
3
- "version": "1.1.17",
3
+ "version": "1.2.0-rc.1",
4
4
  "main": "./dist/main.mjs",
5
5
  "types": "./dist/main.d.mts",
6
6
  "files": [
@@ -19,7 +19,7 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "@datawheel/use-translation": "^0.2.0",
22
- "@datawheel/vizbuilder": "^0.7.0",
22
+ "@datawheel/vizbuilder": "^0.7.4",
23
23
  "@reactour/tour": "^3.7.0",
24
24
  "@reduxjs/toolkit": "^1.9.3",
25
25
  "@tabler/icons-react": "^2.7.0",
@@ -79,4 +79,4 @@
79
79
  "vite": "^6.3.0",
80
80
  "wrangler": "^4.11.0"
81
81
  }
82
- }
82
+ }