@datawheel/data-explorer 0.2.6 → 0.2.8

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 (2) hide show
  1. package/dist/main.js +492 -60
  2. package/package.json +2 -1
package/dist/main.js CHANGED
@@ -1,8 +1,8 @@
1
- import { keyframes, createStyles, Select, rem, Flex, Title, Text, Group, Button, Input, Box, Stack, SimpleGrid, ScrollArea, LoadingOverlay, Table, MultiSelect, Center, NumberInput, Menu, ActionIcon, Alert, Loader, Modal, MantineProvider, Paper, useComponentDefaultProps, Anchor, Tabs, Switch, ThemeIcon, Tooltip, useMantineTheme, CloseButton, Drawer, Divider, Checkbox, UnstyledButton, Accordion, Popover } from '@mantine/core';
1
+ import { keyframes, createStyles, Select, rem, Flex, Title, Text, Group, Button, Input, Box, Stack, SimpleGrid, ScrollArea, LoadingOverlay, Table, MultiSelect, Center, NumberInput, Menu, ActionIcon, UnstyledButton, Alert, Loader, Container, Modal, useMantineTheme, MantineProvider, Paper, useComponentDefaultProps, Anchor, Tabs, Switch, ThemeIcon, Tooltip, CloseButton, Drawer, Divider, Checkbox, packSx, Affix, Accordion, Popover } from '@mantine/core';
2
2
  import { useClipboard, useClickOutside, useFullscreen, useDebouncedState, useMediaQuery, useDisclosure } from '@mantine/hooks';
3
- import { IconWorld, IconExternalLink, IconClipboard, IconSettings, IconMathGreater, IconMathLower, IconArrowsLeftRight, IconAlertCircle, IconAlertTriangle, IconCopy, IconDownload, IconDotsVertical, IconArrowsMinimize, IconArrowsMaximize, IconTrash, IconInfoCircleFilled, IconSearch, IconPhotoDown, IconVectorTriangle, IconArrowsSort, IconSortDescendingNumbers, IconSortDescendingLetters, IconSortAscendingNumbers, IconSortAscendingLetters, IconPlus, IconStack3, IconFilterOff, IconFilter, IconBox, IconClock, IconLanguage } from '@tabler/icons-react';
3
+ import { IconWorld, IconExternalLink, IconClipboard, IconSettings, IconMathGreater, IconMathLower, IconArrowsLeftRight, IconAlertCircle, IconAlertTriangle, IconCopy, IconDownload, IconDotsVertical, IconArrowRight, IconArrowLeft, IconArrowsMinimize, IconArrowsMaximize, IconTrash, IconInfoCircleFilled, IconSearch, IconPhotoDown, IconVectorTriangle, IconArrowsSort, IconSortDescendingNumbers, IconSortDescendingLetters, IconSortAscendingNumbers, IconSortAscendingLetters, IconPlus, IconStack3, IconFilterOff, IconFilter, IconBox, IconClock, IconHelpCircle, IconLanguage } from '@tabler/icons-react';
4
4
  import * as React13 from 'react';
5
- import React13__default, { createContext, forwardRef, useMemo, useCallback, useContext, useState, useEffect, useRef, Suspense, useLayoutEffect } from 'react';
5
+ import React13__default, { createContext, forwardRef, useMemo, useCallback, useContext, useRef, useEffect, useState, Suspense, useLayoutEffect } from 'react';
6
6
  import { translationFactory } from '@datawheel/use-translation';
7
7
  import { translationDict, generateCharts, createChartConfig } from '@datawheel/vizbuilder';
8
8
  import { createSlice, createSelector, combineReducers, bindActionCreators, configureStore } from '@reduxjs/toolkit';
@@ -12,7 +12,7 @@ import { QueryClient, QueryClientProvider, useQuery, useQueryClient } from '@tan
12
12
  import debounce from 'lodash.debounce';
13
13
  import { MRT_ProgressBar, flexRender, MRT_TableBodyCell, MRT_ToolbarAlertBanner, useMantineReactTable, MantineReactTable, MRT_TablePagination } from 'mantine-react-table';
14
14
  import { formatAbbreviate, format } from 'd3plus-format';
15
- import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
15
+ import { TourProvider, useTour } from '@reactour/tour';
16
16
  import yn from 'yn';
17
17
  import { matchSorter } from 'match-sorter';
18
18
  import { BarChart, Donut, Geomap, LinePlot, Pie, StackedArea, Treemap } from 'd3plus-react';
@@ -66,7 +66,7 @@ var require_FileSaver = __commonJS({
66
66
  }
67
67
  var doc = view.document, get_URL = function() {
68
68
  return view.URL || view.webkitURL || view;
69
- }, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a"), can_use_save_link = "download" in save_link, click = function(node) {
69
+ }, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a"), can_use_save_link = "download" in save_link, click2 = function(node) {
70
70
  var event = new MouseEvent("click");
71
71
  node.dispatchEvent(event);
72
72
  }, is_safari = /constructor/i.test(view.HTMLElement) || view.safari, is_chrome_ios = /CriOS\/[\d]+/.test(navigator.userAgent), throw_outside = function(ex) {
@@ -142,7 +142,7 @@ var require_FileSaver = __commonJS({
142
142
  setTimeout(function() {
143
143
  save_link.href = object_url;
144
144
  save_link.download = name4;
145
- click(save_link);
145
+ click2(save_link);
146
146
  dispatch_all();
147
147
  revoke(object_url);
148
148
  filesaver.readyState = filesaver.DONE;
@@ -223,7 +223,9 @@ var defaultTranslation = {
223
223
  formats: {
224
224
  csv: "CSV",
225
225
  json: "JSON",
226
- jsonarrays: "JSON Arrays",
226
+ tsv: "TSV",
227
+ parquet: "Parquet",
228
+ // jsonarrays: "JSON Arrays",
227
229
  jsonrecords: "JSON Records",
228
230
  xlsx: "XLSX"
229
231
  },
@@ -366,6 +368,67 @@ var defaultTranslation = {
366
368
  sort_asc: "Sort Asc",
367
369
  sort_desc: "Sort Desc"
368
370
  },
371
+ tour: {
372
+ controls: {
373
+ prev: "Previous",
374
+ next: "Next",
375
+ help: "Help"
376
+ },
377
+ steps: {
378
+ welcome: {
379
+ title: "Welcome to the Data Explorer",
380
+ text1: "This tutorial will guide you through the steps on how to use the Data Explorer",
381
+ text2: "By following this tutorial, you will be able to find data of interest and generate your own data tables and visualizations."
382
+ },
383
+ locale: {
384
+ title: "Multilingual",
385
+ text1: "The Data Explorer makes data available multiple languages.",
386
+ text2: "Use the dropdown menu to change the output language of the data."
387
+ },
388
+ dataset: {
389
+ title: "Selecting a Dataset",
390
+ text1: "Begin by selecting a topic of interest.",
391
+ text2: "Then, select a specific data table within that topic grouping."
392
+ },
393
+ search: {
394
+ title: "Searching for a Dataset",
395
+ text1: "You can also explore the list of topics and datasets.",
396
+ text2: "Start typing to filter the list of datasets with your search"
397
+ },
398
+ table: {
399
+ title: "Data Table",
400
+ text1: "Results are initially displayed as a data table.",
401
+ text2: "Each column header allows live sorting and filtering options."
402
+ },
403
+ columns: {
404
+ title: "Columns",
405
+ text1: "Select the columns that you are interested in viewing.",
406
+ text2: "When you toggle any column checkbox, the data table will automatically update to reflect your selection."
407
+ },
408
+ filters: {
409
+ title: "Filters",
410
+ text1: "You can filter the elements of each column that you want to display in the data table and visualization.",
411
+ text2: "If you want all available elements to be displayed, you don't need to apply filters."
412
+ },
413
+ download: {
414
+ title: "Downloading the Data",
415
+ text1: "You are able to download the information in CSV and JSON formats."
416
+ },
417
+ api: {
418
+ title: "API",
419
+ text1: "You can access the raw data programmatically using the Data Explorer JSON REST API."
420
+ },
421
+ vizbuilderTab: {
422
+ title: "Vizbuilder",
423
+ text1: "You can see the results of your query in different types of visualizations."
424
+ },
425
+ last: {
426
+ title: "Let's get started!",
427
+ text: "You are ready to start exploring the Data Explorer database and generate your own tables and visualizations.",
428
+ button: "Begin"
429
+ }
430
+ }
431
+ },
369
432
  transfer_input: {
370
433
  count_hidden: "{{n}} item hidden",
371
434
  count_hidden_plural: "{{n}} items hidden",
@@ -508,7 +571,6 @@ var Comparison = /* @__PURE__ */ ((Comparison2) => {
508
571
  })(Comparison || {});
509
572
  var Format = /* @__PURE__ */ ((Format2) => {
510
573
  Format2["csv"] = "csv";
511
- Format2["jsonarrays"] = "jsonarrays";
512
574
  Format2["jsonrecords"] = "jsonrecords";
513
575
  Format2["parquet"] = "parquet";
514
576
  Format2["tsv"] = "tsv";
@@ -1369,7 +1431,7 @@ var ComplexityModuleClient = class {
1369
1431
  init_esm_shims();
1370
1432
  var TesseractModuleClient = class {
1371
1433
  constructor(baseURL, config) {
1372
- this.baseURL = baseURL || "";
1434
+ this.baseURL = baseURL ? baseURL.replace(/\/?$/, "/") : "";
1373
1435
  this.requestConfig = config || { headers: new Headers() };
1374
1436
  }
1375
1437
  fetchStatus(params) {
@@ -1578,6 +1640,10 @@ function useKey(params = {}) {
1578
1640
  }
1579
1641
 
1580
1642
  // src/hooks/settings.tsx
1643
+ var defaultToolbarConfig = {
1644
+ buttons: [],
1645
+ showLabels: true
1646
+ };
1581
1647
  var SettingsContext = createContext(void 0);
1582
1648
  var { Consumer: ContextConsumer, Provider: ContextProvider } = SettingsContext;
1583
1649
  function SettingsProvider(props) {
@@ -1592,10 +1658,11 @@ function SettingsProvider(props) {
1592
1658
  panels: props.panels,
1593
1659
  previewLimit: props.previewLimit || 50,
1594
1660
  paginationConfig: (_a = props.pagination) != null ? _a : { rowsLimits: [100, 300, 500, 1e3], defaultLimit: 100 },
1595
- measuresActive: props.measuresActive
1661
+ measuresActive: props.measuresActive,
1662
+ toolbarConfig: { ...defaultToolbarConfig, ...props.toolbarConfig }
1596
1663
  };
1597
1664
  },
1598
- [props.formatters, props.previewLimit]
1665
+ [props.formatters, props.previewLimit, props.toolbarConfig]
1599
1666
  );
1600
1667
  return /* @__PURE__ */ React13__default.createElement(ContextProvider, { value }, props.children);
1601
1668
  }
@@ -1667,7 +1734,7 @@ function willDownloadQuery(format2) {
1667
1734
  }
1668
1735
  const queryParams = { ...params, pagiLimit: 0, pagiOffset: 0 };
1669
1736
  return tesseract.fetchData({ request: queryParamsToRequest(queryParams), format: format2 }).then((response) => response.blob()).then((result) => ({
1670
- content: result[0],
1737
+ content: result,
1671
1738
  extension: format2.replace(/json\w+/, "json"),
1672
1739
  name: `${params.cube}_${(/* @__PURE__ */ new Date()).toISOString()}`
1673
1740
  }));
@@ -1905,7 +1972,7 @@ function willReloadCube({ locale }) {
1905
1972
  }
1906
1973
  function willSetupClient(baseURL, defaultLocale, requestConfig) {
1907
1974
  return (dispatch, getState, { tesseract }) => {
1908
- tesseract.baseURL = baseURL;
1975
+ tesseract.baseURL = baseURL.replace(/\/?$/, "/");
1909
1976
  getState();
1910
1977
  const search = new URLSearchParams(location.search);
1911
1978
  const locale = search.get("locale");
@@ -2489,10 +2556,10 @@ var ApiAndCsvButtons = (props) => {
2489
2556
  return /* @__PURE__ */ React13__default.createElement(Box, { id: "query-results-debug-view" }, /* @__PURE__ */ React13__default.createElement(Group, { spacing: "xs" }, url && /* @__PURE__ */ React13__default.createElement(
2490
2557
  Button,
2491
2558
  {
2492
- variant: "filled",
2493
- color: "dark",
2559
+ id: "dex-api-btn",
2560
+ variant: "subtle",
2494
2561
  leftIcon: /* @__PURE__ */ React13__default.createElement(IconCopy, { size: 20 }),
2495
- sx: { height: 30, backgroundColor: "#5A5A5A" },
2562
+ sx: { height: 30 },
2496
2563
  onClick: copyHandler
2497
2564
  },
2498
2565
  copied ? t("action_copy_done") : t("action_copy"),
@@ -2508,10 +2575,9 @@ var DownloadQuery = ({ data }) => {
2508
2575
  /* @__PURE__ */ React13__default.createElement(
2509
2576
  ButtonDownload,
2510
2577
  {
2511
- variant: "filled",
2512
- color: "dark",
2578
+ variant: "light",
2513
2579
  leftIcon: /* @__PURE__ */ React13__default.createElement(IconDownload, { size: 20 }),
2514
- sx: { height: 30, backgroundColor: "#5A5A5A" },
2580
+ sx: { height: 30 },
2515
2581
  key: "download_csv",
2516
2582
  provider: () => actions2.willDownloadQuery("csv")
2517
2583
  },
@@ -2521,7 +2587,7 @@ var DownloadQuery = ({ data }) => {
2521
2587
  if (components.length === 0 || data.length === 0) {
2522
2588
  return null;
2523
2589
  }
2524
- return /* @__PURE__ */ React13__default.createElement(Box, { id: "button-group-download-results" }, /* @__PURE__ */ React13__default.createElement(Group, { spacing: "xs" }, components, /* @__PURE__ */ React13__default.createElement(MenuOpts, { formats: formats.filter((f) => f !== "csv") })));
2590
+ return /* @__PURE__ */ React13__default.createElement(Box, { id: "dex-btn-group-download" }, /* @__PURE__ */ React13__default.createElement(Group, { spacing: "xs" }, components, /* @__PURE__ */ React13__default.createElement(MenuOpts, { formats: formats.filter((f) => f !== "csv") })));
2525
2591
  };
2526
2592
  var mimeTypes = {
2527
2593
  csv: "text/csv",
@@ -2695,7 +2761,7 @@ function BarsSVG() {
2695
2761
  );
2696
2762
  }
2697
2763
  function FullScreenSVG() {
2698
- return /* @__PURE__ */ React13__default.createElement("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React13__default.createElement("g", { clipPath: "url(#clip0_905_15763)" }, /* @__PURE__ */ React13__default.createElement(
2764
+ return /* @__PURE__ */ React13__default.createElement("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", strokeWidth: 1.5 }, /* @__PURE__ */ React13__default.createElement("g", { clipPath: "url(#clip0_905_15763)" }, /* @__PURE__ */ React13__default.createElement(
2699
2765
  "path",
2700
2766
  {
2701
2767
  d: "M3.33325 6.66668V5.00001C3.33325 4.55798 3.50885 4.13406 3.82141 3.8215C4.13397 3.50894 4.55789 3.33334 4.99992 3.33334H6.66659",
@@ -3155,10 +3221,17 @@ function TableView({
3155
3221
  }) {
3156
3222
  const isData = Boolean(table.getRowModel().rows.length);
3157
3223
  const loadingState = useSelector$1(selectLoadingState);
3224
+ const viewport = useRef(null);
3225
+ useEffect(() => {
3226
+ var _a;
3227
+ (_a = viewport.current) == null ? void 0 : _a.scrollTo({ top: 0, behavior: "smooth" });
3228
+ }, [pagination == null ? void 0 : pagination.pageIndex, pagination == null ? void 0 : pagination.pageSize]);
3158
3229
  return /* @__PURE__ */ React13__default.createElement(Box, { sx: { height: "100%" } }, /* @__PURE__ */ React13__default.createElement(Flex, { direction: "column", justify: "space-between", sx: { height: "100%", flex: "1 1 auto" } }, /* @__PURE__ */ React13__default.createElement(MRT_ProgressBar, { isTopToolbar: false, table }), /* @__PURE__ */ React13__default.createElement(
3159
3230
  ScrollArea,
3160
3231
  {
3232
+ id: "dex-table",
3161
3233
  h: isData ? "100%" : "auto",
3234
+ viewportRef: viewport,
3162
3235
  sx: {
3163
3236
  flex: "1 1 auto",
3164
3237
  position: "relative",
@@ -3220,11 +3293,22 @@ function TableView({
3220
3293
  key: header.id,
3221
3294
  sx: (theme) => isRowIndex ? index(theme) : base(theme)
3222
3295
  },
3223
- header.isPlaceholder ? null : flexRender(
3224
- (_a = header.column.columnDef.Header) != null ? _a : header.column.columnDef.header,
3225
- header.getContext()
3226
- ),
3227
- !isRowIndex && /* @__PURE__ */ React13__default.createElement(ColumnFilterCell, { isNumeric, header, table })
3296
+ /* @__PURE__ */ React13__default.createElement(
3297
+ Box,
3298
+ {
3299
+ sx: {
3300
+ display: "flex",
3301
+ flexFlow: "column",
3302
+ height: "100%",
3303
+ justifyContent: "space-between"
3304
+ }
3305
+ },
3306
+ header.isPlaceholder ? null : flexRender(
3307
+ (_a = header.column.columnDef.Header) != null ? _a : header.column.columnDef.header,
3308
+ header.getContext()
3309
+ ),
3310
+ !isRowIndex && /* @__PURE__ */ React13__default.createElement(ColumnFilterCell, { isNumeric, header, table })
3311
+ )
3228
3312
  );
3229
3313
  })))
3230
3314
  ),
@@ -3331,9 +3415,13 @@ function AddColumnsDrawer() {
3331
3415
  return /* @__PURE__ */ React13__default.createElement(React13__default.Fragment, null, /* @__PURE__ */ React13__default.createElement(
3332
3416
  Drawer,
3333
3417
  {
3418
+ id: "dex-column-drawer",
3334
3419
  opened,
3335
3420
  position: "right",
3336
3421
  onClose: close2,
3422
+ closeButtonProps: {
3423
+ id: "dex-column-drawer-close"
3424
+ },
3337
3425
  title: /* @__PURE__ */ React13__default.createElement(Group, null, /* @__PURE__ */ React13__default.createElement(IconPlus, { size: "1.2rem" }), /* @__PURE__ */ React13__default.createElement(Text, { fw: 700 }, t("params.add_columns"))),
3338
3426
  styles,
3339
3427
  overlayProps: {
@@ -3342,7 +3430,7 @@ function AddColumnsDrawer() {
3342
3430
  },
3343
3431
  /* @__PURE__ */ React13__default.createElement(MeasuresOptions, null),
3344
3432
  /* @__PURE__ */ React13__default.createElement(DrillDownOptions, null)
3345
- ), /* @__PURE__ */ React13__default.createElement(Group, { position: "center", sx: { flexWrap: "nowrap" } }, smallerThanMd ? /* @__PURE__ */ React13__default.createElement(ActionIcon, { onClick: open, size: "md", variant: "filled", color: theme.primaryColor }, /* @__PURE__ */ React13__default.createElement(IconStack3, { size: "0.75rem" })) : /* @__PURE__ */ React13__default.createElement(Button, { leftIcon: /* @__PURE__ */ React13__default.createElement(IconPlus, { size: "1.2rem" }), onClick: open, m: "md", size: "sm" }, t("params.add_columns"))));
3433
+ ), /* @__PURE__ */ React13__default.createElement(Group, { position: "center", sx: { flexWrap: "nowrap" } }, smallerThanMd ? /* @__PURE__ */ React13__default.createElement(ActionIcon, { onClick: open, size: "md", variant: "filled", color: theme.primaryColor }, /* @__PURE__ */ React13__default.createElement(IconStack3, { size: "0.75rem" })) : /* @__PURE__ */ React13__default.createElement(Button, { id: "dex-column-btn", leftIcon: /* @__PURE__ */ React13__default.createElement(IconPlus, { size: "1.2rem" }), onClick: open, m: "md", size: "sm" }, t("params.add_columns"))));
3346
3434
  }
3347
3435
  function DrillDownOptions() {
3348
3436
  const locale = useSelector$1(selectLocale);
@@ -3380,7 +3468,7 @@ function DimensionItem({
3380
3468
  activeItems
3381
3469
  }
3382
3470
  ));
3383
- return /* @__PURE__ */ React13__default.createElement("div", { key: dimension.name }, /* @__PURE__ */ React13__default.createElement(
3471
+ return /* @__PURE__ */ React13__default.createElement("div", { key: dimension.name, className: "dex-dimension-control", id: `dex-dimension-${dimension.name}` }, /* @__PURE__ */ React13__default.createElement(
3384
3472
  Divider,
3385
3473
  {
3386
3474
  my: "md",
@@ -3496,7 +3584,7 @@ function LevelItem({
3496
3584
  const isDisabled = isOtherHierarchySelected && !checked;
3497
3585
  if (!currentDrilldown) return;
3498
3586
  const paddingLeft = `${5 * depth + 5}px`;
3499
- return currentDrilldown && /* @__PURE__ */ React13__default.createElement(React13__default.Fragment, null, /* @__PURE__ */ React13__default.createElement(Group, { mt: "sm", position: "apart", key: level.name, noWrap: true }, /* @__PURE__ */ React13__default.createElement(
3587
+ return currentDrilldown && /* @__PURE__ */ React13__default.createElement(React13__default.Fragment, null, /* @__PURE__ */ React13__default.createElement(Group, { className: "dex-level-control", mt: "sm", position: "apart", key: level.name, noWrap: true }, /* @__PURE__ */ React13__default.createElement(
3500
3588
  Checkbox,
3501
3589
  {
3502
3590
  sx: { cursor: "pointer", paddingLeft },
@@ -3518,6 +3606,7 @@ function LevelItem({
3518
3606
  ), /* @__PURE__ */ React13__default.createElement(Group, { sx: { flexWrap: "nowrap" } }, /* @__PURE__ */ React13__default.createElement(
3519
3607
  ActionIcon,
3520
3608
  {
3609
+ className: "dex-level-filter",
3521
3610
  size: "sm",
3522
3611
  onClick: () => setActiveFilter((value) => !value),
3523
3612
  disabled: isDisabled
@@ -3843,6 +3932,7 @@ var toolbarSx = (t) => ({
3843
3932
  height: "fit-content"
3844
3933
  });
3845
3934
  function ToolbarButton({ icon, label, onClick = () => void 0 }) {
3935
+ const { toolbarConfig } = useSettings();
3846
3936
  return /* @__PURE__ */ React13__default.createElement(
3847
3937
  UnstyledButton,
3848
3938
  {
@@ -3850,7 +3940,23 @@ function ToolbarButton({ icon, label, onClick = () => void 0 }) {
3850
3940
  py: { base: "0.2rem", md: 0 },
3851
3941
  sx: (t) => ({ "& svg path": { stroke: t.colorScheme === "dark" ? "white" : "black" } })
3852
3942
  },
3853
- /* @__PURE__ */ React13__default.createElement(Group, { spacing: "xs", noWrap: true }, icon, /* @__PURE__ */ React13__default.createElement(Text, { size: "sm" }, label))
3943
+ /* @__PURE__ */ React13__default.createElement(Group, { spacing: "xs", noWrap: true }, icon, (toolbarConfig == null ? void 0 : toolbarConfig.showLabels) && label && /* @__PURE__ */ React13__default.createElement(Text, { size: "sm" }, label))
3944
+ );
3945
+ }
3946
+ function TourButton() {
3947
+ const { setIsOpen, setCurrentStep } = useTour();
3948
+ const { translate: t } = useTranslation();
3949
+ const startTour = () => {
3950
+ setCurrentStep(0);
3951
+ setIsOpen(true);
3952
+ };
3953
+ return /* @__PURE__ */ React13__default.createElement(
3954
+ ToolbarButton,
3955
+ {
3956
+ icon: /* @__PURE__ */ React13__default.createElement(IconHelpCircle, { strokeWidth: 1.5 }),
3957
+ label: t("tour.controls.help"),
3958
+ onClick: startTour
3959
+ }
3854
3960
  );
3855
3961
  }
3856
3962
  function Toolbar({
@@ -3859,11 +3965,12 @@ function Toolbar({
3859
3965
  }) {
3860
3966
  const { translate: t } = useTranslation();
3861
3967
  const theme = useMantineTheme();
3862
- const smallerThanMd = useMediaQuery(`(max-width: ${theme.breakpoints.md})`);
3968
+ const smallerThanLg = useMediaQuery(`(max-width: ${theme.breakpoints.lg})`);
3969
+ const { toolbarConfig } = useSettings();
3863
3970
  const settings = /* @__PURE__ */ React13__default.createElement(
3864
3971
  Flex,
3865
3972
  {
3866
- direction: { base: "column", md: "row" },
3973
+ direction: { base: "column", lg: "row" },
3867
3974
  justify: "flex-start",
3868
3975
  sx: toolbarSx,
3869
3976
  p: "0.325rem",
@@ -3871,6 +3978,8 @@ function Toolbar({
3871
3978
  wrap: "nowrap",
3872
3979
  gap: "xs"
3873
3980
  },
3981
+ toolbarConfig == null ? void 0 : toolbarConfig.buttons.map((b) => /* @__PURE__ */ React13__default.createElement(ToolbarButton, { key: b.label, ...b })),
3982
+ /* @__PURE__ */ React13__default.createElement(TourButton, null),
3874
3983
  /* @__PURE__ */ React13__default.createElement(
3875
3984
  ToolbarButton,
3876
3985
  {
@@ -3880,8 +3989,10 @@ function Toolbar({
3880
3989
  }
3881
3990
  )
3882
3991
  );
3883
- return smallerThanMd ? /* @__PURE__ */ React13__default.createElement(Menu, null, /* @__PURE__ */ React13__default.createElement(Menu.Target, null, /* @__PURE__ */ React13__default.createElement(ActionIcon, null, /* @__PURE__ */ React13__default.createElement(IconSettings, null))), /* @__PURE__ */ React13__default.createElement(Menu.Dropdown, null, settings)) : settings;
3992
+ return smallerThanLg ? /* @__PURE__ */ React13__default.createElement(Menu, null, /* @__PURE__ */ React13__default.createElement(Menu.Target, null, /* @__PURE__ */ React13__default.createElement(ActionIcon, null, /* @__PURE__ */ React13__default.createElement(IconSettings, null))), /* @__PURE__ */ React13__default.createElement(Menu.Dropdown, null, settings)) : settings;
3884
3993
  }
3994
+
3995
+ // src/components/ExplorerResults.tsx
3885
3996
  var useStyles2 = createStyles(() => ({
3886
3997
  container: {
3887
3998
  minHeight: "40vh",
@@ -4011,7 +4122,7 @@ function SuccessResult(props) {
4011
4122
  pagination,
4012
4123
  setPagination
4013
4124
  }
4014
- )))))), /* @__PURE__ */ React13__default.createElement(ReactQueryDevtools, { initialIsOpen: true }));
4125
+ )))))));
4015
4126
  }
4016
4127
 
4017
4128
  // src/components/ParamsExplorer.tsx
@@ -4229,7 +4340,7 @@ function LocaleSelector() {
4229
4340
  if (localeOptions.length < 2) {
4230
4341
  return null;
4231
4342
  }
4232
- return /* @__PURE__ */ React13__default.createElement(Box, { id: "select-locale" }, /* @__PURE__ */ React13__default.createElement(Tooltip, { label: t("params.label_locale") }, /* @__PURE__ */ React13__default.createElement(
4343
+ return /* @__PURE__ */ React13__default.createElement(Box, { id: "dex-select-locale" }, /* @__PURE__ */ React13__default.createElement(Tooltip, { label: t("params.label_locale") }, /* @__PURE__ */ React13__default.createElement(
4233
4344
  SelectObject,
4234
4345
  {
4235
4346
  getLabel: "value",
@@ -4323,10 +4434,42 @@ function SideBarProvider(props) {
4323
4434
  }
4324
4435
  );
4325
4436
  }
4437
+ function SideBarControlBtn({ actionIconProps = {} }) {
4438
+ const { expanded, setExpanded } = useSideBar();
4439
+ const sx = (t) => ({
4440
+ alignSelf: "center",
4441
+ color: t.colorScheme === "dark" ? t.white : t.colors.gray[7]
4442
+ });
4443
+ if (expanded) return null;
4444
+ return /* @__PURE__ */ React13__default.createElement(
4445
+ ActionIcon,
4446
+ {
4447
+ onClick: () => setExpanded(!expanded),
4448
+ variant: "subtle",
4449
+ ...actionIconProps,
4450
+ sx: [sx, ...packSx(actionIconProps.sx)]
4451
+ },
4452
+ /* @__PURE__ */ React13__default.createElement(DataSetSVG, null)
4453
+ );
4454
+ }
4455
+ function SideBarControlBtnFixed() {
4456
+ const actionIconProps = {
4457
+ sx: (t) => ({
4458
+ backgroundColor: `${t.colorScheme === "dark" ? t.colors.dark[8] : t.colors.gray[1]} !important`,
4459
+ padding: `calc(${t.spacing.xs} / 2)`,
4460
+ borderRadius: t.radius.xl,
4461
+ width: 50,
4462
+ height: 50
4463
+ })
4464
+ };
4465
+ return /* @__PURE__ */ React13__default.createElement(Affix, { position: { left: "1rem", bottom: 150 } }, /* @__PURE__ */ React13__default.createElement(SideBarControlBtn, { actionIconProps }));
4466
+ }
4326
4467
  function SideBar(props) {
4327
4468
  const { expanded, setExpanded } = useSideBar();
4328
4469
  const { translate: t } = useTranslation();
4329
- return /* @__PURE__ */ React13__default.createElement(
4470
+ const theme = useMantineTheme();
4471
+ const smallerThanMd = useMediaQuery(`(max-width: ${theme.breakpoints.md})`);
4472
+ return /* @__PURE__ */ React13__default.createElement(React13__default.Fragment, null, smallerThanMd && /* @__PURE__ */ React13__default.createElement(SideBarControlBtnFixed, null), /* @__PURE__ */ React13__default.createElement(
4330
4473
  Box,
4331
4474
  {
4332
4475
  id: "dex-sidebar",
@@ -4341,8 +4484,8 @@ function SideBar(props) {
4341
4484
  boxSizing: "border-box",
4342
4485
  [t2.fn.smallerThan("md")]: {
4343
4486
  position: "absolute",
4344
- width: expanded ? 300 : 54,
4345
- height: expanded ? "calc(100vh - 75px)" : 54,
4487
+ width: expanded ? 300 : 0,
4488
+ height: expanded ? "calc(100vh - 50px)" : 0,
4346
4489
  bottom: expanded ? "unset" : t2.spacing.md,
4347
4490
  left: expanded ? "unset" : t2.spacing.md,
4348
4491
  overflow: "hidden",
@@ -4352,18 +4495,7 @@ function SideBar(props) {
4352
4495
  }
4353
4496
  })
4354
4497
  },
4355
- /* @__PURE__ */ React13__default.createElement(Flex, { h: "100%", direction: "column", justify: "flex-start" }, /* @__PURE__ */ React13__default.createElement(Box, { px: "sm", my: "sm" }, /* @__PURE__ */ React13__default.createElement(Flex, { direction: "column", sx: { flex: 1 } }, /* @__PURE__ */ React13__default.createElement(Flex, { align: "center", justify: "apart" }, /* @__PURE__ */ React13__default.createElement(
4356
- ActionIcon,
4357
- {
4358
- onClick: () => setExpanded(!expanded),
4359
- variant: "subtle",
4360
- sx: (t2) => ({
4361
- alignSelf: "center",
4362
- color: t2.colorScheme === "dark" ? t2.white : t2.colors.gray[7]
4363
- })
4364
- },
4365
- /* @__PURE__ */ React13__default.createElement(DataSetSVG, null)
4366
- ), /* @__PURE__ */ React13__default.createElement(
4498
+ /* @__PURE__ */ React13__default.createElement(Flex, { h: "100%", direction: "column", justify: "flex-start" }, /* @__PURE__ */ React13__default.createElement(Box, { px: "sm", my: "sm" }, /* @__PURE__ */ React13__default.createElement(Flex, { direction: "column", sx: { flex: 1 } }, /* @__PURE__ */ React13__default.createElement(Flex, { align: "center", justify: "apart" }, /* @__PURE__ */ React13__default.createElement(SideBarControlBtn, null), /* @__PURE__ */ React13__default.createElement(
4367
4499
  Group,
4368
4500
  {
4369
4501
  position: "apart",
@@ -4392,8 +4524,9 @@ function SideBar(props) {
4392
4524
  ), /* @__PURE__ */ React13__default.createElement(Box, { sx: { flexGrow: 1 } }))), /* @__PURE__ */ React13__default.createElement(
4393
4525
  ScrollArea,
4394
4526
  {
4395
- sx: (theme) => ({
4396
- borderTopColor: theme.colorScheme === "dark" ? theme.colors.dark[6] : theme.colors.gray[3],
4527
+ id: "dex-select-cube-area",
4528
+ sx: (theme2) => ({
4529
+ borderTopColor: theme2.colorScheme === "dark" ? theme2.colors.dark[6] : theme2.colors.gray[3],
4397
4530
  borderTopWidth: "1px",
4398
4531
  borderTopStyle: expanded ? "solid" : "none"
4399
4532
  })
@@ -4420,7 +4553,7 @@ function SideBar(props) {
4420
4553
  expanded ? /* @__PURE__ */ React13__default.createElement(IconChevronLeft, null) : /* @__PURE__ */ React13__default.createElement(IconChevronRight, null)
4421
4554
  )
4422
4555
  ))
4423
- );
4556
+ ));
4424
4557
  }
4425
4558
  var SideBar_default = SideBar;
4426
4559
  function SideBarItem({ children }) {
@@ -4445,6 +4578,7 @@ function Auto() {
4445
4578
  Input,
4446
4579
  {
4447
4580
  icon: /* @__PURE__ */ React13__default.createElement(IconSearch, null),
4581
+ id: "dex-search",
4448
4582
  radius: "xl",
4449
4583
  size: "md",
4450
4584
  placeholder: t("params.label_search"),
@@ -4524,7 +4658,7 @@ var useStyles3 = createStyles((theme) => ({
4524
4658
  },
4525
4659
  linkActive: {
4526
4660
  backgroundColor: theme.colorScheme === "dark" ? theme.fn.rgba(theme.colors[theme.primaryColor][9], 0.45) : theme.colors[theme.primaryColor][4],
4527
- color: theme.colorScheme === "dark" ? theme.colors[theme.primaryColor][1] : theme.white,
4661
+ color: theme.white,
4528
4662
  fontWeight: 500
4529
4663
  }
4530
4664
  }));
@@ -4597,7 +4731,7 @@ function SelectCubeInternal(props) {
4597
4731
  }
4598
4732
  }
4599
4733
  }, [selectedItem, cube, measuresActive]);
4600
- return /* @__PURE__ */ React13__default.createElement(Stack, { id: "select-cube", spacing: "xs", w: "100%" }, /* @__PURE__ */ React13__default.createElement(CubeTree, { items, locale, selectedItem }));
4734
+ return /* @__PURE__ */ React13__default.createElement(Stack, { id: "dex-select-cube", spacing: "xs", w: "100%" }, /* @__PURE__ */ React13__default.createElement(CubeTree, { items, locale, selectedItem }));
4601
4735
  }
4602
4736
  function AccordionControl(props) {
4603
4737
  return /* @__PURE__ */ React13__default.createElement(Box, { sx: { display: "flex", alignItems: "center" } }, /* @__PURE__ */ React13__default.createElement(Accordion.Control, { ...props }));
@@ -4764,7 +4898,7 @@ function CubeButton({
4764
4898
  }),
4765
4899
  onClick: () => onSelectCube(item, subtopic)
4766
4900
  },
4767
- table
4901
+ table != null ? table : item
4768
4902
  );
4769
4903
  }
4770
4904
  function SubtopicAccordion({
@@ -5534,7 +5668,303 @@ function stringifyMatrix(matrix, formatter2, format2) {
5534
5668
  ].join("\n");
5535
5669
  }
5536
5670
 
5671
+ // src/components/tour/ExplorerTour.tsx
5672
+ init_esm_shims();
5673
+
5674
+ // src/components/tour/useTourSteps.tsx
5675
+ init_esm_shims();
5676
+
5677
+ // src/components/tour/FirstStep.tsx
5678
+ init_esm_shims();
5679
+ function FirstStep({ introImage }) {
5680
+ const { translate: t } = useTranslation();
5681
+ return /* @__PURE__ */ React13__default.createElement(Container, { className: "tour-item tour-welcome", px: 0 }, introImage && /* @__PURE__ */ React13__default.createElement("div", { className: "tour-img" }, introImage), /* @__PURE__ */ React13__default.createElement(Box, { className: "tour-text", px: "md" }, /* @__PURE__ */ React13__default.createElement("h3", null, t("tour.steps.welcome.title")), /* @__PURE__ */ React13__default.createElement("p", null, t("tour.steps.welcome.text1")), /* @__PURE__ */ React13__default.createElement("p", null, t("tour.steps.welcome.text2"))));
5682
+ }
5683
+
5684
+ // src/components/tour/TourStep.tsx
5685
+ init_esm_shims();
5686
+ function TourStep(props) {
5687
+ const { title, texts } = props;
5688
+ const paragraphs = Array.isArray(texts) ? texts : [texts];
5689
+ return /* @__PURE__ */ React13__default.createElement(Container, { className: "tour-item tour-step", pt: "md" }, /* @__PURE__ */ React13__default.createElement("div", { className: "tour-text" }, /* @__PURE__ */ React13__default.createElement(Title, { order: 3 }, title), paragraphs.map((p, i) => /* @__PURE__ */ React13__default.createElement(Text, { component: "p", key: `p-${i + 1}` }, p))));
5690
+ }
5691
+
5692
+ // src/components/tour/LastStep.tsx
5693
+ init_esm_shims();
5694
+ function LastStep({ t }) {
5695
+ return /* @__PURE__ */ React13__default.createElement(Container, { className: "tour-item tour-last", pt: "md" }, /* @__PURE__ */ React13__default.createElement("div", { className: "tour-text" }, /* @__PURE__ */ React13__default.createElement(Title, { order: 3 }, t("tour.steps.last.title")), /* @__PURE__ */ React13__default.createElement(Text, { component: "p" }, t("tour.steps.last.text"))));
5696
+ }
5697
+
5698
+ // src/components/tour/useTourSteps.tsx
5699
+ var click = (selector) => () => {
5700
+ const element = document.querySelector(selector);
5701
+ element == null ? void 0 : element.click();
5702
+ };
5703
+ var useTourSteps = (tourConfig) => {
5704
+ const { translate: t } = useTranslation();
5705
+ const steps = useMemo(() => [
5706
+ {
5707
+ selector: "document",
5708
+ content: /* @__PURE__ */ React13__default.createElement(FirstStep, { introImage: tourConfig.introImage }),
5709
+ position: "center"
5710
+ },
5711
+ {
5712
+ selector: "#dex-select-locale",
5713
+ content: /* @__PURE__ */ React13__default.createElement(
5714
+ TourStep,
5715
+ {
5716
+ title: t("tour.steps.locale.title"),
5717
+ texts: [
5718
+ t("tour.steps.locale.text1"),
5719
+ t("tour.steps.locale.text2")
5720
+ ]
5721
+ }
5722
+ )
5723
+ },
5724
+ {
5725
+ selector: "#dex-select-cube-area",
5726
+ content: /* @__PURE__ */ React13__default.createElement(
5727
+ TourStep,
5728
+ {
5729
+ title: t("tour.steps.dataset.title"),
5730
+ texts: [
5731
+ t("tour.steps.dataset.text1"),
5732
+ t("tour.steps.dataset.text2")
5733
+ ]
5734
+ }
5735
+ )
5736
+ },
5737
+ {
5738
+ selector: "#dex-search",
5739
+ content: /* @__PURE__ */ React13__default.createElement(
5740
+ TourStep,
5741
+ {
5742
+ title: t("tour.steps.search.title"),
5743
+ texts: [
5744
+ t("tour.steps.search.text1"),
5745
+ t("tour.steps.search.text2")
5746
+ ]
5747
+ }
5748
+ )
5749
+ },
5750
+ {
5751
+ selector: "#dex-table",
5752
+ content: /* @__PURE__ */ React13__default.createElement(
5753
+ TourStep,
5754
+ {
5755
+ title: t("tour.steps.table.title"),
5756
+ texts: [
5757
+ t("tour.steps.table.text1"),
5758
+ t("tour.steps.table.text2")
5759
+ ]
5760
+ }
5761
+ )
5762
+ },
5763
+ {
5764
+ selector: "#dex-column-drawer-body",
5765
+ actionBefore: click("#dex-column-btn"),
5766
+ stepInteraction: true,
5767
+ content: /* @__PURE__ */ React13__default.createElement(
5768
+ TourStep,
5769
+ {
5770
+ title: t("tour.steps.columns.title"),
5771
+ texts: [
5772
+ t("tour.steps.columns.text1"),
5773
+ t("tour.steps.columns.text2")
5774
+ ]
5775
+ }
5776
+ )
5777
+ },
5778
+ {
5779
+ selector: ".dex-dimension-control",
5780
+ actionBefore: click(".dex-level-filter"),
5781
+ actionAfter: click("#dex-column-drawer-close"),
5782
+ stepInteraction: true,
5783
+ content: /* @__PURE__ */ React13__default.createElement(
5784
+ TourStep,
5785
+ {
5786
+ title: t("tour.steps.filters.title"),
5787
+ texts: [
5788
+ t("tour.steps.filters.text1"),
5789
+ t("tour.steps.filters.text2")
5790
+ ]
5791
+ }
5792
+ )
5793
+ },
5794
+ {
5795
+ selector: "#dex-btn-group-download",
5796
+ content: /* @__PURE__ */ React13__default.createElement(
5797
+ TourStep,
5798
+ {
5799
+ title: t("tour.steps.download.title"),
5800
+ texts: [t("tour.steps.download.text1")]
5801
+ }
5802
+ )
5803
+ },
5804
+ {
5805
+ selector: "#dex-api-btn",
5806
+ content: /* @__PURE__ */ React13__default.createElement(
5807
+ TourStep,
5808
+ {
5809
+ title: t("tour.steps.api.title"),
5810
+ texts: [t("tour.steps.api.text1")]
5811
+ }
5812
+ )
5813
+ },
5814
+ ...tourConfig.extraSteps || [],
5815
+ {
5816
+ selector: "viewport",
5817
+ content: /* @__PURE__ */ React13__default.createElement(LastStep, { t }),
5818
+ position: "center"
5819
+ }
5820
+ // ...
5821
+ ], [tourConfig.extraSteps]);
5822
+ return steps;
5823
+ };
5824
+
5825
+ // src/components/tour/ExplorerTour.tsx
5826
+ function PrevButton(props) {
5827
+ const { translate: t } = useTranslation();
5828
+ const theme = useMantineTheme();
5829
+ const isRtl = theme.dir === "rtl";
5830
+ const handleClick = () => props.setCurrentStep(
5831
+ (s) => s === 0 ? props.steps.length - 1 : s - 1
5832
+ );
5833
+ return /* @__PURE__ */ React13__default.createElement(
5834
+ Button,
5835
+ {
5836
+ leftIcon: isRtl ? /* @__PURE__ */ React13__default.createElement(IconArrowRight, { size: "0.8rem" }) : /* @__PURE__ */ React13__default.createElement(IconArrowLeft, { size: "0.8rem" }),
5837
+ onClick: handleClick,
5838
+ radius: 0,
5839
+ size: "lg",
5840
+ sx: { flex: "0 0 50%" },
5841
+ variant: "light",
5842
+ disabled: props.currentStep === 0,
5843
+ w: "50%"
5844
+ },
5845
+ t("tour.controls.prev")
5846
+ );
5847
+ }
5848
+ function NextButton(props) {
5849
+ const { translate: t } = useTranslation();
5850
+ const theme = useMantineTheme();
5851
+ const isRtl = theme.dir === "rtl";
5852
+ const handleClick = () => {
5853
+ if (props.currentStep === props.steps.length - 1) {
5854
+ props.setIsOpen(false);
5855
+ props.setCurrentStep(0);
5856
+ } else {
5857
+ const nextStep = props.steps[props.currentStep + 1];
5858
+ if (nextStep.hasOwnProperty("actionBefore")) {
5859
+ nextStep.actionBefore();
5860
+ setTimeout(() => props.setCurrentStep((s) => s + 1), 250);
5861
+ } else {
5862
+ props.setCurrentStep((s) => s + 1);
5863
+ }
5864
+ }
5865
+ };
5866
+ return /* @__PURE__ */ React13__default.createElement(
5867
+ Button,
5868
+ {
5869
+ variant: "filled",
5870
+ w: "50%",
5871
+ size: "lg",
5872
+ sx: { flex: "0 0 50%" },
5873
+ onClick: handleClick,
5874
+ rightIcon: isRtl ? /* @__PURE__ */ React13__default.createElement(IconArrowLeft, { size: "0.8rem" }) : /* @__PURE__ */ React13__default.createElement(IconArrowRight, { size: "0.8rem" }),
5875
+ radius: 0
5876
+ },
5877
+ t("tour.controls.next")
5878
+ );
5879
+ }
5880
+ var withBase = (styles2) => (base) => ({ ...base, ...styles2 });
5881
+ var keyboardHandler = (rtl) => (e, clickProps) => {
5882
+ e.stopPropagation();
5883
+ if (!clickProps) return;
5884
+ function next() {
5885
+ if (clickProps.currentStep === clickProps.steps.length - 1) {
5886
+ clickProps.setIsOpen(false);
5887
+ clickProps.setCurrentStep(0);
5888
+ } else {
5889
+ const nextStep = clickProps.steps[clickProps.currentStep + 1];
5890
+ if (nextStep.hasOwnProperty("actionBefore")) {
5891
+ nextStep.actionBefore();
5892
+ setTimeout(() => clickProps.setCurrentStep((s) => s + 1), 250);
5893
+ } else {
5894
+ clickProps.setCurrentStep((s) => s + 1);
5895
+ }
5896
+ }
5897
+ }
5898
+ function prev() {
5899
+ clickProps.setCurrentStep(
5900
+ (s) => s === 0 ? clickProps.steps.length - 1 : s - 1
5901
+ );
5902
+ }
5903
+ if (e.keyCode === 27) {
5904
+ e.preventDefault();
5905
+ clickProps.setIsOpen(false);
5906
+ }
5907
+ if (e.keyCode === 39) {
5908
+ e.preventDefault();
5909
+ if (rtl) {
5910
+ prev();
5911
+ } else {
5912
+ next();
5913
+ }
5914
+ }
5915
+ if (e.keyCode === 37) {
5916
+ e.preventDefault();
5917
+ if (rtl) {
5918
+ next();
5919
+ } else {
5920
+ prev();
5921
+ }
5922
+ }
5923
+ };
5924
+ function ExplorerTour({ children, tourConfig }) {
5925
+ const theme = useMantineTheme();
5926
+ const steps = useTourSteps(tourConfig);
5927
+ const styles2 = {
5928
+ popover: withBase({ padding: 0, borderRadius: theme.radius.md, overflow: "hidden" }),
5929
+ controls: withBase({ flexWrap: "wrap" }),
5930
+ navigation: withBase({
5931
+ justifyContent: "center",
5932
+ order: -1,
5933
+ width: "100%",
5934
+ margin: `0 auto ${theme.spacing.xs}`
5935
+ }),
5936
+ dot: (base, { current }) => ({
5937
+ ...base,
5938
+ background: current ? theme.fn.primaryColor() : "transparent",
5939
+ color: theme.fn.primaryColor(),
5940
+ borderColor: theme.colors.gray[5]
5941
+ })
5942
+ };
5943
+ const rtl = theme.dir === "rtl";
5944
+ return /* @__PURE__ */ React13__default.createElement(
5945
+ TourProvider,
5946
+ {
5947
+ steps,
5948
+ position: "right",
5949
+ prevButton: PrevButton,
5950
+ nextButton: NextButton,
5951
+ showBadge: false,
5952
+ styles: styles2,
5953
+ rtl: theme.dir === "rtl",
5954
+ keyboardHandler: keyboardHandler(rtl),
5955
+ disableInteraction: true,
5956
+ ...tourConfig == null ? void 0 : tourConfig.tourProps
5957
+ },
5958
+ children
5959
+ );
5960
+ }
5961
+
5537
5962
  // src/components/Explorer.tsx
5963
+ var defaultTourConfig = {
5964
+ extraSteps: [],
5965
+ introImage: null,
5966
+ tourProps: {}
5967
+ };
5538
5968
  function ExplorerComponent(props) {
5539
5969
  const {
5540
5970
  locale = "en",
@@ -5544,6 +5974,7 @@ function ExplorerComponent(props) {
5544
5974
  withinReduxProvider = false,
5545
5975
  withMultiQuery = false,
5546
5976
  pagination,
5977
+ tourConfig,
5547
5978
  measuresActive
5548
5979
  } = props;
5549
5980
  const panels = useMemo(
@@ -5568,9 +5999,10 @@ function ExplorerComponent(props) {
5568
5999
  withPermalink: props.withPermalink,
5569
6000
  panels,
5570
6001
  pagination,
5571
- measuresActive
6002
+ measuresActive,
6003
+ toolbarConfig: props.toolbarConfig
5572
6004
  },
5573
- /* @__PURE__ */ React13__default.createElement(TranslationProvider, { defaultLocale: locale, translations: props.translations }, /* @__PURE__ */ React13__default.createElement(
6005
+ /* @__PURE__ */ React13__default.createElement(TranslationProvider, { defaultLocale: locale, translations: props.translations }, /* @__PURE__ */ React13__default.createElement(ExplorerTour, { tourConfig: { ...defaultTourConfig, ...tourConfig } }, /* @__PURE__ */ React13__default.createElement(
5574
6006
  ExplorerContent,
5575
6007
  {
5576
6008
  defaultCube: props.defaultCube,
@@ -5584,7 +6016,7 @@ function ExplorerComponent(props) {
5584
6016
  splash: props.splash,
5585
6017
  withMultiQuery
5586
6018
  }
5587
- ))
6019
+ )))
5588
6020
  );
5589
6021
  if (withinMantineProvider) {
5590
6022
  content = /* @__PURE__ */ React13__default.createElement(
@@ -6794,4 +7226,4 @@ file-saver/FileSaver.js:
6794
7226
  (*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js *)
6795
7227
  */
6796
7228
 
6797
- export { DebugView, ExplorerComponent as Explorer, PivotView, SettingsConsumer, TableView, TranslationConsumer, createVizbuilderView, reducer as explorerReducer, thunkExtraArg as explorerThunkExtraArg, defaultTranslation as translationDict, useSettings, useTranslation };
7229
+ export { DebugView, ExplorerComponent as Explorer, PivotView, SettingsConsumer, TableView, ToolbarButton, TourStep, TranslationConsumer, createVizbuilderView, reducer as explorerReducer, thunkExtraArg as explorerThunkExtraArg, defaultTranslation as translationDict, useSettings, useTranslation };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datawheel/data-explorer",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "exports": {
5
5
  ".": {
6
6
  "import": "./dist/main.js"
@@ -19,6 +19,7 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "@datawheel/use-translation": "^0.2.0",
22
+ "@reactour/tour": "^3.7.0",
22
23
  "@reduxjs/toolkit": "^1.9.3",
23
24
  "@tabler/icons-react": "^2.7.0",
24
25
  "@tanstack/react-query": "^5.51.23",