@aics/vole-app 3.4.4 → 3.6.0
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.
- package/es/aics-image-viewer/components/App/index.js +15 -5
- package/es/aics-image-viewer/components/ChannelsWidget.js +3 -1
- package/es/aics-image-viewer/components/ChannelsWidgetRow.js +29 -16
- package/es/aics-image-viewer/components/ColorPicker/index.js +9 -1
- package/es/aics-image-viewer/components/ControlPanel/CopySettingsButton.js +445 -0
- package/es/aics-image-viewer/components/ControlPanel/index.js +16 -5
- package/es/aics-image-viewer/components/ControlPanel/styles.css +29 -2
- package/es/aics-image-viewer/components/StyleProvider/index.js +17 -2
- package/es/aics-image-viewer/components/Toolbar/ViewModeRadioButtons.js +1 -1
- package/es/aics-image-viewer/components/Toolbar/index.js +1 -1
- package/es/aics-image-viewer/components/Toolbar/styles.css +0 -10
- package/es/aics-image-viewer/components/{CellViewerCanvasWrapper → ViewerCanvasWrapper}/index.js +3 -2
- package/es/aics-image-viewer/components/dimension_sliders/AxisClipSliders.js +21 -8
- package/es/aics-image-viewer/components/dimension_sliders/RotationSliders.js +6 -8
- package/es/aics-image-viewer/components/dimension_sliders/SliderRows.js +8 -6
- package/es/aics-image-viewer/components/shared/ContextualAlert.js +101 -0
- package/es/aics-image-viewer/components/shared/ControlPanelRow/index.js +4 -2
- package/es/aics-image-viewer/components/shared/ControlPanelRow/styles.css +4 -3
- package/es/aics-image-viewer/components/useVolume.js +59 -25
- package/es/aics-image-viewer/shared/constants.js +25 -1
- package/es/aics-image-viewer/shared/types.js +1 -1
- package/es/aics-image-viewer/shared/utils/controlPointsToLut.js +4 -0
- package/es/aics-image-viewer/shared/utils/parseSnapshot.js +205 -0
- package/es/aics-image-viewer/shared/utils/{urlParsing.js → parseUrl.js} +55 -191
- package/es/aics-image-viewer/shared/utils/permissions.js +46 -0
- package/es/aics-image-viewer/shared/utils/test/camera.test.js +1 -2
- package/es/aics-image-viewer/shared/utils/test/{urlParsing.test.js → parseUrl.test.js} +28 -25
- package/es/aics-image-viewer/shared/utils/test/storage.test.js +2 -2
- package/es/aics-image-viewer/shared/utils/test/viewerChannelSettings.test.js +1 -1
- package/es/aics-image-viewer/state/deserialize.js +443 -331
- package/es/aics-image-viewer/state/reset.js +1 -1
- package/es/aics-image-viewer/state/serialize.js +168 -78
- package/es/aics-image-viewer/state/subscribers.js +1 -1
- package/es/aics-image-viewer/state/test/deserialize.test.js +63 -77
- package/es/aics-image-viewer/state/test/reset.test.js +2 -2
- package/es/aics-image-viewer/state/test/serialize.test.js +42 -43
- package/es/aics-image-viewer/state/test/test_data.js +119 -1
- package/es/aics-image-viewer/state/types.js +157 -245
- package/es/aics-image-viewer/state/util.js +39 -1
- package/es/index.js +4 -2
- package/package.json +26 -44
- package/type-declarations/aics-image-viewer/components/App/types.d.ts +3 -3
- package/type-declarations/aics-image-viewer/components/ChannelsWidget.d.ts +3 -0
- package/type-declarations/aics-image-viewer/components/ChannelsWidgetRow.d.ts +3 -0
- package/type-declarations/aics-image-viewer/components/ControlPanel/CopySettingsButton.d.ts +11 -0
- package/type-declarations/aics-image-viewer/components/Toolbar/ViewModeRadioButtons.d.ts +1 -1
- package/type-declarations/aics-image-viewer/components/{CellViewerCanvasWrapper → ViewerCanvasWrapper}/index.d.ts +4 -3
- package/type-declarations/aics-image-viewer/components/dimension_sliders/AxisClipSliders.d.ts +7 -6
- package/type-declarations/aics-image-viewer/components/dimension_sliders/SliderRows.d.ts +1 -2
- package/type-declarations/aics-image-viewer/components/shared/ContextualAlert.d.ts +29 -0
- package/type-declarations/aics-image-viewer/components/shared/ControlPanelRow/index.d.ts +1 -0
- package/type-declarations/aics-image-viewer/components/useVolume.d.ts +3 -0
- package/type-declarations/aics-image-viewer/shared/constants.d.ts +2 -2
- package/type-declarations/aics-image-viewer/shared/types.d.ts +2 -2
- package/type-declarations/aics-image-viewer/shared/utils/controlPointsToLut.d.ts +1 -1
- package/type-declarations/aics-image-viewer/shared/utils/parseSnapshot.d.ts +49 -0
- package/type-declarations/aics-image-viewer/shared/utils/{urlParsing.d.ts → parseUrl.d.ts} +3 -24
- package/type-declarations/aics-image-viewer/shared/utils/permissions.d.ts +7 -0
- package/type-declarations/aics-image-viewer/shared/utils/viewerChannelSettings.d.ts +1 -1
- package/type-declarations/aics-image-viewer/state/deserialize.d.ts +70 -35
- package/type-declarations/aics-image-viewer/state/reset.d.ts +1 -1
- package/type-declarations/aics-image-viewer/state/serialize.d.ts +44 -10
- package/type-declarations/aics-image-viewer/state/types.d.ts +265 -159
- package/type-declarations/aics-image-viewer/state/util.d.ts +3 -1
- package/type-declarations/index.d.ts +5 -3
- package/es/Globals.d.js +0 -0
- package/es/aics-image-viewer/shared/enums.js +0 -18
- package/es/aics-image-viewer/shared/utils/firebase/index.js +0 -109
- package/type-declarations/aics-image-viewer/shared/enums.d.ts +0 -15
- package/type-declarations/aics-image-viewer/shared/utils/firebase/index.d.ts +0 -69
- package/type-declarations/aics-image-viewer/shared/utils/math.d.ts +0 -1
- /package/es/aics-image-viewer/components/{CellViewerCanvasWrapper → ViewerCanvasWrapper}/styles.css +0 -0
|
@@ -17,6 +17,7 @@ import CustomizeWidget from "../CustomizeWidget";
|
|
|
17
17
|
import GlobalVolumeControls from "../GlobalVolumeControls";
|
|
18
18
|
import MetadataViewer from "../MetadataViewer";
|
|
19
19
|
import ViewerIcon from "../shared/ViewerIcon";
|
|
20
|
+
import CopySettingsButton from "./CopySettingsButton";
|
|
20
21
|
import "./styles.css";
|
|
21
22
|
var ControlTab = /*#__PURE__*/function (ControlTab) {
|
|
22
23
|
ControlTab[ControlTab["Channels"] = 0] = "Channels";
|
|
@@ -38,6 +39,7 @@ function ControlPanel(props) {
|
|
|
38
39
|
var singleChannelMode = useViewerState(select("singleChannelMode"));
|
|
39
40
|
var changeViewerSetting = useViewerState(select("changeViewerSetting"));
|
|
40
41
|
var containerRef = React.useRef(null);
|
|
42
|
+
var columnRef = React.useRef(null);
|
|
41
43
|
var getDropdownContainer = function getDropdownContainer() {
|
|
42
44
|
var _containerRef$current;
|
|
43
45
|
return (_containerRef$current = containerRef.current) !== null && _containerRef$current !== void 0 ? _containerRef$current : document.body;
|
|
@@ -184,10 +186,16 @@ function ControlPanel(props) {
|
|
|
184
186
|
className: "control-panel-col",
|
|
185
187
|
style: {
|
|
186
188
|
flex: "0 0 450px"
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
189
|
+
},
|
|
190
|
+
ref: columnRef
|
|
191
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
192
|
+
className: "control-panel-title-container"
|
|
193
|
+
}, /*#__PURE__*/React.createElement("h2", null, ControlTabNames[tab]), tab === ControlTab.Channels && /*#__PURE__*/React.createElement(CopySettingsButton, {
|
|
194
|
+
imageName: props.imageName,
|
|
195
|
+
scrollContainer: columnRef.current,
|
|
196
|
+
hide: props.collapsed,
|
|
197
|
+
getDropdownContainer: getDropdownContainer
|
|
198
|
+
})), visibleControls.colorPresetsDropdown && tab === ControlTab.Channels && renderChannelSettingsHeader(), hasImage && /*#__PURE__*/React.createElement("div", {
|
|
191
199
|
className: "control-panel-content"
|
|
192
200
|
}, tab === ControlTab.Channels && /*#__PURE__*/React.createElement(ChannelsWidget, {
|
|
193
201
|
channelDataChannels: props.channelDataChannels,
|
|
@@ -196,7 +204,10 @@ function ControlPanel(props) {
|
|
|
196
204
|
onColorChangeComplete: props.onColorChangeComplete,
|
|
197
205
|
onApplyColorPresets: props.onApplyColorPresets,
|
|
198
206
|
filterFunc: props.filterFunc,
|
|
199
|
-
viewerChannelSettings: viewerChannelSettings
|
|
207
|
+
viewerChannelSettings: viewerChannelSettings,
|
|
208
|
+
getDropdownContainer: getDropdownContainer,
|
|
209
|
+
scrollContainer: columnRef.current,
|
|
210
|
+
controlPanelCollapsed: props.collapsed
|
|
200
211
|
}), tab === ControlTab.Advanced && renderAdvancedSettings(), tab === ControlTab.Metadata && /*#__PURE__*/React.createElement(MetadataViewer, {
|
|
201
212
|
metadata: props.metadata
|
|
202
213
|
}))));
|
|
@@ -57,12 +57,18 @@
|
|
|
57
57
|
display:none;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
.control-panel-col-container .control-panel-col .control-panel-title{
|
|
60
|
+
.control-panel-col-container .control-panel-col .control-panel-title-container{
|
|
61
61
|
margin:16px;
|
|
62
62
|
max-height:24px;
|
|
63
|
-
|
|
63
|
+
display:flex;
|
|
64
|
+
align-items:center;
|
|
65
|
+
justify-content:space-between;
|
|
64
66
|
}
|
|
65
67
|
|
|
68
|
+
.control-panel-col-container .control-panel-col .control-panel-title-container > *{
|
|
69
|
+
font-size:1.4em;
|
|
70
|
+
}
|
|
71
|
+
|
|
66
72
|
.control-panel-col-container .control-panel-col .channel-settings-header{
|
|
67
73
|
margin:0 16px 16px;
|
|
68
74
|
display:flex;
|
|
@@ -177,3 +183,24 @@
|
|
|
177
183
|
font-size:10px;
|
|
178
184
|
top:calc(100% + 3px);
|
|
179
185
|
}
|
|
186
|
+
|
|
187
|
+
.control-panel-col-container .ant-modal.modal-settings-import .ant-upload.ant-upload-drag{
|
|
188
|
+
transition-property:background-color, border-color;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.control-panel-col-container .ant-modal.modal-settings-import .ant-upload.ant-upload-drag:hover{
|
|
192
|
+
background-color:#ffffff20;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.control-panel-col-container .ant-dropdown .import-dropdown-menu-item-include-color{
|
|
196
|
+
white-space:nowrap;
|
|
197
|
+
padding-bottom:9px;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.control-panel-col-container .ant-dropdown .import-dropdown-menu-item-include-color.ant-dropdown-menu-item-active{
|
|
201
|
+
background-color:transparent;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.control-panel-col-container .ant-dropdown .ant-dropdown-menu-item-divider{
|
|
205
|
+
background-color:var(--color-controlpanel-border);
|
|
206
|
+
}
|
|
@@ -20,7 +20,8 @@ var palette = {
|
|
|
20
20
|
veryLtPurple: "#e7e4f2",
|
|
21
21
|
brightRed: "#dc4446",
|
|
22
22
|
brightYellow: "#e39b0d",
|
|
23
|
-
|
|
23
|
+
darkGreen: "#294c2f",
|
|
24
|
+
brightGreen: "#0ccf4d",
|
|
24
25
|
veryBrightGreen: "#61ff00",
|
|
25
26
|
brightBlue: "#0099ff",
|
|
26
27
|
veryBrightBlue: "#0dc4d9",
|
|
@@ -126,6 +127,10 @@ var theme = {
|
|
|
126
127
|
textPlaceholder: palette.ltPurple
|
|
127
128
|
},
|
|
128
129
|
alert: {
|
|
130
|
+
success: {
|
|
131
|
+
text: palette.brightGreen,
|
|
132
|
+
bg: palette.darkGreen
|
|
133
|
+
},
|
|
129
134
|
warning: {
|
|
130
135
|
text: palette.brightYellow,
|
|
131
136
|
bg: palette.darkYellow
|
|
@@ -150,7 +155,7 @@ var theme = {
|
|
|
150
155
|
}
|
|
151
156
|
};
|
|
152
157
|
/** 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 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
|
|
158
|
+
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"])), function (_ref) {
|
|
154
159
|
var $theme = _ref.$theme;
|
|
155
160
|
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
161
|
});
|
|
@@ -172,6 +177,10 @@ export default function StyleProvider(props) {
|
|
|
172
177
|
colorBgContainer: "transparent",
|
|
173
178
|
colorSplit: theme.colors.layout.split,
|
|
174
179
|
colorPrimaryTextHover: theme.colors.text.selectionText,
|
|
180
|
+
colorSuccess: theme.colors.alert.success.text,
|
|
181
|
+
colorSuccessBg: theme.colors.alert.success.bg,
|
|
182
|
+
colorSuccessBorder: theme.colors.alert.success.text,
|
|
183
|
+
colorSuccessText: theme.colors.alert.success.text,
|
|
175
184
|
colorWarning: theme.colors.alert.warning.text,
|
|
176
185
|
colorWarningBg: theme.colors.alert.warning.bg,
|
|
177
186
|
colorWarningBorder: theme.colors.alert.warning.text,
|
|
@@ -236,11 +245,17 @@ export default function StyleProvider(props) {
|
|
|
236
245
|
colorTextPlaceholder: theme.colors.button.tertiary.hoverText,
|
|
237
246
|
colorBgContainerDisabled: "transparent"
|
|
238
247
|
},
|
|
248
|
+
Tabs: {
|
|
249
|
+
horizontalItemPaddingLG: "5px 0"
|
|
250
|
+
},
|
|
239
251
|
// Additional tooltip overrides (font-weight, box-shadow, layout) are in GlobalTooltipStyle below,
|
|
240
252
|
// which is required because antd renders tooltips in portals outside the scoped CssProvider.
|
|
241
253
|
Tooltip: {
|
|
242
254
|
colorBgSpotlight: theme.colors.tooltip.bg,
|
|
243
255
|
fontSize: 12
|
|
256
|
+
},
|
|
257
|
+
Upload: {
|
|
258
|
+
padding: 32
|
|
244
259
|
}
|
|
245
260
|
}
|
|
246
261
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Radio } from "antd";
|
|
2
2
|
import React from "react";
|
|
3
|
-
import { ViewMode } from "../../
|
|
3
|
+
import { ViewMode } from "../../state/types";
|
|
4
4
|
var viewModes = [ViewMode.threeD, ViewMode.xy, ViewMode.xz, ViewMode.yz];
|
|
5
5
|
var ViewModeRadioButtons = function ViewModeRadioButtons(props) {
|
|
6
6
|
var onChangeButton = function onChangeButton(_ref) {
|
|
@@ -8,8 +8,8 @@ import { ReloadOutlined } from "@ant-design/icons";
|
|
|
8
8
|
import { Button, Radio, Select, Tooltip } from "antd";
|
|
9
9
|
import { debounce } from "lodash";
|
|
10
10
|
import React from "react";
|
|
11
|
-
import { ImageType, RenderMode, ViewMode } from "../../shared/enums";
|
|
12
11
|
import { select, useViewerState } from "../../state/store";
|
|
12
|
+
import { ImageType, RenderMode, ViewMode } from "../../state/types";
|
|
13
13
|
import ViewerIcon from "../shared/ViewerIcon";
|
|
14
14
|
import DownloadButton from "./DownloadButton";
|
|
15
15
|
import ViewModeRadioButtons from "./ViewModeRadioButtons";
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
width:100%;
|
|
4
4
|
z-index:250;
|
|
5
5
|
}
|
|
6
|
-
|
|
7
6
|
.viewer-toolbar-container .viewer-toolbar-scroll-left,
|
|
8
7
|
.viewer-toolbar-container .viewer-toolbar-scroll-right{
|
|
9
8
|
height:100%;
|
|
@@ -17,28 +16,22 @@
|
|
|
17
16
|
z-index:255;
|
|
18
17
|
transition:color 0.3s;
|
|
19
18
|
}
|
|
20
|
-
|
|
21
19
|
.viewer-toolbar-container .viewer-toolbar-scroll-left:hover, .viewer-toolbar-container .viewer-toolbar-scroll-right:hover{
|
|
22
20
|
color:white;
|
|
23
21
|
}
|
|
24
|
-
|
|
25
22
|
.viewer-toolbar-container .viewer-toolbar-scroll-left{
|
|
26
23
|
left:0;
|
|
27
24
|
}
|
|
28
|
-
|
|
29
25
|
.viewer-toolbar-container .viewer-toolbar-scroll-right{
|
|
30
26
|
right:0;
|
|
31
27
|
}
|
|
32
|
-
|
|
33
28
|
.viewer-toolbar-container.viewer-toolbar-scroll{
|
|
34
29
|
border-bottom:1px solid var(--color-layout-dividers);
|
|
35
30
|
}
|
|
36
|
-
|
|
37
31
|
.viewer-toolbar-container.viewer-toolbar-scroll .viewer-toolbar-scroll-left,
|
|
38
32
|
.viewer-toolbar-container.viewer-toolbar-scroll .viewer-toolbar-scroll-right{
|
|
39
33
|
display:flex;
|
|
40
34
|
}
|
|
41
|
-
|
|
42
35
|
.viewer-toolbar-container.viewer-toolbar-scroll .viewer-toolbar{
|
|
43
36
|
white-space:nowrap;
|
|
44
37
|
justify-content:normal;
|
|
@@ -46,16 +39,13 @@
|
|
|
46
39
|
overflow-x:scroll;
|
|
47
40
|
scrollbar-width:none;
|
|
48
41
|
}
|
|
49
|
-
|
|
50
42
|
.viewer-toolbar-container.viewer-toolbar-scroll .viewer-toolbar::-webkit-scrollbar{
|
|
51
43
|
display:none;
|
|
52
44
|
}
|
|
53
|
-
|
|
54
45
|
.viewer-toolbar-container.viewer-toolbar-scroll .viewer-toolbar .viewer-toolbar-left{
|
|
55
46
|
position:static;
|
|
56
47
|
margin-left:15px;
|
|
57
48
|
}
|
|
58
|
-
|
|
59
49
|
.viewer-toolbar-container.viewer-toolbar-scroll .viewer-toolbar .viewer-toolbar-right{
|
|
60
50
|
position:static;
|
|
61
51
|
margin-right:15px;
|
package/es/aics-image-viewer/components/{CellViewerCanvasWrapper → ViewerCanvasWrapper}/index.js
RENAMED
|
@@ -7,8 +7,8 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|
|
7
7
|
import { LoadingOutlined } from "@ant-design/icons";
|
|
8
8
|
import React from "react";
|
|
9
9
|
import { CLIPPING_PANEL_HEIGHT_DEFAULT, CLIPPING_PANEL_HEIGHT_TALL } from "../../shared/constants";
|
|
10
|
-
import { ViewMode } from "../../shared/enums";
|
|
11
10
|
import { select, useViewerState } from "../../state/store";
|
|
11
|
+
import { ViewMode } from "../../state/types";
|
|
12
12
|
import BottomPanel from "../BottomPanel";
|
|
13
13
|
import { AxisClipSliders } from "../dimension_sliders/AxisClipSliders";
|
|
14
14
|
import { RotationSliders } from "../dimension_sliders/RotationSliders";
|
|
@@ -65,7 +65,8 @@ var ViewerWrapper = function ViewerWrapper(props) {
|
|
|
65
65
|
time: time,
|
|
66
66
|
scene: scene,
|
|
67
67
|
playControls: props.playControls,
|
|
68
|
-
playingAxis: props.playingAxis
|
|
68
|
+
playingAxis: props.playingAxis,
|
|
69
|
+
setScrubbingAxis: props.setScrubbingAxis
|
|
69
70
|
})
|
|
70
71
|
});
|
|
71
72
|
}
|
|
@@ -25,13 +25,25 @@ export var AxisClipSliders = function AxisClipSliders(props) {
|
|
|
25
25
|
changeViewerSetting("region", _defineProperty({}, axis, [start, end]));
|
|
26
26
|
};
|
|
27
27
|
var updateSlice = function updateSlice(axis, slice) {
|
|
28
|
+
var isScrubbing = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
28
29
|
pauseOnInput(axis);
|
|
30
|
+
if (isScrubbing) {
|
|
31
|
+
props.setScrubbingAxis(axis);
|
|
32
|
+
}
|
|
29
33
|
props.changeViewerSetting("slice", _defineProperty({}, axis, slice / props.numSlices[axis]));
|
|
30
34
|
};
|
|
31
35
|
var updateTime = function updateTime(time) {
|
|
36
|
+
var isScrubbing = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
32
37
|
pauseOnInput("t");
|
|
38
|
+
if (isScrubbing) {
|
|
39
|
+
props.setScrubbingAxis("t");
|
|
40
|
+
}
|
|
33
41
|
props.changeViewerSetting("time", time);
|
|
34
42
|
};
|
|
43
|
+
var endScrub = function endScrub() {
|
|
44
|
+
props.setScrubbingAxis(null);
|
|
45
|
+
props.playControls.endHold();
|
|
46
|
+
};
|
|
35
47
|
|
|
36
48
|
// Pause when view mode or volume size has changed
|
|
37
49
|
useEffect(function () {
|
|
@@ -54,20 +66,20 @@ export var AxisClipSliders = function AxisClipSliders(props) {
|
|
|
54
66
|
label: axis.toUpperCase(),
|
|
55
67
|
val: Math.round(props.slices[axis] * numSlices),
|
|
56
68
|
max: numSlices,
|
|
69
|
+
onSlide: function onSlide(val) {
|
|
70
|
+
return updateSlice(axis, val, true);
|
|
71
|
+
},
|
|
57
72
|
onChange: function onChange(val) {
|
|
58
73
|
return updateSlice(axis, val);
|
|
59
74
|
},
|
|
60
75
|
onStart: function onStart() {
|
|
61
76
|
return props.playControls.startHold(axis);
|
|
62
77
|
},
|
|
63
|
-
onEnd:
|
|
64
|
-
return props.playControls.endHold();
|
|
65
|
-
},
|
|
78
|
+
onEnd: endScrub,
|
|
66
79
|
playing: props.playingAxis === axis,
|
|
67
80
|
onTogglePlayback: function onTogglePlayback(willPlay) {
|
|
68
81
|
return handlePlayPause(axis, willPlay);
|
|
69
|
-
}
|
|
70
|
-
updateWhileSliding: numSlices === numSlicesLoaded
|
|
82
|
+
}
|
|
71
83
|
}));
|
|
72
84
|
};
|
|
73
85
|
var create3dAxisSlider = function create3dAxisSlider(axis) {
|
|
@@ -119,15 +131,16 @@ export var AxisClipSliders = function AxisClipSliders(props) {
|
|
|
119
131
|
onTogglePlayback: function onTogglePlayback(willPlay) {
|
|
120
132
|
return handlePlayPause("t", willPlay);
|
|
121
133
|
},
|
|
134
|
+
onSlide: function onSlide(time) {
|
|
135
|
+
return updateTime(time, true);
|
|
136
|
+
},
|
|
122
137
|
onChange: function onChange(time) {
|
|
123
138
|
return updateTime(time);
|
|
124
139
|
},
|
|
125
140
|
onStart: function onStart() {
|
|
126
141
|
return props.playControls.startHold("t");
|
|
127
142
|
},
|
|
128
|
-
onEnd:
|
|
129
|
-
return props.playControls.endHold();
|
|
130
|
-
}
|
|
143
|
+
onEnd: endScrub
|
|
131
144
|
})))), props.numScenes > 1 && /*#__PURE__*/React.createElement("span", {
|
|
132
145
|
className: "slider-group"
|
|
133
146
|
}, /*#__PURE__*/React.createElement("span", {
|
|
@@ -12,9 +12,9 @@ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" !=
|
|
|
12
12
|
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
13
13
|
import { Button, Space } from "antd";
|
|
14
14
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
15
|
-
import { ViewMode } from "../../shared/enums";
|
|
16
15
|
import { applyMatrix, defaultOrientedCamera, getRotationAngles, rotationMatrix, useCameraCallback } from "../../shared/utils/camera";
|
|
17
16
|
import { select, useViewerState } from "../../state/store";
|
|
17
|
+
import { ViewMode } from "../../state/types";
|
|
18
18
|
import { DimensionSliderRow } from "./SliderRows";
|
|
19
19
|
|
|
20
20
|
/** Convert an angle from degrees to radians */
|
|
@@ -100,21 +100,19 @@ export var RotationSliders = function RotationSliders(_ref) {
|
|
|
100
100
|
|
|
101
101
|
// Set up event listeners on mount.
|
|
102
102
|
useEffect(function () {
|
|
103
|
-
|
|
104
|
-
// At time of writing, `setOnRenderCallback` appears not to be used anywhere else in either this package or
|
|
105
|
-
// vole-core, but that could change at any time.
|
|
106
|
-
// Ideally `View3d` would have an `addEventListener`/`removeEventListener` model.
|
|
107
|
-
view3d.setOnRenderCallback(function () {
|
|
103
|
+
var renderListener = function renderListener() {
|
|
108
104
|
if (!hasControlRef.current) {
|
|
109
105
|
setRotation(getRotationAngles(view3d.getCameraState()));
|
|
110
106
|
}
|
|
111
|
-
}
|
|
107
|
+
};
|
|
108
|
+
view3d.addEventListener("render", renderListener);
|
|
112
109
|
var clickListener = function clickListener() {
|
|
113
110
|
return hasControlRef.current = false;
|
|
114
111
|
};
|
|
115
112
|
view3d.getDOMElement().addEventListener("mousedown", clickListener);
|
|
116
113
|
return function () {
|
|
117
|
-
|
|
114
|
+
view3d.removeEventListener("render", renderListener);
|
|
115
|
+
view3d.getDOMElement().removeEventListener("mousedown", clickListener);
|
|
118
116
|
};
|
|
119
117
|
}, [view3d]);
|
|
120
118
|
var createRotateSlider = function createRotateSlider(axis) {
|
|
@@ -116,6 +116,7 @@ export var IndexSliderRow = function IndexSliderRow(props) {
|
|
|
116
116
|
/** Wrapper around `SliderRow` that adds a play button and accounts for the case where not all of an axis is loaded. */
|
|
117
117
|
export var PlaySliderRow = function PlaySliderRow(props) {
|
|
118
118
|
var onChange = props.onChange,
|
|
119
|
+
onSlide = props.onSlide,
|
|
119
120
|
onStart = props.onStart,
|
|
120
121
|
onEnd = props.onEnd;
|
|
121
122
|
// In partially-loaded axes, stores the displayed value of the slider while the user is sliding it
|
|
@@ -131,9 +132,10 @@ export var PlaySliderRow = function PlaySliderRow(props) {
|
|
|
131
132
|
var wrappedOnChange = useCallback(function (val) {
|
|
132
133
|
return onChange === null || onChange === void 0 ? void 0 : onChange(val);
|
|
133
134
|
}, [onChange]);
|
|
134
|
-
var
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
var wrappedOnSlide = useCallback(function (val) {
|
|
136
|
+
setValReadout(val);
|
|
137
|
+
onSlide === null || onSlide === void 0 || onSlide(val);
|
|
138
|
+
}, [onSlide]);
|
|
137
139
|
var wrappedOnStart = useCallback(function () {
|
|
138
140
|
setValReadout(props.val);
|
|
139
141
|
setSliderHeld(true);
|
|
@@ -146,10 +148,10 @@ export var PlaySliderRow = function PlaySliderRow(props) {
|
|
|
146
148
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(IndexSliderRow, {
|
|
147
149
|
label: props.label,
|
|
148
150
|
val: props.val,
|
|
149
|
-
valReadout:
|
|
151
|
+
valReadout: !sliderHeld ? undefined : valReadout,
|
|
150
152
|
max: props.max,
|
|
151
|
-
onSlide:
|
|
152
|
-
onChange:
|
|
153
|
+
onSlide: wrappedOnSlide,
|
|
154
|
+
onChange: wrappedOnChange,
|
|
153
155
|
onStart: wrappedOnStart,
|
|
154
156
|
onEnd: wrappedOnEnd
|
|
155
157
|
}), props.max > 1 && /*#__PURE__*/React.createElement(Tooltip, {
|
|
@@ -0,0 +1,101 @@
|
|
|
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); }
|
|
2
|
+
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); }
|
|
3
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
4
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
5
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
6
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
7
|
+
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); }
|
|
8
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
9
|
+
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."); }
|
|
10
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
11
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
12
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
13
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
14
|
+
import { Alert } from "antd";
|
|
15
|
+
import React from "react";
|
|
16
|
+
import { createPortal } from "react-dom";
|
|
17
|
+
var ALERT_STYLE = {
|
|
18
|
+
position: "absolute",
|
|
19
|
+
bottom: "auto",
|
|
20
|
+
right: "auto",
|
|
21
|
+
zIndex: 1000
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Antd's `Alert`, but positioned immediately under a `target` element to provide contextual information.
|
|
26
|
+
*
|
|
27
|
+
* This is relatively specialized to the use case of attaching to components inside the control panel. Since the
|
|
28
|
+
* control panel can be vertically scrolled and hidden, it has specific props for responding to both.
|
|
29
|
+
*/
|
|
30
|
+
export var ContextualAlert = function ContextualAlert(props) {
|
|
31
|
+
var message = props.message,
|
|
32
|
+
target = props.target,
|
|
33
|
+
scrollContainer = props.scrollContainer,
|
|
34
|
+
hide = props.hide;
|
|
35
|
+
var _React$useState = React.useState({
|
|
36
|
+
top: 0,
|
|
37
|
+
left: 0
|
|
38
|
+
}),
|
|
39
|
+
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
40
|
+
alertPosition = _React$useState2[0],
|
|
41
|
+
setAlertPosition = _React$useState2[1];
|
|
42
|
+
React.useEffect(function () {
|
|
43
|
+
var setPosition = function setPosition() {
|
|
44
|
+
if (target !== null) {
|
|
45
|
+
var rect = target.getBoundingClientRect();
|
|
46
|
+
setAlertPosition({
|
|
47
|
+
top: rect.bottom + 10,
|
|
48
|
+
left: rect.left
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
setPosition();
|
|
53
|
+
if (scrollContainer) {
|
|
54
|
+
scrollContainer.addEventListener("scroll", setPosition);
|
|
55
|
+
return function () {
|
|
56
|
+
return scrollContainer.removeEventListener("scroll", setPosition);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return undefined;
|
|
60
|
+
}, [scrollContainer, target]);
|
|
61
|
+
return /*#__PURE__*/createPortal(/*#__PURE__*/React.createElement("div", {
|
|
62
|
+
style: _objectSpread(_objectSpread(_objectSpread({}, ALERT_STYLE), alertPosition), {}, {
|
|
63
|
+
display: !message || hide ? "none" : "block"
|
|
64
|
+
})
|
|
65
|
+
}, /*#__PURE__*/React.createElement(Alert, props)), document.body);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Creates an `antd` `Alert` element that stays positioned beneath the `target` element, and a function to show
|
|
70
|
+
* time-limited messages in the `Alert`.
|
|
71
|
+
*
|
|
72
|
+
* This is relatively specialized to the use case of attaching to components inside the control panel. Since the
|
|
73
|
+
* control panel can be vertically scrolled and hidden, it has specific props for responding to both.
|
|
74
|
+
*/
|
|
75
|
+
export var useContextualAlert = function useContextualAlert(target, options) {
|
|
76
|
+
var _React$useState3 = React.useState(undefined),
|
|
77
|
+
_React$useState4 = _slicedToArray(_React$useState3, 2),
|
|
78
|
+
message = _React$useState4[0],
|
|
79
|
+
setMessage = _React$useState4[1];
|
|
80
|
+
var _React$useState5 = React.useState(undefined),
|
|
81
|
+
_React$useState6 = _slicedToArray(_React$useState5, 2),
|
|
82
|
+
messageType = _React$useState6[0],
|
|
83
|
+
setMessageType = _React$useState6[1];
|
|
84
|
+
var messageTimeoutRef = React.useRef(undefined);
|
|
85
|
+
var showMessage = React.useCallback(function (message, messageType) {
|
|
86
|
+
if (messageTimeoutRef.current !== undefined) {
|
|
87
|
+
window.clearTimeout(messageTimeoutRef.current);
|
|
88
|
+
}
|
|
89
|
+
messageTimeoutRef.current = window.setTimeout(function () {
|
|
90
|
+
return setMessage(undefined);
|
|
91
|
+
}, options.timeout);
|
|
92
|
+
setMessage(message);
|
|
93
|
+
setMessageType(messageType);
|
|
94
|
+
}, [options.timeout]);
|
|
95
|
+
var alert = /*#__PURE__*/React.createElement(ContextualAlert, _extends({
|
|
96
|
+
message: message,
|
|
97
|
+
target: target,
|
|
98
|
+
type: messageType !== null && messageType !== void 0 ? messageType : "success"
|
|
99
|
+
}, options));
|
|
100
|
+
return [alert, showMessage];
|
|
101
|
+
};
|
|
@@ -31,7 +31,7 @@ var ControlPanelRow = function ControlPanelRow(inputProps) {
|
|
|
31
31
|
var style = {
|
|
32
32
|
"--control-panel-row-vertical-margin": props.verticalMargin + "px"
|
|
33
33
|
};
|
|
34
|
-
var createTitle = props.title !== undefined || props.showColorPicker;
|
|
34
|
+
var createTitle = props.title !== undefined || props.icon !== undefined || props.showColorPicker;
|
|
35
35
|
var baseClass = "control-panel-row".concat(props.highlight ? " control-panel-row-highlight" : "");
|
|
36
36
|
var className = props.className ? "".concat(baseClass, " ").concat(props.className) : baseClass;
|
|
37
37
|
return /*#__PURE__*/React.createElement("div", {
|
|
@@ -40,7 +40,9 @@ var ControlPanelRow = function ControlPanelRow(inputProps) {
|
|
|
40
40
|
onClick: props.onClick
|
|
41
41
|
}, createTitle && /*#__PURE__*/React.createElement("div", {
|
|
42
42
|
className: "control-panel-row-title"
|
|
43
|
-
}, props.
|
|
43
|
+
}, props.icon && /*#__PURE__*/React.createElement("div", {
|
|
44
|
+
className: "control-panel-row-icon"
|
|
45
|
+
}, props.icon), props.showColorPicker && /*#__PURE__*/React.createElement(ColorPicker, _extends({
|
|
44
46
|
disableAlpha: true,
|
|
45
47
|
width: 18
|
|
46
48
|
}, colorPickerProps)), props.title && /*#__PURE__*/React.createElement("h4", null, props.title)), props.children);
|
|
@@ -16,8 +16,10 @@
|
|
|
16
16
|
flex-grow:1;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
.control-panel-col .control-panel-row .control-panel-row-title .color-picker
|
|
20
|
-
|
|
19
|
+
.control-panel-col .control-panel-row .control-panel-row-title .color-picker,
|
|
20
|
+
.control-panel-col .control-panel-row .control-panel-row-title .control-panel-row-icon{
|
|
21
|
+
margin-right:10px;
|
|
22
|
+
font-size:12px;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
.control-panel-col .control-panel-row .control-panel-row-title h4{
|
|
@@ -58,7 +60,6 @@
|
|
|
58
60
|
width:100%;
|
|
59
61
|
border-bottom:1px solid var(--color-controlpanel-border);
|
|
60
62
|
}
|
|
61
|
-
|
|
62
63
|
.control-panel-col .ant-collapse-item:not(:last-child) .control-panel-row:last-child::after{
|
|
63
64
|
border-bottom:none;
|
|
64
65
|
}
|