@aics/vole-app 3.3.0 → 3.3.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.
Files changed (27) hide show
  1. package/LICENSE +21 -25
  2. package/es/aics-image-viewer/components/App/index.js +10 -9
  3. package/es/aics-image-viewer/components/ChannelsWidget.js +2 -2
  4. package/es/aics-image-viewer/components/ControlPanel/index.js +15 -11
  5. package/es/aics-image-viewer/components/ControlPanel/styles.css +5 -5
  6. package/es/aics-image-viewer/components/ErrorAlert/index.js +91 -64
  7. package/es/aics-image-viewer/components/ErrorAlert/styles.css +33 -4
  8. package/es/aics-image-viewer/components/StyleProvider/index.js +42 -22
  9. package/es/aics-image-viewer/components/TfEditor/index.js +8 -1
  10. package/es/aics-image-viewer/components/Toolbar/index.js +33 -12
  11. package/es/aics-image-viewer/components/Toolbar/styles.css +21 -130
  12. package/es/aics-image-viewer/components/shared/ControlPanelRow/styles.css +1 -1
  13. package/es/aics-image-viewer/components/useVolume.js +3 -0
  14. package/es/aics-image-viewer/shared/constants.js +1 -1
  15. package/es/aics-image-viewer/shared/utils/playControls.js +12 -1
  16. package/es/aics-image-viewer/shared/utils/sceneStore.js +8 -0
  17. package/es/aics-image-viewer/shared/utils/viewerChannelSettings.js +3 -4
  18. package/package.json +5 -5
  19. package/type-declarations/aics-image-viewer/components/App/types.d.ts +2 -2
  20. package/type-declarations/aics-image-viewer/components/ControlPanel/index.d.ts +4 -5
  21. package/type-declarations/aics-image-viewer/components/ErrorAlert/index.d.ts +8 -5
  22. package/type-declarations/aics-image-viewer/components/Toolbar/index.d.ts +2 -1
  23. package/type-declarations/aics-image-viewer/components/useVolume.d.ts +1 -1
  24. package/type-declarations/aics-image-viewer/shared/constants.d.ts +1 -1
  25. package/type-declarations/aics-image-viewer/shared/utils/playControls.d.ts +1 -0
  26. package/type-declarations/aics-image-viewer/shared/utils/sceneStore.d.ts +2 -1
  27. package/LICENSE.txt +0 -26
package/LICENSE CHANGED
@@ -1,33 +1,29 @@
1
- Allen Institute Software License – This software license is the 2-clause BSD
2
- license plus clause a third clause that prohibits redistribution and use for
3
- commercial purposes without further permission.
1
+ BSD 3-Clause License
4
2
 
5
- Copyright © 2020. Allen Institute. All rights reserved.
3
+ Copyright (c) 2017-2026, Allen Institute
4
+ All rights reserved.
6
5
 
7
- Redistribution and use in source and binary forms, with or without
6
+ Redistribution and use in source and binary forms, with or without
8
7
  modification, are permitted provided that the following conditions are met:
9
8
 
10
- 1. Redistributions of source code must retain the above copyright notice, this
11
- list of conditions and the following disclaimer.
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
12
11
 
13
- 2. Redistributions in binary form must reproduce the above copyright notice,
14
- this list of conditions and the following disclaimer in the documentation
15
- and/or other materials provided with the distribution.
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
16
15
 
17
- 3. Redistributions and use for commercial purposes are not permitted without
18
- the Allen Institute’s written permission. For purposes of this license,
19
- commercial purposes are the incorporation of the Allen Institute's software
20
- into anything for which you will charge fees or other compensation or use of
21
- the software to perform a commercial service for a third party. Contact
22
- terms@alleninstitute.org for commercial licensing opportunities.
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
23
19
 
24
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
29
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -54,7 +54,8 @@ var defaultVisibleControls = {
54
54
  resetCameraButton: true,
55
55
  showAxesButton: true,
56
56
  showBoundingBoxButton: true,
57
- metadataViewer: true
57
+ metadataViewer: true,
58
+ scaleLevelControls: true
58
59
  };
59
60
  var defaultProps = {
60
61
  // rawData has a "dtype" which is expected to be "uint8", a "shape":[c,z,y,x] and a "buffer" which is a DataView
@@ -151,8 +152,8 @@ var App = function App(props) {
151
152
  var showError = (_props$showError = props.showError) !== null && _props$showError !== void 0 ? _props$showError : _showError;
152
153
  useEffect(function () {
153
154
  // Get notifications of loading errors which occur after the initial load, e.g. on time change or new channel load
154
- view3d.setLoadErrorHandler(function (_vol, e) {
155
- return showError(e);
155
+ view3d.setLoadErrorHandler(function (vol, e) {
156
+ return showError(e, vol);
156
157
  });
157
158
  return function () {
158
159
  return view3d.setLoadErrorHandler(undefined);
@@ -323,17 +324,17 @@ var App = function App(props) {
323
324
 
324
325
  // save the channel's new range for remapping next time
325
326
  channelRangesRef.current[channelIndex] = [thisChannel.rawMin, thisChannel.rawMax];
326
- view3d.updateLuts(image);
327
+
328
+ // Note: updateLuts and updateActiveChannels are not called here because the
329
+ // channelVersion bump (via onChannelDataLoaded) will trigger ChannelUpdater
330
+ // effects that apply LUT/color settings and call updateLuts with the final state.
327
331
  view3d.onVolumeData(image, [channelIndex]);
328
332
  if (image.channelNames[channelIndex] === maskChannelName) {
329
333
  view3d.setVolumeChannelAsMask(image, channelIndex);
330
334
  }
331
- if (image.isLoaded()) {
332
- view3d.updateActiveChannels(image);
333
- }
334
335
  }, [view3d, changeChannelSetting, maskChannelName, props.viewerChannelSettings]);
335
- var onError = useCallback(function (error) {
336
- showError(error);
336
+ var onError = useCallback(function (error, image) {
337
+ showError(error, image);
337
338
  onImageTitleChange === null || onImageTitleChange === void 0 || onImageTitleChange(undefined);
338
339
  }, [showError, onImageTitleChange]);
339
340
  var volume = useVolume(scenes, {
@@ -139,14 +139,14 @@ var ChannelsWidget = function ChannelsWidget(props) {
139
139
  };
140
140
  var renderChannelRow = function renderChannelRow(channelIndex) {
141
141
  var channelName = channelNames[channelIndex];
142
- return channelName ? /*#__PURE__*/React.createElement(ChannelsWidgetRow, {
142
+ return /*#__PURE__*/React.createElement(ChannelsWidgetRow, {
143
143
  key: channelIndex,
144
144
  index: channelIndex,
145
145
  channelDataForChannel: channelDataChannels[channelIndex],
146
146
  name: getDisplayName(channelName, channelIndex, viewerChannelSettings),
147
147
  onColorChangeComplete: props.onColorChangeComplete,
148
148
  saveIsosurface: props.saveIsosurface
149
- }) : null;
149
+ });
150
150
  };
151
151
  var rows = channelDataChannels && Object.entries(channelGroupedByType).filter(function (_ref3) {
152
152
  var _ref4 = _slicedToArray(_ref3, 2),
@@ -1,4 +1,3 @@
1
- function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2
1
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
3
2
  function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
4
3
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -38,10 +37,11 @@ function ControlPanel(props) {
38
37
  var resetToDefaultViewerState = useViewerState(select("resetToDefaultViewerState"));
39
38
  var singleChannelMode = useViewerState(select("singleChannelMode"));
40
39
  var changeViewerSetting = useViewerState(select("changeViewerSetting"));
41
- var controlPanelContainerRef = React.useRef(null);
42
- var getDropdownContainer = controlPanelContainerRef.current ? function () {
43
- return controlPanelContainerRef.current;
44
- } : undefined;
40
+ var containerRef = React.useRef(null);
41
+ var getDropdownContainer = function getDropdownContainer() {
42
+ var _containerRef$current;
43
+ return (_containerRef$current = containerRef.current) !== null && _containerRef$current !== void 0 ? _containerRef$current : document.body;
44
+ };
45
45
  var viewerChannelSettings = props.viewerChannelSettings,
46
46
  visibleControls = props.visibleControls,
47
47
  hasImage = props.hasImage;
@@ -98,12 +98,11 @@ function ControlPanel(props) {
98
98
  }, "Single channel mode"))));
99
99
  };
100
100
  var renderTab = function renderTab(thisTab, icon) {
101
- return /*#__PURE__*/React.createElement(Tooltip, _extends({
101
+ return /*#__PURE__*/React.createElement(Tooltip, {
102
102
  title: ControlTabNames[thisTab],
103
103
  placement: "right"
104
- }, !props.collapsed && {
105
- open: false
106
- }), /*#__PURE__*/React.createElement(Button, {
104
+ }, /*#__PURE__*/React.createElement(Button, {
105
+ "aria-label": ControlTabNames[thisTab],
107
106
  className: tab === thisTab ? "ant-btn-icon-only btn-tabactive" : "ant-btn-icon-only",
108
107
  onClick: function onClick() {
109
108
  return setTab(thisTab);
@@ -151,22 +150,27 @@ function ControlPanel(props) {
151
150
  onClick: resetToDefaultViewerState
152
151
  }, "Clear all settings"))));
153
152
  };
153
+ var collapseLabel = props.collapsed ? "Show panel" : "Hide panel";
154
154
  return /*#__PURE__*/React.createElement("div", {
155
155
  className: "control-panel-col-container",
156
- ref: controlPanelContainerRef
156
+ ref: containerRef
157
157
  }, /*#__PURE__*/React.createElement("div", {
158
158
  className: "control-panel-tab-col",
159
159
  style: {
160
160
  flex: "0 0 50px"
161
161
  }
162
+ }, /*#__PURE__*/React.createElement(Tooltip, {
163
+ title: collapseLabel,
164
+ placement: "right"
162
165
  }, /*#__PURE__*/React.createElement(Button, {
166
+ "aria-label": collapseLabel,
163
167
  className: "ant-btn-icon-only btn-collapse" + (props.collapsed ? " btn-collapse-collapsed" : ""),
164
168
  onClick: function onClick() {
165
169
  return props.setCollapsed(!props.collapsed);
166
170
  }
167
171
  }, /*#__PURE__*/React.createElement(ViewerIcon, {
168
172
  type: "closePanel"
169
- })), /*#__PURE__*/React.createElement("div", {
173
+ }))), /*#__PURE__*/React.createElement("div", {
170
174
  className: "tab-divider"
171
175
  }), renderTab(ControlTab.Channels, /*#__PURE__*/React.createElement(ViewerIcon, {
172
176
  type: "channels"
@@ -20,16 +20,16 @@
20
20
  }
21
21
 
22
22
  .control-panel-col-container .control-panel-tab-col .ant-btn:not([disabled]).btn-tabactive{
23
- color:var(--color-button-icon-activated-text);
24
- background-color:var(--color-button-icon-activated-bg);
25
- border-color:var(--color-button-icon-activated-outline);
23
+ color:var(--color-button-icon-active-text);
24
+ background-color:var(--color-button-icon-active-bg);
25
+ border-color:var(--color-button-icon-active-outline);
26
26
  }
27
27
 
28
28
  .control-panel-col-container .control-panel-tab-col .ant-btn:not([disabled]):hover,
29
29
  .control-panel-col-container .control-panel-tab-col .ant-btn:not([disabled]):focus-visible{
30
- color:var(--color-button-icon-activated-text);
30
+ color:var(--color-button-icon-active-text);
31
31
  background-color:var(--color-button-primary-hover-bg);
32
- border-color:var(--color-button-icon-activated-outline);
32
+ border-color:var(--color-button-icon-active-outline);
33
33
  }
34
34
 
35
35
  .control-panel-col-container .control-panel-tab-col .btn-collapse svg{
@@ -13,7 +13,7 @@ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object
13
13
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
14
14
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
15
15
  import { VolumeLoadErrorType } from "@aics/vole-core";
16
- import { RightOutlined } from "@ant-design/icons";
16
+ import { LeftOutlined, RightOutlined, WarningOutlined } from "@ant-design/icons";
17
17
  import { Alert, Button } from "antd";
18
18
  import React from "react";
19
19
  import { useConstructor } from "../../shared/utils/hooks";
@@ -40,115 +40,142 @@ var getErrorTitle = function getErrorTitle(error) {
40
40
  var _error$toString;
41
41
  return error instanceof Error && ((_error$toString = error.toString) === null || _error$toString === void 0 ? void 0 : _error$toString.call(error)) || typeof error === "string" && error || _typeof(error) === "object" && error !== null && error.title || "Unknown error";
42
42
  };
43
- var getErrorDescription = function getErrorDescription(error) {
43
+ var getErrorDescription = function getErrorDescription(_ref2) {
44
44
  var _ERROR_TYPE_DESCRIPTI2;
45
+ var error = _ref2.error,
46
+ dims = _ref2.dims;
45
47
  var type = error.type;
46
48
  if (!type) {
47
49
  return _typeof(error) === "object" && error !== null && error.description || UNKNOWN_ERROR_DESCRIPTION;
48
50
  }
49
51
  if (type === VolumeLoadErrorType.TOO_LARGE && useViewerState.getState().useExactScaleLevel) {
50
- return /*#__PURE__*/React.createElement(React.Fragment, null, "The viewer cannot load this resolution level within memory limits. Try again with a smaller resolution level.");
52
+ var dimsDetail = "";
53
+ if (Array.isArray(dims)) {
54
+ var _dims = _slicedToArray(dims, 5),
55
+ _t = _dims[0],
56
+ _c = _dims[1],
57
+ z = _dims[2],
58
+ y = _dims[3],
59
+ x = _dims[4];
60
+ dimsDetail = " (".concat(x, " x ").concat(y, " x ").concat(z, ")");
61
+ }
62
+ return /*#__PURE__*/React.createElement(React.Fragment, null, "The viewer cannot load this resolution level", dimsDetail, " within memory limits. Try again with a smaller resolution level.");
51
63
  }
52
64
  return (_ERROR_TYPE_DESCRIPTI2 = ERROR_TYPE_DESCRIPTIONS[type]) !== null && _ERROR_TYPE_DESCRIPTI2 !== void 0 ? _ERROR_TYPE_DESCRIPTI2 : UNKNOWN_ERROR_DESCRIPTION;
53
65
  };
54
- var ErrorAlert = function ErrorAlert(_ref2) {
55
- var errors = _ref2.errors,
56
- _ref2$firstErrorCount = _ref2.firstErrorCount,
57
- firstErrorCount = _ref2$firstErrorCount === void 0 ? 0 : _ref2$firstErrorCount,
58
- _afterClose = _ref2.afterClose,
59
- onSkipError = _ref2.onSkipError;
66
+ var ErrorAlert = function ErrorAlert(_ref3) {
67
+ var errors = _ref3.errors,
68
+ afterClose = _ref3.afterClose;
60
69
  var _React$useState = React.useState(false),
61
70
  _React$useState2 = _slicedToArray(_React$useState, 2),
62
71
  showDetails = _React$useState2[0],
63
72
  setShowDetails = _React$useState2[1];
64
73
  var _React$useState3 = React.useState(0),
65
74
  _React$useState4 = _slicedToArray(_React$useState3, 2),
66
- errorsSeenCount = _React$useState4[0],
67
- setErrorsSeenCount = _React$useState4[1];
68
- var error = Array.isArray(errors) ? errors[0] : errors;
75
+ errorIndex = _React$useState4[0],
76
+ setErrorIndex = _React$useState4[1];
77
+ var _React$useState5 = React.useState(false),
78
+ _React$useState6 = _slicedToArray(_React$useState5, 2),
79
+ flash = _React$useState6[0],
80
+ setFlash = _React$useState6[1];
81
+ var error = errors[errorIndex];
69
82
  var infoStyle = {
70
83
  display: showDetails ? undefined : "none"
71
84
  };
72
- var errorMessage = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
85
+ React.useEffect(function () {
86
+ setErrorIndex(errors.length - 1);
87
+ setFlash(errors.length > 1);
88
+ window.setTimeout(function () {
89
+ return setFlash(false);
90
+ }, 100);
91
+ }, [errors]);
92
+ var cause = error.error.cause;
93
+ var msg = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
73
94
  className: "error-title"
74
- }, getErrorTitle(error) + (firstErrorCount > 1 ? " (".concat(firstErrorCount, ")") : ""), " ", /*#__PURE__*/React.createElement(Button, {
95
+ }, getErrorTitle(error.error) + (error.count > 1 ? " (".concat(error.count, ")") : ""), " ", /*#__PURE__*/React.createElement(Button, {
75
96
  type: "text",
76
97
  onClick: function onClick() {
77
98
  return setShowDetails(!showDetails);
78
99
  }
79
100
  }, showDetails ? "Show less info" : "Show more info")), /*#__PURE__*/React.createElement("div", {
80
101
  style: infoStyle
81
- }, getErrorDescription(error)), error.cause !== undefined && /*#__PURE__*/React.createElement("div", {
102
+ }, getErrorDescription(error)), cause !== undefined && /*#__PURE__*/React.createElement("div", {
82
103
  className: "error-cause",
83
104
  style: infoStyle
84
- }, "Caused by ", getErrorTitle(error.cause)));
85
- var skipErrorButton = Array.isArray(errors) && errors.length > 1 && /*#__PURE__*/React.createElement(Button, {
86
- type: "text",
87
- onClick: function onClick() {
88
- setErrorsSeenCount(function (count) {
89
- return count + 1;
90
- });
91
- onSkipError === null || onSkipError === void 0 || onSkipError();
105
+ }, "Caused by ", getErrorTitle(cause)));
106
+ var pageButton = undefined;
107
+ if (errors.length > 1) {
108
+ if (errorIndex === errors.length - 1) {
109
+ pageButton = /*#__PURE__*/React.createElement(Button, {
110
+ type: "text",
111
+ onClick: function onClick() {
112
+ return setErrorIndex(function (i) {
113
+ return i - 1;
114
+ });
115
+ }
116
+ }, /*#__PURE__*/React.createElement(LeftOutlined, null), " ", errors.length - 1, " previous error", errors.length > 2 ? "s" : "");
117
+ } else {
118
+ pageButton = /*#__PURE__*/React.createElement(React.Fragment, null, errorIndex > 0 && /*#__PURE__*/React.createElement(Button, {
119
+ type: "text",
120
+ onClick: function onClick() {
121
+ return setErrorIndex(function (i) {
122
+ return i - 1;
123
+ });
124
+ }
125
+ }, /*#__PURE__*/React.createElement(LeftOutlined, null)), "Error ", errorIndex + 1, " of ", errors.length, /*#__PURE__*/React.createElement(Button, {
126
+ type: "text",
127
+ onClick: function onClick() {
128
+ return setErrorIndex(function (i) {
129
+ return i + 1;
130
+ });
131
+ }
132
+ }, /*#__PURE__*/React.createElement(RightOutlined, null)));
92
133
  }
93
- }, "Error ", errorsSeenCount + 1, " of ", errors.length + errorsSeenCount, " ", /*#__PURE__*/React.createElement(RightOutlined, null));
134
+ }
135
+ var alertClass = flash ? "load-error-alert error-flash" : "load-error-alert";
94
136
  return /*#__PURE__*/React.createElement(Alert, {
95
137
  showIcon: true,
96
- type: "error",
97
- className: "load-error-alert",
98
- message: errorMessage,
99
138
  closable: true,
100
- afterClose: function afterClose() {
101
- setErrorsSeenCount(0);
102
- _afterClose === null || _afterClose === void 0 || _afterClose();
103
- },
104
- action: skipErrorButton
139
+ type: "error",
140
+ icon: /*#__PURE__*/React.createElement(WarningOutlined, null),
141
+ className: alertClass,
142
+ message: msg,
143
+ afterClose: afterClose,
144
+ action: pageButton
105
145
  });
106
146
  };
107
147
  export var useErrorAlert = function useErrorAlert() {
108
- var _React$useState5 = React.useState([]),
109
- _React$useState6 = _slicedToArray(_React$useState5, 2),
110
- errorList = _React$useState6[0],
111
- setErrorList = _React$useState6[1];
148
+ var _React$useState7 = React.useState([]),
149
+ _React$useState8 = _slicedToArray(_React$useState7, 2),
150
+ errors = _React$useState8[0],
151
+ setErrors = _React$useState8[1];
112
152
  // Keep track of which errors have been seen and how many times
113
153
  var seenErrors = useConstructor(function () {
114
154
  return new Map();
115
155
  });
116
- var _React$useState7 = React.useState([]),
117
- _React$useState8 = _slicedToArray(_React$useState7, 2),
118
- errorCounts = _React$useState8[0],
119
- setErrorCounts = _React$useState8[1];
120
- var addError = React.useCallback(function (error) {
156
+ var addError = React.useCallback(function (error, image) {
121
157
  var _seenErrors$get;
122
158
  var errorTitle = getErrorTitle(error);
123
159
  console.error(error instanceof Error ? error : errorTitle);
124
- var errorSeenCount = ((_seenErrors$get = seenErrors.get(errorTitle)) !== null && _seenErrors$get !== void 0 ? _seenErrors$get : 0) + 1;
125
- setErrorList(function (prev) {
126
- return [].concat(_toConsumableArray(prev), [error]);
160
+ var count = ((_seenErrors$get = seenErrors.get(errorTitle)) !== null && _seenErrors$get !== void 0 ? _seenErrors$get : 0) + 1;
161
+ var imageInfo = image === null || image === void 0 ? void 0 : image.imageInfo.imageInfo;
162
+ var dims = imageInfo && imageInfo.multiscaleLevelDims[imageInfo.multiscaleLevel].shape;
163
+ setErrors(function (prev) {
164
+ return [].concat(_toConsumableArray(prev), [{
165
+ error: error,
166
+ count: count,
167
+ dims: dims
168
+ }]);
127
169
  });
128
- setErrorCounts(function (prev) {
129
- return [].concat(_toConsumableArray(prev), [errorSeenCount]);
130
- });
131
- seenErrors.set(errorTitle, errorSeenCount);
170
+ seenErrors.set(errorTitle, count);
132
171
  }, [seenErrors]);
133
- var onSkipError = React.useCallback(function () {
134
- setErrorList(function (prev) {
135
- return prev.slice(1);
136
- });
137
- setErrorCounts(function (prev) {
138
- return prev.slice(1);
139
- });
140
- }, []);
141
172
  var afterClose = React.useCallback(function () {
142
- setErrorList([]);
143
- setErrorCounts([]);
173
+ return setErrors([]);
144
174
  }, []);
145
- var errCount = errorCounts[0];
146
- var alertComponent = errorList.length > 0 && /*#__PURE__*/React.createElement(ErrorAlert, {
147
- errors: errorList,
148
- firstErrorCount: errCount,
149
- onSkipError: onSkipError,
175
+ var alertNode = errors.length > 0 && /*#__PURE__*/React.createElement(ErrorAlert, {
176
+ errors: errors,
150
177
  afterClose: afterClose
151
178
  });
152
- return [alertComponent, addError];
179
+ return [alertNode, addError];
153
180
  };
154
181
  export default ErrorAlert;
@@ -5,24 +5,53 @@
5
5
  width:40vw;
6
6
  align-items:start;
7
7
  z-index:5000;
8
- border-color:#dc4446;
8
+ border-color:var(--color-text-error);
9
9
  padding:12px 30px;
10
10
  color:var(--color-text-section);
11
11
  }
12
+
13
+ .load-error-alert.error-flash{
14
+ background-color:var(--color-text-error);
15
+ }
16
+
12
17
  .load-error-alert .ant-alert-icon,
13
18
  .load-error-alert .ant-alert-close-icon,
14
19
  .load-error-alert .ant-alert-message div{
15
20
  min-height:24px;
16
21
  }
17
- .load-error-alert .ant-btn-text{
22
+
23
+ .load-error-alert .ant-alert-close-icon{
24
+ margin-inline-start:14px;
25
+ }
26
+
27
+ .load-error-alert .ant-alert-action{
28
+ display:inline-flex;
29
+ align-items:center;
30
+ gap:4px;
31
+ }
32
+
33
+ .load-error-alert .ant-alert-action > button{
34
+ gap:4px;
35
+ border:none !important;
36
+ }
37
+
38
+ .load-error-alert .ant-btn-text,
39
+ .load-error-alert .ant-alert-action{
18
40
  color:var(--color-text-link);
19
41
  }
42
+
20
43
  .load-error-alert .ant-btn-text:hover{
21
- color:#25affe !important;
22
- }
44
+ color:#25affe !important;
45
+ }
46
+
47
+ .load-error-alert .anticon{
48
+ font-size:21px;
49
+ }
50
+
23
51
  .load-error-alert .ant-alert-message > div.error-title{
24
52
  font-weight:600;
25
53
  }
54
+
26
55
  .load-error-alert .ant-alert-message > div.error-cause{
27
56
  font-style:italic;
28
57
  color:var(--color-text-body);
@@ -1,8 +1,8 @@
1
- var _templateObject, _templateObject2;
1
+ var _templateObject, _templateObject2, _templateObject3;
2
2
  function _taggedTemplateLiteral(e, t) { return t || (t = e.slice(0)), Object.freeze(Object.defineProperties(e, { raw: { value: Object.freeze(t) } })); }
3
3
  import { theme as AntTheme, ConfigProvider } from "antd";
4
4
  import React from "react";
5
- import styled, { css } from "styled-components";
5
+ import styled, { createGlobalStyle, css } from "styled-components";
6
6
  var palette = {
7
7
  black: "#000000",
8
8
  white: "#ffffff",
@@ -18,7 +18,7 @@ var palette = {
18
18
  darkPurple: "#7e46d4",
19
19
  veryDarkPurple: "#5f369f",
20
20
  veryLtPurple: "#e7e4f2",
21
- brightRed: "#ff4d4d",
21
+ brightRed: "#dc4446",
22
22
  brightYellow: "#e39b0d",
23
23
  brightGreen: "#61d900",
24
24
  veryBrightGreen: "#61ff00",
@@ -79,10 +79,10 @@ var theme = {
79
79
  outline: palette.ltGrey,
80
80
  hoverOutline: palette.ltPurple,
81
81
  hoverText: palette.ltPurple,
82
- activeOutline: palette.medPurple,
83
- activatedText: palette.white,
84
- activatedBg: palette.medDarkGrey,
85
- activatedOutline: palette.purpleGrey,
82
+ activeText: palette.white,
83
+ activeBg: palette.medDarkGrey,
84
+ activeOutline: palette.purpleGrey,
85
+ disabledOutline: palette.medGrey,
86
86
  disabledText: palette.medGrey
87
87
  }
88
88
  },
@@ -136,7 +136,7 @@ var theme = {
136
136
  }
137
137
  },
138
138
  tooltip: {
139
- bg: palette.black
139
+ bg: palette.medDarkGrey
140
140
  },
141
141
  modal: {
142
142
  maskBg: "#000000cc",
@@ -150,10 +150,11 @@ var theme = {
150
150
  }
151
151
  };
152
152
  /** Makes theme styling available to child components via CSS variables. */
153
- var CssProvider = styled.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n width: 100%;\n height: 100%;\n\n ", "\n\n h1, h2, h3, h4, p {\n font-family: var(--font-family);\n }\n\n h1 {\n color: var(--color-text-header);\n font-size: 28px;\n font-weight: 400;\n }\n\n h2 {\n color: var(--color-text-section);\n font-size: 19px;\n font-weight: 400;\n }\n\n h3 {\n color: var(--color-text-header);\n font-size: 16px;\n font-weight: 600;\n }\n\n h4 {\n color: var(--color-text-header);\n font-size: 14px;\n font-weight: 400;\n }\n\n p {\n color: var(--color-text-body);\n font-size: 14px;\n font-weight: 400;\n }\n\n a {\n color: var(--color-text-link);\n }\n\n & *::selection {\n background-color: var(--color-text-selection-bg);\n color: var(--color-text-selection-text);\n }\n\n /** TODO: Go through these styles and see if we can use Ant ConfigProvider for them instead. */\n .ant-btn-link,\n .ant-btn-text,\n .ant-btn-primary,\n .ant-btn-icon-only {\n box-shadow: none;\n\n &:hover:not(:disabled),\n &:focus-visible:not(:disabled) {\n background-color: var(--color-button-primary-hover-bg);\n border-color: var(--color-button-primary-hover-bg);\n color: var(--color-button-primary-text);\n }\n\n &:active:not(:disabled) {\n background-color: var(--color-button-primary-hover-bg);\n border: 1px solid var(--color-button-primary-active-outline);\n color: var(--color-button-primary-text);\n }\n }\n\n /* Let us use buttons with type=\"text\" as purely semantic containers - don't bring any styling! */\n .ant-btn-text {\n width: unset;\n height: unset;\n padding: unset;\n\n &:hover:not(:disabled),\n &:focus-visible:not(:disabled) {\n background-color: unset;\n border-color: transparent;\n }\n }\n\n .ant-btn-icon-only:disabled {\n color: var(--color-button-icon-disabled-text);\n }\n\n .ant-btn-link:not(:disabled) {\n // Change from default blue link text\n color: var(--color-button-link-text);\n }\n\n /**\n * Tertiary style buttons. Grey outline by default, turns to light\n * purple outline on hover.\n */\n .ant-btn-default:not(.ant-btn-icon-only) {\n background-color: var(--color-button-tertiary-bg);\n color: var(--color-button-tertiary-text);\n border-color: var(--color-button-tertiary-outline);\n\n &:hover:not(:disabled),\n &:focus-visible:not(:disabled) {\n background-color: transparent;\n border-color: var(--color-button-tertiary-hover-bg);\n color: var(--color-button-tertiary-hover-text);\n }\n\n &:active:not(:disabled) {\n background-color: transparent;\n border-color: var(--color-button-tertiary-active-outline);\n color: var(--color-button-tertiary-active-text);\n }\n }\n\n // Overrides for checkbox styling\n & .ant-checkbox-input {\n &:hover,\n &:focus-visible {\n border: 1px solid white;\n }\n }\n\n & .ant-checkbox.ant-checkbox-checked {\n background-color: var(--color-checkbox-bg);\n }\n\n .ant-checkbox-inner {\n background-color: transparent !important;\n }\n\n // Add outlines to modals and dropdowns\n & .ant-select-dropdown,\n & .ant-dropdown-menu,\n & .ant-modal-content {\n border: 1px solid var(--color-modal-border);\n }\n\n // Force active/hovered text to be white instead of grey for better contrast\n & .ant-dropdown-menu-item-active {\n color: var(--color-menu-hover-text);\n }\n\n // Remove padding in dropdown menus and make items reactangular + flush with the edge\n & .ant-dropdown-menu,\n & .ant-select-dropdown {\n padding: 0;\n overflow: hidden;\n\n & .ant-dropdown-menu-item,\n & .ant-select-item {\n border-radius: 0;\n }\n }\n"])), function (_ref) {
153
+ var CssProvider = styled.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n width: 100%;\n height: 100%;\n\n ", "\n\n h1, h2, h3, h4, p {\n font-family: var(--font-family);\n }\n\n h1 {\n color: var(--color-text-header);\n font-size: 28px;\n font-weight: 400;\n }\n\n h2 {\n color: var(--color-text-section);\n font-size: 19px;\n font-weight: 400;\n }\n\n h3 {\n color: var(--color-text-header);\n font-size: 16px;\n font-weight: 600;\n }\n\n h4 {\n color: var(--color-text-header);\n font-size: 14px;\n font-weight: 400;\n }\n\n p {\n color: var(--color-text-body);\n font-size: 14px;\n font-weight: 400;\n }\n\n a {\n color: var(--color-text-link);\n }\n\n *::selection {\n background-color: var(--color-text-selection-bg);\n color: var(--color-text-selection-text);\n }\n\n /** TODO: Go through these styles and see if we can use Ant ConfigProvider for them instead. */\n .ant-btn-link,\n .ant-btn-text,\n .ant-btn-primary,\n .ant-btn-icon-only {\n box-shadow: none;\n\n &:hover:not(:disabled),\n &:focus-visible:not(:disabled) {\n background-color: var(--color-button-primary-hover-bg);\n border-color: var(--color-button-primary-hover-bg);\n color: var(--color-button-primary-text);\n outline: none;\n }\n\n &:active:not(:disabled) {\n background-color: var(--color-button-primary-hover-bg);\n border: 1px solid var(--color-button-primary-active-outline);\n color: var(--color-button-primary-text);\n }\n }\n\n /* Let us use buttons with type=\"text\" as purely semantic containers - don't bring any styling! */\n .ant-btn-text {\n width: unset;\n height: unset;\n padding: unset;\n\n &:hover:not(:disabled),\n &:focus-visible:not(:disabled) {\n background-color: unset;\n border-color: transparent;\n }\n }\n\n .ant-btn-icon-only:disabled {\n color: var(--color-button-icon-disabled-text);\n }\n\n .ant-btn-link:not(:disabled) {\n // Change from default blue link text\n color: var(--color-button-link-text);\n }\n\n /**\n * Tertiary style buttons. Grey outline by default, turns to light\n * purple outline on hover.\n */\n .ant-btn-default:not(.ant-btn-icon-only) {\n background-color: var(--color-button-tertiary-bg);\n color: var(--color-button-tertiary-text);\n border-color: var(--color-button-tertiary-outline);\n\n &:hover:not(:disabled),\n &:focus-visible:not(:disabled) {\n background-color: transparent;\n border-color: var(--color-button-tertiary-hover-outline);\n color: var(--color-button-tertiary-hover-text);\n }\n }\n\n // Overrides for checkbox styling\n .ant-checkbox-input {\n &:hover,\n &:focus-visible {\n border: 1px solid white;\n }\n }\n\n .ant-checkbox.ant-checkbox-checked {\n background-color: var(--color-checkbox-bg);\n }\n\n .ant-checkbox-inner {\n background-color: transparent !important;\n }\n\n // Add outlines to modals and dropdowns\n .ant-select-dropdown,\n .ant-dropdown-menu,\n .ant-modal-content {\n border: 1px solid var(--color-modal-border);\n }\n\n // Force active/hovered text to be white instead of grey for better contrast\n .ant-dropdown-menu-item-active {\n color: var(--color-menu-hover-text);\n }\n\n // Remove padding in dropdown menus and make items reactangular + flush with the edge\n .ant-dropdown-menu,\n .ant-select-dropdown {\n padding: 0;\n overflow: hidden;\n\n .ant-dropdown-menu-item,\n .ant-select-item:not(.ant-select-item-option-disabled) {\n border-radius: 0;\n color: var(--color-button-icon-active-text);\n }\n }\n\n .ant-select {\n &.ant-select-disabled .ant-select-selector {\n border-color: var(--color-button-icon-disabled-outline);\n }\n\n .ant-select-arrow {\n transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);\n }\n\n /* Control response to hover + active menu */\n &:hover:not(.ant-select-disabled),\n &:focus-visible:not(.ant-select-disabled),\n &.ant-select.ant-select-open {\n .ant-select-selector,\n .ant-select-arrow,\n .ant-select-selection-item {\n color: var(--color-button-tertiary-hover-text);\n outline-color: var(--color-button-tertiary-hover-outline);\n }\n }\n }\n\n // Toolbar has special colors for radio buttons and will use these variables to apply them\n --color-button-radio-hover-outline: var(--color-button-tertiary-hover-outline);\n --color-button-radio-hover-text: var(--color-button-tertiary-hover-text);\n\n .ant-radio-button-wrapper {\n &::before {\n content: none;\n }\n\n &.ant-radio-button-wrapper-checked {\n color: var(--color-button-icon-active-text);\n\n &:not(:first-child) {\n box-shadow: -1px 0px 0px 0px var(--color-button-tertiary-active-outline);\n }\n }\n\n &:hover,\n &:has(:focus-visible) {\n color: var(--color-button-radio-hover-text);\n border-color: var(--color-button-radio-hover-outline);\n outline: none;\n z-index: 2;\n\n &:not(:first-child) {\n box-shadow: -1px 0px 0px 0px var(--color-button-radio-hover-outline);\n }\n }\n }\n\n"])), function (_ref) {
154
154
  var $theme = _ref.$theme;
155
- return css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n /* Component and color variables. */\n // TODO: Fix inconsistent use of border vs. outline\n // TODO: Remove variables that aren't used in other CSS files. These should be set directly\n // from the $theme object to reduce unnecessary variables.\n --color-text-link: ", ";\n --color-text-header: ", ";\n --color-text-section: ", ";\n --color-text-body: ", ";\n --color-text-error: ", ";\n\n --color-text-selection-bg: ", ";\n --color-text-selection-text: ", ";\n\n --color-header-title: ", ";\n --color-header-hover-title: ", ";\n --color-header-bg: ", ";\n --color-header-border: ", ";\n\n --color-button-primary-bg: ", ";\n --color-button-primary-text: ", ";\n --color-button-primary-hover-bg: ", ";\n --color-button-primary-active-bg: ", ";\n --color-button-primary-active-outline: ", ";\n --color-button-primary-disabled-bg: ", ";\n\n --color-button-link-text: ", ";\n\n --color-button-secondary-bg: ", ";\n --color-button-secondary-text: ", ";\n --color-button-secondary-outline: ", ";\n\n --color-button-tertiary-bg: transparent;\n --color-button-tertiary-text: ", ";\n --color-button-tertiary-outline: ", ";\n --color-button-tertiary-hover-outline: ", ";\n --color-button-tertiary-hover-text: ", ";\n --color-button-tertiary-active-outline: ", ";\n --color-button-tertiary-active-text: ", ";\n\n --color-button-icon-disabled-text: ", ";\n --color-button-icon-activated-text: ", ";\n --color-button-icon-activated-bg: ", ";\n --color-button-icon-activated-outline: ", ";\n\n --color-toolbar-button-bg: ", ";\n\n --color-controlpanel-bg: ", ";\n --color-controlpanel-border: ", ";\n --color-controlpanel-section-text: ", ";\n --color-controlpanel-text: ", ";\n --color-controlpanel-section-bg: ", ";\n --color-controlpanel-drawer-bg: ", ";\n --color-controlpanel-ramp-slider: ", ";\n --color-controlpanel-isovalue-slider: ", ";\n\n --color-landingpage-bg: ", ";\n --color-landingpage-bg-alt: ", ";\n --color-landingpage-text: ", ";\n --color-landingpage-banner-highlight-bg: ", ";\n\n --color-statusflag-border: ", ";\n --color-statusflag-text: ", ";\n\n --color-alert-warning-text: ", ";\n --color-alert-warning-bg: ", ";\n --color-alert-info-text: ", ";\n --color-alert-info-bg: ", ";\n\n --color-layout-dividers: ", ";\n\n --color-modal-border: ", ";\n\n --color-menu-hover-text: ", ";\n --color-menu-selected-text: ", ";\n\n --color-checkbox-bg: ", ";\n\n --font-family: ", ";\n "])), $theme.colors.text.link, $theme.colors.text.header, $theme.colors.text.section, $theme.colors.text.body, $theme.colors.text.error, $theme.colors.text.selectionBg, $theme.colors.text.selectionText, $theme.colors.header.title, $theme.colors.header.hoverTitle, $theme.colors.header.bg, $theme.colors.header.border, $theme.colors.button.primary.bg, $theme.colors.button.primary.text, $theme.colors.button.primary.hoverBg, $theme.colors.button.primary.hoverBg, $theme.colors.button.primary.activeOutline, $theme.colors.button.primary.disabledBg, $theme.colors.button.link.text, $theme.colors.button.secondary.bg, $theme.colors.button.secondary.text, $theme.colors.button.secondary.outline, $theme.colors.button.tertiary.text, $theme.colors.button.tertiary.outline, $theme.colors.button.tertiary.hoverOutline, $theme.colors.button.tertiary.hoverText, $theme.colors.button.tertiary.activeOutline, $theme.colors.button.tertiary.hoverText, $theme.colors.button.tertiary.disabledText, $theme.colors.button.tertiary.activatedText, $theme.colors.button.tertiary.activatedBg, $theme.colors.button.tertiary.activatedOutline, $theme.colors.toolbar.buttonBg, $theme.colors.controlPanel.bg, $theme.colors.controlPanel.border, $theme.colors.controlPanel.sectionText, $theme.colors.controlPanel.text, $theme.colors.controlPanel.sectionBg, $theme.colors.controlPanel.drawerBg, $theme.colors.controlPanel.rampSlider, $theme.colors.controlPanel.isovalueSlider, $theme.colors.landingPage.bg, $theme.colors.landingPage.bgAlt, $theme.colors.landingPage.text, $theme.colors.landingPage.bannerBg, $theme.colors.statusFlag.border, $theme.colors.statusFlag.text, $theme.colors.alert.warning.text, $theme.colors.alert.warning.bg, $theme.colors.alert.info.text, $theme.colors.alert.info.bg, $theme.colors.layout.dividers, $theme.colors.modal.border, $theme.colors.menu.hoverText, $theme.colors.menu.selectedText, $theme.colors.checkbox.bg, $theme.fonts.family);
155
+ return css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n /* Component and color variables. */\n // TODO: Fix inconsistent use of border vs. outline\n // TODO: Remove variables that aren't used in other CSS files. These should be set directly\n // from the $theme object to reduce unnecessary variables.\n --color-text-link: ", ";\n --color-text-header: ", ";\n --color-text-section: ", ";\n --color-text-body: ", ";\n --color-text-error: ", ";\n\n --color-text-selection-bg: ", ";\n --color-text-selection-text: ", ";\n\n --color-header-title: ", ";\n --color-header-hover-title: ", ";\n --color-header-bg: ", ";\n --color-header-border: ", ";\n\n --color-button-primary-bg: ", ";\n --color-button-primary-text: ", ";\n --color-button-primary-hover-bg: ", ";\n --color-button-primary-active-bg: ", ";\n --color-button-primary-active-outline: ", ";\n --color-button-primary-disabled-bg: ", ";\n\n --color-button-link-text: ", ";\n\n --color-button-secondary-bg: ", ";\n --color-button-secondary-text: ", ";\n --color-button-secondary-outline: ", ";\n\n --color-button-tertiary-bg: transparent;\n --color-button-tertiary-text: ", ";\n --color-button-tertiary-outline: ", ";\n --color-button-tertiary-hover-outline: ", ";\n --color-button-tertiary-hover-text: ", ";\n --color-button-tertiary-active-outline: ", ";\n --color-button-tertiary-active-text: ", ";\n\n --color-button-icon-disabled-outline: ", ";\n --color-button-icon-disabled-text: ", ";\n --color-button-icon-active-text: ", ";\n --color-button-icon-active-bg: ", ";\n --color-button-icon-active-outline: ", ";\n\n --color-toolbar-button-bg: ", ";\n\n --color-controlpanel-bg: ", ";\n --color-controlpanel-border: ", ";\n --color-controlpanel-section-text: ", ";\n --color-controlpanel-text: ", ";\n --color-controlpanel-section-bg: ", ";\n --color-controlpanel-drawer-bg: ", ";\n --color-controlpanel-ramp-slider: ", ";\n --color-controlpanel-isovalue-slider: ", ";\n\n --color-landingpage-bg: ", ";\n --color-landingpage-bg-alt: ", ";\n --color-landingpage-text: ", ";\n --color-landingpage-banner-highlight-bg: ", ";\n\n --color-statusflag-border: ", ";\n --color-statusflag-text: ", ";\n\n --color-alert-warning-text: ", ";\n --color-alert-warning-bg: ", ";\n --color-alert-info-text: ", ";\n --color-alert-info-bg: ", ";\n\n --color-layout-dividers: ", ";\n\n --color-modal-border: ", ";\n\n --color-menu-hover-text: ", ";\n --color-menu-selected-text: ", ";\n\n --color-checkbox-bg: ", ";\n\n --font-family: ", ";\n "])), $theme.colors.text.link, $theme.colors.text.header, $theme.colors.text.section, $theme.colors.text.body, $theme.colors.text.error, $theme.colors.text.selectionBg, $theme.colors.text.selectionText, $theme.colors.header.title, $theme.colors.header.hoverTitle, $theme.colors.header.bg, $theme.colors.header.border, $theme.colors.button.primary.bg, $theme.colors.button.primary.text, $theme.colors.button.primary.hoverBg, $theme.colors.button.primary.hoverBg, $theme.colors.button.primary.activeOutline, $theme.colors.button.primary.disabledBg, $theme.colors.button.link.text, $theme.colors.button.secondary.bg, $theme.colors.button.secondary.text, $theme.colors.button.secondary.outline, $theme.colors.button.tertiary.text, $theme.colors.button.tertiary.outline, $theme.colors.button.tertiary.hoverOutline, $theme.colors.button.tertiary.hoverText, $theme.colors.button.tertiary.activeOutline, $theme.colors.button.tertiary.hoverText, $theme.colors.button.tertiary.disabledOutline, $theme.colors.button.tertiary.disabledText, $theme.colors.button.tertiary.activeText, $theme.colors.button.tertiary.activeBg, $theme.colors.button.tertiary.activeOutline, $theme.colors.toolbar.buttonBg, $theme.colors.controlPanel.bg, $theme.colors.controlPanel.border, $theme.colors.controlPanel.sectionText, $theme.colors.controlPanel.text, $theme.colors.controlPanel.sectionBg, $theme.colors.controlPanel.drawerBg, $theme.colors.controlPanel.rampSlider, $theme.colors.controlPanel.isovalueSlider, $theme.colors.landingPage.bg, $theme.colors.landingPage.bgAlt, $theme.colors.landingPage.text, $theme.colors.landingPage.bannerBg, $theme.colors.statusFlag.border, $theme.colors.statusFlag.text, $theme.colors.alert.warning.text, $theme.colors.alert.warning.bg, $theme.colors.alert.info.text, $theme.colors.alert.info.bg, $theme.colors.layout.dividers, $theme.colors.modal.border, $theme.colors.menu.hoverText, $theme.colors.menu.selectedText, $theme.colors.checkbox.bg, $theme.fonts.family);
156
156
  });
157
+ var GlobalTooltipStyle = createGlobalStyle(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n .ant-tooltip-inner {\n display: flex;\n flex-direction: column;\n justify-content: center;\n /* !important needed: antd hardcodes text-align: start on tooltip inner */\n text-align: center !important;\n line-height: 1.4;\n font-weight: 400;\n /* !important needed: antd's CSS-in-JS injects tooltip styles into portals at higher specificity than global stylesheets */\n box-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.30), 0 3px 6px -4px rgba(0, 0, 0, 0.40), 0 9px 28px 8px rgba(0, 0, 0, 0.20) !important;\n }\n\n"])));
157
158
 
158
159
  /**
159
160
  * Provides CSS variables and global styling for the image viewer.
@@ -192,7 +193,14 @@ export default function StyleProvider(props) {
192
193
  primaryColor: theme.colors.button.primary.text,
193
194
  defaultHoverBg: theme.colors.button.secondary.bg,
194
195
  defaultActiveBg: theme.colors.button.secondary.bg,
195
- defaultActiveBorderColor: theme.colors.button.tertiary.activeOutline
196
+ defaultActiveBorderColor: theme.colors.button.primary.activeOutline
197
+ },
198
+ Checkbox: {
199
+ borderRadiusSM: 2,
200
+ colorBgContainer: theme.colors.checkbox.bg,
201
+ colorPrimary: theme.colors.checkbox.bg,
202
+ colorPrimaryHover: theme.colors.checkbox.hoverBg,
203
+ colorText: theme.colors.checkbox.text
196
204
  },
197
205
  Collapse: {
198
206
  borderRadiusLG: 0,
@@ -205,26 +213,38 @@ export default function StyleProvider(props) {
205
213
  Layout: {
206
214
  siderBg: theme.colors.controlPanel.bg
207
215
  },
208
- Checkbox: {
209
- borderRadiusSM: 2,
210
- colorBgContainer: theme.colors.checkbox.bg,
211
- colorPrimary: theme.colors.checkbox.bg,
212
- colorPrimaryHover: theme.colors.checkbox.hoverBg,
213
- colorText: theme.colors.checkbox.text
214
- },
215
- Tooltip: {
216
- colorBgSpotlight: theme.colors.tooltip.bg
217
- },
218
216
  Modal: {
219
217
  colorBgMask: theme.colors.modal.maskBg,
220
218
  contentBg: theme.colors.modal.bg,
221
219
  headerBg: theme.colors.modal.bg,
222
220
  footerBg: theme.colors.modal.bg,
223
221
  titleFontSize: 19
222
+ },
223
+ Radio: {
224
+ buttonCheckedBg: theme.colors.button.tertiary.activeBg,
225
+ buttonColor: theme.colors.button.tertiary.text,
226
+ // can't style borders and text of activated buttons independently within ant's system, so we set border
227
+ // colors here and text/bg colors in custom css
228
+ colorPrimary: theme.colors.button.tertiary.activeOutline
229
+ },
230
+ Select: {
231
+ colorText: theme.colors.button.tertiary.text,
232
+ colorBorder: theme.colors.button.tertiary.outline,
233
+ // arrow color
234
+ colorTextQuaternary: theme.colors.button.tertiary.text,
235
+ colorTextDisabled: theme.colors.button.tertiary.disabledText,
236
+ colorTextPlaceholder: theme.colors.button.tertiary.hoverText,
237
+ colorBgContainerDisabled: "transparent"
238
+ },
239
+ // Additional tooltip overrides (font-weight, box-shadow, layout) are in GlobalTooltipStyle below,
240
+ // which is required because antd renders tooltips in portals outside the scoped CssProvider.
241
+ Tooltip: {
242
+ colorBgSpotlight: theme.colors.tooltip.bg,
243
+ fontSize: 12
224
244
  }
225
245
  }
226
246
  }
227
- }, /*#__PURE__*/React.createElement(CssProvider, {
247
+ }, /*#__PURE__*/React.createElement(GlobalTooltipStyle, null), /*#__PURE__*/React.createElement(CssProvider, {
228
248
  $theme: theme
229
249
  }, props.children));
230
250
  }