@haniffalab/cherita-react 1.2.0-dev.2025-04-28.623a001f → 1.2.0-dev.2025-04-30.0a204a1c

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.
@@ -3,6 +3,7 @@ import _ from "lodash";
3
3
  import { Dropdown } from "react-bootstrap";
4
4
  import { useDatasetDispatch } from "../../context/DatasetContext";
5
5
  import { useDiseaseSearch, useVarSearch } from "../../utils/search";
6
+ import { VirtualizedList } from "../../utils/VirtualizedList";
6
7
  export function VarSearchResults(_ref) {
7
8
  let {
8
9
  text,
@@ -46,24 +47,28 @@ export function VarSearchResults(_ref) {
46
47
  setShowSuggestions(true);
47
48
  }
48
49
  }, [fetchedData, isPending, serverError, setShowSuggestions]);
49
- const suggestionsList = useMemo(() => {
50
- return deferredData?.map(item => {
51
- return /*#__PURE__*/React.createElement(Dropdown.Item, {
52
- key: item.name,
53
- as: "button",
54
- disabled: isStale,
55
- onClick: () => {
56
- handleSelect(dispatch, item);
57
- _.delay(() => {
58
- setShowSuggestions(false);
59
- }, 150);
60
- }
61
- }, item.name);
62
- });
63
- }, [deferredData, dispatch, handleSelect, isStale, setShowSuggestions]);
50
+ const getDataAtIndex = index => deferredData[index];
51
+ const ItemComponent = item => /*#__PURE__*/React.createElement(Dropdown.Item, {
52
+ key: item.name,
53
+ as: "button",
54
+ disabled: isStale,
55
+ onClick: () => {
56
+ handleSelect(dispatch, item);
57
+ _.delay(() => {
58
+ setShowSuggestions(false);
59
+ }, 150);
60
+ }
61
+ }, item.name);
64
62
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Dropdown.Header, null, "Features"), /*#__PURE__*/React.createElement("div", {
65
63
  className: "search-results"
66
- }, deferredData?.length ? suggestionsList : /*#__PURE__*/React.createElement(Dropdown.Item, {
64
+ }, deferredData?.length ? /*#__PURE__*/React.createElement(VirtualizedList, {
65
+ getDataAtIndex: getDataAtIndex,
66
+ count: deferredData.length,
67
+ ItemComponent: ItemComponent,
68
+ overscan: 500,
69
+ estimateSize: 32,
70
+ maxHeight: "25vh"
71
+ }) : /*#__PURE__*/React.createElement(Dropdown.Item, {
67
72
  key: "empty",
68
73
  as: "button",
69
74
  disabled: true
@@ -110,28 +115,32 @@ export function DiseasesSearchResults(_ref2) {
110
115
  setShowSuggestions(true);
111
116
  }
112
117
  }, [fetchedData, isPending, serverError, setShowSuggestions]);
113
- const suggestionsList = useMemo(() => {
114
- return deferredData?.map(item => {
115
- return /*#__PURE__*/React.createElement(Dropdown.Item, {
116
- key: item.id,
117
- as: "button",
118
- disabled: isStale,
119
- onClick: () => {
120
- dispatch({
121
- type: "select.disease",
122
- id: item.disease_id,
123
- name: item.disease_name
124
- });
125
- _.delay(() => {
126
- setShowSuggestions(false);
127
- }, 150);
128
- }
129
- }, item.disease_name);
130
- });
131
- }, [deferredData, dispatch, isStale, setShowSuggestions]);
118
+ const getDataAtIndex = index => deferredData[index];
119
+ const ItemComponent = item => /*#__PURE__*/React.createElement(Dropdown.Item, {
120
+ key: item.name,
121
+ as: "button",
122
+ disabled: isStale,
123
+ onClick: () => {
124
+ dispatch({
125
+ type: "select.disease",
126
+ id: item.disease_id,
127
+ name: item.disease_name
128
+ });
129
+ _.delay(() => {
130
+ setShowSuggestions(false);
131
+ }, 150);
132
+ }
133
+ }, item.disease_name);
132
134
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Dropdown.Header, null, "Diseases"), /*#__PURE__*/React.createElement("div", {
133
135
  className: "search-results"
134
- }, deferredData?.length ? suggestionsList : /*#__PURE__*/React.createElement(Dropdown.Item, {
136
+ }, deferredData?.length ? /*#__PURE__*/React.createElement(VirtualizedList, {
137
+ getDataAtIndex: getDataAtIndex,
138
+ count: deferredData.length,
139
+ ItemComponent: ItemComponent,
140
+ overscan: 250,
141
+ estimateSize: 32,
142
+ maxHeight: "25vh"
143
+ }) : /*#__PURE__*/React.createElement(Dropdown.Item, {
135
144
  key: "empty",
136
145
  as: "button",
137
146
  disabled: true
@@ -1,9 +1,11 @@
1
1
  import React, { useMemo } from "react";
2
+ import { faDroplet } from "@fortawesome/free-solid-svg-icons";
3
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
2
4
  import _ from "lodash";
3
- import { formatNumerical, FORMATS } from "./string";
4
5
  import { COLOR_ENCODINGS } from "../constants/constants";
5
6
  import { useDataset } from "../context/DatasetContext";
6
7
  import { rgbToHex, useColor } from "../helpers/color-helper";
8
+ import { formatNumerical, FORMATS } from "./string";
7
9
  export function Legend(_ref) {
8
10
  let {
9
11
  isCategorical = false,
@@ -39,20 +41,24 @@ export function Legend(_ref) {
39
41
  className: "gradient"
40
42
  }, /*#__PURE__*/React.createElement("p", {
41
43
  className: "small m-0 p-0"
42
- }, (dataset.colorEncoding === COLOR_ENCODINGS.VAR ? dataset.selectedVar?.name : dataset.selectedObs?.name) + addText), spanList, /*#__PURE__*/React.createElement("span", {
44
+ }, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
45
+ icon: faDroplet,
46
+ className: "me-1"
47
+ }), (dataset.colorEncoding === COLOR_ENCODINGS.VAR ? dataset.selectedVar?.name : dataset.selectedObs?.name) + addText), spanList, /*#__PURE__*/React.createElement("span", {
43
48
  className: "domain-min"
44
49
  }, formatNumerical(min, FORMATS.EXPONENTIAL)), /*#__PURE__*/React.createElement("span", {
45
50
  className: "domain-med"
46
51
  }, formatNumerical((min + max) * 0.5, FORMATS.EXPONENTIAL)), /*#__PURE__*/React.createElement("span", {
47
52
  className: "domain-max"
48
53
  }, formatNumerical(max, FORMATS.EXPONENTIAL))));
49
- } else {
54
+ } else if (dataset.colorEncoding === COLOR_ENCODINGS.OBS && dataset.selectedObs) {
50
55
  return /*#__PURE__*/React.createElement("div", {
51
- className: "cherita-legend"
52
- }, /*#__PURE__*/React.createElement("div", {
53
- className: "gradient"
56
+ className: "cherita-legend categorical"
54
57
  }, /*#__PURE__*/React.createElement("p", {
55
- className: "small m-0 p-0"
56
- }, dataset.colorEncoding === COLOR_ENCODINGS.OBS && dataset.selectedObs ? dataset.selectedObs.name : "")));
58
+ className: "legend-text text-end m-0 p-0"
59
+ }, /*#__PURE__*/React.createElement(FontAwesomeIcon, {
60
+ icon: faDroplet,
61
+ className: "me-2"
62
+ }), dataset.selectedObs.name));
57
63
  }
58
64
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haniffalab/cherita-react",
3
- "version": "1.2.0-dev.2025-04-28.623a001f",
3
+ "version": "1.2.0-dev.2025-04-30.0a204a1c",
4
4
  "author": "Haniffa Lab",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -124,5 +124,5 @@
124
124
  "url": "https://github.com/haniffalab/cherita-react/issues"
125
125
  },
126
126
  "homepage": "https://github.com/haniffalab/cherita-react#readme",
127
- "prereleaseSha": "623a001f39d78904c6e7fe4c9c782a0a486a1119"
127
+ "prereleaseSha": "0a204a1c659c6b7f9438049af143289feccd943b"
128
128
  }
package/scss/cherita.scss CHANGED
@@ -73,15 +73,13 @@ $prefix: "bs-" !default;
73
73
  .cherita-spatial-footer {
74
74
  position: absolute;
75
75
  z-index: 10;
76
- bottom: 1rem;
76
+ bottom: 0;
77
77
  display: flex;
78
78
  justify-content: space-between;
79
- align-items: flex-end;
79
+ align-items: end;
80
80
  flex-wrap: wrap;
81
81
  width: 100%;
82
- padding-left: 1rem;
83
- padding-right: 1rem;
84
- padding-bottom: 1rem;
82
+ padding: 1rem;
85
83
  pointer-events: none;
86
84
 
87
85
  > * {
@@ -105,6 +103,41 @@ $prefix: "bs-" !default;
105
103
  .cherita-legend {
106
104
  order: 2;
107
105
  width: 12rem;
106
+ color: #333;
107
+ }
108
+
109
+ .cherita-legend.categorical {
110
+ display: flex;
111
+ align-items: center;
112
+ justify-content: flex-end;
113
+ padding-left: 1rem;
114
+ flex: 1;
115
+ overflow: hidden;
116
+ white-space: nowrap;
117
+ text-overflow: ellipsis;
118
+ pointer-events: auto;
119
+ .legend-text {
120
+ overflow: hidden;
121
+ text-overflow: ellipsis;
122
+ white-space: nowrap;
123
+ max-width: 100%;
124
+ display: inline-block;
125
+ }
126
+ }
127
+
128
+ @media (max-width: 600px) {
129
+ .cherita-spatial-footer {
130
+ flex-direction: column;
131
+ align-items: center;
132
+ justify-content: center;
133
+ }
134
+
135
+ .cherita-legend {
136
+ flex-direction: column;
137
+ align-items: center;
138
+ margin-top: 1rem;
139
+ padding: 0;
140
+ }
108
141
  }
109
142
 
110
143
  .cherita-accordion-active .accordion-button {
@@ -352,9 +385,6 @@ $gauge-padding: 0.15rem;
352
385
  }
353
386
 
354
387
  .search-results {
355
- max-height: 25vh;
356
- overflow-y: scroll;
357
-
358
388
  .dropdown-item {
359
389
  white-space: normal;
360
390
  overflow-wrap: break-word;
@@ -2,19 +2,21 @@
2
2
  position: relative;
3
3
  }
4
4
 
5
- .cherita-app .cherita-navbar {
6
- @extend .m-3;
7
- @extend .d-block;
8
- @extend .d-xl-none;
9
-
10
- position: absolute;
11
- z-index: 11;
12
- top: 0;
13
- left: 0;
14
- right: 0;
15
- border-radius: 0.25rem;
16
- @media (min-width: 992px) and (max-width: 1199px) {
17
- margin-left: calc(33.33333333% + 1rem) !important;
5
+ .cherita-app {
6
+ .cherita-navbar {
7
+ @extend .m-3;
8
+ @extend .d-block;
9
+ @extend .d-xl-none;
10
+
11
+ position: absolute;
12
+ z-index: 11;
13
+ top: 0;
14
+ left: 0;
15
+ right: 0;
16
+ border-radius: 0.25rem;
17
+ @media (min-width: 992px) and (max-width: 1199px) {
18
+ margin-left: calc(33.33333333% + 1rem) !important;
19
+ }
18
20
  }
19
21
  }
20
22
 
@@ -4,10 +4,8 @@
4
4
  top: 1rem;
5
5
  left: 1rem;
6
6
  width: 3rem;
7
- }
8
-
9
- @media (max-width: 1199.98px) {
10
- .cherita-spatial-controls {
11
- top: 5rem;
7
+ .btn {
8
+ padding-left: 0;
9
+ padding-right: 0;
12
10
  }
13
11
  }