@datawheel/data-explorer 0.3.21 → 0.3.22

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.mjs +72 -75
  2. package/package.json +1 -1
package/dist/main.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { Select, createStyles, rem, keyframes, Input, Box, Text, Stack, Group, Button, SimpleGrid, Flex, ScrollArea, LoadingOverlay, Table, MultiSelect, Center, UnstyledButton, Alert, Loader, Container, Title, NumberInput, Menu, ActionIcon, useMantineTheme, MantineProvider, Modal, useComponentDefaultProps, Anchor, Paper, CloseButton, Tooltip, Tabs, Switch, ThemeIcon, Drawer, Divider, Checkbox, packSx, Affix, Accordion, Popover } from '@mantine/core';
1
+ import { Select, createStyles, rem, keyframes, Input, Box, Text, Stack, Group, Button, SimpleGrid, Flex, ScrollArea, LoadingOverlay, Table, MultiSelect, Center, UnstyledButton, Alert, Loader, Container, Title, NumberInput, Menu, ActionIcon, useMantineTheme, MantineProvider, Modal, useComponentDefaultProps, Anchor, Paper, TextInput, CloseButton, Tooltip, Tabs, Switch, ThemeIcon, Drawer, Divider, Checkbox, packSx, Affix, Accordion, Popover } from '@mantine/core';
2
2
  import { useClipboard, useDebouncedState, useClickOutside, useFullscreen, useMediaQuery, useDisclosure } from '@mantine/hooks';
3
3
  import { IconWorld, IconExternalLink, IconClipboard, IconAlertCircle, IconAlertTriangle, IconSettings, IconMathGreater, IconMathLower, IconArrowsLeftRight, IconCopy, IconDownload, IconDotsVertical, IconArrowRight, IconArrowLeft, IconBrandGithub, IconCheck, IconShare, IconChevronLeft, IconChevronRight, IconSearch, IconLanguage, IconTrash, IconInfoCircleFilled, IconArrowsMinimize, IconArrowsMaximize, IconCircleOff, IconPlus, IconStack3, IconFilterOff, IconFilter, IconAdjustments, IconBox, IconClock, IconArrowsSort, IconSortDescendingNumbers, IconSortDescendingLetters, IconSortAscendingNumbers, IconSortAscendingLetters, IconHelpCircle, IconPhotoDown, IconVectorTriangle } from '@tabler/icons-react';
4
4
  import * as React6 from 'react';
@@ -8832,10 +8832,10 @@ var createContext3 = (name4) => {
8832
8832
  // src/hooks/buildGraph.tsx
8833
8833
  init_esm_shims();
8834
8834
  function useBuildGraph(locale) {
8835
- const items = useSelector(selectOlapCubeItems);
8835
+ const cubes = useSelector(selectOlapCubeItems);
8836
8836
  const graph = useMemo(() => {
8837
8837
  const graph2 = new graph_default();
8838
- const filteredItems = items.map((item) => {
8838
+ const filteredItems = cubes.map((item) => {
8839
8839
  const { name: name4 } = item;
8840
8840
  const topic = getAnnotation(item, "topic", locale);
8841
8841
  const topic_order = getAnnotation(item, "topic_order", locale);
@@ -8857,14 +8857,13 @@ function useBuildGraph(locale) {
8857
8857
  }).filter(Boolean);
8858
8858
  graph2.items = filteredItems;
8859
8859
  return graph2;
8860
- }, [items, locale]);
8860
+ }, [cubes, locale]);
8861
8861
  return graph;
8862
8862
  }
8863
8863
 
8864
8864
  // src/hooks/cubeSearch.tsx
8865
8865
  init_esm_shims();
8866
- function useCubeSearch(input, graph) {
8867
- const { code: locale } = useSelector(selectLocale);
8866
+ function useCubeSearch(graph, input, locale) {
8868
8867
  const results = useMemo(() => {
8869
8868
  if (graph.items.length > 0) {
8870
8869
  const { matches, map } = graph.filter(locale, input);
@@ -8877,32 +8876,22 @@ function useCubeSearch(input, graph) {
8877
8876
  results: [],
8878
8877
  map: /* @__PURE__ */ new Map()
8879
8878
  };
8880
- }, [input, graph]);
8879
+ }, [graph, input, locale]);
8881
8880
  return results;
8882
8881
  }
8883
8882
 
8884
8883
  // src/components/SideBar.tsx
8885
8884
  var [useSideBar, Provider] = createContext3("SideBar");
8886
8885
  function SideBarProvider(props) {
8887
- const [input, setInput] = useDebouncedState("", 200);
8886
+ const [input, setInput] = useDebouncedState("", 150, { leading: true });
8888
8887
  const [expanded, setExpanded] = useState(true);
8889
8888
  const graph = useBuildGraph(props.locale);
8890
- const { results, map } = useCubeSearch(input, graph);
8891
- return /* @__PURE__ */ React6__default.createElement(
8892
- Provider,
8893
- {
8894
- ...props,
8895
- value: {
8896
- expanded,
8897
- graph,
8898
- setExpanded,
8899
- results,
8900
- input,
8901
- map,
8902
- setInput
8903
- }
8904
- }
8889
+ const { results, map } = useCubeSearch(graph, input, props.locale);
8890
+ const value = useMemo(
8891
+ () => ({ expanded, setExpanded, input, setInput, graph, results, map }),
8892
+ [expanded, input, setInput, graph, results, map]
8905
8893
  );
8894
+ return /* @__PURE__ */ React6__default.createElement(Provider, { value }, props.children);
8906
8895
  }
8907
8896
  function SideBarControlBtn({ actionIconProps = {} }) {
8908
8897
  const { expanded, setExpanded } = useSideBar();
@@ -8935,7 +8924,7 @@ function SideBarControlBtnFixed() {
8935
8924
  return /* @__PURE__ */ React6__default.createElement(Affix, { position: { left: "1rem", bottom: 150 } }, /* @__PURE__ */ React6__default.createElement(SideBarControlBtn, { actionIconProps }));
8936
8925
  }
8937
8926
  function SideBar(props) {
8938
- const { expanded, setExpanded } = useSideBar();
8927
+ const { expanded, input, setExpanded, setInput } = useSideBar();
8939
8928
  const { translate: t } = useTranslation();
8940
8929
  const theme = useMantineTheme();
8941
8930
  const smallerThanMd = useMediaQuery(`(max-width: ${theme.breakpoints.md})`);
@@ -8989,7 +8978,7 @@ function SideBar(props) {
8989
8978
  width: expanded ? "100%" : 0
8990
8979
  }
8991
8980
  },
8992
- /* @__PURE__ */ React6__default.createElement(Auto, null)
8981
+ /* @__PURE__ */ React6__default.createElement(CubeSearchInput, { expanded, input, setInput })
8993
8982
  ), /* @__PURE__ */ React6__default.createElement(Box, { sx: { flexGrow: 1 } }))), /* @__PURE__ */ React6__default.createElement(
8994
8983
  ScrollArea,
8995
8984
  {
@@ -9026,7 +9015,7 @@ function SideBar(props) {
9026
9015
  ));
9027
9016
  }
9028
9017
  var SideBar_default = SideBar;
9029
- function SideBarItem({ children }) {
9018
+ function SideBarItem(props) {
9030
9019
  const { expanded } = useSideBar();
9031
9020
  return /* @__PURE__ */ React6__default.createElement(
9032
9021
  Box,
@@ -9038,22 +9027,24 @@ function SideBarItem({ children }) {
9038
9027
  transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1)"
9039
9028
  }
9040
9029
  },
9041
- children
9030
+ props.children
9042
9031
  );
9043
9032
  }
9044
- function Auto() {
9033
+ function CubeSearchInput(props) {
9034
+ const { expanded, input, setInput } = props;
9045
9035
  const { translate: t } = useTranslation();
9046
- const { expanded, input, setInput } = useSideBar();
9036
+ const ref = useRef(null);
9047
9037
  return /* @__PURE__ */ React6__default.createElement(
9048
- Input,
9038
+ TextInput,
9049
9039
  {
9040
+ ref,
9050
9041
  icon: /* @__PURE__ */ React6__default.createElement(IconSearch, null),
9051
9042
  id: "dex-search",
9052
9043
  radius: "xl",
9053
9044
  size: "md",
9054
9045
  placeholder: t("params.label_search"),
9055
9046
  defaultValue: input,
9056
- onInput: (e) => setInput(e.currentTarget.value),
9047
+ onInput: useCallback((e) => setInput(e.currentTarget.value), [setInput]),
9057
9048
  styles: {
9058
9049
  wrapper: {
9059
9050
  width: expanded ? "100%" : 0,
@@ -9068,58 +9059,65 @@ function Auto() {
9068
9059
  CloseButton,
9069
9060
  {
9070
9061
  "aria-label": "Clear input",
9071
- onClick: () => setInput(""),
9062
+ onClick: useCallback(() => {
9063
+ setInput("");
9064
+ if (ref.current) {
9065
+ ref.current.value = "";
9066
+ }
9067
+ }, [setInput]),
9072
9068
  style: { display: input ? void 0 : "none" }
9073
9069
  }
9074
9070
  )
9075
9071
  }
9076
9072
  );
9077
9073
  }
9074
+ CubeSearchInput.displayName = "CubeSearchInput";
9078
9075
 
9079
9076
  // src/components/Results.tsx
9080
9077
  function Results(props) {
9081
9078
  const { onSelectCube, graph, selectedItem, locale, getCube: getCube2, isSelected: isSelected2, isSelectionInProgress } = props;
9082
9079
  const { classes } = useStyles();
9083
- const { setExpanded, setInput, map } = useSideBar();
9084
- const result = [];
9085
- if (map) {
9086
- for (let [key, items] of map) {
9087
- const [topic, subtopic] = key.split(" - ");
9088
- const component = /* @__PURE__ */ React6__default.createElement("div", { key }, /* @__PURE__ */ React6__default.createElement(Divider, { my: "xs", label: key }), items.map((item) => {
9089
- const cube = getCube2(graph.items, item, subtopic, locale);
9090
- if (!cube) return null;
9091
- const table = getAnnotation(cube, "table", locale);
9092
- const isItemSelected = isSelected2(selectedItem, cube);
9093
- const handleClick = () => {
9094
- if (!isSelectionInProgress) {
9095
- onSelectCube(item, subtopic);
9096
- setExpanded(false);
9097
- setInput("");
9098
- }
9099
- };
9100
- return /* @__PURE__ */ React6__default.createElement(
9101
- Text,
9102
- {
9103
- key: cube.name,
9104
- component: "a",
9105
- fz: "xs",
9106
- className: isItemSelected ? `${classes.link} ${classes.linkActive}` : classes.link,
9107
- sx: (theme) => ({
9108
- opacity: isSelectionInProgress ? 0.5 : 1,
9109
- cursor: isSelectionInProgress ? "not-allowed" : "pointer",
9110
- transition: "opacity 0.2s ease",
9111
- pointerEvents: isSelectionInProgress ? "none" : "auto"
9112
- }),
9113
- onClick: handleClick
9114
- },
9115
- table
9116
- );
9117
- }));
9118
- result.push(component);
9119
- }
9120
- }
9121
- return /* @__PURE__ */ React6__default.createElement(Box, { px: "sm" }, result);
9080
+ const { map, setExpanded, setInput } = useSideBar();
9081
+ const results = [...map].flatMap((entry) => {
9082
+ const [key, items] = entry;
9083
+ const [topic, subtopic] = key.split(" - ");
9084
+ const topicResults = filterMap(items, (item) => {
9085
+ const cube = getCube2(graph.items, item, subtopic, locale);
9086
+ if (!cube) return null;
9087
+ const table = getAnnotation(cube, "table", locale);
9088
+ const isItemSelected = isSelected2(selectedItem, cube);
9089
+ const handleClick = () => {
9090
+ if (!isSelectionInProgress) {
9091
+ onSelectCube(item, subtopic);
9092
+ setExpanded(false);
9093
+ setInput("");
9094
+ }
9095
+ };
9096
+ return /* @__PURE__ */ React6__default.createElement(
9097
+ Text,
9098
+ {
9099
+ key: cube.name,
9100
+ component: "a",
9101
+ fz: "xs",
9102
+ className: isItemSelected ? `${classes.link} ${classes.linkActive}` : classes.link,
9103
+ sx: (t) => ({
9104
+ opacity: isSelectionInProgress ? 0.5 : 1,
9105
+ cursor: isSelectionInProgress ? "not-allowed" : "pointer",
9106
+ transition: "opacity 0.2s ease",
9107
+ pointerEvents: isSelectionInProgress ? "none" : "auto"
9108
+ }),
9109
+ onClick: handleClick
9110
+ },
9111
+ table
9112
+ );
9113
+ });
9114
+ if (topicResults.length === 0) return [];
9115
+ const label = `${topic} - ${subtopic}`;
9116
+ return [/* @__PURE__ */ React6__default.createElement(Divider, { key: label, my: "xs", label }), ...topicResults];
9117
+ });
9118
+ return /* @__PURE__ */ React6__default.createElement(Box, { px: "sm" }, results.length ? results : "No results");
9122
9119
  }
9120
+ Results.displayName = "SearchResults";
9123
9121
  var useStyles = createStyles((t) => ({
9124
9122
  link: {
9125
9123
  ...t.fn.focusStyles(),
@@ -9144,7 +9142,6 @@ var useStyles = createStyles((t) => ({
9144
9142
  fontWeight: 500
9145
9143
  }
9146
9144
  }));
9147
- var Results_default = Results;
9148
9145
 
9149
9146
  // src/components/SelectCubes.tsx
9150
9147
  var EMPTY_RESPONSE = {
@@ -9234,9 +9231,9 @@ function isSelected(selectedItem, currentItem) {
9234
9231
  return selectedItem.name === currentItem.name;
9235
9232
  }
9236
9233
  }
9237
- function getCube(items, table, subtopic, locale) {
9234
+ function getCube(items, name4, subtopic, locale) {
9238
9235
  const cube = items.find(
9239
- (item) => item.name === table && getAnnotation(item, "subtopic", locale) === subtopic
9236
+ (item) => item.name === name4 && getAnnotation(item, "subtopic", locale) === subtopic
9240
9237
  );
9241
9238
  return cube;
9242
9239
  }
@@ -9284,7 +9281,7 @@ function CubeTree({
9284
9281
  return /* @__PURE__ */ React6__default.createElement(Text, { ta: "center", fz: "xs", my: "sm", italic: true }, t("params.label_no_results"));
9285
9282
  }
9286
9283
  return map && map.size > 0 ? /* @__PURE__ */ React6__default.createElement(
9287
- Results_default,
9284
+ Results,
9288
9285
  {
9289
9286
  onSelectCube,
9290
9287
  selectedItem,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datawheel/data-explorer",
3
- "version": "0.3.21",
3
+ "version": "0.3.22",
4
4
  "main": "./dist/main.mjs",
5
5
  "types": "./dist/main.d.mts",
6
6
  "files": [