col-browser 2.1.0 → 2.2.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.
@@ -69613,6 +69613,21 @@ html body {
69613
69613
  ] })
69614
69614
  ] });
69615
69615
  };
69616
+ const PREFIX = "col-browser:";
69617
+ function readSetting(key2, fallback) {
69618
+ try {
69619
+ const raw = window.localStorage.getItem(PREFIX + key2);
69620
+ return raw === null ? fallback : JSON.parse(raw);
69621
+ } catch {
69622
+ return fallback;
69623
+ }
69624
+ }
69625
+ function writeSetting(key2, value) {
69626
+ try {
69627
+ window.localStorage.setItem(PREFIX + key2, JSON.stringify(value));
69628
+ } catch {
69629
+ }
69630
+ }
69616
69631
  const INFRASPECIFIC_RANKS$1 = [
69617
69632
  "infraspecific name",
69618
69633
  "species",
@@ -69684,8 +69699,10 @@ html body {
69684
69699
  /* @__PURE__ */ jsxRuntimeExports.jsx(
69685
69700
  Checkbox,
69686
69701
  {
69702
+ defaultChecked: this.state.showInfo,
69687
69703
  onChange: ({ target: { checked } }) => {
69688
69704
  this.setState({ showInfo: checked });
69705
+ writeSetting("tree-show-source", checked);
69689
69706
  },
69690
69707
  children: "Source"
69691
69708
  }
@@ -69693,9 +69710,10 @@ html body {
69693
69710
  /* @__PURE__ */ jsxRuntimeExports.jsx(
69694
69711
  Checkbox,
69695
69712
  {
69696
- defaultChecked: false,
69713
+ defaultChecked: this.state.hideExtinct,
69697
69714
  onChange: ({ target: { checked } }) => {
69698
69715
  this.setState({ hideExtinct: checked });
69716
+ writeSetting("tree-extant-only", checked);
69699
69717
  },
69700
69718
  children: "Extant only"
69701
69719
  }
@@ -69721,8 +69739,8 @@ html body {
69721
69739
  });
69722
69740
  setAuth(this.props.auth);
69723
69741
  this.state = {
69724
- hideExtinct: false,
69725
- showInfo: false,
69742
+ hideExtinct: readSetting("tree-extant-only", false),
69743
+ showInfo: readSetting("tree-show-source", false),
69726
69744
  dataset: null
69727
69745
  };
69728
69746
  this.cache = createTreeCache(this.props.datasetKey);
@@ -70651,6 +70669,7 @@ html body {
70651
70669
  this.getDatasets.cancel();
70652
70670
  }
70653
70671
  }
70672
+ const CONTENT_TYPE_KEY = "search-content-type";
70654
70673
  const FormItem = Form.Item;
70655
70674
  const RadioGroup = Radio.Group;
70656
70675
  const FACET_VOCAB = [
@@ -70781,8 +70800,12 @@ html body {
70781
70800
  params.TAXON_ID = defaultTaxonKey;
70782
70801
  }
70783
70802
  if (isEmpty(params)) {
70784
- params = defaultParams;
70785
- this.pushParams(defaultParams);
70803
+ params = { ...defaultParams };
70804
+ const storedContentType = readSetting(CONTENT_TYPE_KEY, void 0);
70805
+ if (storedContentType !== void 0 && storedContentType !== null) {
70806
+ params.sectorMode = storedContentType;
70807
+ }
70808
+ this.pushParams(params);
70786
70809
  } else if (!params.facet) {
70787
70810
  params.facet = FACET_VOCAB;
70788
70811
  }
@@ -70856,6 +70879,7 @@ html body {
70856
70879
  this.setState({ params: query }, () => this.pushParams(query));
70857
70880
  });
70858
70881
  __publicField(this, "updateSearch", (params) => {
70882
+ if ("sectorMode" in params) writeSetting(CONTENT_TYPE_KEY, params.sectorMode);
70859
70883
  let newParams = { ...this.state.params, offset: 0, limit: 50 };
70860
70884
  forEach(params, (v2, k) => {
70861
70885
  newParams[k] = v2;
@@ -78025,25 +78049,9 @@ html body {
78025
78049
  return k == null ? MISSING_COLOR : ESTABLISHMENT_COLORS[k];
78026
78050
  };
78027
78051
  const POSITRON_STYLE = "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json";
78028
- const GBIF_VISIBLE_STORAGE_KEY = "col-browser:gbif-visible";
78029
- const readStoredGbifVisible = (defaultValue) => {
78030
- try {
78031
- const v2 = window.sessionStorage.getItem(GBIF_VISIBLE_STORAGE_KEY);
78032
- if (v2 === "true") return true;
78033
- if (v2 === "false") return false;
78034
- } catch {
78035
- }
78036
- return defaultValue;
78037
- };
78038
- const writeStoredGbifVisible = (visible) => {
78039
- try {
78040
- window.sessionStorage.setItem(
78041
- GBIF_VISIBLE_STORAGE_KEY,
78042
- visible ? "true" : "false"
78043
- );
78044
- } catch {
78045
- }
78046
- };
78052
+ const GBIF_VISIBLE_KEY = "gbif-visible";
78053
+ const readStoredGbifVisible = (defaultValue) => readSetting(GBIF_VISIBLE_KEY, defaultValue);
78054
+ const writeStoredGbifVisible = (visible) => writeSetting(GBIF_VISIBLE_KEY, visible);
78047
78055
  const GBIF_TILE_PATH = "/v2/map/occurrence/density/{z}/{x}/{y}@1x.png?srs=EPSG%3A3857&style=iNaturalist.poly&bin=hex&hexPerTile=64&hasCoordinate=true&hasGeospatialIssue=false&occurrenceStatus=PRESENT&checklistKey={checklistKey}&taxonKey={taxonKey}";
78048
78056
  const FOCAL_SOURCE = "col-focal-distributions";
78049
78057
  const FOCAL_FILL = "col-focal-fill";
@@ -78175,7 +78183,7 @@ html body {
78175
78183
  const [focalVisible, setFocalVisible] = reactExports.useState(true);
78176
78184
  const isGbifOnly = !!gbifChecklistKey && (!records || records.length === 0);
78177
78185
  const [gbifVisible, setGbifVisible] = reactExports.useState(
78178
- () => isGbifOnly ? true : readStoredGbifVisible(true)
78186
+ () => readStoredGbifVisible(true)
78179
78187
  );
78180
78188
  const [visibleTaxonIds, setVisibleTaxonIds] = reactExports.useState(/* @__PURE__ */ new Set());
78181
78189
  const [controlOpen, setControlOpen] = reactExports.useState(false);
@@ -78183,10 +78191,14 @@ html body {
78183
78191
  const handleToggleGbif = () => {
78184
78192
  setGbifVisible((v2) => {
78185
78193
  const next2 = !v2;
78186
- if (!isGbifOnly) writeStoredGbifVisible(next2);
78194
+ writeStoredGbifVisible(next2);
78187
78195
  return next2;
78188
78196
  });
78189
78197
  };
78198
+ const activateGbif = () => {
78199
+ setGbifVisible(true);
78200
+ writeStoredGbifVisible(true);
78201
+ };
78190
78202
  const presentMeans = reactExports.useMemo(() => {
78191
78203
  if (!(records == null ? void 0 : records.length)) return [];
78192
78204
  const seen = /* @__PURE__ */ new Set();
@@ -78603,6 +78615,44 @@ html body {
78603
78615
  }
78604
78616
  );
78605
78617
  }
78618
+ if (isGbifOnly && !gbifVisible) {
78619
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
78620
+ "div",
78621
+ {
78622
+ className: "col-distributions-map col-distributions-map--collapsed",
78623
+ style: {
78624
+ display: "flex",
78625
+ alignItems: "center",
78626
+ gap: 6,
78627
+ padding: "8px 12px",
78628
+ background: "#fafafa",
78629
+ border: "1px solid #eee",
78630
+ borderRadius: 4,
78631
+ color: "#666",
78632
+ fontSize: 12
78633
+ },
78634
+ children: [
78635
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "No curated distribution data." }),
78636
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
78637
+ "a",
78638
+ {
78639
+ role: "button",
78640
+ tabIndex: 0,
78641
+ style: { cursor: "pointer" },
78642
+ onClick: activateGbif,
78643
+ onKeyDown: (e2) => {
78644
+ if (e2.key === "Enter" || e2.key === " ") {
78645
+ e2.preventDefault();
78646
+ activateGbif();
78647
+ }
78648
+ },
78649
+ children: "Show GBIF occurrences"
78650
+ }
78651
+ )
78652
+ ]
78653
+ }
78654
+ );
78655
+ }
78606
78656
  const focalName = ((_a2 = focalTaxon == null ? void 0 : focalTaxon.name) == null ? void 0 : _a2.scientificName) || "This taxon";
78607
78657
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "col-distributions-map", style: { position: "relative" }, children: [
78608
78658
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -86546,6 +86596,7 @@ html body {
86546
86596
  }
86547
86597
  var highchartsReact_minExports = requireHighchartsReact_min();
86548
86598
  const HighchartsReact = /* @__PURE__ */ getDefaultExportFromCjs(highchartsReact_minExports);
86599
+ const BREAKDOWN_LEVEL_KEY = "breakdown-level";
86549
86600
  const MAX_SLICES_PER_RING = 100;
86550
86601
  const canonicalRanks = [
86551
86602
  "kingdom",
@@ -86588,10 +86639,15 @@ html body {
86588
86639
  const [options, setOptions] = reactExports.useState(null);
86589
86640
  const [loading, setLoading] = reactExports.useState(false);
86590
86641
  const [invalid, setInvalid] = reactExports.useState(false);
86591
- const [activeLevel, setActiveLevel] = reactExports.useState(level);
86642
+ const [activeLevel, setActiveLevel] = reactExports.useState(
86643
+ () => showLevelSwitch ? readSetting(BREAKDOWN_LEVEL_KEY, level) : level
86644
+ );
86592
86645
  reactExports.useEffect(() => {
86593
- setActiveLevel(level);
86594
- }, [level]);
86646
+ if (!showLevelSwitch) setActiveLevel(level);
86647
+ }, [level, showLevelSwitch]);
86648
+ reactExports.useEffect(() => {
86649
+ if (showLevelSwitch) writeSetting(BREAKDOWN_LEVEL_KEY, activeLevel);
86650
+ }, [activeLevel, showLevelSwitch]);
86595
86651
  reactExports.useEffect(() => {
86596
86652
  if ((taxon == null ? void 0 : taxon.id) && datasetKey) {
86597
86653
  getData();
@@ -89713,8 +89769,10 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
89713
89769
  level = 1,
89714
89770
  showLevelSwitch = false,
89715
89771
  darkMode,
89772
+ auth,
89716
89773
  ...routerProps
89717
89774
  }) => {
89775
+ setAuth(auth);
89718
89776
  const [taxon, setTaxon] = reactExports.useState(null);
89719
89777
  const [dataset, setDataset] = reactExports.useState(null);
89720
89778
  const [rank, setRank] = reactExports.useState([]);
@@ -89753,8 +89811,10 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
89753
89811
  datasetKey,
89754
89812
  gbifChecklistKey,
89755
89813
  style: style2,
89814
+ auth,
89756
89815
  ...routerProps
89757
89816
  }) => {
89817
+ setAuth(auth);
89758
89818
  const [taxon, setTaxon] = reactExports.useState(null);
89759
89819
  const [distributions, setDistributions] = reactExports.useState(null);
89760
89820
  const [rank, setRank] = reactExports.useState([]);
@@ -89827,40 +89887,41 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
89827
89887
  window.addEventListener(evt, cb);
89828
89888
  return () => window.removeEventListener(evt, cb);
89829
89889
  };
89830
- const hrefFor = (mode, prefix2, args) => {
89890
+ const hrefFor = (mode, prefix2, args, reserved = {}) => {
89831
89891
  if (!prefix2) return null;
89832
89892
  const arg = args == null ? "" : typeof args === "object" ? "" : String(args);
89833
- const tail = typeof args === "object" && args && Object.keys(args).length > 0 ? `?${queryString.stringify(args, { arrayFormat: "none" })}` : "";
89893
+ const queryObj = typeof args === "object" && args ? { ...args, ...reserved } : { ...reserved };
89894
+ const tail = Object.keys(queryObj).length > 0 ? `?${queryString.stringify(queryObj, { arrayFormat: "none" })}` : "";
89834
89895
  const url = `${prefix2}${arg}${tail}`;
89835
89896
  return isHash(mode) ? `#${url}` : url;
89836
89897
  };
89837
- const navigate = (mode, navigation2, prefix2, args) => {
89898
+ const navigate = (mode, navigation2, prefix2, args, reserved = {}) => {
89838
89899
  if (!prefix2) return;
89839
89900
  if (navigation2 === "reload") {
89840
- const url = hrefFor(mode, prefix2, args);
89901
+ const url = hrefFor(mode, prefix2, args, reserved);
89841
89902
  if (url != null && typeof window !== "undefined") {
89842
89903
  window.location.assign(url);
89843
89904
  }
89844
89905
  return;
89845
89906
  }
89846
89907
  let path = prefix2;
89847
- let search = null;
89908
+ let search = Object.keys(reserved).length > 0 ? { ...reserved } : null;
89848
89909
  if (typeof args === "string" || typeof args === "number") {
89849
89910
  path = `${prefix2}${args}`;
89850
89911
  } else if (args && typeof args === "object") {
89851
- search = args;
89912
+ search = { ...search || {}, ...args };
89852
89913
  }
89853
89914
  writeLocation(mode, path, search);
89854
89915
  };
89855
- const buildNavProps = (mode, navigation2, paths) => ({
89856
- hrefForTaxon: (id) => hrefFor(mode, paths.taxon, id),
89857
- hrefForTree: (a) => hrefFor(mode, paths.tree, a),
89858
- hrefForSearch: (a) => hrefFor(mode, paths.search, a),
89859
- hrefForSource: (id) => hrefFor(mode, paths.source, id),
89860
- onNavigateToTaxon: (id) => navigate(mode, navigation2, paths.taxon, id),
89861
- onNavigateToTree: (a) => navigate(mode, navigation2, paths.tree, a),
89862
- onNavigateToSearch: (a) => navigate(mode, navigation2, paths.search, a),
89863
- onNavigateToSource: (id) => navigate(mode, navigation2, paths.source, id)
89916
+ const buildNavProps = (mode, navigation2, paths, reserved = {}) => ({
89917
+ hrefForTaxon: (id) => hrefFor(mode, paths.taxon, id, reserved),
89918
+ hrefForTree: (a) => hrefFor(mode, paths.tree, a, reserved),
89919
+ hrefForSearch: (a) => hrefFor(mode, paths.search, a, reserved),
89920
+ hrefForSource: (id) => hrefFor(mode, paths.source, id, reserved),
89921
+ onNavigateToTaxon: (id) => navigate(mode, navigation2, paths.taxon, id, reserved),
89922
+ onNavigateToTree: (a) => navigate(mode, navigation2, paths.tree, a, reserved),
89923
+ onNavigateToSearch: (a) => navigate(mode, navigation2, paths.search, a, reserved),
89924
+ onNavigateToSource: (id) => navigate(mode, navigation2, paths.source, id, reserved)
89864
89925
  });
89865
89926
  const lastSegmentAfter = (path, prefix2) => {
89866
89927
  if (!prefix2) return void 0;
@@ -89872,12 +89933,20 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
89872
89933
  return path.slice(prefix2.length).split("/").filter(Boolean).pop();
89873
89934
  };
89874
89935
  function withRouting(Component, options) {
89875
- const { kind, mode = "path", navigation: navigation2 = "spa", paths = {} } = options;
89936
+ const { kind, mode = "path", navigation: navigation2 = "spa", paths = {}, query = "" } = options;
89937
+ const reserved = query ? queryString.parse(query) : {};
89938
+ const reservedKeys = Object.keys(reserved);
89939
+ const stripReserved = (obj) => {
89940
+ if (reservedKeys.length === 0) return obj;
89941
+ const out = { ...obj };
89942
+ for (const k of reservedKeys) delete out[k];
89943
+ return out;
89944
+ };
89876
89945
  const Wrapped = (props) => {
89877
89946
  const [tick, setTick] = reactExports.useState(0);
89878
89947
  reactExports.useEffect(() => subscribe(mode, () => setTick((t2) => t2 + 1)), []);
89879
89948
  const { path, search } = readLocationKind(mode);
89880
- const navProps = reactExports.useMemo(() => buildNavProps(mode, navigation2, paths), []);
89949
+ const navProps = reactExports.useMemo(() => buildNavProps(mode, navigation2, paths, reserved), []);
89881
89950
  let extra = {};
89882
89951
  if (kind === "taxon") {
89883
89952
  extra.taxonKey = lastSegmentAfter(path, paths.taxon);
@@ -89890,7 +89959,7 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
89890
89959
  } else if (kind === "bibtex") {
89891
89960
  extra.sourceDatasetKey = lastSegmentAfter(path, paths.bibtex);
89892
89961
  } else if (kind === "tree") {
89893
- const parsed = queryString.parse(search);
89962
+ const parsed = stripReserved(queryString.parse(search));
89894
89963
  extra.expandedTaxonKey = parsed.taxonKey || void 0;
89895
89964
  extra.onExpandedTaxonKeyChange = reactExports.useCallback((id) => {
89896
89965
  const cur = readLocationKind(mode);
@@ -89900,11 +89969,11 @@ Please report this to https://github.com/markedjs/marked.`, e2) {
89900
89969
  writeLocation(mode, cur.path || paths.tree || "/", next2);
89901
89970
  }, []);
89902
89971
  } else if (kind === "search") {
89903
- const parsed = queryString.parse(search, { arrayFormat: "none" });
89972
+ const parsed = stripReserved(queryString.parse(search, { arrayFormat: "none" }));
89904
89973
  extra.filters = parsed;
89905
89974
  extra.onFiltersChange = reactExports.useCallback((filters) => {
89906
89975
  const cur = readLocationKind(mode);
89907
- writeLocation(mode, cur.path || paths.search || "/", filters);
89976
+ writeLocation(mode, cur.path || paths.search || "/", { ...reserved, ...filters });
89908
89977
  }, []);
89909
89978
  }
89910
89979
  return /* @__PURE__ */ jsxRuntimeExports.jsx(Component, { ...navProps, ...extra, ...props });