From c391c007ffedb28f46a84654a8f969e4069cb580 Mon Sep 17 00:00:00 2001 From: Rodrigo Antinarelli Date: Thu, 13 Feb 2020 19:43:20 -0300 Subject: [PATCH] initial structure for components rewrite --- platform/ui/.all-contributorsrc | 135 - platform/ui/.env | 11 - platform/ui/.gitignore | 2 + platform/ui/.stylelintrc.json | 3 + platform/ui/.webpack/webpack.prod.js | 37 - platform/ui/LICENSE | 21 - platform/ui/README.md | 136 +- platform/ui/app.css | 12 - platform/ui/babel.config.js | 1 - platform/ui/doczrc.js | 75 - platform/ui/jest.config.js | 10 - platform/ui/package.json | 61 +- platform/ui/postcss.config.js | 8 +- platform/ui/public/docz.css | 44 - .../ui/src/ScrollableArea/ScrollableArea.js | 152 - .../ui/src/ScrollableArea/ScrollableArea.styl | 69 - platform/ui/src/__docs__/NameSpace.js | 17 - platform/ui/src/__docs__/assets/github.png | Bin 37651 -> 0 bytes platform/ui/src/__docs__/assets/npm.png | Bin 9156 -> 0 bytes platform/ui/src/__docs__/assets/react.png | Bin 61998 -> 0 bytes .../ui/src/__docs__/assets/typescript.png | Bin 18302 -> 0 bytes platform/ui/src/__docs__/compatibility.mdx | 15 - platform/ui/src/__docs__/config/Wrapper.js | 0 platform/ui/src/__docs__/docs-settings.mdx | 13 - platform/ui/src/__docs__/getting-started.mdx | 76 - platform/ui/src/__docs__/index.html | 83 - platform/ui/src/__docs__/introduction.mdx | 76 - .../ui/src/__docs__/styling-and-theming.mdx | 56 - platform/ui/src/__docs__/translating.mdx | 87 - platform/ui/src/__docs__/wrapper.js | 22 - platform/ui/src/__docs__/wrapper.styl | 15 - platform/ui/src/components/Alert.jsx | 34 + platform/ui/src/components/Alert.mdx | 28 + platform/ui/src/components/Button/Button.jsx | 124 + platform/ui/src/components/Button/Button.mdx | 180 + platform/ui/src/components/Button/index.js | 2 + platform/ui/src/components/Input/Input.jsx | 17 + platform/ui/src/components/Input/Input.mdx | 30 + platform/ui/src/components/Input/index.js | 2 + platform/ui/src/components/Label/Label.jsx | 34 + platform/ui/src/components/Label/Label.mdx | 20 + platform/ui/src/components/Label/index.js | 2 + .../components/checkbox/__docs__/checkbox.mdx | 42 - .../ui/src/components/checkbox/checkbox.css | 56 - .../ui/src/components/checkbox/checkbox.js | 58 - platform/ui/src/components/checkbox/index.js | 1 - .../src/components/cineDialog/CineDialog.js | 197 - .../src/components/cineDialog/CineDialog.styl | 172 - .../cineDialog/__docs__/cineDialog.mdx | 57 - .../ui/src/components/cineDialog/index.js | 2 - .../content/aboutContent/AboutContent.js | 107 - .../content/aboutContent/AboutContent.styl | 20 - .../ViewportDownloadForm.js | 431 - .../ViewportDownloadForm.styl | 140 - .../__docs__/viewportDownloadForm.mdx | 39 - .../content/viewportDownloadForm/index.js | 2 - .../components/contextMenu/ContextMenu.css | 33 - .../ui/src/components/contextMenu/index.js | 1 - .../languageSwitcher/LanguageSwitcher.styl | 4 - .../components/layoutButton/LayoutButton.js | 64 - .../layoutButton/LayoutChooser.styl | 47 - .../layoutButton/__docs__/layoutButton.css | 10 - .../layoutButton/__docs__/layoutButton.mdx | 49 - .../ui/src/components/layoutButton/index.js | 2 - .../measurementTable/MeasurementTable.js | 218 - .../measurementTable/MeasurementTable.styl | 116 - .../measurementTable/MeasurementTableItem.js | 165 - .../__docs__/measurementTable.mdx | 49 - .../measurementTable/__docs__/measurements.js | 93 - .../measurementTable/__docs__/timepoints.js | 14 - .../measurementTable/__docs__/warnings.js | 6 - .../src/components/measurementTable/index.js | 2 - .../ui/src/components/ohifModal/OHIFModal.js | 76 - .../src/components/ohifModal/OHIFModal.styl | 67 - .../ohifModal/__docs__/ohifModal.mdx | 39 - platform/ui/src/components/ohifModal/index.js | 2 - .../ui/src/components/overlayTrigger/Fade.js | 102 - .../src/components/overlayTrigger/Overlay.js | 102 - .../overlayTrigger/OverlayTrigger.js | 330 - .../__docs__/OverlayTrigger.mdx | 84 - .../overlayTrigger/createChainedFunction.js | 31 - .../ui/src/components/overlayTrigger/index.js | 2 - .../components/quickSwitch/QuickSwitch.styl | 209 - .../components/quickSwitch/SeriesList.styl | 0 .../components/quickSwitch/StudiesList.styl | 0 .../ui/src/components/quickSwitch/index.js | 1 - .../radioButtonList/RadioButtonList.css | 62 - .../radioButtonList/RadioButtonList.js | 74 - .../__docs__/radioButtonList.mdx | 74 - .../src/components/radioButtonList/index.js | 1 - .../roundedButtonGroup/RoundedButtonGroup.js | 84 - .../__docs__/roundedButtonGroup.mdx | 51 - .../components/roundedButtonGroup/index.js | 1 - .../src/components/selectTree/InputRadio.js | 37 - .../src/components/selectTree/SelectTree.js | 192 - .../src/components/selectTree/SelectTree.styl | 108 - .../selectTree/SelectTreeBreadcrumb.js | 37 - .../selectTree/__docs__/selectTree.mdx | 42 - .../selectTree/__docs__/selectTreeItems.js | 30 - .../ui/src/components/selectTree/index.js | 1 - .../components/simpleDialog/SimpleDialog.js | 95 - .../components/simpleDialog/SimpleDialog.styl | 110 - .../simpleDialog/__docs__/simpleDialog.mdx | 83 - .../ui/src/components/simpleDialog/index.js | 1 - .../components/snackbar/SnackbarContainer.js | 53 - .../src/components/snackbar/SnackbarItem.js | 31 - .../src/components/snackbar/SnackbarTypes.js | 6 - .../studyBrowser/ImageThumbnail.styl | 99 - .../components/studyBrowser/StudyBrowser.styl | 40 - .../components/studyBrowser/Thumbnail.styl | 98 - .../__docs__/ExampleDropTarget.css | 30 - .../studyBrowser/__docs__/studyBrowser.mdx | 22 - .../__docs__/wrappedStudyBrowser.js | 41 - .../ui/src/components/studyBrowser/index.js | 2 - .../studyList/CustomDateRangePicker.css | 119 - .../studyList/CustomDateRangePicker.js | 140 - .../src/components/studyList/PageToolbar.js | 38 - .../components/studyList/PaginationArea.styl | 63 - .../studyList/StudyListLoadingText.js | 18 - .../components/studyList/TableSearchFilter.js | 150 - platform/ui/src/components/studyList/index.js | 4 - .../src/components/tableList/TableList.styl | 50 - .../components/tableList/TableListItem.styl | 46 - .../tableList/__docs__/tableList.mdx | 48 - platform/ui/src/components/tableList/index.js | 2 - .../toolbarSection/ToolbarSection.js | 65 - .../toolbarSection/ToolbarSection.styl | 4 - .../toolbarSection/__docs__/exampleButtons.js | 41 - .../__docs__/toolbarSection.docs.mdx | 39 - .../ui/src/components/toolbarSection/index.js | 1 - platform/ui/src/components/tooltip/Tooltip.js | 66 - .../ui/src/components/tooltip/Tooltip.styl | 92 - .../tooltip/__docs__/tooltip.noshow-mdx | 20 - .../src/components/tooltip/__tests__/.githold | 0 platform/ui/src/components/tooltip/index.js | 1 - .../ui/src/contextProviders/DialogProvider.js | 291 - .../src/contextProviders/DialogProvider.styl | 21 - .../src/contextProviders/LanguageProvider.js | 28 - .../ui/src/contextProviders/ModalProvider.js | 134 - .../src/contextProviders/SnackbarProvider.js | 142 - platform/ui/src/contextProviders/index.js | 20 - .../ui/src/design/styles/common/button.styl | 53 - .../ui/src/design/styles/common/form.styl | 121 - .../ui/src/design/styles/common/global.styl | 71 - .../ui/src/design/styles/common/modal.styl | 203 - .../ui/src/design/styles/common/navbar.styl | 57 - .../ui/src/design/styles/common/state.styl | 25 - .../ui/src/design/styles/common/table.styl | 15 - platform/ui/src/elements/Icon/Icon.js | 15 - platform/ui/src/elements/Icon/Icon.styl | 11 - .../ui/src/elements/Icon/__docs__/icon.mdx | 84 - .../ui/src/elements/Icon/icons/3d-rotate.svg | 13 - .../ui/src/elements/Icon/icons/adjust.svg | 11 - .../elements/Icon/icons/angle-double-down.svg | 11 - .../elements/Icon/icons/angle-double-up.svg | 11 - .../ui/src/elements/Icon/icons/angle-left.svg | 11 - .../src/elements/Icon/icons/arrows-alt-h.svg | 11 - .../src/elements/Icon/icons/arrows-alt-v.svg | 11 - .../ui/src/elements/Icon/icons/arrows.svg | 22 - platform/ui/src/elements/Icon/icons/bars.svg | 11 - platform/ui/src/elements/Icon/icons/brain.svg | 24 - .../ui/src/elements/Icon/icons/caret-down.svg | 11 - .../ui/src/elements/Icon/icons/caret-up.svg | 11 - .../elements/Icon/icons/check-circle-o.svg | 11 - .../src/elements/Icon/icons/check-circle.svg | 11 - platform/ui/src/elements/Icon/icons/check.svg | 11 - .../src/elements/Icon/icons/chevron-down.svg | 14 - .../src/elements/Icon/icons/circle-notch.svg | 11 - .../ui/src/elements/Icon/icons/circle-o.svg | 11 - .../ui/src/elements/Icon/icons/circle.svg | 11 - platform/ui/src/elements/Icon/icons/cog.svg | 11 - .../elements/Icon/icons/create-comment.svg | 12 - .../Icon/icons/create-screen-capture.svg | 15 - .../ui/src/elements/Icon/icons/crosshairs.svg | 15 - platform/ui/src/elements/Icon/icons/cube.svg | 12 - .../ui/src/elements/Icon/icons/database.svg | 11 - .../ui/src/elements/Icon/icons/dot-circle.svg | 11 - platform/ui/src/elements/Icon/icons/edit.svg | 11 - .../elements/Icon/icons/ellipse-circle.svg | 11 - .../ui/src/elements/Icon/icons/ellipse-h.svg | 11 - .../ui/src/elements/Icon/icons/ellipse-v.svg | 11 - .../ui/src/elements/Icon/icons/eraser.svg | 15 - .../Icon/icons/exclamation-circle.svg | 13 - .../Icon/icons/exclamation-triangle.svg | 11 - .../src/elements/Icon/icons/fast-backward.svg | 10 - .../src/elements/Icon/icons/fast-forward.svg | 10 - platform/ui/src/elements/Icon/icons/info.svg | 11 - .../src/elements/Icon/icons/inline-edit.svg | 11 - platform/ui/src/elements/Icon/icons/level.svg | 13 - .../src/elements/Icon/icons/link-circles.svg | 15 - platform/ui/src/elements/Icon/icons/link.svg | 12 - platform/ui/src/elements/Icon/icons/list.svg | 11 - platform/ui/src/elements/Icon/icons/liver.svg | 16 - .../ui/src/elements/Icon/icons/lock-alt.svg | 11 - platform/ui/src/elements/Icon/icons/lock.svg | 11 - platform/ui/src/elements/Icon/icons/lung.svg | 25 - .../Icon/icons/measure-non-target.svg | 29 - .../elements/Icon/icons/measure-target-cr.svg | 23 - .../elements/Icon/icons/measure-target-ne.svg | 16 - .../elements/Icon/icons/measure-target-un.svg | 23 - .../elements/Icon/icons/measure-target.svg | 13 - .../src/elements/Icon/icons/measure-temp.svg | 16 - .../src/elements/Icon/icons/object-group.svg | 20 - .../ui/src/elements/Icon/icons/ohif-logo.svg | 17 - .../elements/Icon/icons/ohif-text-logo.svg | 3 - platform/ui/src/elements/Icon/icons/oval.svg | 11 - .../ui/src/elements/Icon/icons/palette.svg | 11 - platform/ui/src/elements/Icon/icons/play.svg | 10 - platform/ui/src/elements/Icon/icons/plus.svg | 11 - .../ui/src/elements/Icon/icons/power-off.svg | 11 - platform/ui/src/elements/Icon/icons/reset.svg | 11 - .../src/elements/Icon/icons/rotate-right.svg | 11 - .../ui/src/elements/Icon/icons/rotate.svg | 11 - .../src/elements/Icon/icons/save-regular.svg | 11 - .../src/elements/Icon/icons/search-plus.svg | 14 - .../ui/src/elements/Icon/icons/search.svg | 11 - .../src/elements/Icon/icons/soft-tissue.svg | 16 - .../ui/src/elements/Icon/icons/sort-down.svg | 11 - .../ui/src/elements/Icon/icons/sort-up.svg | 11 - platform/ui/src/elements/Icon/icons/sort.svg | 11 - .../ui/src/elements/Icon/icons/square-o.svg | 11 - platform/ui/src/elements/Icon/icons/star.svg | 11 - .../src/elements/Icon/icons/step-backward.svg | 10 - .../src/elements/Icon/icons/step-forward.svg | 10 - platform/ui/src/elements/Icon/icons/stop.svg | 11 - platform/ui/src/elements/Icon/icons/sun.svg | 11 - .../ui/src/elements/Icon/icons/th-large.svg | 12 - .../ui/src/elements/Icon/icons/th-list.svg | 11 - platform/ui/src/elements/Icon/icons/th.svg | 11 - platform/ui/src/elements/Icon/icons/times.svg | 12 - platform/ui/src/elements/Icon/icons/trash.svg | 11 - .../ui/src/elements/Icon/icons/unlink.svg | 11 - platform/ui/src/elements/Icon/icons/user.svg | 11 - .../ui/src/elements/Icon/icons/youtube.svg | 11 - platform/ui/src/elements/Icon/index.js | 4 - platform/ui/src/elements/Svg/Svg.js | 14 - platform/ui/src/elements/Svg/Svg.styl | 0 platform/ui/src/elements/Svg/__docs__/svg.mdx | 57 - platform/ui/src/elements/Svg/getSvg.js | 24 - platform/ui/src/elements/Svg/index.js | 2 - .../src/elements/Svg/svgs/ohif-logo-text.svg | 3 - .../Svg/svgs/ohif-logo-wrapped-text.svg | 14 - .../ui/src/elements/form/DropdownMenu.css | 86 - platform/ui/src/elements/form/DropdownMenu.js | 138 - platform/ui/src/elements/form/Label.css | 8 - platform/ui/src/elements/form/Label.js | 27 - platform/ui/src/elements/form/OldSelect.js | 49 - platform/ui/src/elements/form/Range.css | 65 - platform/ui/src/elements/form/Select.css | 63 - platform/ui/src/elements/form/Select.js | 49 - platform/ui/src/elements/form/TextArea.css | 7 - platform/ui/src/elements/form/TextInput.css | 34 - platform/ui/src/elements/form/TextInput.js | 45 - .../form/__docs__/dropdownMenu.doc.mdx | 42 - .../src/elements/form/__docs__/label.doc.mdx | 32 - .../src/elements/form/__docs__/range.doc.mdx | 33 - .../elements/form/__docs__/select.docs.mdx | 39 - .../elements/form/__docs__/textArea.doc.mdx | 29 - .../elements/form/__docs__/textInput.docs.mdx | 27 - platform/ui/src/elements/form/index.js | 10 - platform/ui/src/elements/index.js | 2 - platform/ui/src/gatsby-theme-docz/app.css | 59614 ++++++++++++++++ platform/ui/src/gatsby-theme-docz/wrapper.js | 5 + platform/ui/src/hooks/index.js | 4 - platform/ui/src/hooks/useDebounce.js | 41 - platform/ui/src/hooks/useMedia.js | 178 - platform/ui/src/index.mdx | 20 + platform/ui/src/styles/app.css | 3 + platform/ui/src/styles/tailwind.css | 3 + platform/ui/src/utils/getScrollbarSize.js | 41 - platform/ui/src/utils/styleProperty.js | 57 - platform/ui/src/utils/throttled.js | 26 - .../ui/src/utils/viewerbaseDragDropContext.js | 21 - platform/ui/src/viewer/ExpandableToolMenu.js | 144 - .../ui/src/viewer/ExpandableToolMenu.styl | 136 - platform/ui/src/viewer/PlayClipButton.js | 45 - platform/ui/src/viewer/PresetToggle.js | 78 - platform/ui/src/viewer/SimpleToolbarButton.js | 31 - platform/ui/src/viewer/Toolbar.js | 151 - platform/ui/src/viewer/ToolbarButton.js | 70 - .../ui/src/viewer/ViewportErrorIndicator.js | 30 - platform/ui/src/viewer/toolbar-button.styl | 33 - platform/ui/tailwind.js | 706 + yarn.lock | 13157 ++-- 284 files changed, 68087 insertions(+), 17215 deletions(-) delete mode 100644 platform/ui/.all-contributorsrc delete mode 100644 platform/ui/.env create mode 100644 platform/ui/.gitignore create mode 100644 platform/ui/.stylelintrc.json delete mode 100644 platform/ui/.webpack/webpack.prod.js delete mode 100644 platform/ui/LICENSE delete mode 100644 platform/ui/app.css delete mode 100644 platform/ui/babel.config.js delete mode 100644 platform/ui/doczrc.js delete mode 100644 platform/ui/jest.config.js delete mode 100644 platform/ui/public/docz.css delete mode 100644 platform/ui/src/ScrollableArea/ScrollableArea.js delete mode 100644 platform/ui/src/ScrollableArea/ScrollableArea.styl delete mode 100644 platform/ui/src/__docs__/NameSpace.js delete mode 100644 platform/ui/src/__docs__/assets/github.png delete mode 100644 platform/ui/src/__docs__/assets/npm.png delete mode 100644 platform/ui/src/__docs__/assets/react.png delete mode 100644 platform/ui/src/__docs__/assets/typescript.png delete mode 100644 platform/ui/src/__docs__/compatibility.mdx delete mode 100644 platform/ui/src/__docs__/config/Wrapper.js delete mode 100644 platform/ui/src/__docs__/docs-settings.mdx delete mode 100644 platform/ui/src/__docs__/getting-started.mdx delete mode 100644 platform/ui/src/__docs__/index.html delete mode 100644 platform/ui/src/__docs__/introduction.mdx delete mode 100644 platform/ui/src/__docs__/styling-and-theming.mdx delete mode 100644 platform/ui/src/__docs__/translating.mdx delete mode 100644 platform/ui/src/__docs__/wrapper.js delete mode 100644 platform/ui/src/__docs__/wrapper.styl create mode 100644 platform/ui/src/components/Alert.jsx create mode 100644 platform/ui/src/components/Alert.mdx create mode 100644 platform/ui/src/components/Button/Button.jsx create mode 100644 platform/ui/src/components/Button/Button.mdx create mode 100644 platform/ui/src/components/Button/index.js create mode 100644 platform/ui/src/components/Input/Input.jsx create mode 100644 platform/ui/src/components/Input/Input.mdx create mode 100644 platform/ui/src/components/Input/index.js create mode 100644 platform/ui/src/components/Label/Label.jsx create mode 100644 platform/ui/src/components/Label/Label.mdx create mode 100644 platform/ui/src/components/Label/index.js delete mode 100644 platform/ui/src/components/checkbox/__docs__/checkbox.mdx delete mode 100644 platform/ui/src/components/checkbox/checkbox.css delete mode 100644 platform/ui/src/components/checkbox/checkbox.js delete mode 100644 platform/ui/src/components/checkbox/index.js delete mode 100644 platform/ui/src/components/cineDialog/CineDialog.js delete mode 100644 platform/ui/src/components/cineDialog/CineDialog.styl delete mode 100644 platform/ui/src/components/cineDialog/__docs__/cineDialog.mdx delete mode 100644 platform/ui/src/components/cineDialog/index.js delete mode 100644 platform/ui/src/components/content/aboutContent/AboutContent.js delete mode 100644 platform/ui/src/components/content/aboutContent/AboutContent.styl delete mode 100644 platform/ui/src/components/content/viewportDownloadForm/ViewportDownloadForm.js delete mode 100644 platform/ui/src/components/content/viewportDownloadForm/ViewportDownloadForm.styl delete mode 100644 platform/ui/src/components/content/viewportDownloadForm/__docs__/viewportDownloadForm.mdx delete mode 100644 platform/ui/src/components/content/viewportDownloadForm/index.js delete mode 100644 platform/ui/src/components/contextMenu/ContextMenu.css delete mode 100644 platform/ui/src/components/contextMenu/index.js delete mode 100644 platform/ui/src/components/languageSwitcher/LanguageSwitcher.styl delete mode 100644 platform/ui/src/components/layoutButton/LayoutButton.js delete mode 100644 platform/ui/src/components/layoutButton/LayoutChooser.styl delete mode 100644 platform/ui/src/components/layoutButton/__docs__/layoutButton.css delete mode 100644 platform/ui/src/components/layoutButton/__docs__/layoutButton.mdx delete mode 100644 platform/ui/src/components/layoutButton/index.js delete mode 100644 platform/ui/src/components/measurementTable/MeasurementTable.js delete mode 100644 platform/ui/src/components/measurementTable/MeasurementTable.styl delete mode 100644 platform/ui/src/components/measurementTable/MeasurementTableItem.js delete mode 100644 platform/ui/src/components/measurementTable/__docs__/measurementTable.mdx delete mode 100644 platform/ui/src/components/measurementTable/__docs__/measurements.js delete mode 100644 platform/ui/src/components/measurementTable/__docs__/timepoints.js delete mode 100644 platform/ui/src/components/measurementTable/__docs__/warnings.js delete mode 100644 platform/ui/src/components/measurementTable/index.js delete mode 100644 platform/ui/src/components/ohifModal/OHIFModal.js delete mode 100644 platform/ui/src/components/ohifModal/OHIFModal.styl delete mode 100644 platform/ui/src/components/ohifModal/__docs__/ohifModal.mdx delete mode 100644 platform/ui/src/components/ohifModal/index.js delete mode 100644 platform/ui/src/components/overlayTrigger/Fade.js delete mode 100644 platform/ui/src/components/overlayTrigger/Overlay.js delete mode 100644 platform/ui/src/components/overlayTrigger/OverlayTrigger.js delete mode 100644 platform/ui/src/components/overlayTrigger/__docs__/OverlayTrigger.mdx delete mode 100644 platform/ui/src/components/overlayTrigger/createChainedFunction.js delete mode 100644 platform/ui/src/components/overlayTrigger/index.js delete mode 100644 platform/ui/src/components/quickSwitch/QuickSwitch.styl delete mode 100644 platform/ui/src/components/quickSwitch/SeriesList.styl delete mode 100644 platform/ui/src/components/quickSwitch/StudiesList.styl delete mode 100644 platform/ui/src/components/quickSwitch/index.js delete mode 100644 platform/ui/src/components/radioButtonList/RadioButtonList.css delete mode 100644 platform/ui/src/components/radioButtonList/RadioButtonList.js delete mode 100644 platform/ui/src/components/radioButtonList/__docs__/radioButtonList.mdx delete mode 100644 platform/ui/src/components/radioButtonList/index.js delete mode 100644 platform/ui/src/components/roundedButtonGroup/RoundedButtonGroup.js delete mode 100644 platform/ui/src/components/roundedButtonGroup/__docs__/roundedButtonGroup.mdx delete mode 100644 platform/ui/src/components/roundedButtonGroup/index.js delete mode 100644 platform/ui/src/components/selectTree/InputRadio.js delete mode 100644 platform/ui/src/components/selectTree/SelectTree.js delete mode 100644 platform/ui/src/components/selectTree/SelectTree.styl delete mode 100644 platform/ui/src/components/selectTree/SelectTreeBreadcrumb.js delete mode 100644 platform/ui/src/components/selectTree/__docs__/selectTree.mdx delete mode 100644 platform/ui/src/components/selectTree/__docs__/selectTreeItems.js delete mode 100644 platform/ui/src/components/selectTree/index.js delete mode 100644 platform/ui/src/components/simpleDialog/SimpleDialog.js delete mode 100644 platform/ui/src/components/simpleDialog/SimpleDialog.styl delete mode 100644 platform/ui/src/components/simpleDialog/__docs__/simpleDialog.mdx delete mode 100644 platform/ui/src/components/simpleDialog/index.js delete mode 100644 platform/ui/src/components/snackbar/SnackbarContainer.js delete mode 100644 platform/ui/src/components/snackbar/SnackbarItem.js delete mode 100644 platform/ui/src/components/snackbar/SnackbarTypes.js delete mode 100644 platform/ui/src/components/studyBrowser/ImageThumbnail.styl delete mode 100644 platform/ui/src/components/studyBrowser/StudyBrowser.styl delete mode 100644 platform/ui/src/components/studyBrowser/Thumbnail.styl delete mode 100644 platform/ui/src/components/studyBrowser/__docs__/ExampleDropTarget.css delete mode 100644 platform/ui/src/components/studyBrowser/__docs__/studyBrowser.mdx delete mode 100644 platform/ui/src/components/studyBrowser/__docs__/wrappedStudyBrowser.js delete mode 100644 platform/ui/src/components/studyBrowser/index.js delete mode 100644 platform/ui/src/components/studyList/CustomDateRangePicker.css delete mode 100644 platform/ui/src/components/studyList/CustomDateRangePicker.js delete mode 100644 platform/ui/src/components/studyList/PageToolbar.js delete mode 100644 platform/ui/src/components/studyList/PaginationArea.styl delete mode 100644 platform/ui/src/components/studyList/StudyListLoadingText.js delete mode 100644 platform/ui/src/components/studyList/TableSearchFilter.js delete mode 100644 platform/ui/src/components/studyList/index.js delete mode 100644 platform/ui/src/components/tableList/TableList.styl delete mode 100644 platform/ui/src/components/tableList/TableListItem.styl delete mode 100644 platform/ui/src/components/tableList/__docs__/tableList.mdx delete mode 100644 platform/ui/src/components/tableList/index.js delete mode 100644 platform/ui/src/components/toolbarSection/ToolbarSection.js delete mode 100644 platform/ui/src/components/toolbarSection/ToolbarSection.styl delete mode 100644 platform/ui/src/components/toolbarSection/__docs__/exampleButtons.js delete mode 100644 platform/ui/src/components/toolbarSection/__docs__/toolbarSection.docs.mdx delete mode 100644 platform/ui/src/components/toolbarSection/index.js delete mode 100644 platform/ui/src/components/tooltip/Tooltip.js delete mode 100644 platform/ui/src/components/tooltip/Tooltip.styl delete mode 100644 platform/ui/src/components/tooltip/__docs__/tooltip.noshow-mdx delete mode 100644 platform/ui/src/components/tooltip/__tests__/.githold delete mode 100644 platform/ui/src/components/tooltip/index.js delete mode 100644 platform/ui/src/contextProviders/DialogProvider.js delete mode 100644 platform/ui/src/contextProviders/DialogProvider.styl delete mode 100644 platform/ui/src/contextProviders/LanguageProvider.js delete mode 100644 platform/ui/src/contextProviders/ModalProvider.js delete mode 100644 platform/ui/src/contextProviders/SnackbarProvider.js delete mode 100644 platform/ui/src/contextProviders/index.js delete mode 100644 platform/ui/src/design/styles/common/button.styl delete mode 100644 platform/ui/src/design/styles/common/form.styl delete mode 100644 platform/ui/src/design/styles/common/global.styl delete mode 100644 platform/ui/src/design/styles/common/modal.styl delete mode 100644 platform/ui/src/design/styles/common/navbar.styl delete mode 100644 platform/ui/src/design/styles/common/state.styl delete mode 100644 platform/ui/src/design/styles/common/table.styl delete mode 100644 platform/ui/src/elements/Icon/Icon.js delete mode 100644 platform/ui/src/elements/Icon/Icon.styl delete mode 100644 platform/ui/src/elements/Icon/__docs__/icon.mdx delete mode 100644 platform/ui/src/elements/Icon/icons/3d-rotate.svg delete mode 100644 platform/ui/src/elements/Icon/icons/adjust.svg delete mode 100644 platform/ui/src/elements/Icon/icons/angle-double-down.svg delete mode 100644 platform/ui/src/elements/Icon/icons/angle-double-up.svg delete mode 100644 platform/ui/src/elements/Icon/icons/angle-left.svg delete mode 100644 platform/ui/src/elements/Icon/icons/arrows-alt-h.svg delete mode 100644 platform/ui/src/elements/Icon/icons/arrows-alt-v.svg delete mode 100644 platform/ui/src/elements/Icon/icons/arrows.svg delete mode 100644 platform/ui/src/elements/Icon/icons/bars.svg delete mode 100644 platform/ui/src/elements/Icon/icons/brain.svg delete mode 100644 platform/ui/src/elements/Icon/icons/caret-down.svg delete mode 100644 platform/ui/src/elements/Icon/icons/caret-up.svg delete mode 100644 platform/ui/src/elements/Icon/icons/check-circle-o.svg delete mode 100644 platform/ui/src/elements/Icon/icons/check-circle.svg delete mode 100644 platform/ui/src/elements/Icon/icons/check.svg delete mode 100644 platform/ui/src/elements/Icon/icons/chevron-down.svg delete mode 100644 platform/ui/src/elements/Icon/icons/circle-notch.svg delete mode 100644 platform/ui/src/elements/Icon/icons/circle-o.svg delete mode 100644 platform/ui/src/elements/Icon/icons/circle.svg delete mode 100644 platform/ui/src/elements/Icon/icons/cog.svg delete mode 100644 platform/ui/src/elements/Icon/icons/create-comment.svg delete mode 100644 platform/ui/src/elements/Icon/icons/create-screen-capture.svg delete mode 100644 platform/ui/src/elements/Icon/icons/crosshairs.svg delete mode 100644 platform/ui/src/elements/Icon/icons/cube.svg delete mode 100644 platform/ui/src/elements/Icon/icons/database.svg delete mode 100644 platform/ui/src/elements/Icon/icons/dot-circle.svg delete mode 100644 platform/ui/src/elements/Icon/icons/edit.svg delete mode 100644 platform/ui/src/elements/Icon/icons/ellipse-circle.svg delete mode 100644 platform/ui/src/elements/Icon/icons/ellipse-h.svg delete mode 100644 platform/ui/src/elements/Icon/icons/ellipse-v.svg delete mode 100644 platform/ui/src/elements/Icon/icons/eraser.svg delete mode 100644 platform/ui/src/elements/Icon/icons/exclamation-circle.svg delete mode 100644 platform/ui/src/elements/Icon/icons/exclamation-triangle.svg delete mode 100644 platform/ui/src/elements/Icon/icons/fast-backward.svg delete mode 100644 platform/ui/src/elements/Icon/icons/fast-forward.svg delete mode 100644 platform/ui/src/elements/Icon/icons/info.svg delete mode 100644 platform/ui/src/elements/Icon/icons/inline-edit.svg delete mode 100644 platform/ui/src/elements/Icon/icons/level.svg delete mode 100644 platform/ui/src/elements/Icon/icons/link-circles.svg delete mode 100644 platform/ui/src/elements/Icon/icons/link.svg delete mode 100644 platform/ui/src/elements/Icon/icons/list.svg delete mode 100644 platform/ui/src/elements/Icon/icons/liver.svg delete mode 100644 platform/ui/src/elements/Icon/icons/lock-alt.svg delete mode 100644 platform/ui/src/elements/Icon/icons/lock.svg delete mode 100644 platform/ui/src/elements/Icon/icons/lung.svg delete mode 100644 platform/ui/src/elements/Icon/icons/measure-non-target.svg delete mode 100644 platform/ui/src/elements/Icon/icons/measure-target-cr.svg delete mode 100644 platform/ui/src/elements/Icon/icons/measure-target-ne.svg delete mode 100644 platform/ui/src/elements/Icon/icons/measure-target-un.svg delete mode 100644 platform/ui/src/elements/Icon/icons/measure-target.svg delete mode 100644 platform/ui/src/elements/Icon/icons/measure-temp.svg delete mode 100644 platform/ui/src/elements/Icon/icons/object-group.svg delete mode 100644 platform/ui/src/elements/Icon/icons/ohif-logo.svg delete mode 100644 platform/ui/src/elements/Icon/icons/ohif-text-logo.svg delete mode 100644 platform/ui/src/elements/Icon/icons/oval.svg delete mode 100644 platform/ui/src/elements/Icon/icons/palette.svg delete mode 100644 platform/ui/src/elements/Icon/icons/play.svg delete mode 100644 platform/ui/src/elements/Icon/icons/plus.svg delete mode 100644 platform/ui/src/elements/Icon/icons/power-off.svg delete mode 100644 platform/ui/src/elements/Icon/icons/reset.svg delete mode 100644 platform/ui/src/elements/Icon/icons/rotate-right.svg delete mode 100644 platform/ui/src/elements/Icon/icons/rotate.svg delete mode 100644 platform/ui/src/elements/Icon/icons/save-regular.svg delete mode 100644 platform/ui/src/elements/Icon/icons/search-plus.svg delete mode 100644 platform/ui/src/elements/Icon/icons/search.svg delete mode 100644 platform/ui/src/elements/Icon/icons/soft-tissue.svg delete mode 100644 platform/ui/src/elements/Icon/icons/sort-down.svg delete mode 100644 platform/ui/src/elements/Icon/icons/sort-up.svg delete mode 100644 platform/ui/src/elements/Icon/icons/sort.svg delete mode 100644 platform/ui/src/elements/Icon/icons/square-o.svg delete mode 100644 platform/ui/src/elements/Icon/icons/star.svg delete mode 100644 platform/ui/src/elements/Icon/icons/step-backward.svg delete mode 100644 platform/ui/src/elements/Icon/icons/step-forward.svg delete mode 100644 platform/ui/src/elements/Icon/icons/stop.svg delete mode 100644 platform/ui/src/elements/Icon/icons/sun.svg delete mode 100644 platform/ui/src/elements/Icon/icons/th-large.svg delete mode 100644 platform/ui/src/elements/Icon/icons/th-list.svg delete mode 100644 platform/ui/src/elements/Icon/icons/th.svg delete mode 100644 platform/ui/src/elements/Icon/icons/times.svg delete mode 100644 platform/ui/src/elements/Icon/icons/trash.svg delete mode 100644 platform/ui/src/elements/Icon/icons/unlink.svg delete mode 100644 platform/ui/src/elements/Icon/icons/user.svg delete mode 100644 platform/ui/src/elements/Icon/icons/youtube.svg delete mode 100644 platform/ui/src/elements/Icon/index.js delete mode 100644 platform/ui/src/elements/Svg/Svg.js delete mode 100644 platform/ui/src/elements/Svg/Svg.styl delete mode 100644 platform/ui/src/elements/Svg/__docs__/svg.mdx delete mode 100644 platform/ui/src/elements/Svg/getSvg.js delete mode 100644 platform/ui/src/elements/Svg/index.js delete mode 100644 platform/ui/src/elements/Svg/svgs/ohif-logo-text.svg delete mode 100644 platform/ui/src/elements/Svg/svgs/ohif-logo-wrapped-text.svg delete mode 100644 platform/ui/src/elements/form/DropdownMenu.css delete mode 100644 platform/ui/src/elements/form/DropdownMenu.js delete mode 100644 platform/ui/src/elements/form/Label.css delete mode 100644 platform/ui/src/elements/form/Label.js delete mode 100644 platform/ui/src/elements/form/OldSelect.js delete mode 100644 platform/ui/src/elements/form/Range.css delete mode 100644 platform/ui/src/elements/form/Select.css delete mode 100644 platform/ui/src/elements/form/Select.js delete mode 100644 platform/ui/src/elements/form/TextArea.css delete mode 100644 platform/ui/src/elements/form/TextInput.css delete mode 100644 platform/ui/src/elements/form/TextInput.js delete mode 100644 platform/ui/src/elements/form/__docs__/dropdownMenu.doc.mdx delete mode 100644 platform/ui/src/elements/form/__docs__/label.doc.mdx delete mode 100644 platform/ui/src/elements/form/__docs__/range.doc.mdx delete mode 100644 platform/ui/src/elements/form/__docs__/select.docs.mdx delete mode 100644 platform/ui/src/elements/form/__docs__/textArea.doc.mdx delete mode 100644 platform/ui/src/elements/form/__docs__/textInput.docs.mdx delete mode 100644 platform/ui/src/elements/form/index.js delete mode 100644 platform/ui/src/elements/index.js create mode 100644 platform/ui/src/gatsby-theme-docz/app.css create mode 100644 platform/ui/src/gatsby-theme-docz/wrapper.js delete mode 100644 platform/ui/src/hooks/index.js delete mode 100644 platform/ui/src/hooks/useDebounce.js delete mode 100644 platform/ui/src/hooks/useMedia.js create mode 100644 platform/ui/src/index.mdx create mode 100644 platform/ui/src/styles/app.css create mode 100644 platform/ui/src/styles/tailwind.css delete mode 100644 platform/ui/src/utils/getScrollbarSize.js delete mode 100644 platform/ui/src/utils/styleProperty.js delete mode 100644 platform/ui/src/utils/throttled.js delete mode 100644 platform/ui/src/utils/viewerbaseDragDropContext.js delete mode 100644 platform/ui/src/viewer/ExpandableToolMenu.js delete mode 100644 platform/ui/src/viewer/ExpandableToolMenu.styl delete mode 100644 platform/ui/src/viewer/PlayClipButton.js delete mode 100644 platform/ui/src/viewer/PresetToggle.js delete mode 100644 platform/ui/src/viewer/SimpleToolbarButton.js delete mode 100644 platform/ui/src/viewer/Toolbar.js delete mode 100644 platform/ui/src/viewer/ToolbarButton.js delete mode 100644 platform/ui/src/viewer/ViewportErrorIndicator.js delete mode 100644 platform/ui/src/viewer/toolbar-button.styl create mode 100644 platform/ui/tailwind.js diff --git a/platform/ui/.all-contributorsrc b/platform/ui/.all-contributorsrc deleted file mode 100644 index c90301bbb..000000000 --- a/platform/ui/.all-contributorsrc +++ /dev/null @@ -1,135 +0,0 @@ -{ - "projectName": "@ohif/ui", - "projectOwner": "OHIF", - "repoType": "github", - "repoHost": "https://github.com", - "files": [ - "README.md" - ], - "imageSize": 100, - "commit": true, - "commitConvention": "none", - "contributors": [ - { - "login": "swederik", - "name": "Erik Ziegler", - "avatar_url": "https://avatars3.githubusercontent.com/u/607793?v=4", - "profile": "https://github.com/swederik", - "contributions": [ - "code", - "maintenance" - ] - }, - { - "login": "dannyrb", - "name": "Danny Brown", - "avatar_url": "https://avatars1.githubusercontent.com/u/5797588?v=4", - "profile": "http://dannyrb.com/", - "contributions": [ - "code", - "maintenance" - ] - }, - { - "login": "galelis", - "name": "Gustavo André Lelis", - "avatar_url": "https://avatars3.githubusercontent.com/u/2378326?v=4", - "profile": "https://github.com/galelis", - "contributions": [ - "code", - "maintenance" - ] - }, - { - "login": "maltempi", - "name": "Thiago Maltempi", - "avatar_url": "https://avatars3.githubusercontent.com/u/7017182?v=4", - "profile": "https://github.com/maltempi", - "contributions": [ - "code" - ] - }, - { - "login": "EsrefDurna", - "name": "Esref Durna", - "avatar_url": "https://avatars0.githubusercontent.com/u/1230575?v=4", - "profile": "https://www.linkedin.com/in/siliconvalleynextgeneration/", - "contributions": [ - "code" - ] - }, - { - "login": "pieper", - "name": "Steve Pieper", - "avatar_url": "https://avatars0.githubusercontent.com/u/126077?v=4", - "profile": "http://www.isomics.com", - "contributions": [ - "code" - ] - }, - { - "login": "biharck", - "name": "Biharck Araujo", - "avatar_url": "https://avatars0.githubusercontent.com/u/1713255?v=4", - "profile": "http://www.biharck.com.br", - "contributions": [ - "code" - ] - }, - { - "login": "rodrigolabs", - "name": "Rodrigo Antinarelli", - "avatar_url": "https://avatars3.githubusercontent.com/u/1905961?v=4", - "profile": "https://rodrigoea.com/", - "contributions": [ - "code" - ] - }, - { - "login": "jfmedeiros1820", - "name": "João Felipe de Medeiros Moreira", - "avatar_url": "https://avatars1.githubusercontent.com/u/2211708?v=4", - "profile": "https://github.com/jfmedeiros1820", - "contributions": [ - "code" - ] - }, - { - "login": "jamesg1", - "name": "James Gosbell", - "avatar_url": "https://avatars3.githubusercontent.com/u/3621147?v=4", - "profile": "https://github.com/jamesg1", - "contributions": [ - "code" - ] - }, - { - "login": "evren217", - "name": "Evren Ozkan", - "avatar_url": "https://avatars1.githubusercontent.com/u/4920551?v=4", - "profile": "https://github.com/evren217", - "contributions": [ - "code" - ] - }, - { - "login": "zsaltzman", - "name": "Zach S.", - "avatar_url": "https://avatars1.githubusercontent.com/u/19156530?v=4", - "profile": "https://github.com/zsaltzman", - "contributions": [ - "code" - ] - }, - { - "login": "muakdogan", - "name": "Mete Ugur Akdogan", - "avatar_url": "https://avatars0.githubusercontent.com/u/19971240?v=4", - "profile": "https://github.com/muakdogan", - "contributions": [ - "code" - ] - } - ], - "contributorsPerLine": 7 -} diff --git a/platform/ui/.env b/platform/ui/.env deleted file mode 100644 index 0708aefac..000000000 --- a/platform/ui/.env +++ /dev/null @@ -1,11 +0,0 @@ -#### -## -## We need to pin WebPack's version for docz to work. See this issue: -## https://github.com/pedronauck/docz/issues/704#issuecomment-480295032 -## -## react-scripts checks that dependency versions match before running -## Our top level webpack version causes the preflight check to fail -## This prevents that check -## -#### -SKIP_PREFLIGHT_CHECK=true diff --git a/platform/ui/.gitignore b/platform/ui/.gitignore new file mode 100644 index 000000000..fdb33ee9a --- /dev/null +++ b/platform/ui/.gitignore @@ -0,0 +1,2 @@ +.docz +node_modules \ No newline at end of file diff --git a/platform/ui/.stylelintrc.json b/platform/ui/.stylelintrc.json new file mode 100644 index 000000000..40db42c66 --- /dev/null +++ b/platform/ui/.stylelintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "stylelint-config-standard" +} diff --git a/platform/ui/.webpack/webpack.prod.js b/platform/ui/.webpack/webpack.prod.js deleted file mode 100644 index da7b819bb..000000000 --- a/platform/ui/.webpack/webpack.prod.js +++ /dev/null @@ -1,37 +0,0 @@ -const merge = require('webpack-merge'); -const path = require('path'); -const webpackCommon = require('./../../../.webpack/webpack.commonjs.js'); -const pkg = require('./../package.json'); - -const ROOT_DIR = path.join(__dirname, './..'); -const SRC_DIR = path.join(__dirname, '../src'); -const DIST_DIR = path.join(__dirname, '../dist'); - -module.exports = (env, argv) => { - const commonConfig = webpackCommon(env, argv, { SRC_DIR, DIST_DIR }); - - return merge(commonConfig, { - devtool: 'source-map', - stats: { - colors: true, - hash: true, - timings: true, - assets: true, - chunks: false, - chunkModules: false, - modules: false, - children: false, - warnings: true, - }, - optimization: { - minimize: true, - sideEffects: true, - }, - output: { - path: ROOT_DIR, - library: 'ohifUi', - libraryTarget: 'umd', - filename: pkg.main, - }, - }); -}; diff --git a/platform/ui/LICENSE b/platform/ui/LICENSE deleted file mode 100644 index 19e20dd35..000000000 --- a/platform/ui/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 Open Health Imaging Foundation - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/platform/ui/README.md b/platform/ui/README.md index c4c8907ce..f3517820b 100644 --- a/platform/ui/README.md +++ b/platform/ui/README.md @@ -1,125 +1,41 @@ - - -
-

@ohif/ui

+# Basic Docz example -

@ohif/ui is a collection of components and utilities that power OHIF's zero-footprint DICOM viewer.

-
+## Using `create-docz-app` -
-Read The Docs | -Edit the docs - -
- -
- -[![NPM version][npm-version-image]][npm-url] -[![NPM downloads][npm-downloads-image]][npm-url] -[![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors) -[![MIT License][license-image]][license-url] - - - -This set of "Medical Imaging Viewer" React components are maintained separately -to: - -- Decouple presentation from business logic -- Test and develop components in isolation -- Provide well documented, reusable components -- Aid rapid application development for context specific viewers - -## Install - -> This component library is pre- v1.0. All realeases until a v1.0 have the -> possibility of introducing breaking changes. Please depend on an "exact" -> version in your projects to prevent issues caused by loose versioning. - -For full installation instructions, be sure to check out our -[getting started](https://react.ohif.org/getting-started#installation) guide. - -```bash -// with npm -npm i @ohif/ui --save-exact - -// with yarn -yarn add @ohif/ui --exact +```sh +npx create-docz-app docz-app-basic +# or +yarn create docz-app docz-app-basic ``` -## Usage +## Download manually -```jsx -import React, { Component } from 'react'; -import { LayoutButton } from '@ohif/ui'; - -class Example extends Component { - constructor(props) { - super(props); - - this.state = { - selectedCell: { - className: 'hover', - col: 1, - row: 1, - }, - }; - } - - render() { - return ( - this.setState({ selectedCell: cell })} - /> - ); - } -} +```sh +curl https://codeload.github.com/doczjs/docz/tar.gz/master | tar -xz --strip=2 docz-master/examples/basic +mv basic docz-basic-example +cd docz-basic-example ``` -## Developing Locally - -_Restore dependencies after cloning:_ - -```bash -# Restore workspace dependencies (from repository root) -yarn install - -# From project root -yarn run dev:ui - -# OR from this project's directory -yarn run dev +## Setup +```sh +yarn # npm i ``` -## Contributors ✨ +## Run -Thanks goes to these wonderful people -([emoji key](https://allcontributors.org/docs/en/emoji-key)): +```sh +yarn dev # npm run dev +``` - - -
Erik Ziegler
Erik Ziegler

💻 🚧
Danny Brown
Danny Brown

💻 🚧
Gustavo André Lelis
Gustavo André Lelis

💻 🚧
Thiago Maltempi
Thiago Maltempi

💻
Esref Durna
Esref Durna

💻
Steve Pieper
Steve Pieper

💻
Biharck Araujo
Biharck Araujo

💻
Rodrigo Antinarelli
Rodrigo Antinarelli

💻
João Felipe de Medeiros Moreira
João Felipe de Medeiros Moreira

💻
James Gosbell
James Gosbell

💻
Evren Ozkan
Evren Ozkan

💻
Zach S.
Zach S.

💻
Mete Ugur Akdogan
Mete Ugur Akdogan

💻
+## Build - +```sh +yarn build # npm run build +``` -This project follows the -[all-contributors](https://github.com/all-contributors/all-contributors) -specification. Contributions of any kind welcome! +## Serve built app -## License - -MIT © [OHIF](https://github.com/OHIF) - - - - -[all-contributors-image]: https://img.shields.io/badge/all_contributors-0-orange.svg?style=flat-square -[npm-url]: https://npmjs.org/package/@ohif/ui -[npm-downloads-image]: https://img.shields.io/npm/dm/@ohif/ui.svg?style=flat-square -[npm-version-image]: https://img.shields.io/npm/v/@ohif/ui.svg?style=flat-square -[license-image]: https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square -[license-url]: LICENSE - +```sh +yarn serve # npm run serve +``` \ No newline at end of file diff --git a/platform/ui/app.css b/platform/ui/app.css deleted file mode 100644 index 96f3a6db2..000000000 --- a/platform/ui/app.css +++ /dev/null @@ -1,12 +0,0 @@ -.ExampleDropTarget{display:-webkit-box;display:flex;-webkit-box-pack:center;justify-content:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column;min-height:100px;border:2px dashed #000;padding:20px;-webkit-transition:all .2s ease;transition:all .2s ease}.ExampleDropTarger p,.ExampleDropTarget h4{text-align:center;word-break:break-word}.ExampleDropTarget.can-drop{border:2px dashed #20a5d6;background-color:#fafafa;color:#000}.ExampleDropTarget.hovered{border:2px dashed #20a5d6;background-color:#000;color:#91b9cd;cursor:copy} -.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}@-webkit-keyframes shake{0%,to{-webkit-transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px)}}@keyframes shake{0%,to{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}.shake{-webkit-animation-name:shake;animation-name:shake}.modal{display:block}.modal-content>.close{position:absolute;top:10px;right:10px}@media (min-width:768px){.modal-sm>.modal-dialog{width:300px}}@media (min-width:992px){.modal-lg>.modal-dialog{width:900px}} -.RoundedButtonGroup{--height:25px;position:relative;z-index:0}.roundedButtonWrapper{cursor:pointer;display:inline-block;float:left;margin-left:-2px;text-decoration:none;text-align:center}.roundedButtonWrapper.disabled{opacity:.5;cursor:not-allowed}.RoundedButtonGroup .roundedButtonWrapper .roundedButton{-webkit-box-align:center;align-items:center;background-color:var(--ui-gray-dark);border:2px solid var(--ui-border-color-dark);color:var(--text-secondary-color);display:-webkit-box;display:flex;font-size:15px;font-weight:500;-webkit-box-pack:center;justify-content:center;height:var(--height);line-height:var(--height);padding:0 22px;position:relative;text-transform:uppercase;-webkit-transition:var(--sidebar-transition);transition:var(--sidebar-transition);z-index:1}.roundedButtonWrapper .roundedButton svg .roundedButtonWrapper .roundedButton span{margin:0 2px}.roundedButtonWrapper .roundedButton i{line-height:15px;font-size:15px}.bottomLabel{color:var(--text-secondary-color);font-size:12px;font-weight:500;line-height:12px;margin-top:8px}.roundedButtonWrapper:first-child{margin-left:0}.RoundedButtonGroup .roundedButtonWrapper:first-child .roundedButton{border-bottom-left-radius:var(--height);border-top-left-radius:var(--height)}.RoundedButtonGroup .roundedButtonWrapper:last-child .roundedButton{border-bottom-right-radius:var(--height);border-top-right-radius:var(--height)}.roundedButtonWrapper:hover .roundedButton{background-color:var(--box-background-color);color:var(--ui-gray-dark)}.roundedButtonWrapper.active .roundedButton{background-color:var(--active-color);border-color:var(--ui-border-color-active);color:var(--ui-gray-dark);z-index:2} -.PresetDateRangePicker_panel{padding:0 22px 11px}.PresetDateRangePicker_button{position:relative;height:100%;text-align:center;background:0 0;border:2px solid #00a699;color:#00a699;padding:4px 12px;margin-right:8px;font:inherit;font-weight:700;line-height:normal;overflow:visible;box-sizing:border-box;cursor:pointer}.PresetDateRangePicker_button:active{outline:0}.PresetDateRangePicker_button__selected{color:#fff;background:#00a699}.SingleDatePickerInput{display:inline-block;background-color:#fff}.SingleDatePickerInput__withBorder{border-radius:2px;border:1px solid #dbdbdb}.SingleDatePickerInput__rtl{direction:rtl}.SingleDatePickerInput__disabled{background-color:#f2f2f2}.SingleDatePickerInput__block{display:block}.SingleDatePickerInput__showClearDate{padding-right:30px}.SingleDatePickerInput_clearDate{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;cursor:pointer;padding:10px;margin:0 10px 0 5px;position:absolute;right:0;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.SingleDatePickerInput_clearDate__default:focus,.SingleDatePickerInput_clearDate__default:hover{background:#dbdbdb;border-radius:50%}.SingleDatePickerInput_clearDate__small{padding:6px}.SingleDatePickerInput_clearDate__hide{visibility:hidden}.SingleDatePickerInput_clearDate_svg{fill:#82888a;height:12px;width:15px;vertical-align:middle}.SingleDatePickerInput_clearDate_svg__small{height:9px}.SingleDatePickerInput_calendarIcon{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;cursor:pointer;display:inline-block;vertical-align:middle;padding:10px;margin:0 5px 0 10px}.SingleDatePickerInput_calendarIcon_svg{fill:#82888a;height:15px;width:14px;vertical-align:middle}.SingleDatePicker{position:relative;display:inline-block}.SingleDatePicker__block{display:block}.SingleDatePicker_picker{z-index:1;background-color:#fff;position:absolute}.SingleDatePicker_picker__rtl{direction:rtl}.SingleDatePicker_picker__directionLeft{left:0}.SingleDatePicker_picker__directionRight{right:0}.SingleDatePicker_picker__portal{background-color:rgba(0,0,0,.3);position:fixed;top:0;left:0;height:100%;width:100%}.SingleDatePicker_picker__fullScreenPortal{background-color:#fff}.SingleDatePicker_closeButton{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;cursor:pointer;position:absolute;top:0;right:0;padding:15px;z-index:2}.SingleDatePicker_closeButton:focus,.SingleDatePicker_closeButton:hover{color:darken(#cacccd,10%);text-decoration:none}.SingleDatePicker_closeButton_svg{height:15px;width:15px;fill:#cacccd}.DayPickerKeyboardShortcuts_buttonReset{background:0 0;border:0;border-radius:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;cursor:pointer;font-size:14px}.DayPickerKeyboardShortcuts_buttonReset:active{outline:0}.DayPickerKeyboardShortcuts_show{width:33px;height:26px;position:absolute;z-index:2}.DayPickerKeyboardShortcuts_show:before{content:"";display:block;position:absolute}.DayPickerKeyboardShortcuts_show__bottomRight{bottom:0;right:0}.DayPickerKeyboardShortcuts_show__bottomRight:before{border-top:26px solid transparent;border-right:33px solid #00a699;bottom:0;right:0}.DayPickerKeyboardShortcuts_show__bottomRight:hover:before{border-right:33px solid #008489}.DayPickerKeyboardShortcuts_show__topRight{top:0;right:0}.DayPickerKeyboardShortcuts_show__topRight:before{border-bottom:26px solid transparent;border-right:33px solid #00a699;top:0;right:0}.DayPickerKeyboardShortcuts_show__topRight:hover:before{border-right:33px solid #008489}.DayPickerKeyboardShortcuts_show__topLeft{top:0;left:0}.DayPickerKeyboardShortcuts_show__topLeft:before{border-bottom:26px solid transparent;border-left:33px solid #00a699;top:0;left:0}.DayPickerKeyboardShortcuts_show__topLeft:hover:before{border-left:33px solid #008489}.DayPickerKeyboardShortcuts_showSpan{color:#fff;position:absolute}.DayPickerKeyboardShortcuts_showSpan__bottomRight{bottom:0;right:5px}.DayPickerKeyboardShortcuts_showSpan__topRight{top:1px;right:5px}.DayPickerKeyboardShortcuts_showSpan__topLeft{top:1px;left:5px}.DayPickerKeyboardShortcuts_panel{overflow:auto;background:#fff;border:1px solid #dbdbdb;border-radius:2px;position:absolute;top:0;bottom:0;right:0;left:0;z-index:2;padding:22px;margin:33px;text-align:left}.DayPickerKeyboardShortcuts_title{font-size:16px;font-weight:700;margin:0}.DayPickerKeyboardShortcuts_list{list-style:none;padding:0;font-size:14px}.DayPickerKeyboardShortcuts_close{position:absolute;right:22px;top:22px;z-index:2}.DayPickerKeyboardShortcuts_close:active{outline:0}.DayPickerKeyboardShortcuts_closeSvg{height:15px;width:15px;fill:#cacccd}.DayPickerKeyboardShortcuts_closeSvg:focus,.DayPickerKeyboardShortcuts_closeSvg:hover{fill:#82888a}.CalendarDay{box-sizing:border-box;cursor:pointer;font-size:14px;text-align:center}.CalendarDay:active{outline:0}.CalendarDay__defaultCursor{cursor:default}.CalendarDay__default{border:1px solid #e4e7e7;color:#484848;background:#fff}.CalendarDay__default:hover{background:#e4e7e7;border:1px solid #e4e7e7;color:inherit}.CalendarDay__hovered_offset{background:#f4f5f5;border:1px double #e4e7e7;color:inherit}.CalendarDay__outside{border:0;background:#fff;color:#484848}.CalendarDay__outside:hover{border:0}.CalendarDay__blocked_minimum_nights{background:#fff;border:1px solid #eceeee;color:#cacccd}.CalendarDay__blocked_minimum_nights:active,.CalendarDay__blocked_minimum_nights:hover{background:#fff;color:#cacccd}.CalendarDay__highlighted_calendar{background:#ffe8bc;color:#484848}.CalendarDay__highlighted_calendar:active,.CalendarDay__highlighted_calendar:hover{background:#ffce71;color:#484848}.CalendarDay__selected_span{background:#66e2da;border:1px double #33dacd;color:#fff}.CalendarDay__selected_span:active,.CalendarDay__selected_span:hover{background:#33dacd;border:1px double #33dacd;color:#fff}.CalendarDay__last_in_range,.CalendarDay__last_in_range:hover{border-style:solid}.CalendarDay__selected,.CalendarDay__selected:active,.CalendarDay__selected:hover{background:#00a699;border:1px double #00a699;color:#fff}.CalendarDay__hovered_span,.CalendarDay__hovered_span:hover{background:#b2f1ec;border:1px double #80e8e0;color:#007a87}.CalendarDay__hovered_span:active{background:#80e8e0;border:1px double #80e8e0;color:#007a87}.CalendarDay__blocked_calendar,.CalendarDay__blocked_calendar:active,.CalendarDay__blocked_calendar:hover{background:#cacccd;border:1px solid #cacccd;color:#82888a}.CalendarDay__blocked_out_of_range,.CalendarDay__blocked_out_of_range:active,.CalendarDay__blocked_out_of_range:hover{background:#fff;border:1px solid #e4e7e7;color:#cacccd}.CalendarMonth{background:#fff;text-align:center;vertical-align:top;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.CalendarMonth_table{border-collapse:collapse;border-spacing:0}.CalendarMonth_verticalSpacing{border-collapse:initial}.CalendarMonth_caption{color:#484848;font-size:18px;text-align:center;padding-top:22px;padding-bottom:37px;caption-side:top}.CalendarMonth_caption__verticalScrollable{padding-top:12px;padding-bottom:7px}.CalendarMonthGrid{background:#fff;text-align:left;z-index:0}.CalendarMonthGrid__animating{z-index:1}.CalendarMonthGrid__horizontal{position:absolute;left:9px}.CalendarMonthGrid__vertical{margin:0 auto}.CalendarMonthGrid__vertical_scrollable{margin:0 auto;overflow-y:scroll}.CalendarMonthGrid_month__horizontal{display:inline-block;vertical-align:top;min-height:100%}.CalendarMonthGrid_month__hideForAnimation{position:absolute;z-index:-1;opacity:0;pointer-events:none}.CalendarMonthGrid_month__hidden{visibility:hidden}.DayPickerNavigation{position:relative;z-index:2}.DayPickerNavigation__horizontal{height:0}.DayPickerNavigation__verticalDefault{position:absolute;width:100%;height:52px;bottom:0;left:0}.DayPickerNavigation__verticalScrollableDefault{position:relative}.DayPickerNavigation_button{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:0;padding:0;margin:0}.DayPickerNavigation_button__default{border:1px solid #e4e7e7;background-color:#fff;color:#757575}.DayPickerNavigation_button__default:focus,.DayPickerNavigation_button__default:hover{border:1px solid #c4c4c4}.DayPickerNavigation_button__default:active{background:#f2f2f2}.DayPickerNavigation_button__disabled{cursor:default;border:1px solid #f2f2f2}.DayPickerNavigation_button__disabled:focus,.DayPickerNavigation_button__disabled:hover{border:1px solid #f2f2f2}.DayPickerNavigation_button__disabled:active{background:0 0}.DayPickerNavigation_button__horizontalDefault{position:absolute;top:18px;line-height:.78;border-radius:3px;padding:6px 9px}.DayPickerNavigation_leftButton__horizontalDefault{left:22px}.DayPickerNavigation_rightButton__horizontalDefault{right:22px}.DayPickerNavigation_button__verticalDefault{padding:5px;background:#fff;box-shadow:0 0 5px 2px rgba(0,0,0,.1);position:relative;display:inline-block;text-align:center;height:100%;width:50%}.DayPickerNavigation_nextButton__verticalDefault{border-left:0}.DayPickerNavigation_nextButton__verticalScrollableDefault{width:100%}.DayPickerNavigation_svg__horizontal{height:19px;width:19px;fill:#82888a;display:block}.DayPickerNavigation_svg__vertical{height:42px;width:42px;fill:#484848}.DayPickerNavigation_svg__disabled{fill:#f2f2f2}.DayPicker{position:relative;text-align:left}.DayPicker,.DayPicker__horizontal{background:#fff}.DayPicker__verticalScrollable{height:100%}.DayPicker__hidden{visibility:hidden}.DayPicker__withBorder{box-shadow:0 2px 6px rgba(0,0,0,.05),0 0 0 1px rgba(0,0,0,.07);border-radius:3px}.DayPicker_portal__horizontal{box-shadow:none;position:absolute;left:50%;top:50%}.DayPicker_portal__vertical{position:static}.DayPicker_focusRegion{outline:0}.DayPicker_calendarInfo__horizontal,.DayPicker_wrapper__horizontal{display:inline-block;vertical-align:top}.DayPicker_weekHeaders{position:relative}.DayPicker_weekHeaders__horizontal{margin-left:9px}.DayPicker_weekHeader{color:#757575;position:absolute;top:62px;z-index:2;text-align:left}.DayPicker_weekHeader__vertical{left:50%}.DayPicker_weekHeader__verticalScrollable{top:0;display:table-row;border-bottom:1px solid #dbdbdb;background:#fff;margin-left:0;left:0;width:100%;text-align:center}.DayPicker_weekHeader_ul{list-style:none;margin:1px 0;padding-left:0;padding-right:0;font-size:14px}.DayPicker_weekHeader_li{display:inline-block;text-align:center}.DayPicker_transitionContainer{position:relative;overflow:hidden;border-radius:3px}.DayPicker_transitionContainer__horizontal{-webkit-transition:height .2s ease-in-out;transition:height .2s ease-in-out}.DayPicker_transitionContainer__vertical{width:100%}.DayPicker_transitionContainer__verticalScrollable{padding-top:20px;height:100%;position:absolute;top:0;bottom:0;right:0;left:0;overflow-y:scroll}.DateInput{margin:0;padding:0;background:#fff;position:relative;display:inline-block;width:130px;vertical-align:middle}.DateInput__small{width:97px}.DateInput__block{width:100%}.DateInput__disabled{background:#f2f2f2;color:#dbdbdb}.DateInput_input{font-weight:200;font-size:19px;line-height:24px;color:#484848;background-color:#fff;width:100%;padding:11px 11px 9px;border:0;border-bottom:2px solid transparent;border-radius:0}.DateInput_input__small{font-size:15px;line-height:18px;letter-spacing:.2px;padding:7px 7px 5px}.DateInput_input__regular{font-weight:auto}.DateInput_input__readOnly{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.DateInput_input__focused{outline:0;background:#fff;border:0;border-bottom:2px solid #008489}.DateInput_input__disabled{background:#f2f2f2;font-style:italic}.DateInput_screenReaderMessage{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.DateInput_fang{position:absolute;width:20px;height:10px;left:22px;z-index:2}.DateInput_fangShape{fill:#fff}.DateInput_fangStroke{stroke:#dbdbdb;fill:transparent}.DateRangePickerInput{background-color:#fff;display:inline-block}.DateRangePickerInput__disabled{background:#f2f2f2}.DateRangePickerInput__withBorder{border-radius:2px;border:1px solid #dbdbdb}.DateRangePickerInput__rtl{direction:rtl}.DateRangePickerInput__block{display:block}.DateRangePickerInput__showClearDates{padding-right:30px}.DateRangePickerInput_arrow{display:inline-block;vertical-align:middle;color:#484848}.DateRangePickerInput_arrow_svg{vertical-align:middle;fill:#484848;height:24px;width:24px}.DateRangePickerInput_clearDates{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;cursor:pointer;padding:10px;margin:0 10px 0 5px;position:absolute;right:0;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.DateRangePickerInput_clearDates__small{padding:6px}.DateRangePickerInput_clearDates_default:focus,.DateRangePickerInput_clearDates_default:hover{background:#dbdbdb;border-radius:50%}.DateRangePickerInput_clearDates__hide{visibility:hidden}.DateRangePickerInput_clearDates_svg{fill:#82888a;height:12px;width:15px;vertical-align:middle}.DateRangePickerInput_clearDates_svg__small{height:9px}.DateRangePickerInput_calendarIcon{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;cursor:pointer;display:inline-block;vertical-align:middle;padding:10px;margin:0 5px 0 10px}.DateRangePickerInput_calendarIcon_svg{fill:#82888a;height:15px;width:14px;vertical-align:middle}.DateRangePicker{position:relative;display:inline-block}.DateRangePicker__block{display:block}.DateRangePicker_picker{z-index:1;background-color:#fff;position:absolute}.DateRangePicker_picker__rtl{direction:rtl}.DateRangePicker_picker__directionLeft{left:0}.DateRangePicker_picker__directionRight{right:0}.DateRangePicker_picker__portal{background-color:rgba(0,0,0,.3);position:fixed;top:0;left:0;height:100%;width:100%}.DateRangePicker_picker__fullScreenPortal{background-color:#fff}.DateRangePicker_closeButton{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;cursor:pointer;position:absolute;top:0;right:0;padding:15px;z-index:2}.DateRangePicker_closeButton:focus,.DateRangePicker_closeButton:hover{color:darken(#cacccd,10%);text-decoration:none}.DateRangePicker_closeButton_svg{height:15px;width:15px;fill:#cacccd} -.select-ohif{display:block;font-family:Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;font-size:.8em;font-weight:600;color:#444;line-height:1.3;padding:.6em 1.4em .5em .8em;width:100%;max-width:100%;box-sizing:border-box;margin:0;border:1px solid #aaa;box-shadow:0 1px 0 1px rgba(0,0,0,.04);border-radius:.5em;-moz-appearance:none;-webkit-appearance:none;appearance:none;background-color:#fff;background-image:url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23007CB2%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E"),-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e5e5e5));background-image:url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23007CB2%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E"),linear-gradient(180deg,#fff 0,#e5e5e5);background-repeat:no-repeat,repeat;background-position:right .7em top 50%,0 0;background-size:.65em auto,100%}.select-ohif::-ms-expand{display:none}.select-ohif:hover{border-color:#888}.select-ohif:focus{border-color:#aaa;box-shadow:0 0 1px 3px rgba(59,153,252,.7);box-shadow:0 0 0 3px -moz-mac-focusring;color:#222;outline:none}.select-ohif option{font-weight:400} -.label-ohif{font-size:1em;color:#fff}.label-example{background-color:var(--ui-gray-darker)} -.range{margin:0;width:100%;-webkit-appearance:none}.range:focus{outline:none}.range::-webkit-slider-runnable-track{width:100%;height:2px;cursor:pointer;box-shadow:none;background-color:var(--ui-border-color-dark);border-radius:0;border:0 solid var(--ui-border-color-dark)}.range::-moz-range-track{width:100%;height:2px;cursor:pointer;box-shadow:none;background-color:var(--ui-border-color-dark);border-radius:0;border:0 solid var(--ui-border-color-dark)}.range::-webkit-slider-thumb{box-shadow:none;border:0 solid var(--active-color);box-shadow:0 10px 10px rgba(0,0,0,.25);height:21px;width:11px;border-radius:11px;background:var(--active-color);cursor:pointer;-webkit-appearance:none;margin-top:-10px}.range::-moz-range-thumb{box-shadow:none;border:0 solid var(--active-color);box-shadow:0 10px 10px rgba(0,0,0,.25);height:21px;width:11px;border-radius:11px;background:var(--active-color);cursor:pointer;-webkit-appearance:none;margin-top:-10px}.range::-moz-focus-outer{border:0}.range-example{background:#000;height:2em} -.textarea-ohif{background-color:#b6b6b6;border-color:#b6b6b6;font-family:Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;font-size:1em} -.input-ohif{background-color:#b6b6b6;border-color:#b6b6b6;font-family:Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;font-size:1em} -.dd-menu{float:left;margin-right:10px;cursor:pointer;position:relative;z-index:999}.dd-title{font-size:13px}.dd-caret-down,.dd-menu-toggle{display:inline-block}.dd-caret-down{width:0;height:0;margin-top:.5rem;margin-left:.5rem;border-top:5px solid;border-right:5px solid transparent;border-left:5px solid transparent}.dd-menu-list{position:absolute;top:100%;margin-top:10px;background:#fff;border-radius:5px;-webkit-border-radius:5px;-moz-border-radius:5px;-ms-border-radius:5px;-o-border-radius:5px;overflow:hidden;transition:all .3s ease;-webkit-transition:all .3s ease;-moz-transition:all .3s ease;-ms-transition:all .3s ease;-o-transition:all .3s ease}.dd-menu-list.open{display:inline-block}.dd-menu-list.left{left:0}.dd-menu-list.right{right:0}.dd-menu-list.center{left:50%;transform:translateX(-50%);-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);-o-transform:translateX(-50%)}.dd-item{display:-webkit-box;display:flex;color:var(--text-color-active);padding:10px 15px;border-bottom:1px solid #ccc}.dd-item:hover{text-decoration:none;background:#eee}.dd-item:last-child{border-bottom:none}.dd-item-icon{margin-right:10px;margin-top:2px} -.viewport-container{float:left;position:relative;border:var(--viewport-border-thickness) solid var(--ui-border-color)}.viewport-container.active{border:var(--viewport-border-thickness) solid var(--active-color)}.EmptyViewport{display:-webkit-box;display:flex;-webkit-box-pack:center;justify-content:center;-webkit-box-align:center;align-items:center;height:100%;color:var(--text-secondary-color)}.LayoutPanel{width:100%;height:100%} -.LayoutPanelDropTarget{width:100%;height:100%;opacity:1;-webkit-transition:all .3s ease;transition:all .3s ease}.LayoutPanelDropTarget.hovered{opacity:.5;cursor:copy} diff --git a/platform/ui/babel.config.js b/platform/ui/babel.config.js deleted file mode 100644 index fed6f05fe..000000000 --- a/platform/ui/babel.config.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require("../../babel.config.js"); diff --git a/platform/ui/doczrc.js b/platform/ui/doczrc.js deleted file mode 100644 index b3abf4cd3..000000000 --- a/platform/ui/doczrc.js +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Docz Configuration File: - * https://www.docz.site/docs/project-configuration - */ - -import { css } from "docz-plugin-css"; - -export default { - dest: "example/build", - public: "/public", - wrapper: "src/__docs__/wrapper", - indexHtml: "src/__docs__/index.html", - // Limited support for importing `.styl` files - codeSandbox: false, - // https://github.com/pedronauck/docz/pull/849/files - // Because we re-export using `index.js` files - notUseSpecifiers: true, - menu: [ - "Introduction", - "Getting Started", - { name: "Elements", menu: ["Form / Select"] }, - { - name: "Components", - menu: [ - "CINE Dialog", - "Layout Button", - "Measurement Table", - "Overlay Trigger", - "Quick Switch", - "Rounded Button Group", - "Select Tree", - "Simple Dialog", - "Study Browser", - "Study List", - "Table List", - "Toolbar Section", - "About Modal", - "User Preferences Modal" - ] - }, - "Styling & Theming", - "Translating", - "Compatibility" - ], - // Rollup Aliases? - // https://github.com/pedronauck/docz/issues/373 - plugins: [ - // CSS - css(), - // Stylus - css({ - preprocessor: "stylus", - cssmodules: false - }) - ], - // `docz` uses file-loader to pull in SVGs. This kills our icons before - // They can be picked up by our `babel-plugin-inline-react-svg` dependency - // You can see where it's configured here: - // https://github.com/pedronauck/docz/blob/f72624d0aa5231dab17e1770e8d36be920f590a2/core/docz-core/src/bundler/loaders.ts#L135-L144 - // How we delete our rule: - // https://github.com/neutrinojs/webpack-chain/issues/48 - onCreateWebpackChain: config => { - config.module.rules.delete("svg"); - }, - modifyBabelRc: babelrc => { - const newBabelRc = { - ...babelrc, - plugins: [ - ...babelrc.plugins, - require.resolve("babel-plugin-inline-react-svg") - ] - }; - return newBabelRc; - } -}; diff --git a/platform/ui/jest.config.js b/platform/ui/jest.config.js deleted file mode 100644 index 78c435aa3..000000000 --- a/platform/ui/jest.config.js +++ /dev/null @@ -1,10 +0,0 @@ -const base = require("../../jest.config.base.js"); -const pkg = require("./package"); - -const esModules = ["react-dnd"]; - -module.exports = { - ...base, - name: pkg.name, - displayName: pkg.name -}; diff --git a/platform/ui/package.json b/platform/ui/package.json index ea67c6537..ef907d308 100644 --- a/platform/ui/package.json +++ b/platform/ui/package.json @@ -1,12 +1,10 @@ { "name": "@ohif/ui", - "version": "1.4.4", + "version": "2.0.0", "description": "A set of React components for Medical Imaging Viewers", "author": "OHIF Contributors", "license": "MIT", "repository": "OHIF/Viewers", - "main": "dist/index.umd.js", - "module": "src/index.js", "publishConfig": { "access": "public" }, @@ -20,51 +18,24 @@ "README.md" ], "scripts": { - "dev": "docz dev", - "dev:ui": "yarn run dev", - "docs": "docz build", - "build": "cross-env NODE_ENV=production webpack --config .webpack/webpack.prod.js", - "build:package": "yarn run build", - "prepublishOnly": "yarn run build", - "test:unit": "jest --watchAll", - "test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests" - }, - "peerDependencies": { - "@ohif/i18n": "^0.2.3", - "i18next": "^17.0.3", - "react": "^16.8.6", - "react-dom": "^16.8.6", - "react-i18next": "^10.11.0" + "dev": "concurrently \"npm run watch:css\" \"docz dev\"", + "build": "concurrently \"npm run build:css\" \"docz build\"", + "serve": "docz serve", + "build:css": "postcss src/styles/tailwind.css -o src/gatsby-theme-docz/app.css", + "watch:css": "postcss src/styles/tailwind.css -o src/gatsby-theme-docz/app.css -w" }, "dependencies": { - "@babel/runtime": "^7.5.5", - "@ohif/i18n": "^0.2.3", - "browser-detect": "^0.2.28", - "classnames": "2.2.6", - "i18next": "^17.0.3", - "i18next-browser-languagedetector": "^3.0.1", - "lodash.debounce": "^4.0.8", - "lodash.isequal": "4.5.0", - "moment": "2.24.0", - "prop-types": "15.6.2", - "react-bootstrap-modal": "4.2.0", - "react-dates": "21.2.1", - "react-dnd": "9.4.0", - "react-dnd-html5-backend": "^9.4.0", - "react-dnd-touch-backend": "^9.4.0", - "react-draggable": "^4.1.0", - "react-i18next": "^10.11.0", - "react-modal": "^3.11.1", - "react-with-direction": "1.3.0" + "concurrently": "^5.1.0", + "docz": "latest", + "prop-types": "^15.7.2", + "react": "^16.11.0", + "react-dom": "^16.11.0" }, "devDependencies": { - "@mdx-js/tag": "^0.20.3", - "autoprefixer": "^9.6.0", - "docz": "1.2.0", - "docz-core": "1.2.0", - "docz-plugin-css": "0.11.0", - "docz-theme-default": "1.2.0", - "lodash.clonedeep": "^4.5.0", - "react-powerplug": "1.0.0" + "autoprefixer": "^9.7.4", + "postcss-cli": "^7.1.0", + "stylelint": "^13.1.0", + "stylelint-config-standard": "^20.0.0", + "tailwindcss": "^1.2.0" } } diff --git a/platform/ui/postcss.config.js b/platform/ui/postcss.config.js index 6402436e4..67b84dc96 100644 --- a/platform/ui/postcss.config.js +++ b/platform/ui/postcss.config.js @@ -1 +1,7 @@ -module.exports = require("../../postcss.config.js"); +const tailwindcss = require('tailwindcss'); +const configs = require('../../postcss.config.js'); + +module.exports = { + ...configs, + plugins: [tailwindcss('./tailwind.js'), require('autoprefixer')], +}; diff --git a/platform/ui/public/docz.css b/platform/ui/public/docz.css deleted file mode 100644 index 1c45c19aa..000000000 --- a/platform/ui/public/docz.css +++ /dev/null @@ -1,44 +0,0 @@ -/* Tip & Success "Call outs" */ - -p.tip { - border-left-color: #f66; -} -p.success { - border-left-color: #42b983; -} -p.tip::before { - content: '!'; - background-color: #f66; -} -p.success::before { - content: '\f00c'; - font-family: FontAwesome; - background-color: #42b983; -} -p.tip, -p.success { - padding: 12px 24px 12px 30px; - margin: 2em 0; - line-height: 1.6em; - border-left-width: 4px; - border-left-style: solid; - background-color: #f8f8f8; - position: relative; - border-bottom-right-radius: 2px; - border-top-right-radius: 2px; -} -p.tip::before, -p.success::before { - position: absolute; - top: 14px; - left: -12px; - color: #fff; - width: 20px; - height: 20px; - border-radius: 100%; - text-align: center; - line-height: 20px; - font-weight: bold; - font-family: 'Dosis', 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif; - font-size: 14px; -} diff --git a/platform/ui/src/ScrollableArea/ScrollableArea.js b/platform/ui/src/ScrollableArea/ScrollableArea.js deleted file mode 100644 index 0a76c63e5..000000000 --- a/platform/ui/src/ScrollableArea/ScrollableArea.js +++ /dev/null @@ -1,152 +0,0 @@ -import './ScrollableArea.styl'; - -import React, { Component } from 'react'; - -import { Icon } from './../elements/Icon'; -import PropTypes from 'prop-types'; -import getScrollbarSize from '../utils/getScrollbarSize.js'; -import throttled from '../utils/throttled.js'; - -export class ScrollableArea extends Component { - static propTypes = { - children: PropTypes.node.isRequired, - class: PropTypes.string, - scrollableClass: PropTypes.string, - scrollX: PropTypes.bool, - scrollY: PropTypes.bool, - hideScrollbar: PropTypes.bool, - scrollStep: PropTypes.number, - }; - - static defaultProps = { - hideScrollbar: true, - class: 'flex-grow fit', - scrollY: true, - scrollX: false, - scrollStep: 100, - }; - - constructor(props) { - super(props); - - this.state = { - scrollAreaClasses: '', - }; - - this.scrollHandlerThrottled = throttled(150, this.scrollHandler); - } - - render() { - let scrollableClass = 'scrollable'; - if (this.props.scrollableClass) { - scrollableClass += ` ${this.props.scrollableClass}`; - } - if (this.props.scrollX) { - scrollableClass += ` scrollX`; - } - if (this.props.scrollY) { - scrollableClass += ` scrollY`; - } - - return ( -
-
{ - this.scrollableElement = element; - }} - onScroll={this.scrollHandlerThrottled} - onMouseEnter={this.scrollHandlerThrottled} - onTransitionEnd={this.scrollHandlerThrottled} - > - {this.props.children} -
-
- {/* */} - -
-
- -
-
- ); - } - - componentDidMount() { - this.adjustMargins(); - this.scrollHandler(); - window.addEventListener('resize', this.adjustMargins); - } - - componentDidUpdate() { - this.adjustMargins(); - this.scrollHandler(); - } - - componentWillUnmount() { - window.removeEventListener('resize', this.adjustMargins); - } - - scrollNavDown = event => { - const { - scrollTop: currentTop, - offsetHeight: height, - scrollHeight, - } = this.scrollableElement; - - const limit = scrollHeight - height; - let scrollTop = currentTop + this.props.scrollStep; - scrollTop = scrollTop > limit ? limit : scrollTop; - this.scrollableElement.scrollTop = scrollTop; - }; - - scrollNavUp = event => { - const { scrollTop: currentTop } = this.scrollableElement; - - let scrollTop = currentTop - this.props.scrollStep; - scrollTop = scrollTop < 0 ? 0 : scrollTop; - - this.scrollableElement.scrollTop = scrollTop; - }; - - adjustMargins = () => { - if (this.props.hideScrollbar) { - const x = this.props.scrollX ? 1 : 0; - const y = this.props.scrollY ? 1 : 0; - const scrollbarSize = getScrollbarSize(); - this.scrollableElement.style.marginRight = `${0 - - scrollbarSize[0] * y}px`; - this.scrollableElement.style.marginBottom = `${0 - - scrollbarSize[1] * x}px`; - } - }; - - scrollHandler = () => { - const { - offsetHeight: height, - scrollTop: scrollTop, - scrollHeight, - } = this.scrollableElement; - let scrollAreaClasses = ''; - - // Check if can scroll up - if (scrollTop) { - scrollAreaClasses += 'canScrollUp'; - } - - // Check if can scroll down - if (scrollTop + height < scrollHeight) { - scrollAreaClasses += ' canScrollDown'; - } - - if (this.state.scrollAreaClasses !== scrollAreaClasses) { - this.setState({ - scrollAreaClasses, - }); - } - }; -} diff --git a/platform/ui/src/ScrollableArea/ScrollableArea.styl b/platform/ui/src/ScrollableArea/ScrollableArea.styl deleted file mode 100644 index 6c49f8197..000000000 --- a/platform/ui/src/ScrollableArea/ScrollableArea.styl +++ /dev/null @@ -1,69 +0,0 @@ -.scrollArea - overflow: hidden - position: relative - - .scrollable - max-height: inherit - overflow: hidden - zoom: 1 - - &.scrollX - overflow-x: scroll - - &.scrollY - overflow-y: scroll - - &.fit - height: 100% - width: 100% - - .scrollable - bottom: 0 - left: 0 - max-height: none - position: absolute - right: 0 - top: 0 - - .scrollNav - background-color: rgba(0, 0, 0, 0.75) - box-shadow: 0 0 10px 10px rgba(0, 0, 0, 0.75) - cursor: pointer - height: 24px - left: 10px - opacity: 0 - position: absolute - right: 10px - transition: all 0.3s ease - - .scrollNavIcon - color: var(--active-color); - display: block; - width: 18px; - height: 18px; - margin: 0 auto; - transition: color 0.3s ease; - - &:hover - background-color: rgba(0, 0, 0, 0.9) - box-shadow: 0 0 10px 10px rgba(0, 0, 0, 0.9) - - .scrollNavIcon - color: var(--hover-color) - - .scrollNavUp - border-bottom-left-radius: 12px - border-bottom-right-radius: 12px - top: 0 - transform: translateY(-24px) - - .scrollNavDown - border-top-left-radius: 12px - border-top-right-radius: 12px - bottom: 0 - transform: translateY(24px) - - &.canScrollUp .scrollNavUp, - &.canScrollDown .scrollNavDown - opacity: 1 - transform: translateY(0) diff --git a/platform/ui/src/__docs__/NameSpace.js b/platform/ui/src/__docs__/NameSpace.js deleted file mode 100644 index 81e1bfa34..000000000 --- a/platform/ui/src/__docs__/NameSpace.js +++ /dev/null @@ -1,17 +0,0 @@ -import React, { Fragment } from 'react'; -import { Link } from 'docz'; -import PropTypes from 'prop-types'; - -const NameSpace = ({ name }) => ( - - The namespace used on this component was:
{name}
Check the{' '} - translation docs{' '} - to see how to override it. -
-); - -NameSpace.propTypes = { - name: PropTypes.string.isRequired, -}; - -export default NameSpace; diff --git a/platform/ui/src/__docs__/assets/github.png b/platform/ui/src/__docs__/assets/github.png deleted file mode 100644 index 7db0aaceca3f5cf2a0c744cd38c5f6a74cd208f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37651 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�XMGC@*y{B@%%*7(2)N zOVX}G2blly!@*tRx@Ye!fIt&7BO|Es{#JZJDgf3nQCR*eTf%0ruCA`Jtl(Z0lr*-l zJ0JxAydthb#NVsK2>Vtu_J|;STv8MU>)A<3NmANe<67`D7QreLGqV66t`AoXY#8iC zX*)jL|73w8z#D9j5ODVn2*4B$W)-IZtu-M-1EJdK=M6jE=V``M16QMZ*%*L zNKFl{T}8i|L$d=iQU9>;6XL5Gv!GmsSJI43-$b3%^z~(O$HOTVH8*`4v8z3e4(FrC z%wTAvC?$)#rrWM&M2XdX#^Ig6r=9u}q30Z+AB=%bU>E3;UpH@Veq_mFJM)EQ>oKj& z@AkJC&aPdT*&~n2h*rBTI|VhYA{y;cEbvapkI6p@*N~S18k_4q*J znGE&aDS`VG3f|U0z-e_FXsWC}{fj&1uW) z?E#K9JHL^R+@sDrp8E_2*d~)deq1KfME&`~4R|0_U(8~#=hFoB_l<&31)Gc2Wo6{< zn4-HfGBTgz)5QZ&x^~V_a$}jgTUx8K!ouui#$HFu{V{r2#9|`{xyLN&pMH>!rvE(2 zQdlU&DEH%y)|=A_c>{Ah`$)~`Xe;MnM;<_3F7;veA2)gT`lGI#oPxM-iH4v5s%t$1 zNdNBM6_gK1VjKO)#Hl$QuBR_m+4QDY>@NtroUm`gXjp8-`&x}H@6wTp(;eJ;(s00E zO446Sz%p4t@>*)S$=Bx9?u72zhuTC3diru9G`>s)SL7aMxfU1lHKE3*qY}ht8Ws6n z{|@9tVWC<|M^V>Aq?NDl>(f{fjqAD3TtD5^Z<&`D7oEXGwx%xjG_9W;X6@gPgaj@Ap*Pl2r$D$H=yK7He)^Qu6c?j< z{;~S?cvFsjD3~)=rG1#_%)@ded7QQma}R4jf4fW=ebZ;s{ybJZ>*4tH@s&gEDycu# z0d!RU>+H|UO;0&_pGwp!7RA+MMrz}t4)5Fno)};2KQx0BH03*{46A%VBAOC zJVp+21q`Q*)?U6^SGRrzVH~20RMZX>CEu4uEiXRzvS-oVDy!pJ;hhb0M>XuvYz*5KCE|}c2 znJ6+LvF`J`<6#!tFX-f^`D%Bm`e)jwLibfXcwS|tq|5`V77E#P-B^C8?0YQ)7m$t_ zxcHj$V_zu~)1G-#RbF2HSTOOvtw|%>3_3G!$+crrld88ZT?6ffJ>1_Br?AUSiLXUO zMAYJEBSH0K*3iO!Wk3&5^Q9C#^ZB4XA>g*XH8Ql^XZzn;IKW$ToQb5I3JE5UdmNKUeE2gr(TE$pY;{ zP5iMR1~3Mv3n;SI=6bw&)47^(cP-ke0y|;XgKLAlvihS8q|#*}S>*i}v$WSO?uIR< z5L-Jtagx;H@d8VvLK%4u#pE1n_U^{{3>ME|LuhE^Wi3O4O zuLTPW7ABpYs;Ztmx`lOqBMnli{@TOy+S_0B7T-|MCX)aw?Rq z-Zd#>>-Ju-o9Cln$LL|~RLrlVAzq5A8R<03u=9Fo5jHUrkEQXa-oLIRG$5Uz6(UFa z{GX}67W4@z>0Q|h12)?G7&Zf5KYXXz@uiAK_!jewzJ>cU*dJchtNDi|CnudoNwk(sSlrN^$9U5?0hj82}zltq@T+=UmO-%G+vLP)@RcZng@z4x2sjIUMr4bQ3r0|V1~ z>z_Z7bnc*D?yY^$>@QJKYeH;fp{Pk>vi7?+ekCn^#lsrKJlk0CPGQw-G9ep#hLG*~ z1y(q33?|{jmmi9q#w$)a&4k3dx;3~vff7{vE zj;q0&(>?$4XC7B*fE$!q4}q!t6*AT!4XkT zJR4KhCzcGHkX@n6OcaOM-s|YgJ5oQLWL#q8wh+pckzo^f^P1S7e%om=L}!lEoGLxt zIk{ag^5BqX$Y==93~%{eG)F#d+6tq2LDzwpX+ zh{x3Xd!(MvlzD}Om~MXH#f{|D08Oj?p3N6^|h&UvOsy6cfRWAN@`CQuQZ`_X$ps(+vLM534109eY@2o4oV7tr}i&#N=4p0 zYs*EIz9#3JPIAZce9x-1v`Q1f7&}#~qOD+|M>6~$$ z(9Q8F)i_HQ;S4Hof7(o{b*gV58JBtToB4q6iD-k`!<&EdzhVn|`Zi^f^^>KE3jxkS zIdKMRUJiWRiw}JklieMDm%YOE-=`xBqPXQhR#x6m9(}2A#h$FfF1JEu5UkB!@cRKn zKlN9#tJuC*Mn?M?d9=(WNk4-QDuaZlBF7C1v787(lYQE9-%xIR-SAuA$@MAO$qXXx^>5>FO>sNX|%09x*(1 znV#P-a0`5U_rO`eyd3XSd%H~Z(!&HJzPKqxwtQ_CD77{zzK#di=%(K6%6BK_fjVLx zzS-ZOu>72-e?IDeFUj}JEbj+xuI{&qCbITj#jgYTbxc*ikZr+=wyflMe--Qm@RixWfsjl`0RshBv(qD zwQxVPQl;Q8nj*n#X2}ch)U<@ewY_dQo~?FXjs0Wtjh~jBeA2QM)L2Hk7Rxm{;rBh8 z@}6la`enzKhC0wOb!y69 zYgI|7P}CkcyFW6+baL1&y~-YI`ArQ(-^^~ep15C~h(W`CpS!lo@g$JE?uP8?h?>4q zR6dg9u!AizwzRg=`DTWjh7S;aRv#*-;i=z*6_NOn&R#>-$7J)mE@hIxrv2Xc!oH-i z%FMj1mwG+2yF;TEllxtTd1`KsHqg?FQ0+0p(7fao&scBz3ZD_-7^0oJm^w}Srd8*d zY22z#R_?3V*LLN!L?gnsjt+me=ORjEg~r>{EQoP-}b#G?}L8PSdA`4@^Pb9#|s-uQJ3Si0cgEzv`n~HcD%^e&LBGQ$BBJ(jom$?y=SQ+!+7V4G zfBSZ=cs)NT3f(`2Ur1WZ^B2FRrRjLp5>lOXHaKWR9239dV0Q#4f&n9CgHP% z-%?n}7Nk#L6e=~@JMG5qC?VQ`{Vb&Jf*(~s5JUcXEx;YCWk^3>U4ehV+9EOBT z_qOez2kH^y`;9p{T{u~+DWwyr2Wx`r*V_q zSA=&vjOO7RS+2Fo6FytXOE3u5F(04A3PX?N6BYbvsgCx$nZIr8;r!` zQQ{%#5PXI!ZX%CJK!n7AoYYCf10A|ne#aj8QGXX9 zmN`7kQ*9azq^?CP6{;cSlll8Yb3wR2T?@E;x+?f)luG$tKIqR1w$Eji+(c@5HPo6z ztQ-vi((;>eCa3l0hx>*^8V?A5Hght*h_3jllq zlpFybv?N4~FN@n6M@V3Q%QrR?S?=0rE^#ng0F=n;;#`1#? zpEAZkuQDMVivF}?kY}9%ic6UkF(5Ec_lzMfukJurVKL&-fj9_nz)HUty!c)KG<^Ej zWKn&=JE7`&)OoOB6-XH=s}d&k0!1hbw)+Ir07{_tJ<YBli~}vRfq2C>d1)ELly|D&pzi^m#DZ zId*S!xv$2pjJWt7k7|Qb{k= z%;C*-`H#;=jeU)(fRLW4A4nm|oWcMHUUCwmVxU5CBV_0y|4|ohF#|yizd~y|7m`vMX>VwC;uB| zb5{Zz4>Zted=&X_^w>O|;^KEg#qCHB$rny3?8B5OZIyn;fuYo`E!Oh7aSu3T1jC6G zE`Xv3ZabK6(ENBtxwCzC28g$j))M<($2^aa0XIO_qs=d0^t^INd^-Ccvwz40Wl~vL z*q4x7{I%j9>bsKAuk^ZSPbQ{moTMl#ztJj~5mTo&?52XCdq)kiJ8d!2itb3Vq4df} zX2gvwGeqZh76XN+(ewcO?q?@&Yz3yW9KH)Z-d^K;AVRb$f7eX5KC3J8t;nbZ4BbkX zfGPz>%)6UFmd=opIuTXG>d$-_)7u~?^()y_-~Y}nuDM&Ssih4QKo?=BA&S&!5+dhX2=WHj)RPf9qdPSK4rP*yGROxzG#wnl=_nh1T0p*QEmV zABb(Y?n}nr&{Qf9cc9Cn9@I%wH)#MAU{@Gd8lpeiD>UdpAdQ;|iFib{pLU8^bXV1H->WvhTL+sj&fnUC8Ly1uX$!}99v0EFKh6uz>$;}7W#aR6}FyC;c7P;Gv3Q!Q|*Fr+~U7qCLA(iH+J zgrgq_LZ8dLw&-XBo0&1Hsu^pdukV}49oGvgyFx}WFZDIIwnoy!#a2Ew9)0!#v19-* zSs5*O@Sv6dZWIKEBolAssFFr4@pUTuFWaG|U&#v3o(Evz!0#krtfn<6#OjaR#Q7-5 zGTm`E7f#p<3)Ohku}DHG@ww?k)10lj_xS(w4OxJJ_q%h9b{a_Mom};>uAerh+dfDKFZ%(f#XCUH@m$)Y~)wEa`^({qIcqgJlo+qXb86GHTgf z`tX6*JlzK(TWVu?5|_4k+XNMY#R{zCRDex+(3C2=8b-RI_$V~h)TaDRYh_v$I){+= zHMU7D6cvNt+p1t6I`)V{aVs4goN72~AgJr+1Nn3o4V(bBsKV1osk^!6t{=o}nqP&= z_ZOw$n?_RqLC4#(hQ^%1++dJ~h2D;?Qb~`Elc;&OKONiZFl-lRNHs9b*odSA9Hn?I z#&X|@7?&a!Y=|KH+Q`zeZ^6My(Zfh0iy}2>AgiFXbm)0NaEB>>g{KjuMyAHCUnAG# zH8Jl~fYh-FPL|KVvDxXk(D)M-Zt;T8U^Ap9^3QCl##68rgrdPMnY4urx2;i0WP0c4 zEsPY>?y08r$mu2sm@3{?5X*dl6$c?sLXD7UK1KQi zgDk3JDk{7+O%4juNAJ@QWa$0eo_~2b+ETNlMwK7HmN4;}505N!e9z@R#Q5&ryVhTw zXJ<%6l%W4OQGu{|QbKO8=2TP}kIvDT4FhtzW=A-%khceW!2j`lF?&3CjuKaLneDvo zMko>e$6ph>63h5`8es|K4+NLKwF?CcZ6aHEJ zq@L0)xt)}$p>&d|*EIN3W`smUe-)}ct5>tm!PyZP4oLfF-#z07ZYIQ!I)WL%@TKtP z`=F2Oggt{z$;0`4a6~#SE7=-@5rmew&Sa|5q&f~UavU+ahim%%{6}||oC^9BcJy9s zZG564`l6$Ok&pReRnQx$9mVj!MdU%$GKw&YAhP@_L1r}6*eVr_ zFKy}w3a6+d)!lIT+~<#bZ^i@&LJyADC~NuPz`d|_xyKaS81Lo?RC;F5)%ZX@*p=ZQKbx>v~QQlPOxtXWoWNGhYplv))ams*r6Mta;;nV2&35)-Mqh{?XccO@015U+Ol9ry<=c;&1wr|+)r>K zWc*hFQTG%=^6uy2pn|actmvKOuZC$>w@7xW;zmHN?-1=yRvv#y-RY=8_t`j@Ryfw! z)f|C@gK({r7T?P&T&Kw<#mrR&MlN?2=z-!MR*CUu=6P<)2LO4 z*CdiAa$`51a}zwaih6q6=SL)(dVj zEBNReU5(+)*-whCjDP(La)Uo2(C!w^G8?s$>%^BPgo44|g(y(t-T`leCMGP2Oyz|R z?@-HJv%n`4gH(Nh)Px!D)!|jRj)JLB6Tvi9#(caV{ps ze&G`|7$x-fm_yU?=VJLPOd#k3*%1!fIa~BHIow40jAkinKhDq3FAj$R9tFnFB{^t; zliY_nfyl<8(C-8qsUb{2tcZ(&fZ^sEA3&z5TYDAPg-OM-TRUZ4A{i@Y{yl3jWIliE zDQe`Pod%R!s*^AGU1EVE3pw#7RvdMH9FwPzlFCX==82y3F{L|Tv{u?9E0-R<}g`lBSd2?ak zb0KOl$erndb0@F*5+-y(yVMLuS?EAIiXoc~AiAKkb;Yxs z?nu{6+n%Ael(bAW#3KSfZ^v488hxO9*@STZheNLkltdYKwYIbeY_wiu{ziD<-wx6R zQjuI*kxaE^phM!~R`kYrcQYq$w(E*Er zl=jHf!lK(ug#dSR4^HYdXG$>jGI5xc)bb7C%0o8)=s6nXV_8%mSl@(cJ8}<#Nr;@K ze@WAuy(c!kx;(cBuE+v{uzm&VF``v@(L=7O*-(S{Wk$`TwfsjSX=pIIEW(lQeDhyn8?Gb4lN z1*D{Gh{X%#8nmId9ZXo*-P?*`lDQ~JK7H(J1Os`6qSyrQf^^d?aoYa4z>4ioSdoW_ zlMM^gnBdjKgLUFd-M@lA_&z7avwhre(N4d~jZ^CBJn|MYmIfCCWC(@UACrwT^m(kG zi%LK@5_s^5`i|rfnF|XXfS{tMO_DB=)>ee`^RG_9TR5Z@7WECFe)-><0E1X~<6r({ z*OBox4~Oq^EL$F{e@jpZWp2QQ8r8&11#t3^`_p_D9X-pZsN+uhuP9*$XBBQJoPIL$ zS_}RS#lw{aj{Xkw0^Jbp>7zq)VIy%4e|xGx!uUlALBYK&eP}xWtyshrkuEj9ob%$f zA0^l_=Z)|R1O_?}SN3-f@DZYPmBCFfqhihrOIRT-^!_xmEQGh|=AHlq?v(ZO_u@fI zy_FGuGf!sB?8x}9D{g@5^SE<&pRxqONM}Mo=98t5;P`FCR;lpg+hs0zfku2Mq($j( zTG*u?4`E-N?Cf*ZNH$Fi~@<)$asI7)1DAs7eU1{@*Run|p#3YkCdd zS=cqTWy?RnGGzwsUJR`2@pKa7qjl8bjw6;!3i*djz5VLZS2WETHi4?l&9EiM8(wiN zVt5*gg2Rxt#pGW^1j?NXP@MiST0+U`My>MR!W3JGhWP8Z2eK3@0G}vWK{Dg@{{E(g zra=uuoGSg~<&w>g_NVgwF%y|iKiJ_^b$0W{=ou5Z0j&}yNt|h+)>4_jhSbOfR7W%! zDR0iitaN0M`&yFbCxMIC6?;EmuHhHg@~@PXB=Z2u&IWENN-St$9Ybpz`)yQUwuO1L zZ(b_M0?&C(zyF+^bS+twJ;J_(^Uj4ePS3Py&lz!vdXor&Y7~!{z(tB)Nbza@UPp)- zwDCD)Dw@gi9!$`C;aJchRK;=kYQj;1gFBC0kkL|@?>(7M!5vH#fXf_)wYTC4xJ$mtM)r9ery@CJM}yQ~3Zb1^>`fpspaY<3G|zaa_?90uT3(1Jy_x%p$S9 zz;JQj#z)y^Ba0ga)1aS z^yve0tTlI-O6r*ozPUklBQ4sHEtL462{J>{C=fuajX4AyG1rv|mCFY&o;)uk<)j46 z6HG0W96`3l|NY1K0g5gL(Gli7*b>DzIPOo9zJ5-Y-0_GQzQGR=e>6k^QT=83Mff@3K0ykXV zH(q}9SId#sKhiU;vn$Q#z)~o;9M(ZiI0CYF`hzXlRn!y zjM4?pf~kQ_w7kaS)MLN@%Y%oIp7>MN@Mt*l`Gc+SVxR_A_(iM*LIblVz(;AonU}^P zx4DW-I;u=D+MLy(Q&%BZAiSuL%i<0*2|X_QYf5p!H){pgw-5=3(+j# z3cGzrTHa=?8ufqv7XT2<=8S7)>2xRTSs|MJg+t*;UX*a2r_j9qL@qQn7rcbS1zoPu z*xuC9tGEP$F_K(>Qnn{+`hhewtg1WT*JEh9~6w7u0vCJ$PZv-lt3nTfYw%K>apYw^KbN0~eowh&;~ zK64drN{EVzFf{o?e#RLH+#Zi2-Wu!g?<=kIrchW}Ee$HMK^sWQkp}|#d-KQ6BW|zY zgRda~d=!4YsPUXKGq(XGLK`jZ$buXc1QZ;}6#o}oSfDkrk&Ov-C{0i77rcz!0eG3K zIvV@mbAAOTh=acXKExE-eg7Kt0Aj4#v+M+LXt@xI6k3<~($oDheB)~L7N-LrW_07^ zzX1RrP;kRXEB$Nb*MZa|JiHZ{S1|BH$#)x%cWPx1qFoBi4ZJYWS4?mD|HsouSWt}# z!G#ji75)SPqM-NDDTfPP_rQQ`P*)k=D&PKiJ*-*IJ~iZiwGU+=u$BChVEYcs+UF1c1T4?UT3nm1}rC!_1uHDI+s|0>_cgyLuvQpXTQmO z*^CksF6IIad6uH2ADIk#f^Q*XvLWK&{RKxWev20b>pug!o@^%HmgDx&gb4O|1s#e$j1)Dk`1Sn*xz|jjliJ>H@m(?R^bzLGh4Fbdx6V`uJ zYcPYq@I;vj+u~eGQ$&;t@ELPcr4&pZAt zmm(i?4gi`HW+J*C)jnfct*HDT=KK;r$)*@ZtN34pp;t>i)r2;L#PhJeHXJsQ!~LJL zOd$WfuI~D81#!YEUZdy(+FzhGc*3&bgmOhtb58evS90TqumGS1-hkI(Fu_5m0dlnf z0cnz=<>Qn_1IAv^wUXdQ=rFtUFeBcrX@3hcb82$%w4(a7>;^VQh9J#^O8=ba3;oZZ zKWXJ37oPs!G~~t-f+(kmJJc^AV!Ms?NKZ(5WX3}O*#oKu+yYUoFGnBe9|^6^{a!{K zWKcLocg^z?@@%8w?)SsN4go#@G2z6Hu!q!KJ0K)IWMxah&A{uk-$BSqxb8LI`-=8o zV)-o&AcT8vM}k}4m=mTb7{>}&_1HEOGLyaRf$D4g-y+=j#mQT(n{x&ip#YEL;9GlF zL6eH~F=j04^<(~9$!WZ#4d|RS!)i<1wS-J}CNwGX&P?6=z1!Tv(+TMEm)909;Db}r z!Vkt1I~!P;I0Di2Z{KAB0>uQ*=9C9?U=#UMg)obN#dfgqYe1ko zQpnYqQQ{p6J4Z+P2nuzi88ZkywWN%*^RqVd z|M2yaHL!-p#zqT5L#nD*t;G%cP@$QL3EpT$IR2sv+CuVY#0EVXMz1=Cak+u{zZ{X^ zC!aGWEh7?67X)ZA-9NJdhZD)*HbG;9#OO)u#7aQXK58-kS2rjCD?ghGj+BHlLM2t6 zUtCK=5XNAvMSQTML)RD~$i-7D|L5n+jF1CatPp#MTLA{*p0hWrtWANY8nsY)_MLIC>n~{H-?nizM@0PC};}nK; z;l&ffW$gC@7~0HhDK`lfH%8$XMP>guxoEI|v=hD`xGF#~c2t=nt|TBizNH}o0lBEr z_V5=ewfO*_1uNkzBSXX2(=(j8`2RhSDHJB|-BuB?d+=V_p&prQdxTB7PUFr5Jf6V9 z6v1jfwvXcfH3OcB$xbL;-KfV_^50G;K;~2RCI70fSgN`L*zYekx#lzJ6B5CxM7&5z zquXVL67W9tz6RKUgq1STppaIWeO3b41;&PZLGqc=Dmhz@U%q+FFM@L2N8YWr?Ol}x zAlFc&`}34q*2sX6&40xmb8uf@AE7dn7Z7(sVQ5&&LrGJQ&?GZnDVzfEie5XjHO*H2-IXR&O`Y>Lg5~);0(`s-f)kRYhwdekmxI(t+ruT zE%Ffvlcp=gb0arTkK?UYszMbCt%T$RYy9)(DO|-ek&5x_94Nc{2sygyS3>CW692?B z38%zIV1MzuQ6#}!eF}kBuBCW2ElO$|K%A5Q76G0Pe6ZL@$ToV)InlU92YvlTJ#Zn~ux|6r76%ao_MaHj95$&lW++`)Nlohy}Kxg=NVny4zdte_h;LD952&&#`sPOg_byWqW};^z$G#1+&6iz zAXO~FZ4=`?L99KWCLx$;QD@%iIH-c7rdtNNX@d-FTKVL8C z6!SUXxa(nsPLO|nNU+QEjnDsLf8}2?Z7}=28e;KMwoy%ekr!^O9{n=ULW_njTBW)EBLx1nfSk&P+i20AU1kMx{ z0rwF*y12W)6Y0tnC|Z*#pojm7Zuj@EjV0Cr4^{Y}q;FCn5L@WJ>yDDuczT$gKIc{T zRyLVf$os=U_ z;TZ4v)H(z*Qb)6IU;M`sh9eZt#`ci#j{T?863p(I- zyHV%}z58?}R|lN{B46><`P=n4i;zD$Vk1w`ui_=Ob>b_>58LD##6%aAfC=8Nw;kKy z?~OA)0tKPX*~FU$)`#ziI%Gz!7Zw(b-Lc=6wQxp`fUqYx4(t<%XWJ_Ne2sPAwP2K8 zPniNZJswD<@A#V(b-a9kAF-D z@%_6yN5DOE#UY)-yPO!yPU>kLB~B4=IYb1cY4vBFWpF*IS$_*9IfKbgg}uOzS*q-| z*a(fnkqm-MP6}fxK`(IaozBcBEdM#$jY98%}A9=>S?3%N|#xjZXb%y5F>M$6J0a#BYr zq$?*aHOC_2o-W60E{I3}X%+a!?hX2A5x}?Tm?{CUwa^@yv zylwO_)UB6R0<51EN}qy`Fh5@GFd;$er+ob9=7`oKj#cP@E8WN zS9m;Lhy>k!%cfHrd0e~GDa55_Vg8;{2FMn1(QUmdmxWCXyY}YW{4r85_4#~_tZBCj znGK=E+sVoruv%NwdisojTY~wYehjE3VrWE>5IJ$Y#89-Yvw!zTSLEpibK=wGpy{Qh zM`6+y&+Q%CXpe$F2_Gol6N&aI)Ngam*P)wmev-M**8PLODRFs)I5!9 zidlq%KIC?!64gRyi!|i#57-5x>l9A(pJ>9uKQh_JSgw&#Q!~QRHW;gLg_u659)bcH z+b8CDnKocTNC2ZXAF0&VxrWY#sR*44LOvlW6&&^?)R;XZJQrbRX0G3`E_6bXgdz9< z4zyDmDO^3IG?{t1=`QAFACA3!uy7tLR3DzAG|?us4F_kqQ0R{zf47RM9(i2EibLjo zV^zQmFO!2XZjAP7%zeYQe4iDd1009FrHuR=j4j$0#gM}^fCTp%hn|iu?qli8^*C?< zk6)7shn*t1cbvMCiso6@axl4aLxg-KLY~}u>Cl(bqX4ZxzFU&se4e2x!2i(JFNbW7 zjyN=(3jz`Si@$!QfI41NnMC0GrJ_$xH8!j@Jsfe71>wjvKVf1XTX$ljEp=X=xqrgq zL1ge|I1h@u(JkI>$U=y1aeiees`y(V{rp#1zRi-rt0)o`BmgkWpxL`z*LnbHxb=2wqsPLw}v*LSbA+V z7SRtrPsytEA#gMTAQ)RislZ` z&-%+W@$#;+j6ZRfhpaN%vzGj#;b1mPf8-8MU~w3hhz_m{lW`DOAEBFx-j>)!j)nv$ z_`;i>WKfC%gFqh-k2~E4nlcXeXB}YGeOviyTO4&gNHaH>h*<6hvuayGFt2Vf7|U=_&Z#5 zl?9)h(SNiEduWFw%-I!vH2!i>zniBEtRI2;K>6|U@oKt;ZA7d9ZceZN8|30%M+*Vd zX#T=qcW2_5=#mi0D{}|_(FwfUm2dhS5A>F(=SD0kN?=l01qaz%H>#>j0oWb0-mBBG zJEGJNj0KLQIRTAjWm`&Vu6{4QQBX|&S*CxDZbU4sXK}n=n>N46CsYz+R`y)-IXSyOYem!J9*M) zZ3qHYs=2nJLY9d7n~K_V=2UkQh{cM*lT=XiXHYA3a7Mg}@RR*Pd23AXLK3_Q-TcdA zg|YgB=$yH%-Lr%nvVz`uofhlEa47sNHXuNzqc40eg@p60gv?#$g>0H1>6zL)+E`t< z4g7X_4^=3?4ey;)&dlWG@zP4oLkS21D2H7YSQ;R^;vv{_Q)^J~kXpW&go#U4EuQE? zGUsDp<{N)pCjT;gd!hFd>h5A#iz4|EOltU1>=67vmDO`o1(t3y;PwvWZh2J>rzp{~ z6%~z*n@U$<>-R?1>2b&lQs#emJ&gFW?pSQiAIV<`;~co;ioESJ)>i{OpWyX*6Up6I zpPZbGC~tfy;bC(V_Z4eMIa=ZCuBiF-_9T!3U6O$+0$2T zYjgPmv|ma573eaN~`Wj{I$Bmq2%M}7Bc4=Kvz`SZH8 zSv=9kGSMOHgolTjPuq-Y!ktrvBsxYTIZ=}>`=^&lam8sfNXy6RQaX3^u@9={6AM&< zGSb5M1YMQLm@6?`U(3edo(@Nf5y zr`P-Wj&tqP#ZR0+EIPb@_vQ9$`!H(;DZI$_T23IF*Yox75mw+OHQ5B9SFm;~u;>TQ zebrQ|>hGQkU%0MBUg0h#+DK7nzg}NE`4)k#TJ@c<)TJ5Z)5>{>5-mkq)#?jn49nH3 zoeFcr`tzqL9lI;tU9L^jv6ba`1oD(e=6g(1sEiJk9E8t%v?cG{w;s3SIH6Wm|7nkc*fx)4hg z3v)=2TkM$O&g7F2|DqzOCjoY`fxXNJX3`C_(BLj|EP<3OF<2!T4!#h`C3t0__K+wo z^;p>{`M$`_H64wJ23GCxb@KL^j`dQE=(_JexbO zcWZ`CQ*=AXiL|M@Tz$=eE&KYi%ReqDAby=84M8i^hw+FHDn z9)`{bVTHfVU+f5SLd4`WepNb2NI1AI%kyIkb_h|SJFPbVG5b247hbODwY^{ z?svg5AioI0qVxRgd|VM*l0KwRG3+*Hdns#4v@S{nY9B-hay z6siL93|fVYKVeD9bhuiAz%S#>w*}mamLTX!(ahsm`iz8vIX5Kma7a_puco#2F##lx zAMN@cJGCz0uViOK}gK~&X7AmV&6_u%4875xW54j@Vem#wZ z>lIk)v-5N0BDnasYHs)sjN}KLE6v}DJ2nWUfR4-61@Vj%l&v>hpFh?_w1-IT=;7)g zuukCTrY7kS11nf8UAlod5@Ew_tLG7TWf9|7Uo#^gPAKKs{bHLR*;u4Mi53S0N@wZ% z_?Rz;+A02um#)_`XBAS{Dd~{m>#gh@scZR=kCS-!OxXX;E>}rHM0a5;Vq1@k@UErI z&U#vv>=U8SM;@`9AFD@o#Mx%D#kQ>*7P*r3v(^8-N-HmY}oWJf;@=c3T`q`xn zoexTW^wCzHfORyzzpUilA$Bg;IzNl@zRu6#vA!+4;x~&SOJz0N(V-pV4%l}~#?XK$ z{^3ztDk;-!1E`*A{z0+1&O#h(!L;RgMN?#_fo$LIfmlL`0P0SjgTBUY+>19jlAx1J^It?{W1ti7S(ZJqx6A% zbqQ?=+2!HowX0+gl@HdFYZ?0i8ijlD&1=)bkASsAL2NDfe%wjzKneEcEnPlyqmX<5)~4oP_apcuEQ zGd|eus~lcewv1J1O7RobBD$^t&of9=eczNVH>LwGXSlb-VhSn;1SI;9AC3QAH@dm; zG7`8U(R`){gyA~D&Mcz3vb@W6?+)Hu_2D09`O75m+N-X~p8S*$dZNXJH9kFj`$jx60a|v4Us}^b_;i6^KwydnBfMtiebLxU zT-*0ZCqvz)P_{c8dfwdD7zdH3A5<$c56gMt?ojt-n;{)be=}uF(6$z>UY7NDlQjud zDEyhr)>38&=7AN6k#{lNcz^$XpU=7081wwA90bk@q`NCEb>raDz4>m1BBZLl6pnFy zW?gsVk}Xj85>Z8Vmb4{B<|IQK)!%u5Bk3)6laE7ZrY7WE-r9{7^4CR|HS?KgVS$5B zpm(9xZ2Zy1vM=J4(hA34E-$ot!0H=zaGcMKEHJ+=@VVc0Ezvw@=O>@Tvt79yM@>Qc zmcSUb5>S1O!t*?#EJa&n(huxVq!@^b~rDYxTEGu>u^L zRozhrJO^$)-7v_N8P`ods0MZ|oF}S2$(8Ve@;*>gjWUl9M%l=_D#&;dn@T{If?Y%z zEE8T;ahBq{F$xbqNSm-+y(y&ws1iLe7Ohg5ci8k{rLW3&TX98-Qp6ZIhO3tdh#x5a z38LmBL|zI~XfFEY#FZRf##{zn%WLaAUKSQYINmfq)W|__d!u?^k%~oc@cuHq+i6a~ zyiT`x_%53+)6ayTy!F~~qL>TQ=+`!L>PwH~(=vpE*N5aV`7cyYOhs}a9e~X;aO%$1 zPJ-75PWnLjM4IF^Q_t1|g~tQs{k$<6srEWZ;c(R`NwGAh1_U5AY3uaX*C@jhZNjKFESMpavHCj4IAUS} zf-CRO9=*CGUZpQC=3O83$QBVL`0HnwVfDDL6Wzrkx5-GJKQ)t?F*A~XgvL5!z;THa znZt>ejoVB@C){;`mk~QM9wS5Hq{;bIvAt#$U%ni2Paqqc<;N6q6X?SK*5miGR{>XM z;niBZ7IC6M)Ui)xmYbh!<@k;@dmn$lMqY<*Znp;?|FCpaSK*M{+?wrRz4)tS$fn~- zGPUQudI{ZF7(R#z+KYZ_lny7A6~_qToR@#3S7>Adz;RLL;or>e2qFXt_YvN%;K#sQg)7J`-;;-{Cl#QoU(8C zF6IU`%X#!a6EE&D@9)v5Yec3S*?}TBg`jO78I@X2Xp?2aydV`ZAzX))&J+Xfd)abf z8-H(~PL(d&7W0^7pkyd^-{KSpX(*Fw7aUjw-8c}Zf19)P`6!Gz%8M6k$$jMh& z>tf;VQYyi@z9%gl9<**PeC;F{8xL-4@fX=!ZKGqIcd-sxA~mX)>e_TT|M)>H<+nAn z3mLg1ISg7rJqk6=SkyCvrh-B-NdAkgj9JkS*D=Xf&?i5yfB!Czlr#9D`i|)tiV>=n zK?&usZ9TnEe3(O|lq$;l3WpE2_?9*TqoDZE4>#pn1`QjlqanoFrxFSISR_+&xi(O> z-vs@H8?8<E|M-ZBsnl{J zX|Rqy@MEDe#>&Mz^WAa<>ZXscl0lK?IvLw_lH3OxD~}sFH<@FCYgN9t(*@nt@%?*w zGNMHwB)^Br7Yx*P}o0AB3G=&2rpfnHD(H#6GY*dA?h`SvI=Zss7M3K^?#%l-kii!gliD(1h>MZyZ0xchee>Ayi{)smH%>mLDCDRF~H)D(=jxO?Ce2 z<{oSGPiRBo zPDo6Wn&vPS#jX^9YWvVb=Wn`4i(k3l(R~N=AF5xu+AS@P?}nT6+q63l7Tp6c+ux0f zT`suy8n#Am4ZW=_QirEfdU>4JMf`an!`350vrZ|+zr&a+d$mInAw7)ws%@Znk+1vr zTF9=ma=#!uMs9@V@pKX6GSuxopFo~wB%;Y;XpNIOeAOc;DCjX=lzK|RI8M^r+Z*Hb zA=T<Lh@=Dt4iL$&dTW-GN%3LNu_xq{QZ^8Q*?>eBMD5`PE#2bn@KzxE#G$ zhmARVCzHRU$*dSgeJfjWP!%(~TK((p{l&>LlLQb!`95RYD383_DnqMs{Tes;fajnr zTM#GB^2Jro$=ml(TH~7EyMO&Zjk(RZZw}pa#(eCw7;Crw^0Cgu4I1}cA=&4xUs=Ql zR-3FT>}U0r>}j@@gRbr-KjwIW(e1}hxmaS)vE$6e3sUHb&z+j?$ig0X-FssiTG~2Q zYx24S)TY{ctF&$6u0AW@>9*+U!?FU_P2v`1$w(HnBg@M=M(X>qv8O>f5W)J3ApT*9 z&5xVbm&mUj?1e8i>Ae7u*gHsQF!UzlUb#$$x zZL%3ih`WZ)`?J>1MiaZ-huuss_4LMU4Y23EDDY`jQt36{BGv4LZk`It-L+BTUw>(Ocqc!M7SO2ISg>OXK&&TGo= zs+i^|KE!r{@=|?)((uv)7}pU^yY2nWIYmsQ8J?oS{_r@WV87boHZafh+!4huo|Ejv zZ1T?^_ThPx55~@>{SEgb;*(3EIeV(iy;W+c`LSdHrZq?Hpz7X;pq{BJjt2qvv8BAU z#-<;W;&d-o=-6QW@89xzNmtnP)vC#!Kg+6$hxl2cC9=Q=o4Y{ci1&4wU8i1Op+6TF z#qndq+tHK0*X-CmMaZIGNxHgjFLYJ#J~r75+AvuKBnz4jJU)9AM}MfKAea6UHM(Jz z#y(~sOqDKds+RxC*D?*-K~LM&p=X^jz$M7L^BP4GzPGJd%QXKj?qybWhyF}(cOF)9Bxkj#egHw3Z|`q<993?FWs;i5o3?f?NaF$?_*gYc3PYD%f_Qc zCfezL@UZQA?~d%)Q)7?6u&{<%eHDD;^qGao@S7{1x$tG;8qe@Oho3Y=kr97?+vfhW z^ZXZqGQz@^%33I;Mi?SACP{D6APOHhx@WXV%b&|$8S!nDAke{yg9E!P3knBb@}y4Q zvO~;u3^;h91D`CqW&=#Dbw9-BX}$Skg2I)XU09gRIKN=4IBeq#J(&9%uu^lqrP!ld=Zr9`EL?%P z!0l}^nkh8GU{SmRiGazv{SJn#&vqQY^LAHkg1nF?QGo9%X|1Ar0|bekOMxFow(Vk+ z_J5VAWaD}ssX5;9m;-}?cbDu_>8gFU z4w==LdB%;w*$7I7+8LzGle=)FmvQ5ZOjjw;yL4iU;Hw7=4Z8*KMbDA zD=0+H8ZB@5o^AdKp7kJ=18A^ZUBQ-wm^2`YO>MTfv-6HP@ZNDVvr6^;Pq3sYwWCMQ zail%wu$S?q1YxiN!?H(0yn&sUm)EM`#`kqOOoUh3>|#Ab>YLGS$3O2rZAo!6yv^fT zbTrsx^%c#VW)Kp;H@Lf$uGM$+Z-zZ5 z>oA7N;CY{g ztP%je5k<>VTYb61=m_jNCc=r#Ee4T)^D*OysJkYjl>oNu#v^fw?oCs56saylCj9%o z8Qs5?9L2&(c0paR7S~JP=ADXU`IBa(!XOOnpj!a}0n-p72Tu)+MAhi+fh9E^9VWxq zj-Tn;pT*y6GPT|7Vg=CLMrKOz#SIi6Z_d8_ltBbf+V?#Y>el-eNiaVjq*MjmrIz^7 za1wj-RJ&%47vnC}4gN|CgZoo&bx@QVFZ}JnlcUZ4alxQX!;nAmrbq;)b_Hn?!o+a- z$xLVFYRP8f%ZMMKCnM86dmMO~{>G~{ zo-rg#^^PB;-LpVHri;!v>&jsX<>@;<`r^^*cI9ArX&Cx#^nRRP+h!8t#lF3k3R5jR&#D343H0utk0ZP4-)0*R}xe1lSLEPEbLtuqYtzft(%SKlGhEN zlQUI|tP7$tRpYl@p`7|tZyYJ&Cruwi)6N4B9k@3&3upX+WCnCJs ztAf~}FYpSE3Y&$t7*oaY1#LLCLaCeaPGGsb$seSa7bs%GgW?d^!bA-sD?D1%U)neW z2>Qk2zC@3Zur)%tSUJwt1FFKG1~VT(%xYn6m{*)O)}C+Ke!rt48>TBqMX}_ZAKmX( z=;2-Q4(k@ckoy*VM~=J7f+lb$zoGKLvsF~^A^sYtnyiGe^qpd3>8LD>|9zj@6P za;%uX%J2NA<*TK-H_S73z}M+*a_clzLClvTq&wP@fTv_ zvBw$nXmz_QK_^DF)a=B=LyC7^$aitlsd)D(y|E-)2dQ*pb#p6}MR<$(gM1~&KdEKS z%bHxMd_X|`_56O4B37uu8MQpC@rdz}-mjfbBGM;*#p7JM;Z8xqV&^d5z;w~4ly#*5 zJ^ZgyX^IEBJ+K$p$T5M&%)#y-JdiotzPGs*Py)by-rp;HZsJ%Qo=LV5pAkeaq)3$i zL2zR0T1BXJaDaqVTs&@OiE4!Y+Xh$k=R*Sk4+3i_$ zR&!Qdb3;P8B)4_tN*IQ;E}b_hdlf_)zLBV}ssF{^AKq5k=gEpxctqI=JDzK7EFDWW zdyz|Y#%M;v&JS&1jlJM5<}rFL%opU%KwB3!Lua;g^f-`Lm2qfGkLKB~1xOdpe-6j& z#lWC>OyG91ue8OR6q9=0ZddQ?spW}O_m$vsu-f`7CGCl8DRl!6sZsz8S zRo9JP`j4Jb#jCgP&Y8&%(M?U8P5$C}bc;Gyn%*!*Q;< zcoD6Z`6gi_wE9G5W1K5H`F^~#bgrz?MQv+gb(+1cbfQ~hdTJ^f2f}pADnewtT@c>k z67gC>t;DZA14n}c{j2K4KG%<9|IH&tjg#~I2Cu;!&Uf@-i{@F&{p-Fm;=a4Q4>F+E z+M!7UXLOChfy7~2aWg%9!c5`|IO`~R?#DuCxZ{X2&de|%rpLcGWOodS`EGPAFONmX z@H|%5FL3cU(U2ois*&$tV-#T023WKB_+j|iVDM6 zJE7LS@WpP=F?I=_61uj@-@Rt$tR^I)*K@}F1{pV%FhZnY@PiIE>+YyaN$LWqL3=$|dWav8Llg|G*nD&ODV^Idq}SCD&R}Y=R~x zIY~TCWWwNCdU)at=6T5yJ{kAC_xC%0a}FT&Js%HG8bXD#+BK5pP2b(%p6P>)p%u;W z&=kLbu7seFP+jkE8_PkAWHT-#p7lqZJnL%)r50j zK1HnYSFC3cLv#S;*y?%rvLg*EvF{(t${uy?pIFNdNL~Y~j!ClPyyzx-3vx1~xn5(% zW$G{$L~p6V84mavL!u`n`!9j_PT1i>5DQ+DAobfv4GzwED_y;FH()f?=R?TXm zmxlNCfL0jEAic-fT&W6TJmC~&T>sf z#SzW;jJ}=gyg*!k)pH6$H@<6vU{It@icg~@R5c+WXw5QaY#?1I62*p(Nkb?dBJ|&&h2F0}$>{;#~39Z=7R-K9ZJ6$l5D0|X@ES+aU5nlczzCD;A=k+rm)I&32!oi@B zbM^QVcTzE^gcS$*jdnS#?`OM&1Y1`|T|^yiAsmt6P%Nj9 zBqWVSt0@siOU0#TrJ|zZF0qyU?SV(d&D1jNUYH$gHq_j_AdU1#wqP|Yd3>XMai6q+ zq@gY8lxZfCP5k96LVo0ckLiI@rOvyB`Q6;#nA77wCs9evcoarJfN5Jtcmup#x zG4s`&9(A6w_w|#3{@g!wu&XRyYu*_$;d4(MhQToM!gl?B+WMTaAKxwM91=L|O4}B1 zcE`-HGc~oDtT{lwEE>KF|BFz>Pj{!F_hF&L#yK0NJ93&{#2ZamCq&f>HF;7gL_~1l z1xYBCz$r|?6*O#~>f@!Ke46G+D2;uvDjS`ELgU=Bnx%O$`k>L-uC^!YP;gjQSV@zvrvzC)%DVL5+*x(IW8IRC@x)yN?{m{#weR)L%>JT6D2xrh-KXErXO=ActvAE?78XowQ zX1Ay=;%K4e(sm#9Py%Ct=E+O8`=$k?vx?-G;slOPjA&>2=l~d1z^aPG(v-lX_ArmD z6nfGNTeTN>Tpz!yH8ht)TkyX{r*K<14=B|x9&JT2DnQ(3m$=az%=R0yiK7ClM3X0R9X_#A_+X+9&N2K%pL6%(5_QKg9XoA z`hJyJer}C@@woA8npp61d9xHl5^pc>H^gLod#0Ih((DtyrmVS21}MDp%cAlHJ5)}} zT>8q4AYM1Ol3OGOx|5))4Vi(+y?NN)r`-QxT@@sWe)WY7(%adP)+{@TS(l_~-eeIgdeu2#&9901knOySaj*@Q;Z$tCTfEYz-KZC(&yZCH;gb zbfCtDzQ4TjHP$ORkRA%p%b!1;n6NH~Y8LIPFyhO6{VFzH*!jHwh2~c{{)%y!lMX-# zk^Lc!$HD}K1*D@=lh?Y78>@pT?# ztdLH73>GLpEb8le1pt1ZGoEm2!fHq4C`EkIbNxDs7R)BhK9EuBQCkt@7NZBAsqVy1 z;M)enJs#KqTS%sO1uP98ax?Jz{5?(Kn19+^M*GZCeEI?mN%YP?td2$kL$wFVso%U( zh0zYfRBav^39AwSb|aMc?0*=m7)xz+0CqhT5oK!c3(P;tG}q`m?9GK1E#3uMEfU~E zQ#DSwd%Y?zJan28&ws+vF2lzjPbNfFc$!~{QgD~)7#)KkME=Oxz_G_8|FES*GpKez zQAVrXLI6H>DH6cw`H((tPvj|CM%~Z%u4pHwi6@(yLVI9i)SR0Rjk81r&(_O7AEjAT2?9 zRZ0LM5UNV(pwbgint~uA^&%yLbhxxoli%Fu{S)5#GV|rkGkfNoz1Kc_&Dw19Re-d{ zNg9uSS#0AuBikI&3gVDJtrB93Iq3fD(cBr%Y8rb^h6rr9#9zp+I{WJHBU^%d@J zIa}cVzwlY6N4KnO*-xa|P)553-)z#evFObKDG)nIw<92 zX#9_3$r}Ko=n*V9&L$9plZ_AlT5n$875>O>Zs9OF|4fkZyH`CXr%Xilb0l=Y@0Df6 zq2ol=jj_Coy7G~m6=lM`=&mCBCZwP$HmlqITG4SV7FYa(ogqPI{%7E#sOJ1my5>C^0^cEseg4DQ>D`dL%3ug4 zGp|<}WSF#J$V)J_HbRQVPk)$pzCfuyqP2^^d=0z|kn5*2f_;0E|;RLH@`-ML(#2P)uPHs@ij0qAXkzJGUqc&La`$SS&hJ!u^q z4jyvVIkJe42l^9}2n0_tk$7?|-C1t&VZ8L4

Bc(iSWsSLyK8Y~5i4udLEH7Db8$37|4qeTP?8=gh|0gD%I^mCHAoI4#8csGdujgk|eH)3R~$*lA~B z;HdFS$V{8b(PL$|P>mjnritaEBTF9rhz&ck=Z1_YLo86OFm?MaiFQ5b5y&yW#K!5% z2j<|kuvo5~C|!PsPRSkoLW%F%c)yg3)!<+SV;~Y@Z$!W1@RVTYbIKI(GvG+# zvKBc?Eddyx_$igFV3o{*m3#%Y8^3sNM1VbWbgATC=JBupvXcuXOY4=`yl$G@G(jQl zK_)1#q&=5}YJt*6(Wn+~M(fz^*N>RPw}iI4 z#lzENUgrOzy1wIJ>zOdt8nkTK0bM>Mk-lXUL~Cm3i~59iKS@9mo;f^?fPzg-h2`x_;k3UJL{BD93?fNl?46(YWd{1S6Yq3 zSyY1M00q$pN&2(*^AgSk|Eh#_^6n(Jzqxk-+Vcl}j!?2t+@k=^ zUxZFQ_cVd0*nM%;d~}2^EP)t1l6|7y);t-}b1!MyQUJ+9wRyDp3oN*EEz|c~(|w|P z82U1$LpSi^r589Ll6~32NipAa_dv}~?wCuMr-7C?uFoMinxXqeCbQs`jjlW0Rfm|? z4_p@;TpsT5O3JW!X5ZrR)6Y;x%F(nFvOt|q z3w4$`dkc{8KWAnR)Vs~0{4N4%pRKcwLj22Aw?UOS&~HOH<+3JZ&rI+@bYZIOfP3=b z=t!F>$n<;&Zx1?u*uIN4JSh@BY<4$Hn}1$jy4Gj*y*)im%sVFS!ULgw3Gs)-=Qn#(YxROJ4O!@qRL_6Wqj z_{jzD4B2svPL;NU%7z|>>_TB47@W`t%~?RBVv;qa)oU$8Xt!s$1ukYO&{Z}hWh0c6 zp|`}Ha$#L8h8z{Qg4C{r*l4~K6g!^u7ffWo^*vCKr!!)m*I9y$7i8-ZC(YyCHFSGz zj_G!9TGGQn(vR#MS{1Wh`)m7WXJ#B8)79k!(H56jAH#PSMq#jS-2T&aD>9^tbS=7m zYxJrD#X~B`bd>YIxL5_EZe9|fHWy(rCU;?`!14-w0lCB}N0;FpIx1yZrU9!3mkYYH z``LIW8%j&-d{pwhBLdx&St_x&~zI3z9d8%y+6JBs6M;q_)RL8GBkyF%hG4ctww**3bV<11#s~D3K}7@|RQLJDraFyqkz# z^Du$8R2msN<-K*upw|mFV5naf$#*Vg!9BSwx9Xz8bA~iAp<461CbLhe0q3?2#0Rj<$@$KKP4Ae*?$6Zb6xgj74>0*W4 zv@IdG(ougo)ek>1U@^>_*#Z?Y zJw}x;HBvJ@#yy~BhAtUt0VlZluIen91^M|OhH`oYmT2gZF57Rbgnr8 zm^Ta|5jvb#<70cm+h8IbBBEaQx9)7Ts47Opi!phh}}*6pfYB5 zYJ^ykv@>$pEREU*-Z+Rfk>)P3vAu1s>*KXH7Pcf4igBIpXZ74f3>o#^uxLXw8d?Qa zO{h+?yo=3YL)i@(m%ST<&EX)XsmBQ(Rr3jBXSk{-TY%1IV}}L6&rks70^5}mH-#ja zQUARM-s1@w1e_gY+u6M#OGY|~KUzNcz0fG5uXfhKhJQU1cKeK}nhH8`;zx{l@+D&= zE%0h3xxK`nN=Ln_x~-;E%REC0#9s$f%go3?2HD7Cp&jU9L%-^(ulz>h;X1@>lG03% zckA9g@S4-fr`D>k+d;zdCe~}r1PFYtpum&9Hm@;LRWeyIJ<{8*^f+*ZBoNd0=L^Z^ z1*|!iaD4$aT}Swpw8JIV==2K^erKJn<4@ic$6BtstZhoYhbA)g6s~J`c6PpnF>bt7 zpPDL$!WS0@RAT*E5@^kb+naB+@2G zbhuoUrR*OBONvxGGxzCmIX=E-$LaJsZ=6 z&v)Kx^&D0Tq`GEn5NTEjr@<3qW*u@iPpwHngoSLCq6E4v5n$9dCsyM=UkieT|`(e*l(Qr^Yig- z0UBjYp*R|;#I*0CS~$o;X0oNCUWw~Bv@KEEk}oA+fF?uffqAIn%8ycW>+6*Ho`&_E zyYIVhN`Aik4?CDC5vc0HPL#CkaPy-oe=wKB=1NCiVvr4Htj41>Wojn}K;MRYFZ@|VSYEwh9c{HQBcJVRJ<?dl9E%e&rQXic}dgS#zGU##X;vKTcAPdo}p7?8h3E8tn9y`AEz6K zq^K!*p6N$N2j!yFN9FaC&(Uhtr`Z3?pOOE+6HFI+9=#>?SYc{5jvE9V#s=o_T0N(j F{{iE1lW_n5 diff --git a/platform/ui/src/__docs__/assets/npm.png b/platform/ui/src/__docs__/assets/npm.png deleted file mode 100644 index 4fbd0761bb4ce0ba53aa2fafbd91062d86d6ee0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9156 zcmeI2`9GB3-^a&9NEwkxqCP@puTZv8D$7VJOFmhX)L4cvS!YO+2rZUuQ`xd_*=86b z<|CgmWgBKPmcd}`V~k~R&u4u9fcx>d@9+2VxF2^vUDvtJoYy(mxz6i(z2E1W7)uM| z1N)@*0RVslrY2Wz0RTYGDG(sAmvdMN?A_oTc-=2uzXSkOBnYux_y7R85YsD{tO9xF z$mE2Rwqbyg+dcYpyD~d+GwGS8poHtZq{y16ZY+cU_|>2evCCt!hL`mwPIN$I{`hwL z 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 diff --git a/platform/ui/src/__docs__/assets/react.png b/platform/ui/src/__docs__/assets/react.png deleted file mode 100644 index e307be8227202b5a9dbf512c8161234e107bf610..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61998 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 byI&E+Vs7EVtzD`B*iT7L{rwLa%kcjKfY(^{ diff --git a/platform/ui/src/__docs__/assets/typescript.png b/platform/ui/src/__docs__/assets/typescript.png deleted file mode 100644 index 69a60783dd744a336062762ce24dc74723587abe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18302 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 diff --git a/platform/ui/src/__docs__/compatibility.mdx b/platform/ui/src/__docs__/compatibility.mdx deleted file mode 100644 index fd6b842c7..000000000 --- a/platform/ui/src/__docs__/compatibility.mdx +++ /dev/null @@ -1,15 +0,0 @@ ---- -name: Compatibility -route: /compatibility ---- - -# Compatibility - -## Browser Support - -`@ohif/ui` relies on -[browsers supported by Styled Components](https://www.styled-components.com/docs/faqs#which-browsers-are-supported) -or browsers supported by emotion. - -Supported Browsers: IE11, IE 9+ (with Map + Set polyfills), Chrome, Firefox (and -derivatives), Edge, and Safari. diff --git a/platform/ui/src/__docs__/config/Wrapper.js b/platform/ui/src/__docs__/config/Wrapper.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/platform/ui/src/__docs__/docs-settings.mdx b/platform/ui/src/__docs__/docs-settings.mdx deleted file mode 100644 index 200133a85..000000000 --- a/platform/ui/src/__docs__/docs-settings.mdx +++ /dev/null @@ -1,13 +0,0 @@ ---- -name: Docs Settings -route: /docs-settings ---- - -import LanguageSwitcher from '../components/languageSwitcher'; - -# Components Language - -You can change the language of the components displayed in this documentation by -choosing an option in the selector below: - - diff --git a/platform/ui/src/__docs__/getting-started.mdx b/platform/ui/src/__docs__/getting-started.mdx deleted file mode 100644 index eea8c528d..000000000 --- a/platform/ui/src/__docs__/getting-started.mdx +++ /dev/null @@ -1,76 +0,0 @@ ---- -name: Getting Started -route: /getting-started ---- - -# Getting Started - -## Installation - -> This component library is pre- v1.0. All realeases until a v1.0 have the -> possibility of introducing breaking changes. Please depend on an "exact" -> version in your projects to prevent issues caused by loose versioning. - -Install `@ohif/ui` from npm: - -```shell -// with npm -npm i @ohif/ui --save-exact - -// with yarn -yarn add @ohif/ui --exact -``` - -## Usage - -There is some setup required for `@ohif/ui`. We are working to eliminate these -requirements with the goal of providing ready to use components. - -### External Dependencies - -We have tried to keep the number of external dependencies limited to make setup -as easy as possible. You will, however, need to include either the default font -or the font you set for your theme: - -```js -// Google Fonts, Roboto -'https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700&display=swap'; -``` - -`@ohif/ui` also looks for theme CSS variabled defined on `:root`. You can find a -list of variables [on the theming page](/styling-and-theming) - -### Import & Use - -You can use components in your React app: - -```js -import React, { Component } from 'react'; -import { LayoutButton } from '@ohif/ui'; - -class Example extends Component { - constructor(props) { - super(props); - - this.state = { - selectedCell: { - className: 'hover', - col: 1, - row: 1, - }, - }; - } - - render() { - return ( - this.setState({ selectedCell: cell })} - /> - ); - } -} -``` - -> NOTE: It is heavily recommended that you use a CSS reset or normalize. As well -> as the following style: `* { Box-sizing: Border-box }` diff --git a/platform/ui/src/__docs__/index.html b/platform/ui/src/__docs__/index.html deleted file mode 100644 index 7920139aa..000000000 --- a/platform/ui/src/__docs__/index.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - - - {{ title }} - - - - - - - {{ head }} - - - -

- {{ footer }} - - - diff --git a/platform/ui/src/__docs__/introduction.mdx b/platform/ui/src/__docs__/introduction.mdx deleted file mode 100644 index 061928b0a..000000000 --- a/platform/ui/src/__docs__/introduction.mdx +++ /dev/null @@ -1,76 +0,0 @@ ---- -name: Introduction -route: / ---- - -import { Playground, Props } from 'docz'; -import { State } from 'react-powerplug'; -import { TableList, TableListItem } from './../index.js'; - -# Introduction - -**@ohif/ui is a collection of components and utilities** that power OHIF's -[zero-footprint DICOM viewer](https://github.com/OHIF/Viewers) -([demo][demo-url]). We maintain them as a separate component library to: - -- Decouple presentation from business logic -- Test and develop components in isolation -- Provide well documented, reusable components -- Aid rapid application development for context specific viewers - -## Quick Example - -> This component library is pre- v1.0. All realeases until a v1.0 have the -> possibility of introducing breaking changes. Please depend on an "exact" -> version in your projects to prevent issues caused by loose versioning. - -```js -// Add '@ohif/ui' as a dependency -yarn add @ohif/ui - -// Import and use components -import { TableList } from '@ohif/ui' -``` - - - - {({ state, setState }) => ( - - {state.listItems.map((item, index) => { - return ( - alert('item clicked')} - > - - - ); - })} - - )} - - - -## FAQ - -... - - - - -[demo-url]: https://docs.ohif.org/demo/ - diff --git a/platform/ui/src/__docs__/styling-and-theming.mdx b/platform/ui/src/__docs__/styling-and-theming.mdx deleted file mode 100644 index ce98dcde0..000000000 --- a/platform/ui/src/__docs__/styling-and-theming.mdx +++ /dev/null @@ -1,56 +0,0 @@ ---- -name: Styling & Theming -route: /styling-and-theming ---- - -# Styling & Theming - -```css -:root { - /* Interface UI Colors */ - --default-color: #9ccef9; - --hover-color: #ffffff; - --active-color: #20a5d6; - --ui-border-color: #44626f; - --ui-border-color-dark: #3c5d80; - --ui-border-color-active: #00a4d9; - --primary-background-color: #000000; - --box-background-color: #3e5975; - - --text-primary-color: #ffffff; - --text-secondary-color: #91b9cd; - --input-background-color: #2c363f; - --input-placeholder-color: #d3d3d3; - - --table-hover-color: #2c363f; - --table-text-primary-color: #ffffff; - --table-text-secondary-color: #91b9cd; - - --large-numbers-color: #6fbde2; - - --state-error: #ffcccc; - --state-error-border: #ffcccc; - --state-error-text: #ffcccc; - - /* Common palette */ - --ui-yellow: #e29e4a; - --ui-sky-blue: #6fbde2; - - /* State palette */ - --ui-state-error: #ffcccc; - --ui-state-error-border: #993333; - --ui-state-error-text: #661111; - --ui-gray-lighter: #436270; - --ui-gray-light: #516873; - --ui-gray: #263340; - --ui-gray-dark: #16202b; - --ui-gray-darker: #151a1f; - --ui-gray-darkest: #14202a; - - --calendar-day-color: #d3d3d3; - --calendar-day-border-color: #d3d3d3; - --calendar-day-active-hover-background-color: #516873; - --calendar-main-color: #263340; - --viewport-border-thickness: 1px; -} -``` diff --git a/platform/ui/src/__docs__/translating.mdx b/platform/ui/src/__docs__/translating.mdx deleted file mode 100644 index 194ad0c80..000000000 --- a/platform/ui/src/__docs__/translating.mdx +++ /dev/null @@ -1,87 +0,0 @@ ---- -name: Translating -route: /translating ---- - -# Translating - -**React Viewerbase** supports internationalization using -[i18next](https://www.i18next.com/) through the npm package -[@ohif/i18n](https://www.npmjs.com/package/@ohif/i18n), where is the main -instance of i18n containing several languages and tools. - -## How to translate components - -All you need is to use the internal custom superset of -[withTranslation HOC](https://react.i18next.com/latest/withtranslation-hoc), -available at `src/utils/LanguageProvider.js` - -e.g.: - -```js -import React from 'react'; -import { withTranslation } from '../utils/LanguageProvider.js'; - -function MyComponent({ t }) { - return

{t('my translated text')}

; -} - -export default withTranslation('MyNameSpace')(MyComponent); -``` - ---- - -## Namespaces - -For further information about namespaces and how they work, please visit -[OHIF Namespaces docs](https://docs.ohif.org/viewer/internationalization.html#namespaces). - -### How to get right the Namespace of a `@ohif/ui` component? - -Check the component's page in this site, the Namespace information should be on -the bottom line. - -Also, a nameSpace is defined when exporting a component, this information can be -found on exports trough the code, in case of missing in docs. - -E.g. - -``` -export default withTranslation('TheNamespaceYouAreLookingFor')(TheComponentYouWantToUse); -``` - -### How to use another Namespace inside the current Namespace? - -i18next provides a parsing feature able to get translations strings from any -Namespace, like this following example getting data from `InnerSpace` Namespace: - -``` -$t(InnerSpace:Reset) -export default withTranslation('OuterSpace')(TheComponent); -``` - ---- - -## I18next Provider - -**@ohif/ui** pass down the `t` function trough the custom -[withTranslation HOC](https://github.com/OHIF/Viewers/blob/master/platform/ui/src/utils/LanguageProvider.js). - ---- - -## Extending and Overriding languages - -[How to Extend languages with @ohif/i18n](https://docs.ohif.org/viewer/internationalization.html#extending-languages-in-ohifi18n) - -## Changing the language - -The language choosing method is the same implemented in -[OHIF Viewers](https://docs.ohif.org/viewer/internationalization.html#changing-the-language) - -> You can also change the language of the components displayed in this -> documentation by choosing an option in the -> [Docs Settings](https://react.ohif.org/docs-settings) section. - -## Debugging translations - -[How to Debug @ohif/i18n](https://docs.ohif.org/viewer/internationalization.html#debugging-translations) diff --git a/platform/ui/src/__docs__/wrapper.js b/platform/ui/src/__docs__/wrapper.js deleted file mode 100644 index 0e94c5559..000000000 --- a/platform/ui/src/__docs__/wrapper.js +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react'; - -import PropTypes from 'prop-types'; -import LanguageSwitcher from '../components/languageSwitcher'; - -import './wrapper.styl'; - -const Wrapper = ({ children }) => ( - -
- Display components in: - -
- {children} -
-); - -Wrapper.propTypes = { - children: PropTypes.node.isRequired, -}; - -export default Wrapper; diff --git a/platform/ui/src/__docs__/wrapper.styl b/platform/ui/src/__docs__/wrapper.styl deleted file mode 100644 index b1a4dae6d..000000000 --- a/platform/ui/src/__docs__/wrapper.styl +++ /dev/null @@ -1,15 +0,0 @@ -[class*="Sidebar__Menus"] - @media (min-width: 1120px) - margin-top: 80px - -.sidebarLanguageSwitcher - position: fixed - top: 155px - left 0 - z-index: 1049 - padding: 0 24px 20px - border-bottom: 1px dotted #CED4DE - background: #F5F6F7 - transition: all 200ms ease - @media (max-width: 1119px) - left -100% diff --git a/platform/ui/src/components/Alert.jsx b/platform/ui/src/components/Alert.jsx new file mode 100644 index 000000000..361dc16bc --- /dev/null +++ b/platform/ui/src/components/Alert.jsx @@ -0,0 +1,34 @@ +import React from 'react'; +import t from 'prop-types'; + +const kinds = { + info: '#5352ED', + positive: '#2ED573', + negative: '#FF4757', + warning: '#FFA502', +}; + +export const Alert = ({ children, kind, ...rest }) => ( +
+ {children} +
+); + +Alert.propTypes = { + /** + * The kind prop is used to set the alert's background color + */ + kind: t.oneOf(['info', 'positive', 'negative', 'warning']), +}; + +Alert.defaultProps = { + kind: 'info', +}; diff --git a/platform/ui/src/components/Alert.mdx b/platform/ui/src/components/Alert.mdx new file mode 100644 index 000000000..c0eab1417 --- /dev/null +++ b/platform/ui/src/components/Alert.mdx @@ -0,0 +1,28 @@ +--- +name: Alert +menu: Components +--- + +import { Playground, Props } from 'docz' +import { Alert } from './Alert' + +# Alert + +## Properties + + + +## Basic usage + + + Some message + + +## Using different kinds + + + Some message + Some message + Some message + Some message + diff --git a/platform/ui/src/components/Button/Button.jsx b/platform/ui/src/components/Button/Button.jsx new file mode 100644 index 000000000..391b9fbd0 --- /dev/null +++ b/platform/ui/src/components/Button/Button.jsx @@ -0,0 +1,124 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +const Button = ({ + children, + variant = defaults.variant, + color = defaults.color, + size = defaults.size, + radius = defaults.radius, + disabled = defaults.disabled, + elevation, + type = defaults.type, + startIcon: startIconProp, + endIcon: endIconProp, + className, + ...rest +}) => { + const hasIcon = startIconProp || endIconProp; + const getClasses = () => { + const classes = []; + let buttonElevation; + + if (variant === 'text') { + if (elevation) { + buttonElevation = elevation; + } else { + buttonElevation = false; + } + } else { + buttonElevation = defaults.elevation; + } + + classes.push(variantClasses[variant][color]); + classes.push(radiusClasses[radius]); + classes.push(sizeClasses[size]); + classes.push(disabledClasses[disabled]); + classes.push(elevationClasses[buttonElevation]); + classes.push(className); + + if (hasIcon) { + classes.push(baseIconClasses); + } + + return classes.join(' '); + }; + + const baseIconClasses = 'inline-flex items-center'; + const baseClasses = + 'outline-none transition duration-300 ease-in-out rounded font-bold focus:outline-none'; + + const startIcon = startIconProp && ( +
{startIconProp}
+ ); + + const endIcon = endIconProp &&
{endIconProp}
; + + return ( + + ); +}; + +const defaults = { + variant: 'outlined', + color: 'default', + size: 'medium', + radius: 'medium', + disabled: false, + elevation: true, + type: 'button', +}; + +const radiusClasses = { + small: 'rounded-sm', + medium: 'rounded-md', + large: 'rounded-lg', + full: 'rounded-full', +}; + +const disabledClasses = { + true: 'cursor-not-allowed', + false: '', +}; + +const elevationClasses = { + true: 'shadow', + false: 'shadow-none', +}; + +const variantClasses = { + text: { + default: 'hover:bg-gray-200 text-black', + primary: 'hover:bg-blue-100 text-blue-900', + secondary: 'hover:bg-blue-100 text-blue-300', + }, + outlined: { + default: 'border border-black text-black hover:bg-gray-200', + primary: 'border border-blue-900 text-blue-900 hover:bg-blue-100', + secondary: 'border border-blue-300 text-blue-300 hover:bg-blue-100', + }, + contained: { + default: 'bg-black hover:bg-gray-800 text-white', + primary: 'bg-blue-900 hover:bg-blue-800 text-white', + secondary: 'bg-blue-300 hover:bg-blue-500 text-black', + }, +}; + +const sizeClasses = { + small: 'py-1 px-2 text-sm', + medium: 'py-2 px-4 text-base', + large: 'py-3 px-6 text-lg', +}; + +Button.propTypes = { + size: PropTypes.oneOf(['small', 'medium', 'large']), + radius: PropTypes.oneOf(['small', 'medium', 'large', 'full']), + variant: PropTypes.oneOf(['text', 'outlined', 'contained']), + color: PropTypes.oneOf(['default', 'primary', 'secondary']), +}; + +export default Button; diff --git a/platform/ui/src/components/Button/Button.mdx b/platform/ui/src/components/Button/Button.mdx new file mode 100644 index 000000000..8f0e45713 --- /dev/null +++ b/platform/ui/src/components/Button/Button.mdx @@ -0,0 +1,180 @@ +--- +name: Button +menu: Components +route: components/button +--- + +import { Playground, Props } from 'docz'; +import Button from './'; + +# Button + +Buttons are used to execute actions when users interacts with them. + +## Properties + + + +## Contained Buttons + + + <> + + + + + + +## Outlined Buttons + + + <> + + + + + + +## Text Buttons + + + <> + + + + + + +## Sizes + + + <> +
+ + + +
+
+ + + +
+
+ + + +
+ + + +
+ +## Buttons with icons + + +{() => { + return ( +
+ + +
+ ) + }} + +
diff --git a/platform/ui/src/components/Button/index.js b/platform/ui/src/components/Button/index.js new file mode 100644 index 000000000..4ae846f77 --- /dev/null +++ b/platform/ui/src/components/Button/index.js @@ -0,0 +1,2 @@ +import Button from './Button'; +export default Button; diff --git a/platform/ui/src/components/Input/Input.jsx b/platform/ui/src/components/Input/Input.jsx new file mode 100644 index 000000000..d2954ef23 --- /dev/null +++ b/platform/ui/src/components/Input/Input.jsx @@ -0,0 +1,17 @@ +import React from 'react'; +import Label from '../Label'; + +const Input = ({ label, ...rest }) => { + return ( + <> + + + ); +}; + +export default Input; diff --git a/platform/ui/src/components/Input/Input.mdx b/platform/ui/src/components/Input/Input.mdx new file mode 100644 index 000000000..0124f4a6d --- /dev/null +++ b/platform/ui/src/components/Input/Input.mdx @@ -0,0 +1,30 @@ +--- +name: Input +menu: Components +route: components/input +--- + +import { Playground, Props } from 'docz'; +import Input from './'; + +# Input + +## Properties + + + +## Basic usage + + + {() => { + const [inputValue, setInputValue] = React.useState(''); + return ( + setInputValue(e.target.value)} + /> + ); + }} + diff --git a/platform/ui/src/components/Input/index.js b/platform/ui/src/components/Input/index.js new file mode 100644 index 000000000..edaf55496 --- /dev/null +++ b/platform/ui/src/components/Input/index.js @@ -0,0 +1,2 @@ +import Input from './Input'; +export default Input; diff --git a/platform/ui/src/components/Label/Label.jsx b/platform/ui/src/components/Label/Label.jsx new file mode 100644 index 000000000..7721a8b96 --- /dev/null +++ b/platform/ui/src/components/Label/Label.jsx @@ -0,0 +1,34 @@ +import React from 'react'; +import t from 'prop-types'; + +const Label = ({ children, spacing, className, text, ...rest }) => { + const baseClasses = 'block text-gray-700 text-sm font-bold'; + + const getClasses = () => { + const classes = []; + classes.push(baseClasses); + classes.push(className); + return classes.join(' '); + }; + + return ( +
+ +
+ ); +}; + +const spacing = { + small: 'mb-1', + medium: 'mb-2', + large: 'mb-3', +}; + +Label.defaultProps = {}; + +Label.prototypes = {}; + +export default Label; diff --git a/platform/ui/src/components/Label/Label.mdx b/platform/ui/src/components/Label/Label.mdx new file mode 100644 index 000000000..07664b61f --- /dev/null +++ b/platform/ui/src/components/Label/Label.mdx @@ -0,0 +1,20 @@ +--- +name: Label +menu: Components +route: components/label +--- + +import { Playground, Props } from 'docz'; +import Label from './'; + +# Label + +## Properties + + + +## Basic usage + + + diff --git a/platform/ui/src/components/Label/index.js b/platform/ui/src/components/Label/index.js new file mode 100644 index 000000000..614295c24 --- /dev/null +++ b/platform/ui/src/components/Label/index.js @@ -0,0 +1,2 @@ +import Label from './Label'; +export default Label; diff --git a/platform/ui/src/components/checkbox/__docs__/checkbox.mdx b/platform/ui/src/components/checkbox/__docs__/checkbox.mdx deleted file mode 100644 index dd74a6af5..000000000 --- a/platform/ui/src/components/checkbox/__docs__/checkbox.mdx +++ /dev/null @@ -1,42 +0,0 @@ ---- -name: Checkbox -menu: Elements -route: /components/checkbox ---- - -import { Playground, Props } from 'docz' -import { State } from 'react-powerplug' -import { Checkbox } from './../index' -import NameSpace from '../../../__docs__/NameSpace' - -# Checkbox - -## Basic usage - - - - {({ state, setState }) => ( - -
-
{JSON.stringify(state, null, 2)}
-
-
- -
-
- )} -
-
- -## API - - - -## Translation Namespace - - \ No newline at end of file diff --git a/platform/ui/src/components/checkbox/checkbox.css b/platform/ui/src/components/checkbox/checkbox.css deleted file mode 100644 index 96311b6fd..000000000 --- a/platform/ui/src/components/checkbox/checkbox.css +++ /dev/null @@ -1,56 +0,0 @@ -.ohif-check-container { - --check-button-dim: 15px; -} - -.ohif-check-container input { - position: absolute; - opacity: 0; - height: inherit; - width: inherit; - cursor: default; -} - -.ohif-check-container { - display: block; - position: relative; - padding-left: 35px; - margin-bottom: 12px; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.ohif-checkbox { - width: var(--check-button-dim); - height: var(--check-button-dim); - position: absolute; - top: 20%; - left: 5%; - cursor: pointer; - background-color: var(--ui-gray-lighter); -} - -.ohif-checkbox:hover { - background-color: var(--default-color); -} - -.ohif-checkbox:after { - content: ''; - position: absolute; - width: 70%; - height: 70%; -} - -.ohif-checkbox.ohif-checked:after { - display: block; - top: 14%; - left: 14%; - background: white; -} - -.ohif-check-label { - font-size: 12px; - font-weight: 500; -} diff --git a/platform/ui/src/components/checkbox/checkbox.js b/platform/ui/src/components/checkbox/checkbox.js deleted file mode 100644 index 0315bab02..000000000 --- a/platform/ui/src/components/checkbox/checkbox.js +++ /dev/null @@ -1,58 +0,0 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import './checkbox.css'; - -export class Checkbox extends Component { - static propTypes = { - label: PropTypes.string.isRequired, - checked: PropTypes.bool, - onChange: PropTypes.func, - }; - - constructor(props) { - super(props); - this.state = { checked: !!props.checked, label: props.label }; - } - - handleChange(e) { - const checked = e.target.checked; - this.setState({ checked }); - if (this.props.onChange) this.props.onChange(checked); - } - - componentDidUpdate(props) { - const { checked = false, label } = props; - - if (this.state.checked !== checked || this.state.label !== label) { - this.setState({ - checked, - label, - }); - } - } - - render() { - let checkbox; - if (this.state.checked) { - checkbox = ; - } else { - checkbox = ; - } - - return ( -
-
- -
-
- ); - } -} diff --git a/platform/ui/src/components/checkbox/index.js b/platform/ui/src/components/checkbox/index.js deleted file mode 100644 index 9d1514175..000000000 --- a/platform/ui/src/components/checkbox/index.js +++ /dev/null @@ -1 +0,0 @@ -export { Checkbox } from './checkbox.js'; diff --git a/platform/ui/src/components/cineDialog/CineDialog.js b/platform/ui/src/components/cineDialog/CineDialog.js deleted file mode 100644 index e64d94aa7..000000000 --- a/platform/ui/src/components/cineDialog/CineDialog.js +++ /dev/null @@ -1,197 +0,0 @@ -import './CineDialog.styl'; - -import React, { PureComponent } from 'react'; -import { withTranslation } from '../../contextProviders'; -import { Icon } from './../../elements/Icon'; -import PropTypes from 'prop-types'; - -class CineDialog extends PureComponent { - constructor(props) { - super(props); - - this.state = { - cineFrameRate: props.cineFrameRate, - isPlaying: props.isPlaying, - }; - } - - static propTypes = { - /** Minimum value for range slider */ - cineMinFrameRate: PropTypes.number.isRequired, - /** Maximum value for range slider */ - cineMaxFrameRate: PropTypes.number.isRequired, - /** Increment range slider can "step" in either direction. */ - cineStepFrameRate: PropTypes.number.isRequired, - cineFrameRate: PropTypes.number.isRequired, - /** 'True' if playing, 'False' if paused. */ - isPlaying: PropTypes.bool.isRequired, - onPlayPauseChanged: PropTypes.func, - onFrameRateChanged: PropTypes.func, - onClickNextButton: PropTypes.func, - onClickBackButton: PropTypes.func, - onClickSkipToStart: PropTypes.func, - onClickSkipToEnd: PropTypes.func, - /** i18next translation function */ - t: PropTypes.func.isRequired, - }; - - static defaultProps = { - cineMinFrameRate: 1, - cineMaxFrameRate: 90, - cineStepFrameRate: 1, - cineFrameRate: 24, - isPlaying: false, - }; - - componentDidUpdate(prevProps) { - // TODO: Not sure if we should just switch this to a stateless - // fully-controlled component instead - if ( - this.props.isPlaying !== prevProps.isPlaying || - this.props.isPlaying !== this.state.isPlaying - ) { - this.setState({ - isPlaying: this.props.isPlaying, - }); - } - - if ( - this.props.cineFrameRate !== prevProps.cineFrameRate || - this.props.cineFrameRate !== this.state.cineFrameRate - ) { - this.setState({ - cineFrameRate: this.props.cineFrameRate, - }); - } - } - - handleInputChange = event => { - const target = event.target; - - let value = target.value; - - if (target.type === 'range') { - value = parseFloat(target.value); - } - - const name = target.name; - - this.setState({ - [name]: value, - }); - - if (name === 'cineFrameRate' && this.props.onFrameRateChanged) { - this.props.onFrameRateChanged(parseFloat(value)); - } - }; - - onClickPlayPause = () => { - const value = !this.state.isPlaying; - - this.setState({ - isPlaying: value, - }); - - if (this.props.onPlayPauseChanged) { - this.props.onPlayPauseChanged(value); - } - }; - - onClickNextButton = event => { - if (this.props.onClickNextButton) { - this.props.onClickNextButton(event); - } - }; - - onClickBackButton = event => { - if (this.props.onClickBackButton) { - this.props.onClickBackButton(event); - } - }; - - onClickSkipToStart = event => { - if (this.props.onClickSkipToStart) { - this.props.onClickSkipToStart(event); - } - }; - - onClickSkipToEnd = event => { - if (this.props.onClickSkipToEnd) { - this.props.onClickSkipToEnd(event); - } - }; - - render() { - const { t } = this.props; - return ( -
-
-
-
- - - - - -
-
-
-
- -
- - {this.state.cineFrameRate.toFixed(1)} {t('fps')} - -
-
-
- ); - } -} - -const connectedComponent = withTranslation('CineDialog')(CineDialog); -export { connectedComponent as CineDialog }; -export default connectedComponent; diff --git a/platform/ui/src/components/cineDialog/CineDialog.styl b/platform/ui/src/components/cineDialog/CineDialog.styl deleted file mode 100644 index 67b59cff3..000000000 --- a/platform/ui/src/components/cineDialog/CineDialog.styl +++ /dev/null @@ -1,172 +0,0 @@ -@import './../../design/styles/common/global.styl' -@import './../../design/styles/common/form.styl' - -.CineDialog - background: var(--ui-gray-darkest); - color: var(--text-secondary-color); - filter: drop-shadow(0 0 3px var(--ui-gray-darkest)) - border: none - border-radius: 8px - width: inherit; - - h5 - font-size: 20px - line-height: 35px - margin: 0 - - h5, label - font-weight: 400 - - .cine-navigation, .cine-controls, .cine-options - cursor: default - - .fps-section - input[type="range"] - background-color: transparent - border: 0 none - outline: 0 none - - &::-ms-tooltip - display: none - - .double-row-style - box-sizing: border-box - width: 290px - height: 70px - padding: 10px - top: 2% - left: 35% - - .cine-navigation - position: absolute - right: 16px - top: 10px - - .btn - padding: 0 4px - - i - font-size: 32px - line-height: 32px - - .cine-controls - left: 0px - - .cine-options - padding: 0px 0 - - .fps-section - width: 175px - float: left - - .fps - float: right - - - .single-row-style - box-sizing: content-box - width: 425px - height: 45px - padding: 4px 8px - top: 2% - left: 35% - - .cine-navigation - float: right - overflow: hidden - padding-right: 12px - position: relative - - .btn - padding: 0 2px - margin: 0 0 0 2px - border: 0 none - &:first-of-type - margin-left: 0 - - i - font-size: 32px - line-height: 45px - - .cine-controls - position: relative - float: left - overflow: hidden - - .btn - font-size: 22px - line-height: 45px - min-width: 28px - padding: 0 0px - margin: 0 4px - border: 0 none - - .cine-options - display: block - position: relative - width: 150px - float: left - overflow: hidden - padding: 0 - margin: 0 0 0 10px - - .fps-section - display: block - float: left - width: 80px - input[type="range"] - line-height: 45px - height: 45px - - .fps - display: block - width: 68px - float: left - padding: 0 - margin: 0 0 0 2px - text-align: center - line-height: 45px - font-size: 14px; - line-height: 1.42857143; - - .btn - color: var(--text-secondary-color); - background-color: transparent - border: 0 - border-radius: 4px - font-size: 15px - width: 45px - font-weight: normal - height: 37px - line-height: 37px - padding: 0 12px - - &:hover, &:active, &.active - color: var(--hover-color); - - &[disabled] - &:hover - color: inherit - &:active - color: var(--text-secondary-color); - - &.btn-primary, &.btn-secondary, &.btn-danger - transition: background-color 0.3s ease - - &:hover, &:active, &:focus - opacity: 0.8 - - &.btn-primary - background-color: var(--active-color); - color: var(--primary-background-color) - - &.btn-secondary - background-color: var(--text-secondary-color); - color: var(--primary-background-color) - - &.btn-danger - background-color: var(--text-destructive-color); - color: var(--text-primary-color); - - &.active - box-shadow: inset 1px 1px 2px var(--ui-gray-darkest) diff --git a/platform/ui/src/components/cineDialog/__docs__/cineDialog.mdx b/platform/ui/src/components/cineDialog/__docs__/cineDialog.mdx deleted file mode 100644 index 48ecfa0fd..000000000 --- a/platform/ui/src/components/cineDialog/__docs__/cineDialog.mdx +++ /dev/null @@ -1,57 +0,0 @@ ---- -name: CINE Dialog -menu: Components -route: /components/cine-dialog ---- - -import { Playground, Props } from 'docz' -import { State } from 'react-powerplug' -import { CineDialog } from './../index' -import NameSpace from '../../../__docs__/NameSpace' - -# CINE Dialog - -## Basic usage - - - - {({ state, setState }) => ( - -
-
{JSON.stringify(state, null, 2)}
-
-
- - setState({ lastChange: 'Clicked SkipToStart' }) - } - onClickSkipToEnd={() => - setState({ lastChange: 'Clicked SkipToEnd' }) - } - onClickNextButton={() => setState({ lastChange: 'Clicked Next' })} - onClickBackButton={() => setState({ lastChange: 'Clicked Back' })} - onLoopChanged={value => setState({ isLoopEnabled: value })} - onFrameRateChanged={value => setState({ cineFrameRate: value })} - onPlayPauseChanged={() => setState({ isPlaying: !state.isPlaying })} - /> -
-
- )} -
-
- -## API - - - -## Translation Namespace - - diff --git a/platform/ui/src/components/cineDialog/index.js b/platform/ui/src/components/cineDialog/index.js deleted file mode 100644 index 5827ce588..000000000 --- a/platform/ui/src/components/cineDialog/index.js +++ /dev/null @@ -1,2 +0,0 @@ -import CineDialog from './CineDialog'; -export { CineDialog }; diff --git a/platform/ui/src/components/content/aboutContent/AboutContent.js b/platform/ui/src/components/content/aboutContent/AboutContent.js deleted file mode 100644 index 9f38e8974..000000000 --- a/platform/ui/src/components/content/aboutContent/AboutContent.js +++ /dev/null @@ -1,107 +0,0 @@ -import React from 'react'; -import detect from 'browser-detect'; -import { useTranslation } from 'react-i18next'; - -import './AboutContent.styl'; - -const AboutContent = () => { - const { t } = useTranslation('AboutContent'); - - const { os, version, name } = detect(); - const capitalize = s => - s.substr(0, 1).toUpperCase() + s.substr(1).toLowerCase(); - - const itemsPreset = () => { - return [ - { - name: t('Repository URL'), - value: 'https://github.com/OHIF/Viewers/', - link: 'https://github.com/OHIF/Viewers/', - }, - { - name: t('Latest Master Commits'), - value: 'https://github.com/OHIF/Viewers/commits/master', - link: 'https://github.com/OHIF/Viewers/commits/master', - }, - { - name: 'Version Number', - value: process.env.VERSION_NUMBER, - }, - { - name: t('Build Number'), - value: process.env.BUILD_NUM, - }, - { - name: t('Browser'), - value: `${capitalize(name)} ${version}`, - }, - { - name: t('OS'), - value: os, - }, - ]; - }; - - const renderTableRow = ({ name, value, link }) => ( - - {name} - - {link ? ( -
- {value} - - ) : ( - value - )} - - - ); - - return ( -
- -
-

{t('Version Information')}

- - - - - - - - {itemsPreset().map(item => renderTableRow(item))} -
{t('Name')}{t('Value')}
-
-
- ); -}; - -export { AboutContent }; -export default AboutContent; diff --git a/platform/ui/src/components/content/aboutContent/AboutContent.styl b/platform/ui/src/components/content/aboutContent/AboutContent.styl deleted file mode 100644 index 08d7ff6a9..000000000 --- a/platform/ui/src/components/content/aboutContent/AboutContent.styl +++ /dev/null @@ -1,20 +0,0 @@ -@import '../../../design/styles/common/button.styl' -@import '../../../design/styles/common/table.styl' - -.AboutContent - .btn - border-color: #ccc; - - .table - thead:first-child - tr:first-child - th, td - border-top: 0; - - thead, tbody, tfoot - tr - th, td - padding: 8px; - line-height: 1.42857143; - vertical-align: top; - border-top: 1px solid #ddd; diff --git a/platform/ui/src/components/content/viewportDownloadForm/ViewportDownloadForm.js b/platform/ui/src/components/content/viewportDownloadForm/ViewportDownloadForm.js deleted file mode 100644 index 367d66243..000000000 --- a/platform/ui/src/components/content/viewportDownloadForm/ViewportDownloadForm.js +++ /dev/null @@ -1,431 +0,0 @@ -import React, { - useRef, - useCallback, - useEffect, - useState, - createRef, -} from 'react'; -import PropTypes from 'prop-types'; -import { useTranslation } from 'react-i18next'; - -import './ViewportDownloadForm.styl'; -import { TextInput, Select, Icon } from '@ohif/ui'; -import classnames from 'classnames'; - -const FILE_TYPE_OPTIONS = [ - { - key: 'jpg', - value: 'jpg', - }, - { - key: 'png', - value: 'png', - }, -]; - -const DEFAULT_FILENAME = 'image'; -const REFRESH_VIEWPORT_TIMEOUT = 1000; - -const ViewportDownloadForm = ({ - activeViewport, - onClose, - updateViewportPreview, - enableViewport, - disableViewport, - toggleAnnotations, - loadImage, - downloadBlob, - defaultSize, - minimumSize, - maximumSize, - canvasClass, -}) => { - const [t] = useTranslation('ViewportDownloadForm'); - - const [filename, setFilename] = useState(DEFAULT_FILENAME); - const [fileType, setFileType] = useState('jpg'); - - const [dimensions, setDimensions] = useState({ - width: defaultSize, - height: defaultSize, - }); - - const [showAnnotations, setShowAnnotations] = useState(true); - - const [keepAspect, setKeepAspect] = useState(true); - const [aspectMultiplier, setAspectMultiplier] = useState({ - width: 1, - height: 1, - }); - - const [viewportElement, setViewportElement] = useState(); - const [viewportElementDimensions, setViewportElementDimensions] = useState({ - width: defaultSize, - height: defaultSize, - }); - - const [downloadCanvas, setDownloadCanvas] = useState({ - ref: createRef(), - width: defaultSize, - height: defaultSize, - }); - - const [viewportPreview, setViewportPreview] = useState({ - src: null, - width: defaultSize, - height: defaultSize, - }); - - const [error, setError] = useState({ - width: false, - height: false, - filename: false, - }); - - const hasError = Object.values(error).includes(true); - - const refreshViewport = useRef(null); - - const downloadImage = () => { - downloadBlob( - filename || DEFAULT_FILENAME, - fileType, - viewportElement, - downloadCanvas.ref.current - ); - }; - - /** - * @param {object} event - Input change event - * @param {string} dimension - "height" | "width" - */ - const onDimensionsChange = (event, dimension) => { - const oppositeDimension = dimension === 'height' ? 'width' : 'height'; - const sanitizedTargetValue = event.target.value.replace(/\D/, ''); - const isEmpty = sanitizedTargetValue === ''; - const newDimensions = { ...dimensions }; - const updatedDimension = isEmpty - ? '' - : Math.min(sanitizedTargetValue, maximumSize); - - if (updatedDimension === dimensions[dimension]) { - return; - } - - newDimensions[dimension] = updatedDimension; - - if (keepAspect && newDimensions[oppositeDimension] !== '') { - newDimensions[oppositeDimension] = Math.round( - newDimensions[dimension] * aspectMultiplier[oppositeDimension] - ); - } - - // In current code, keepAspect is always `true` - // And we always start w/ a square width/height - setDimensions(newDimensions); - - // Only update if value is non-empty - if (!isEmpty) { - setViewportElementDimensions(newDimensions); - setDownloadCanvas(state => ({ - ...state, - ...newDimensions, - })); - } - }; - - const error_messages = { - width: t('minWidthError'), - height: t('minHeightError'), - filename: t('emptyFilenameError'), - }; - - const renderErrorHandler = errorType => { - if (!error[errorType]) { - return null; - } - - return
{error_messages[errorType]}
; - }; - - const onKeepAspectToggle = () => { - const { width, height } = dimensions; - const aspectMultiplier = { ...aspectMultiplier }; - if (!keepAspect) { - const base = Math.min(width, height); - aspectMultiplier.width = width / base; - aspectMultiplier.height = height / base; - setAspectMultiplier(aspectMultiplier); - } - - setKeepAspect(!keepAspect); - }; - - const validSize = value => (value >= minimumSize ? value : minimumSize); - const loadAndUpdateViewports = useCallback(async () => { - const { width: scaledWidth, height: scaledHeight } = await loadImage( - activeViewport, - viewportElement, - dimensions.width, - dimensions.height - ); - - toggleAnnotations(showAnnotations, viewportElement); - - const scaledDimensions = { - height: validSize(scaledHeight), - width: validSize(scaledWidth), - }; - - setViewportElementDimensions(scaledDimensions); - setDownloadCanvas(state => ({ - ...state, - ...scaledDimensions, - })); - - const { - dataUrl, - width: viewportElementWidth, - height: viewportElementHeight, - } = await updateViewportPreview( - viewportElement, - downloadCanvas.ref.current, - fileType - ); - - setViewportPreview(state => ({ - ...state, - src: dataUrl, - width: validSize(viewportElementWidth), - height: validSize(viewportElementHeight), - })); - }, [ - activeViewport, - viewportElement, - showAnnotations, - loadImage, - toggleAnnotations, - updateViewportPreview, - fileType, - downloadCanvas.ref, - minimumSize, - maximumSize, - viewportElementDimensions, - ]); - - useEffect(() => { - enableViewport(viewportElement); - - return () => { - disableViewport(viewportElement); - }; - }, [disableViewport, enableViewport, viewportElement]); - - useEffect(() => { - if (refreshViewport.current !== null) { - clearTimeout(refreshViewport.current); - } - - refreshViewport.current = setTimeout(() => { - refreshViewport.current = null; - loadAndUpdateViewports(); - }, REFRESH_VIEWPORT_TIMEOUT); - }, [ - activeViewport, - viewportElement, - showAnnotations, - dimensions, - loadImage, - toggleAnnotations, - updateViewportPreview, - fileType, - downloadCanvas.ref, - minimumSize, - maximumSize, - ]); - - useEffect(() => { - const { width, height } = dimensions; - const hasError = { - width: width < minimumSize, - height: height < minimumSize, - filename: !filename, - }; - - setError({ ...hasError }); - }, [dimensions, filename, minimumSize]); - - return ( -
-
{t('formTitle')}
- -
-
-
-
- onDimensionsChange(evt, 'width')} - data-cy="image-width" - /> - {renderErrorHandler('width')} -
-
- onDimensionsChange(evt, 'height')} - data-cy="image-height" - /> - {renderErrorHandler('height')} -
-
-
- -
-
- -
-
- setFilename(event.target.value)} - label={t('filename')} - id="file-name" - /> - {renderErrorHandler('filename')} -
-
- setShowAnnotations(event.target.checked)} - /> - {t('showAnnotations')} - -
-
-
- -
setViewportElement(ref)} - > - -
- - {viewportPreview.src ? ( -
-
{t('imagePreview')}
- {t('imagePreview')} -
- ) : ( -
- - {t('loadingPreview')} -
- )} - -
-
- -
-
- -
-
-
- ); -}; - -ViewportDownloadForm.propTypes = { - onClose: PropTypes.func.isRequired, - activeViewport: PropTypes.object, - updateViewportPreview: PropTypes.func.isRequired, - enableViewport: PropTypes.func.isRequired, - disableViewport: PropTypes.func.isRequired, - toggleAnnotations: PropTypes.func.isRequired, - loadImage: PropTypes.func.isRequired, - downloadBlob: PropTypes.func.isRequired, - /** A default width & height, between the minimum and maximum size */ - defaultSize: PropTypes.number.isRequired, - minimumSize: PropTypes.number.isRequired, - maximumSize: PropTypes.number.isRequired, - canvasClass: PropTypes.string.isRequired, -}; - -export default ViewportDownloadForm; diff --git a/platform/ui/src/components/content/viewportDownloadForm/ViewportDownloadForm.styl b/platform/ui/src/components/content/viewportDownloadForm/ViewportDownloadForm.styl deleted file mode 100644 index 1ec488623..000000000 --- a/platform/ui/src/components/content/viewportDownloadForm/ViewportDownloadForm.styl +++ /dev/null @@ -1,140 +0,0 @@ -@import '../../../design/styles/common/global.styl' -@import '../../../design/styles/common/form.styl' -@import '../../../design/styles/common/button.styl' - -.ViewportDownloadForm - display: flex; - flex-direction: column; - z-index: 1080 !important; - - input, select - max-height: 30px; - - #keep-aspect svg - margin-top: 3px; - - .title - margin: 0; - font-weight: bold; - - .file-info-container - display: flex; - flex-direction: row; - justify-content: space-around; - margin: 20px 0; - border-radius: 5px; - padding: 20px 10px; - background-color: var(--ui-gray-dark); - - @media screen and (max-width: 1023px) - flex-direction: column; - align-items: flex-start; - - .width, - .height, - .file-name, - .file-type - height: 56px; - - .input-ohif - margin: 0 5px; - - .file-name, - .file-type - .select-ohif, .input-ohif - width: 170px; - - .input-ohif-label, .select-ohif-label - width: 90px; - display: inline-block; - @media screen and (max-width: 1023px) - width: 120px; - - .dimension-wrapper - display: flex; - flex-direction: row; - - .dimensions - display: flex; - flex-direction: column; - - .input-ohif-label - width: 120px; - display: inline-block; - - .input-ohif - @media screen and (max-width: 1023px) - width: 170px; - - .keep-aspect-wrapper - display: flex; - justify-content: center; - align-items: center; - padding: 0 10px; - height: 86px; - - .show-annotations - font-weight: bold; - line-height: 30px; - input - margin-right: 7px; - vertical-align: middle; - label - display: flex; - justify-content: center; - align-items: center; - - .loading-image - height: 580px; - display: flex; - justify-content: center; - align-items: center; - color: var(--active-color); - font-size: 20px; - - .icon-spin - margin-right: 15px; - - .preview - display: flex; - flex-direction: column; - background-color: var(--ui-gray-dark); - padding: 10px; - border-radius: 5px; - justify-content: flex-start; - align-items: center; - height: 580px; - - .viewport-preview - max-height: 512px; - max-width: 512px; - - .preview-header - width: 100%; - text-align center; - font-size: 1.3em; - margin: 0 0 10px; - - .actions - display: flex; - flex-wrap: nowrap; - justify-content: flex-end; - align-items: center; - margin-top: 20px; - - .btn - margin: 0 10px; - - .input-error - font-size: 12px; - color: red; - text-align: center; - margin: 3px 0; - - -.modal-dialog - height: 100%; - - .modal-body - display: flex; - flex-direction: column; diff --git a/platform/ui/src/components/content/viewportDownloadForm/__docs__/viewportDownloadForm.mdx b/platform/ui/src/components/content/viewportDownloadForm/__docs__/viewportDownloadForm.mdx deleted file mode 100644 index f5c1422c3..000000000 --- a/platform/ui/src/components/content/viewportDownloadForm/__docs__/viewportDownloadForm.mdx +++ /dev/null @@ -1,39 +0,0 @@ ---- -name: Viewport Download Form -menu: Components -route: /components/viewport-download-form ---- - -import { Playground, Props } from 'docz' -import { State } from 'react-powerplug' -import { ViewportDownloadForm } from './../index' -import NameSpace from '../../../__docs__/NameSpace' - -# Viewport Download Form - -## Basic usage - - - - {({ state, setState }) => ( - -
-
{JSON.stringify(state, null, 2)}
-
-
- -
-
- )} -
-
- -## API - - - -## Translation Namespace - - diff --git a/platform/ui/src/components/content/viewportDownloadForm/index.js b/platform/ui/src/components/content/viewportDownloadForm/index.js deleted file mode 100644 index b7026641f..000000000 --- a/platform/ui/src/components/content/viewportDownloadForm/index.js +++ /dev/null @@ -1,2 +0,0 @@ -import ViewportDownloadForm from './ViewportDownloadForm'; -export { ViewportDownloadForm }; diff --git a/platform/ui/src/components/contextMenu/ContextMenu.css b/platform/ui/src/components/contextMenu/ContextMenu.css deleted file mode 100644 index 4facf3c41..000000000 --- a/platform/ui/src/components/contextMenu/ContextMenu.css +++ /dev/null @@ -1,33 +0,0 @@ -.ContextMenu { - position: relative; - background-color: white; - border-radius: 5px; - z-index: 1000; - display: block; - width: 170px; -} - -.ContextMenu>ul { - list-style-type: none; - padding-left: 0; - margin: 0; -} - -.ContextMenu>ul>li>button { - padding: 10px; - font-size: 14px; - border: none; - color: #516873; - border-radius: 3px; - outline: none; - cursor: pointer; - background: none; -} - -.ContextMenu>ul>li>button:hover { - color: #16202b; -} - -.ContextMenu>ul>li>button:active { - color: #79f9fe; -} diff --git a/platform/ui/src/components/contextMenu/index.js b/platform/ui/src/components/contextMenu/index.js deleted file mode 100644 index 5cb9a3ad5..000000000 --- a/platform/ui/src/components/contextMenu/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default as ContextMenu } from './ContextMenu.js'; diff --git a/platform/ui/src/components/languageSwitcher/LanguageSwitcher.styl b/platform/ui/src/components/languageSwitcher/LanguageSwitcher.styl deleted file mode 100644 index 51284c874..000000000 --- a/platform/ui/src/components/languageSwitcher/LanguageSwitcher.styl +++ /dev/null @@ -1,4 +0,0 @@ -.language-select - color: var(--primary-background-color) - display: block - min-width: 150px diff --git a/platform/ui/src/components/layoutButton/LayoutButton.js b/platform/ui/src/components/layoutButton/LayoutButton.js deleted file mode 100644 index fd6bdee6a..000000000 --- a/platform/ui/src/components/layoutButton/LayoutButton.js +++ /dev/null @@ -1,64 +0,0 @@ -import React, { PureComponent } from 'react'; - -import { LayoutChooser } from './LayoutChooser.js'; -import PropTypes from 'prop-types'; -import ToolbarButton from '../../viewer/ToolbarButton'; - -export class LayoutButton extends PureComponent { - static defaultProps = { - dropdownVisible: false, - }; - - static propTypes = { - dropdownVisible: PropTypes.bool.isRequired, - /** Called with the selectedCell number when grid sell is selected */ - onChange: PropTypes.func, - /** The cell to show as selected */ - selectedCell: PropTypes.object, - }; - - state = { - dropdownVisible: this.props.dropdownVisible, - }; - - componentDidUpdate(prevProps) { - if (this.props.dropdownVisible !== prevProps.dropdownVisible) { - this.setState({ - dropdownVisible: this.props.dropdownVisible, - }); - } - } - - onClick = () => { - this.setState({ - dropdownVisible: !this.state.dropdownVisible, - }); - }; - - onChange = selectedCell => { - if (this.props.onChange) { - this.props.onChange(selectedCell); - } - }; - - render() { - return ( -
- - -
- ); - } -} - -export default LayoutButton; diff --git a/platform/ui/src/components/layoutButton/LayoutChooser.styl b/platform/ui/src/components/layoutButton/LayoutChooser.styl deleted file mode 100644 index aeb77018d..000000000 --- a/platform/ui/src/components/layoutButton/LayoutChooser.styl +++ /dev/null @@ -1,47 +0,0 @@ -@import './../../design/styles/common/button.styl' -@import './../../design/styles/common/global.styl' - -$borderColor = rgba(77, 99, 110, 0.81) - -.layoutChooser-dropdown-menu - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; - font-size: 14px; - text-align: left; - list-style: none; - background-color: #fff; - -webkit-background-clip: padding-box; - background-clip: padding-box; - border: 1px solid #ccc; - border: 1px solid rgba(0,0,0,.15); - border-radius: 4px; - -webkit-box-shadow: 0 6px 12px rgba(0,0,0,.175); - box-shadow: 0 6px 12px rgba(0,0,0,.175); - -.layoutChooser - .selectedBefore - background-color: #5cc3eb - - border: 1px solid $borderColor; - border-radius: 8px - padding: 5px 0; - position: absolute; - z-index: 5000 - - table - margin: 0 auto - border-spacing: 0; - border-collapse: collapse; - td - cursor: pointer - transition(background-color 0.1s ease) - - &:hover, &.hover // Add the hover class here to be triggered by mouseenter/mouseleave - background-color: #209ac9 diff --git a/platform/ui/src/components/layoutButton/__docs__/layoutButton.css b/platform/ui/src/components/layoutButton/__docs__/layoutButton.css deleted file mode 100644 index 21ec59d7e..000000000 --- a/platform/ui/src/components/layoutButton/__docs__/layoutButton.css +++ /dev/null @@ -1,10 +0,0 @@ -.LayoutExample { - background-color: var(--primary-background-color); - width: 160px; - height: 160px; -} - -.GridLayout td { - padding: 5px; - border: 1px solid black; -} diff --git a/platform/ui/src/components/layoutButton/__docs__/layoutButton.mdx b/platform/ui/src/components/layoutButton/__docs__/layoutButton.mdx deleted file mode 100644 index fc6a5a6ac..000000000 --- a/platform/ui/src/components/layoutButton/__docs__/layoutButton.mdx +++ /dev/null @@ -1,49 +0,0 @@ ---- -name: Layout Button -menu: Components -route: /components/layout-button ---- - -import { Playground, Props } from 'docz' -import { State } from 'react-powerplug' -import { LayoutButton } from './../index.js' -import './layoutButton.css' -import NameSpace from '../../../__docs__/NameSpace' - -# Layout Button - -## Basic usage - - - - {({ state, setState }) => ( - - {/* STATE */} -
{JSON.stringify(state, null, 2) }
- - {/* COMPONENT */} -
- setState({ selectedCell: cell })} - /> -
-
- )} -
- -
- -## API - - - -## Translation Namespace - - diff --git a/platform/ui/src/components/layoutButton/index.js b/platform/ui/src/components/layoutButton/index.js deleted file mode 100644 index b7615590a..000000000 --- a/platform/ui/src/components/layoutButton/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { LayoutButton } from './LayoutButton.js'; -export { LayoutChooser } from './LayoutChooser.js'; diff --git a/platform/ui/src/components/measurementTable/MeasurementTable.js b/platform/ui/src/components/measurementTable/MeasurementTable.js deleted file mode 100644 index 47bbe1adf..000000000 --- a/platform/ui/src/components/measurementTable/MeasurementTable.js +++ /dev/null @@ -1,218 +0,0 @@ -import './MeasurementTable.styl'; - -import React, { Component } from 'react'; -import { withTranslation } from '../../contextProviders'; - -import { Icon } from './../../elements/Icon'; -import { MeasurementTableItem } from './MeasurementTableItem.js'; -import { OverlayTrigger } from './../overlayTrigger'; -import PropTypes from 'prop-types'; -import { ScrollableArea } from './../../ScrollableArea/ScrollableArea.js'; -import { TableList } from './../tableList'; -import { Tooltip } from './../tooltip'; - -class MeasurementTable extends Component { - static propTypes = { - measurementCollection: PropTypes.array.isRequired, - timepoints: PropTypes.array.isRequired, - overallWarnings: PropTypes.object.isRequired, - readOnly: PropTypes.bool, - onItemClick: PropTypes.func, - onRelabelClick: PropTypes.func, - onDeleteClick: PropTypes.func, - onEditDescriptionClick: PropTypes.func, - selectedMeasurementNumber: PropTypes.number, - t: PropTypes.func, - saveFunction: PropTypes.func, - onSaveComplete: PropTypes.func, - }; - - static defaultProps = { - overallWarnings: { - warningList: [], - }, - readOnly: false, - }; - - state = { - selectedKey: null, - }; - - render() { - const { overallWarnings, saveFunction, t } = this.props; - const hasOverallWarnings = overallWarnings.warningList.length > 0; - - return ( -
-
- {hasOverallWarnings && ( - -
- {t('Criteria nonconformities')} -
-
- {this.getWarningContent()} -
- - } - > - - - - - -
- )} - {this.getTimepointsHeader()} -
- -
{this.getMeasurementsGroups()}
-
-
- {saveFunction && ( - - )} -
-
- ); - } - - saveFunction = async event => { - const { saveFunction, onSaveComplete } = this.props; - if (saveFunction) { - try { - const result = await saveFunction(); - if (onSaveComplete) { - onSaveComplete({ - title: 'STOW SR', - message: result.message, - type: 'success', - }); - } - } catch (error) { - if (onSaveComplete) { - onSaveComplete({ - title: 'STOW SR', - message: error.message, - type: 'error', - }); - } - } - } - }; - - getMeasurementsGroups = () => { - return this.props.measurementCollection.map((measureGroup, index) => { - return ( - - {this.getMeasurements(measureGroup)} - - ); - }); - }; - - getMeasurements = measureGroup => { - const selectedKey = this.props.selectedMeasurementNumber - ? this.props.selectedMeasurementNumber - : this.state.selectedKey; - return measureGroup.measurements.map((measurement, index) => { - const key = measurement.measurementNumber; - const itemIndex = measurement.itemNumber || index + 1; - const itemClass = - selectedKey === key && !this.props.readOnly ? 'selected' : ''; - - return ( - - ); - }); - }; - - onItemClick = (event, measurementData) => { - if (this.props.readOnly) return; - - this.setState({ - selectedKey: measurementData.measurementNumber, - }); - - if (this.props.onItemClick) { - this.props.onItemClick(event, measurementData); - } - }; - - getCustomHeader = measureGroup => { - return ( - -
- {this.props.t(measureGroup.groupName)} -
- {measureGroup.maxMeasurements && ( -
- {this.props.t('MAX')} {measureGroup.maxMeasurements} -
- )} -
{measureGroup.measurements.length}
-
- ); - }; - - getTimepointsHeader = () => { - const { timepoints, t } = this.props; - - return timepoints.map((timepoint, index) => { - return ( -
-
{t(timepoint.key)}
-
{timepoint.date}
-
- ); - }); - }; - - getWarningContent = () => { - const { warningList = '' } = this.props.overallWarnings; - - if (Array.isArray(warningList)) { - const listedWarnings = warningList.map((warn, index) => { - return
  • {warn}
  • ; - }); - - return
      {listedWarnings}
    ; - } else { - return {warningList}; - } - }; -} - -const connectedComponent = withTranslation(['MeasurementTable', 'Common'])( - MeasurementTable -); -export { connectedComponent as MeasurementTable }; -export default connectedComponent; diff --git a/platform/ui/src/components/measurementTable/MeasurementTable.styl b/platform/ui/src/components/measurementTable/MeasurementTable.styl deleted file mode 100644 index 42150d84f..000000000 --- a/platform/ui/src/components/measurementTable/MeasurementTable.styl +++ /dev/null @@ -1,116 +0,0 @@ -.measurementTable - background-color: var(--primary-background-color) - height: 100% - width: 100% - display: flex - flex-direction: column - - .maxMeasurements - border-radius: 3px - color: var(--primary-background-color) - font-size: 12px - font-weight: 500 - height: 19px - line-height: 17px - margin-top: 22px - margin-right: 15px - padding: 2px 6px 0 - text-transform: uppercase - transition: all 0.3s ease - background-color: var(--default-color) - - .measurementTableHeader - padding-left: 45px - - .measurementTableHeaderItem - display: inline-block - margin-top: 9px - margin-left: 9px - padding-left: 9px - width: 90px - font-size: 14px - line-height: 20px - border-left: 1px solid var(--text-secondary-color) - color: var(--text-primary-color) - - .timepointLabel - color: var(--text-secondary-color) - font-size: 12px - - .warning-status - display: block - position: absolute - width: 50px - height: 40px - padding-left: 7px - left: 15px - top: 7px - - .warning-border - display: block - border: 2px solid #e29e4a - border-radius: 36px - padding: 6px 7px - width: 40px - height: 40px - - svg - color: #e29e4a - width: 22px - height: 20px - pointer-events: inherit - - .measurementTableFooter - padding: 10px - color: #fff - text-align: center - z-index: 1 - - .saveBtn - border: 1px solid var(--ui-border-color-active) - border-radius: 25px - background-color: var(--active-color) - color: var(--ui-gray-dark) - line-height: 25px - padding: 0 20px - outline: none - cursor: pointer - - &:hover, &:active - background-color: var(--ui-sky-blue) - - svg - margin-right: 4px - position: relative - top: 2px - -.tooltip-warning - &.in - opacity 1 - - .tooltip-inner - padding: 0 - - .warningTitle - text-align: left - background-color: var(--ui-gray-darkest) - padding: 7px 15px - border-top-left-radius: 7px - border-top-right-radius: 7px - - .warningContent - text-align center - background-color: var(--ui-gray) - border-bottom-left-radius: 7px - border-bottom-right-radius: 7px - - ol - margin-top: auto - padding-inline-start: 20px - padding-top: 10px - padding-bottom: 10px - padding-left: 25px - text-align: left - - li - padding-right: 10px diff --git a/platform/ui/src/components/measurementTable/MeasurementTableItem.js b/platform/ui/src/components/measurementTable/MeasurementTableItem.js deleted file mode 100644 index bb0c3ada8..000000000 --- a/platform/ui/src/components/measurementTable/MeasurementTableItem.js +++ /dev/null @@ -1,165 +0,0 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import { withTranslation } from '../../contextProviders'; - -import { Icon } from './../../elements/Icon'; -import { OverlayTrigger } from './../overlayTrigger'; -import { Tooltip } from './../tooltip'; -import { TableListItem } from './../tableList/TableListItem.js'; - -import './MeasurementTableItem.styl'; - -class MeasurementTableItem extends Component { - static propTypes = { - measurementData: PropTypes.object.isRequired, - onItemClick: PropTypes.func.isRequired, - onRelabel: PropTypes.func, - onDelete: PropTypes.func, - onEditDescription: PropTypes.func, - itemClass: PropTypes.string, - itemIndex: PropTypes.number, - t: PropTypes.func, - }; - - render() { - const { warningTitle = '', hasWarnings } = this.props.measurementData; - - return ( - - {hasWarnings ? ( - -
    {this.props.t(warningTitle)}
    -
    {this.getWarningContent()}
    - - } - > -
    {this.getTableListItem()}
    -
    - ) : ( - {this.getTableListItem()} - )} -
    - ); - } - - getActionButton = (btnLabel, onClickCallback) => { - return ( - - ); - }; - - getTableListItem = () => { - const hasWarningClass = this.props.measurementData.hasWarnings - ? 'hasWarnings' - : ''; - - const actionButtons = []; - - if (typeof this.props.onRelabel === 'function') { - const relabelButton = this.getActionButton( - 'Relabel', - this.onRelabelClick - ); - actionButtons.push(relabelButton); - } - if (typeof this.props.onEditDescription === 'function') { - const descriptionButton = this.getActionButton( - 'Description', - this.onEditDescriptionClick - ); - actionButtons.push(descriptionButton); - } - if (typeof this.props.onDelete === 'function') { - const deleteButton = this.getActionButton('Delete', this.onDeleteClick); - actionButtons.push(deleteButton); - } - - return ( - -
    -
    - {this.props.t(this.props.measurementData.label, { - keySeparator: '>', - nsSeparator: '|', - })} -
    -
    {this.getDataDisplayText()}
    -
    {actionButtons}
    -
    -
    - ); - }; - - onItemClick = event => { - this.props.onItemClick(event, this.props.measurementData); - }; - - onRelabelClick = event => { - // Prevent onItemClick from firing - event.stopPropagation(); - - this.props.onRelabel(event, this.props.measurementData); - }; - - onEditDescriptionClick = event => { - // Prevent onItemClick from firing - event.stopPropagation(); - - this.props.onEditDescription(event, this.props.measurementData); - }; - - onDeleteClick = event => { - // Prevent onItemClick from firing - event.stopPropagation(); - - this.props.onDelete(event, this.props.measurementData); - }; - - getDataDisplayText = () => { - return this.props.measurementData.data.map((data, index) => { - return ( -
    - {data.displayText ? data.displayText : '...'} -
    - ); - }); - }; - - getWarningContent = () => { - const { warningList = '' } = this.props.measurementData; - - if (Array.isArray(warningList)) { - const listedWarnings = warningList.map((warn, index) => { - return
  • {warn}
  • ; - }); - - return
      {listedWarnings}
    ; - } else { - return {warningList}; - } - }; -} - -const connectedComponent = withTranslation('MeasurementTable')( - MeasurementTableItem -); -export { connectedComponent as MeasurementTableItem }; -export default connectedComponent; diff --git a/platform/ui/src/components/measurementTable/__docs__/measurementTable.mdx b/platform/ui/src/components/measurementTable/__docs__/measurementTable.mdx deleted file mode 100644 index d85d87490..000000000 --- a/platform/ui/src/components/measurementTable/__docs__/measurementTable.mdx +++ /dev/null @@ -1,49 +0,0 @@ ---- -name: Measurement Table -menu: Components -route: /components/measurement-table ---- - -import { Playground, Props } from 'docz' -import { State } from 'react-powerplug' -import { MeasurementTable } from './../index.js' -import NameSpace from '../../../__docs__/NameSpace' -// -import measurements from './measurements.js' -import timepoints from './timepoints.js' -import warnings from './warnings.js' - -# Measurement Table - -## Basic usage - - - - {({ state, setState }) => ( -
    - alert('onItemClick')} - onRelabelClick={() => alert('onRelabelClick')} - onDeleteClick={() => alert('onDeleteClick')} - onEditDescriptionClick={() => alert('onEditDescriptionClick')} - /> -
    - )} -
    -
    - -## API - - - -## Translation Namespace - - diff --git a/platform/ui/src/components/measurementTable/__docs__/measurements.js b/platform/ui/src/components/measurementTable/__docs__/measurements.js deleted file mode 100644 index 2a0507902..000000000 --- a/platform/ui/src/components/measurementTable/__docs__/measurements.js +++ /dev/null @@ -1,93 +0,0 @@ -export default [ - { - maxMeasurements: 5, - groupName: 'Targets', - measurements: [ - { - measurementId: '123', - measurementNumber: '123', - itemNumber: 1, - label: 'Chest Wall Posterior', - hasWarnings: true, - warningTitle: 'Criteria nonconformities', - isSplitLesion: false, - warningList: [ - 'All measurements should have a location', - 'Nodal lesions must be >= 15mm short axis AND >= double the acquisition slice thickness by CT and MR', - ], - data: [ - { - displayText: '25.7 x 12.9', - }, - { - displayText: '24.7 x 11.5', - }, - {}, - ], - }, - { - measurementId: '124', - measurementNumber: '124', - itemNumber: 2, - label: 'Bone Extremity', - data: [ - { - displayText: '24.7 x 11.1', - }, - { - displayText: '21.2 x 10.9', - }, - {}, - ], - }, - ], - }, - { - maxMeasurements: 3, - groupName: 'NonTargets', - measurements: [ - { - measurementId: '125', - measurementNumber: '125', - itemNumber: 1, - label: 'Chest Wall Single Site', - data: [ - { - displayText: 'MD', - }, - { - displayText: 'NM', - }, - {}, - ], - }, - { - measurementId: '126', - measurementNumber: '126', - itemNumber: 2, - label: 'Extremity Multiple Sites', - data: [ - { - displayText: 'CR', - }, - {}, - {}, - ], - }, - { - measurementId: '127', - measurementNumber: '127', - label: 'Extremity Site', - data: [ - { - displayText: 'CR', - }, - {}, - { - displayText: 'NM', - }, - ], - }, - ], - }, -]; diff --git a/platform/ui/src/components/measurementTable/__docs__/timepoints.js b/platform/ui/src/components/measurementTable/__docs__/timepoints.js deleted file mode 100644 index e42b44156..000000000 --- a/platform/ui/src/components/measurementTable/__docs__/timepoints.js +++ /dev/null @@ -1,14 +0,0 @@ -export default [ - { - label: 'Follow-up 2', - date: '20-Dec-18', - }, - { - label: 'Follow-up 1', - date: '15-Jun-18', - }, - { - label: 'Baseline', - date: '10-Apr-18', - }, -]; diff --git a/platform/ui/src/components/measurementTable/__docs__/warnings.js b/platform/ui/src/components/measurementTable/__docs__/warnings.js deleted file mode 100644 index a2da7f90d..000000000 --- a/platform/ui/src/components/measurementTable/__docs__/warnings.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - warningList: [ - 'All measurements should have a location', - 'Nodal lesions must be >= 15mm short axis AND >= double the acquisition slice thickness by CT and MR', - ], -}; diff --git a/platform/ui/src/components/measurementTable/index.js b/platform/ui/src/components/measurementTable/index.js deleted file mode 100644 index e70bd51eb..000000000 --- a/platform/ui/src/components/measurementTable/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { MeasurementTable } from './MeasurementTable.js'; -export { MeasurementTableItem } from './MeasurementTableItem.js'; diff --git a/platform/ui/src/components/ohifModal/OHIFModal.js b/platform/ui/src/components/ohifModal/OHIFModal.js deleted file mode 100644 index 3f9302ced..000000000 --- a/platform/ui/src/components/ohifModal/OHIFModal.js +++ /dev/null @@ -1,76 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import Modal from 'react-modal'; -import classNames from 'classnames'; - -import './OHIFModal.styl'; - -const customStyle = { - overlay: { - zIndex: 1071, - backgroundColor: 'rgb(0, 0, 0, 0.5)', - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - }, -}; - -Modal.setAppElement(document.getElementById('root')); - -const OHIFModal = ({ - className, - closeButton, - shouldCloseOnEsc, - isOpen, - title, - onClose, - children, -}) => { - const renderHeader = () => { - return ( - title && ( -
    -

    {title}

    - {closeButton && ( - - )} -
    - ) - ); - }; - - return ( - - <> - {renderHeader()} -
    - {children} -
    - -
    - ); -}; - -OHIFModal.propTypes = { - className: PropTypes.string, - closeButton: PropTypes.bool, - shouldCloseOnEsc: PropTypes.bool, - isOpen: PropTypes.bool, - title: PropTypes.string, - onClose: PropTypes.func, - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.node), - PropTypes.node, - ]).isRequired, -}; - -export default OHIFModal; diff --git a/platform/ui/src/components/ohifModal/OHIFModal.styl b/platform/ui/src/components/ohifModal/OHIFModal.styl deleted file mode 100644 index 0118e7809..000000000 --- a/platform/ui/src/components/ohifModal/OHIFModal.styl +++ /dev/null @@ -1,67 +0,0 @@ -.OHIFModal - background-color: var(--ui-gray-darker) - border-color: var(--ui-border-color) - color: var(--text-secondary-color) - border-radius: 6px - border: 0 - color: var(--text-primary-color) - position: relative - -webkit-box-shadow: 0 3px 9px rgba(0,0,0,.5) - box-shadow: 0 3px 9px rgba(0,0,0,.5); - background-clip: padding-box - outline: 0 - - @media (min-width: 320px) - width: 78% - min-width: 300px - - @media (min-width: 768px) - width: 600px - - @media (min-width: 992px) - width: 900px - - &__content - padding: 20px - max-height: 90vh; - overflow-x: hidden; - overflow-y: auto; - scrollbar-width: none; - -ms-overflow-style: none; - &::-webkit-scrollbar - display: none; - - &__header - display: flex - justify-content: space-between - align-items: center - border-bottom-width: 3px - border-bottom-style: solid - border-bottom-color: #000000 - padding: 20px - position: relative - - h4 - color: var(--text-secondary-color) - font-size: 20px - font-weight: 500 - line-height: 24px - padding-right: 24px - margin: 0 - - button - cursor: pointer - margin: -10px 0 0 0 - padding: 0 - background-color: transparent - border: none - color: var(--text-secondary-color) - font-size: 25px - font-weight: lighter - - &:active, - &:focus, - &:focus:active - background-image: none - outline: 0 - box-shadow: none diff --git a/platform/ui/src/components/ohifModal/__docs__/ohifModal.mdx b/platform/ui/src/components/ohifModal/__docs__/ohifModal.mdx deleted file mode 100644 index 67bb3f054..000000000 --- a/platform/ui/src/components/ohifModal/__docs__/ohifModal.mdx +++ /dev/null @@ -1,39 +0,0 @@ ---- -name: OHIFModal -menu: Components -route: /components/ohif-modal ---- - -import { Playground, Props } from 'docz' -import { State } from 'react-powerplug' -import { OHIFModal } from './../index' -import NameSpace from '../../../__docs__/NameSpace' - -# OHIF Modal - -## Basic usage - - - - {({ state, setState }) => ( - -
    -
    {JSON.stringify(state, null, 2)}
    -
    -
    - -
    -
    - )} -
    -
    - -## API - - - -## Translation Namespace - - diff --git a/platform/ui/src/components/ohifModal/index.js b/platform/ui/src/components/ohifModal/index.js deleted file mode 100644 index 6e9820766..000000000 --- a/platform/ui/src/components/ohifModal/index.js +++ /dev/null @@ -1,2 +0,0 @@ -import OHIFModal from './OHIFModal'; -export { OHIFModal }; diff --git a/platform/ui/src/components/overlayTrigger/Fade.js b/platform/ui/src/components/overlayTrigger/Fade.js deleted file mode 100644 index 34a5cad79..000000000 --- a/platform/ui/src/components/overlayTrigger/Fade.js +++ /dev/null @@ -1,102 +0,0 @@ -import classNames from 'classnames'; -import React from 'react'; -import PropTypes from 'prop-types'; -import Transition, { - ENTERED, - ENTERING, -} from 'react-transition-group/Transition'; - -const propTypes = { - /** - * Show the component; triggers the fade in or fade out animation - */ - in: PropTypes.bool, - - /** - * Wait until the first "enter" transition to mount the component (add it to the DOM) - */ - mountOnEnter: PropTypes.bool, - - /** - * Unmount the component (remove it from the DOM) when it is faded out - */ - unmountOnExit: PropTypes.bool, - - /** - * Run the fade in animation when the component mounts, if it is initially - * shown - */ - appear: PropTypes.bool, - - /** - * Duration of the fade animation in milliseconds, to ensure that finishing - * callbacks are fired even if the original browser transition end events are - * canceled - */ - timeout: PropTypes.number, - - /** - * Callback fired before the component fades in - */ - onEnter: PropTypes.func, - /** - * Callback fired after the component starts to fade in - */ - onEntering: PropTypes.func, - /** - * Callback fired after the has component faded in - */ - onEntered: PropTypes.func, - /** - * Callback fired before the component fades out - */ - onExit: PropTypes.func, - /** - * Callback fired after the component starts to fade out - */ - onExiting: PropTypes.func, - /** - * Callback fired after the component has faded out - */ - onExited: PropTypes.func, -}; - -const defaultProps = { - in: false, - timeout: 300, - mountOnEnter: false, - unmountOnExit: false, - appear: false, -}; - -const fadeStyles = { - [ENTERING]: 'in', - [ENTERED]: 'in', -}; - -class Fade extends React.Component { - render() { - const { className, children, ...props } = this.props; - - return ( - - {(status, innerProps) => - React.cloneElement(children, { - ...innerProps, - className: classNames( - 'fade', - className, - children.props.className, - fadeStyles[status] - ), - }) - } - - ); - } -} - -Fade.propTypes = propTypes; -Fade.defaultProps = defaultProps; - -export default Fade; diff --git a/platform/ui/src/components/overlayTrigger/Overlay.js b/platform/ui/src/components/overlayTrigger/Overlay.js deleted file mode 100644 index 4e59ab9be..000000000 --- a/platform/ui/src/components/overlayTrigger/Overlay.js +++ /dev/null @@ -1,102 +0,0 @@ -import classNames from 'classnames'; -import React, { cloneElement } from 'react'; -import PropTypes from 'prop-types'; -import { Overlay as BaseOverlay } from 'react-overlays'; -import elementType from 'prop-types-extra/lib/elementType'; -import { withTranslation } from '../../contextProviders'; - -import Fade from './Fade'; - -const propTypes = { - /** - * Set the visibility of the Overlay - */ - show: PropTypes.bool, - /** - * Specify whether the overlay should trigger onHide when the user clicks outside the overlay - */ - rootClose: PropTypes.bool, - /** - * A callback invoked by the overlay when it wishes to be hidden. Required if - * `rootClose` is specified. - */ - onHide: PropTypes.func, - - /** - * Use animation - */ - animation: PropTypes.oneOfType([PropTypes.bool, elementType]), - - /** - * Callback fired before the Overlay transitions in - */ - onEnter: PropTypes.func, - - /** - * Callback fired as the Overlay begins to transition in - */ - onEntering: PropTypes.func, - - /** - * Callback fired after the Overlay finishes transitioning in - */ - onEntered: PropTypes.func, - - /** - * Callback fired right before the Overlay transitions out - */ - onExit: PropTypes.func, - - /** - * Callback fired as the Overlay begins to transition out - */ - onExiting: PropTypes.func, - - /** - * Callback fired after the Overlay finishes transitioning out - */ - onExited: PropTypes.func, - - /** - * Sets the direction of the Overlay. - */ - placement: PropTypes.oneOf(['top', 'right', 'bottom', 'left']), -}; - -const defaultProps = { - animation: Fade, - rootClose: false, - show: false, - placement: 'right', -}; - -class Overlay extends React.Component { - render() { - const { animation, children, ...props } = this.props; - - const transition = animation === true ? Fade : animation || null; - - let child; - - if (!transition) { - child = cloneElement(children, { - className: classNames(children.props.className, 'in'), - }); - } else { - child = children; - } - - return ( - - {child} - - ); - } -} - -Overlay.propTypes = propTypes; -Overlay.defaultProps = defaultProps; - -const connectedComponent = withTranslation()(Overlay); -export { connectedComponent as Overlay }; -export default connectedComponent; diff --git a/platform/ui/src/components/overlayTrigger/OverlayTrigger.js b/platform/ui/src/components/overlayTrigger/OverlayTrigger.js deleted file mode 100644 index b9216fcb3..000000000 --- a/platform/ui/src/components/overlayTrigger/OverlayTrigger.js +++ /dev/null @@ -1,330 +0,0 @@ -import contains from 'dom-helpers/query/contains'; -import React, { cloneElement } from 'react'; -import PropTypes from 'prop-types'; -import ReactDOM from 'react-dom'; -import warning from 'warning'; - -import { Overlay } from './Overlay'; - -import createChainedFunction from './createChainedFunction'; - -/** - * Check if value one is inside or equal to the of value - * - * @param {string} one - * @param {string|array} of - * @returns {boolean} - */ -function isOneOf(one, of) { - if (Array.isArray(of)) { - return of.indexOf(one) >= 0; - } - return one === of; -} - -const triggerType = PropTypes.oneOf(['click', 'hover', 'focus']); - -const propTypes = { - /** - * Specify which action or actions trigger Overlay visibility - */ - trigger: PropTypes.oneOfType([triggerType, PropTypes.arrayOf(triggerType)]), - - /** - * A millisecond delay amount to show and hide the Overlay once triggered - */ - delay: PropTypes.number, - /** - * A millisecond delay amount before showing the Overlay once triggered. - */ - delayShow: PropTypes.number, - /** - * A millisecond delay amount before hiding the Overlay once triggered. - */ - delayHide: PropTypes.number, - - // FIXME: This should be `defaultShow`. - /** - * The initial visibility state of the Overlay. For more nuanced visibility - * control, consider using the Overlay component directly. - */ - defaultOverlayShown: PropTypes.bool, - - /** - * An element or text to overlay next to the target. - */ - overlay: PropTypes.node.isRequired, - - /** - * A function to be called once the hide is triggered - */ - handleHide: PropTypes.func, - - /** - * @private - */ - onBlur: PropTypes.func, - /** - * @private - */ - onClick: PropTypes.func, - /** - * @private - */ - onFocus: PropTypes.func, - /** - * @private - */ - onMouseOut: PropTypes.func, - /** - * @private - */ - onMouseOver: PropTypes.func, - - // Overridden props from ``. - /** - * @private - */ - target: PropTypes.oneOf([null]), - /** - * @private - */ - onHide: PropTypes.oneOf([null]), - /** - * @private - */ - show: PropTypes.oneOf([null]), -}; - -const defaultProps = { - defaultOverlayShown: false, - trigger: ['hover', 'focus'], -}; - -class OverlayTrigger extends React.Component { - constructor(props, context) { - super(props, context); - - this.handleToggle = this.handleToggle.bind(this); - this.handleDelayedShow = this.handleDelayedShow.bind(this); - this.handleDelayedHide = this.handleDelayedHide.bind(this); - this.handleHide = createChainedFunction( - this.handleHide.bind(this), - props.handleHide - ); - - this.handleMouseOver = e => - this.handleMouseOverOut(this.handleDelayedShow, e, 'fromElement'); - this.handleMouseOut = e => - this.handleMouseOverOut(this.handleDelayedHide, e, 'toElement'); - - this._mountNode = null; - - this.state = { - show: props.defaultOverlayShown, - }; - } - - componentDidMount() { - this._mountNode = document.createElement('div'); - this.renderOverlay(); - } - - componentDidUpdate() { - this.renderOverlay(); - } - - componentWillUnmount() { - ReactDOM.unmountComponentAtNode(this._mountNode); - this._mountNode = null; - - clearTimeout(this._hoverShowDelay); - clearTimeout(this._hoverHideDelay); - } - - handleDelayedHide() { - if (this._hoverShowDelay != null) { - clearTimeout(this._hoverShowDelay); - this._hoverShowDelay = null; - return; - } - - if (!this.state.show || this._hoverHideDelay != null) { - return; - } - - const delay = - this.props.delayHide != null ? this.props.delayHide : this.props.delay; - - if (!delay) { - this.hide(); - return; - } - - this._hoverHideDelay = setTimeout(() => { - this._hoverHideDelay = null; - this.hide(); - }, delay); - } - - handleDelayedShow() { - if (this._hoverHideDelay != null) { - clearTimeout(this._hoverHideDelay); - this._hoverHideDelay = null; - return; - } - - if (this.state.show || this._hoverShowDelay != null) { - return; - } - - const delay = - this.props.delayShow != null ? this.props.delayShow : this.props.delay; - - if (!delay) { - this.show(); - return; - } - - this._hoverShowDelay = setTimeout(() => { - this._hoverShowDelay = null; - this.show(); - }, delay); - } - - handleHide() { - this.hide(); - } - - // Simple implementation of mouseEnter and mouseLeave. - // React's built version is broken: https://github.com/facebook/react/issues/4251 - // for cases when the trigger is disabled and mouseOut/Over can cause flicker - // moving from one child element to another. - handleMouseOverOut(handler, e, relatedNative) { - const target = e.currentTarget; - const related = e.relatedTarget || e.nativeEvent[relatedNative]; - - if ((!related || related !== target) && !contains(target, related)) { - handler(e); - } - } - - handleToggle() { - if (this.state.show) { - this.hide(); - } else { - this.show(); - } - } - - hide() { - this.setState({ show: false }); - } - - makeOverlay(overlay, props) { - return ( - - {overlay} - - ); - } - - show() { - this.setState({ show: true }); - } - - renderOverlay() { - ReactDOM.unstable_renderSubtreeIntoContainer( - this, - this._overlay, - this._mountNode - ); - } - - render() { - const { - trigger, - overlay, - children, - onBlur, - onClick, - onFocus, - onMouseOut, - onMouseOver, - ...props - } = this.props; - - delete props.delay; - delete props.delayShow; - delete props.delayHide; - delete props.defaultOverlayShown; - - const child = React.Children.only(children); - const childProps = child.props; - const triggerProps = {}; - - if (this.state.show) { - triggerProps['aria-describedby'] = overlay.props.id; - } - - // FIXME: The logic here for passing through handlers on this component is - // inconsistent. We shouldn't be passing any of these props through. - - triggerProps.onClick = createChainedFunction(childProps.onClick, onClick); - - if (isOneOf('click', trigger)) { - triggerProps.onClick = createChainedFunction( - triggerProps.onClick, - this.handleToggle - ); - } - - if (isOneOf('hover', trigger)) { - warning( - !(trigger === 'hover'), - '[react-bootstrap] Specifying only the `"hover"` trigger limits the ' + - 'visibility of the overlay to just mouse users. Consider also ' + - 'including the `"focus"` trigger so that touch and keyboard only ' + - 'users can see the overlay as well.' - ); - - triggerProps.onMouseOver = createChainedFunction( - childProps.onMouseOver, - onMouseOver, - this.handleMouseOver - ); - triggerProps.onMouseOut = createChainedFunction( - childProps.onMouseOut, - onMouseOut, - this.handleMouseOut - ); - } - - if (isOneOf('focus', trigger)) { - triggerProps.onFocus = createChainedFunction( - childProps.onFocus, - onFocus, - this.handleDelayedShow - ); - triggerProps.onBlur = createChainedFunction( - childProps.onBlur, - onBlur, - this.handleDelayedHide - ); - } - - this._overlay = this.makeOverlay(overlay, props); - - return cloneElement(child, triggerProps); - } -} - -OverlayTrigger.propTypes = propTypes; -OverlayTrigger.defaultProps = defaultProps; - -export { OverlayTrigger }; diff --git a/platform/ui/src/components/overlayTrigger/__docs__/OverlayTrigger.mdx b/platform/ui/src/components/overlayTrigger/__docs__/OverlayTrigger.mdx deleted file mode 100644 index 4fc48ee56..000000000 --- a/platform/ui/src/components/overlayTrigger/__docs__/OverlayTrigger.mdx +++ /dev/null @@ -1,84 +0,0 @@ ---- -name: Overlay Trigger -menu: Components -route: /components/overlay-trigger ---- - -import { Playground, Props } from 'docz' -import { Tooltip } from './../../tooltip' -import { OverlayTrigger } from './../index.js' - -# Overlay Trigger - -## Basic usage - -### On Hover - - - -
    - { - ['right', 'left', 'bottom', 'top'].map((placement) => { - return ( - - - Here I am! - - } - > - - - - ) - }) - } -
    - -
    - -### On Click - - -
    - {['right', 'left', 'bottom', 'top'].map(placement => { - return ( - - Here I am! - - } - > - - - ) - })} -
    -
    - -## API - - diff --git a/platform/ui/src/components/overlayTrigger/createChainedFunction.js b/platform/ui/src/components/overlayTrigger/createChainedFunction.js deleted file mode 100644 index c5e231bc6..000000000 --- a/platform/ui/src/components/overlayTrigger/createChainedFunction.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Safe chained function - * - * Will only create a new function if needed, - * otherwise will pass back existing functions or null. - * - * @param {function} functions to chain - * @returns {function|null} - */ -function createChainedFunction(...funcs) { - return funcs - .filter(f => f != null) - .reduce((acc, f) => { - if (typeof f !== 'function') { - throw new Error( - 'Invalid Argument Type, must only provide functions, undefined, or null.' - ); - } - - if (acc === null) { - return f; - } - - return function chainedFunction(...args) { - acc.apply(this, args); - f.apply(this, args); - }; - }, null); -} - -export default createChainedFunction; diff --git a/platform/ui/src/components/overlayTrigger/index.js b/platform/ui/src/components/overlayTrigger/index.js deleted file mode 100644 index 68a4d0874..000000000 --- a/platform/ui/src/components/overlayTrigger/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { Overlay } from './Overlay.js'; -export { OverlayTrigger } from './OverlayTrigger.js'; diff --git a/platform/ui/src/components/quickSwitch/QuickSwitch.styl b/platform/ui/src/components/quickSwitch/QuickSwitch.styl deleted file mode 100644 index bb98b9674..000000000 --- a/platform/ui/src/components/quickSwitch/QuickSwitch.styl +++ /dev/null @@ -1,209 +0,0 @@ -.series-quick-switch - position: relative; - - &:before - box-shadow: 0 0 0 5000px rgba(0, 0, 0, 0.8) - transition: opacity 0.3s ease - opacity: 0 - content: '' - - &:hover - z-index: 50 - - &:before - display: table; - opacity: 1 - content: '' - - &:not(.left):not(.right) - left: 50% - transform: translateX(-50%) - - &.left - border-right: 1px solid var(--ui-border-color) - right: 0 - - &.right - left: 0 - - .series-switch - float: right - - .study-switch - float: left - - .study-browser - left: auto - right: 0 - transform-origin: calc(100% - 1em) calc(1em + 17px) - - .series-browser - left: 0 - right: auto - transform-origin: 1em calc(1em + 15px) - - .thumbnails-wrapper - transform-origin: 0% 0% - - .thumbnail - float: left - - .series-item - float: left - - .title-label - color: var(--text-secondary-color) - font-size: 12px - font-weight: 500 - line-height: 12px - opacity: 1 - padding-bottom: 3px - text-align: center - transition: opacity 0.3s ease - - .series-switch - padding-right: 10px; - - .series-switch, - .study-switch - float: left - position: relative - - .study-switch:hover:after - content: '' - display: block - height: 100px - left: 0 - position: absolute - top: 0 - width: 300px - - .study-browser - left: 0 - padding-top: 60px; - max-height: calc(100vh - 60px); - transform-origin: 1em calc(1em + 17px) - width: 300px - - .study-browser-list - padding: 0 10px - - .series-browser - max-height: 100vh - max-width: 720px - right: 0 - transform-origin: calc(100% - 1em) calc(1em + 15px) - - .thumbnails-wrapper - transition: transform 0.3s ease - transform-origin: 100% 0% - - .thumbnail - float: right - - .series-details - opacity: 0 - transform: translateY(-100%) - transition: transform 0.3s ease, opacity 0.3s ease - - .scrollable - padding-top: 15px - transition: padding-bottom 0.3s ease - - .study-browser-series { - overflow hidden - } - - .series-browser, - .study-browser - min-height: 120px - opacity: 0 - position: absolute - top: 0 - transform: scale(0) - transition: transform 0.3s ease , opacity 0.3s ease - z-index: 3 - - .series-box, - .study-box - height: 57px - width: 57px - - .study-box - background-color: var(--ui-gray-dark) - border: solid 2px var(--ui-border-color-dark) - border-radius: 11px - - .series-item - background-color: var(--box-background-color) - border-radius: 3px - float: right - height: 15px - margin: 2px - transition: opacity 0.3s ease - width: 15px - - &.count - color: var(--text-primary-color) - background-color: transparent - font-size: 12px - font-weight: 500 - line-height: 17px - text-align: center - - &.active - background-color: var(--active-color) - - &.series-triggered .series-browser, - .series-switch:hover .series-browser, - .study-switch:hover .study-browser - opacity: 1 - transform: scale(1) - - &.series-triggered .series-item, - .series-switch:hover .title-label - opacity: 0 - - &.series-triggered - .thumbnails-wrapper - transform: scale(0.9) translateY(80px) - - .series-browser:not(:hover) - &>.scrollable - padding-bottom: 80px - - &>.scrollNav - opacity: 0 - - .series-switch:hover .series-browser - .thumbnails-wrapper - transform: scale(1) translateY(0) - - .thumbnail .series-details - opacity: 1 - transform: translateY(0) - transition-delay: 0.3s - - .study-browser-item.active .study-item-box - box-shadow: inset 0 0 0 3px var(--active-color) - -@media screen and (max-width: 1599px) - .series-quick-switch - - .series-box, - .study-box - width: 36px - height: 36px - - .study-box - border-radius: 7px - - .series-item - height: 10px - margin: 1px - width: 10px - - &.count - font-size: 10px - font-weight: 300 - line-height: 10px diff --git a/platform/ui/src/components/quickSwitch/SeriesList.styl b/platform/ui/src/components/quickSwitch/SeriesList.styl deleted file mode 100644 index e69de29bb..000000000 diff --git a/platform/ui/src/components/quickSwitch/StudiesList.styl b/platform/ui/src/components/quickSwitch/StudiesList.styl deleted file mode 100644 index e69de29bb..000000000 diff --git a/platform/ui/src/components/quickSwitch/index.js b/platform/ui/src/components/quickSwitch/index.js deleted file mode 100644 index c92ec79d5..000000000 --- a/platform/ui/src/components/quickSwitch/index.js +++ /dev/null @@ -1 +0,0 @@ -export { QuickSwitch } from './QuickSwitch.js'; diff --git a/platform/ui/src/components/radioButtonList/RadioButtonList.css b/platform/ui/src/components/radioButtonList/RadioButtonList.css deleted file mode 100644 index d7c6305dc..000000000 --- a/platform/ui/src/components/radioButtonList/RadioButtonList.css +++ /dev/null @@ -1,62 +0,0 @@ -.ohif-radio-button-container { - --radio-button-dim: 20px; -} - -.ohif-radio-button-container input { - position: absolute; - opacity: 0; - z-index: 10000; - cursor: pointer; - height: inherit; - width: inherit; -} - -.ohif-radio-button-container { - display: block; - position: relative; - padding-left: 35px; - margin-bottom: 12px; - cursor: pointer; - font-size: 22px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.ohif-radio-button { - width: var(--radio-button-dim); - height: var(--radio-button-dim); - position: absolute; - top: 25%; - left: 0; - background-color: var(--ui-gray-lighter); - border-radius: 50%; - z-index: 1; -} - -.ohif-radio-button:hover { - background-color: var(--default-color); - border-radius: 100%; -} - -.ohif-radio-button:after { - content: ''; - position: absolute; - display: none; - width: 70%; - height: 70%; -} - -.ohif-radio-button-container .ohif-radio-button.ohif-selected:after { - display: block; - top: 14%; - left: 14%; - border-radius: 50%; - background: white; -} - -.ohif-radio-button-label { - font-size: 12px; - font-weight: 500; -} diff --git a/platform/ui/src/components/radioButtonList/RadioButtonList.js b/platform/ui/src/components/radioButtonList/RadioButtonList.js deleted file mode 100644 index 0bbcf8b59..000000000 --- a/platform/ui/src/components/radioButtonList/RadioButtonList.js +++ /dev/null @@ -1,74 +0,0 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import './RadioButtonList.css'; - -export class RadioButtonList extends Component { - static className = 'RadioButtonList'; - - //TODO: Add fields to propTypes.description? - //These would be label (required), id (required), and checked (optional). - static propTypes = { - description: PropTypes.arrayOf( - PropTypes.shape({ - label: PropTypes.string.isRequired, - id: PropTypes.string.isRequired, - checked: PropTypes.bool, - }) - ), - }; - - constructor(props) { - super(props); - this.state = {}; - - for (let button of props.description) { - if (button.checked) { - this.state.checked = button.id; - } - } - } - - handleChange(e) { - this.setState({ checked: e.target.value }); - } - - render() { - let buttons = this.props.description.map(button => { - let input = ( - { - this.handleChange(e); - }} - value={button.id} - /> - ); - - //needed to style the custom radio check - let inputSpan; - if (this.state.checked === button.id) { - inputSpan = ( - {input} - ); - } else { - inputSpan = {input}; - } - - return ( - - - - ); - }); - - return ( -
    -
    {buttons}
    -
    - ); - } -} diff --git a/platform/ui/src/components/radioButtonList/__docs__/radioButtonList.mdx b/platform/ui/src/components/radioButtonList/__docs__/radioButtonList.mdx deleted file mode 100644 index 2ad2b205d..000000000 --- a/platform/ui/src/components/radioButtonList/__docs__/radioButtonList.mdx +++ /dev/null @@ -1,74 +0,0 @@ ---- -name: Radio Button List -menu: Elements -route: /components/radio-button-list ---- - -import { Playground, Props } from 'docz' -import { State } from 'react-powerplug' -import { RadioButtonList } from './../index' -import NameSpace from '../../../__docs__/NameSpace' - -#Radio Button List - -## Basic usage - - - - {({ state, setState }) => ( - -
    -
    {JSON.stringify(state, null, 2)}
    -
    -
    - -
    -
    - )} -
    -
    - -## API - - - -## Translation Namespace - - \ No newline at end of file diff --git a/platform/ui/src/components/radioButtonList/index.js b/platform/ui/src/components/radioButtonList/index.js deleted file mode 100644 index f8361a3b0..000000000 --- a/platform/ui/src/components/radioButtonList/index.js +++ /dev/null @@ -1 +0,0 @@ -export { RadioButtonList } from './RadioButtonList.js'; diff --git a/platform/ui/src/components/roundedButtonGroup/RoundedButtonGroup.js b/platform/ui/src/components/roundedButtonGroup/RoundedButtonGroup.js deleted file mode 100644 index cd861f146..000000000 --- a/platform/ui/src/components/roundedButtonGroup/RoundedButtonGroup.js +++ /dev/null @@ -1,84 +0,0 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import classnames from 'classnames'; -import { Icon } from './../../elements/Icon'; -import './RoundedButtonGroup.css'; - -// TODO: Rename to Toggle? -class RoundedButtonGroup extends Component { - static className = 'RoundedButtonGroup'; - - static propTypes = { - options: PropTypes.arrayOf( - PropTypes.shape({ - value: PropTypes.any, - label: PropTypes.string, - icon: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.shape({ - name: PropTypes.string.isRequired, - }), - ]), - }) - ), - value: PropTypes.string, - onValueChanged: PropTypes.func, - }; - - static defaultProps = { - options: [], - value: null, - }; - - onClickOption = value => { - let newValue = value; - if (this.props.value === value) { - newValue = null; - } - - if (this.props.onValueChanged) { - this.props.onValueChanged(newValue); - } - }; - - render() { - let className = classnames( - RoundedButtonGroup.className, - 'clearfix center-table' - ); - - const buttons = this.props.options.map((option, index) => { - const className = classnames({ - roundedButtonWrapper: true, - noselect: true, - active: this.props.value === option.value, - }); - - const optionText = option.label && {option.label}; - const iconProps = - typeof option.icon === 'string' ? { name: option.icon } : option.icon; - - const bottomLabel = option.bottomLabel && ( -
    {option.bottomLabel}
    - ); - - return ( -
    this.onClickOption(option.value)} - > -
    - {optionText} - {iconProps && } -
    - {bottomLabel} -
    - ); - }); - - return
    {buttons}
    ; - } -} - -export { RoundedButtonGroup }; diff --git a/platform/ui/src/components/roundedButtonGroup/__docs__/roundedButtonGroup.mdx b/platform/ui/src/components/roundedButtonGroup/__docs__/roundedButtonGroup.mdx deleted file mode 100644 index 5d00b32fc..000000000 --- a/platform/ui/src/components/roundedButtonGroup/__docs__/roundedButtonGroup.mdx +++ /dev/null @@ -1,51 +0,0 @@ ---- -name: Rounded Button Group -menu: Components -route: /components/rounded-button-group ---- - -import { Playground, Props } from 'docz'; -import { State } from 'react-powerplug'; -import { RoundedButtonGroup } from './../index.js'; - -# Rounded Button Group - -A basic styled toggle switch - -## Basic usage - - - - {({ state, setState }) => ( - -
    -
    value: {JSON.stringify(state.value, null, 2)}
    -
    - setState({ value })} - /> -
    - )} -
    -
    - -## API - - diff --git a/platform/ui/src/components/roundedButtonGroup/index.js b/platform/ui/src/components/roundedButtonGroup/index.js deleted file mode 100644 index e33e0490c..000000000 --- a/platform/ui/src/components/roundedButtonGroup/index.js +++ /dev/null @@ -1 +0,0 @@ -export { RoundedButtonGroup } from './RoundedButtonGroup.js'; diff --git a/platform/ui/src/components/selectTree/InputRadio.js b/platform/ui/src/components/selectTree/InputRadio.js deleted file mode 100644 index e4de02a06..000000000 --- a/platform/ui/src/components/selectTree/InputRadio.js +++ /dev/null @@ -1,37 +0,0 @@ -import { Component } from 'react'; -import React from 'react'; -import PropTypes from 'prop-types'; - -export default class InputRadio extends Component { - static propTypes = { - value: PropTypes.string, - label: PropTypes.string.isRequired, - itemData: PropTypes.object.isRequired, - labelClass: PropTypes.string, - id: PropTypes.string.isRequired, - onSelected: PropTypes.func.isRequired, - }; - - render() { - const labelClass = this.props.labelClass ? this.props.labelClass : ''; - return ( - - ); - } - - onSelected = evt => { - this.props.onSelected(evt, this.props.itemData); - }; -} diff --git a/platform/ui/src/components/selectTree/SelectTree.js b/platform/ui/src/components/selectTree/SelectTree.js deleted file mode 100644 index 708a29e99..000000000 --- a/platform/ui/src/components/selectTree/SelectTree.js +++ /dev/null @@ -1,192 +0,0 @@ -import './SelectTree.styl'; - -import React, { Component } from 'react'; - -import { Icon } from './../../elements/Icon'; -import InputRadio from './InputRadio.js'; -import PropTypes from 'prop-types'; -import SelectTreeBreadcrumb from './SelectTreeBreadcrumb.js'; -import cloneDeep from 'lodash.clonedeep'; - -export class SelectTree extends Component { - static propTypes = { - autoFocus: PropTypes.bool, - searchEnabled: PropTypes.bool, - selectTreeFirstTitle: PropTypes.string, - selectTreeSecondTitle: PropTypes.string, - /** Called when 'componentDidUpdate' is triggered */ - onComponentChange: PropTypes.func, - /** [{ label, value, items[]}] - An array of items than can be expanded to show child items */ - items: PropTypes.array.isRequired, - /** fn(evt, item) - Called when a child item is selected; receives event and selected item */ - onSelected: PropTypes.func.isRequired, - }; - - static defaultProps = { - searchEnabled: true, - autoFocus: true, - selectTreeFirstTitle: 'First Level itens', - items: [], - }; - - constructor(props) { - super(props); - - this.state = { - searchTerm: null, - currentNode: null, - value: null, - }; - } - - render() { - const treeItems = this.getTreeItems(); - - return ( -
    -
    - {this.headerItem()} -
    - {this.state.currentNode && ( - - )} -
    -
    {treeItems}
    -
    -
    -
    -
    - ); - } - - componentDidUpdate = () => { - if (this.props.onComponentChange) { - this.props.onComponentChange(); - } - }; - - isLeafSelected = item => item && !Array.isArray(item.items); - - getLabelClass = item => { - let labelClass = 'treeLeaf'; - if (this.state.searchTerm || Array.isArray(item.items)) { - labelClass = 'treeNode'; - } - return labelClass; - }; - - filterItems() { - const filteredItems = []; - const rawItems = cloneDeep(this.props.items); - rawItems.forEach(item => { - if (Array.isArray(item.items)) { - item.items.forEach(item => { - const label = item.label.toLowerCase(); - const searchTerm = this.state.searchTerm.toLowerCase(); - if (label.indexOf(searchTerm) !== -1) { - filteredItems.push(item); - } - }); - } else { - const label = item.label.toLowerCase(); - const searchTerm = this.state.searchTerm.toLowerCase(); - if (label.indexOf(searchTerm) !== -1) { - filteredItems.push(item); - } - } - }); - return filteredItems; - } - - getTreeItems() { - const storageKey = 'SelectTree'; - let treeItems; - - if (this.state.searchTerm) { - treeItems = this.filterItems(); - } else if (this.state.currentNode) { - treeItems = cloneDeep(this.state.currentNode.items); - } else { - treeItems = cloneDeep(this.props.items); - } - - return treeItems.map((item, index) => { - let itemKey = index; - if (this.state.currentNode) { - itemKey += `_${this.state.currentNode.value}`; - } - return ( - - ); - }); - } - - headerItem = () => { - let title = this.props.selectTreeFirstTitle; - if (this.state.currentNode && this.props.selectTreeSecondTitle) { - title = this.props.selectTreeSecondTitle; - } - - return ( -
    -
    {title}
    - {this.props.searchEnabled && ( -
    -
    - -
    - -
    - )} -
    - ); - }; - - searchLocations = evt => { - this.setState({ - currentNode: null, - searchTerm: evt.currentTarget.value, - }); - }; - - onSelected = (event, item) => { - if (this.isLeafSelected(item)) { - this.setState({ - searchTerm: null, - currentNode: null, - value: null, - }); - } else { - this.setState({ - currentNode: item, - }); - } - return this.props.onSelected(event, item); - }; - - onBreadcrumbSelected = () => { - this.setState({ - currentNode: null, - }); - }; -} diff --git a/platform/ui/src/components/selectTree/SelectTree.styl b/platform/ui/src/components/selectTree/SelectTree.styl deleted file mode 100644 index adb1ddba5..000000000 --- a/platform/ui/src/components/selectTree/SelectTree.styl +++ /dev/null @@ -1,108 +0,0 @@ -@import './../../design/styles/common/global.styl' - -.selectTreeRoot - text-align: initial; - width: 320px; - max-height: inherit; - font-size: 14px; - line-height: 26px; - - .treeContent - max-height: inherit; - overflow: hidden; - border: 1px solid #c4c4c4; - border-radius: 5px; - background-color: #ffffff; - display: flex; - flex-direction: column; - - .treeHeader - background-color: #c0c0c0; - border-bottom: 1px solid #c4c4c4; - color: #303030; - padding: 5px; - text-align: center; - - .wrapperText - font-weight: bold; - padding-bottom: 2px; - - .wrapperSearch - width: 100%; - - .searchIcon - position: absolute; - width: 18px; - height: 15px; - margin: 7px 10px 13px 10px; - color: #a3a3a3; - - .searchInput - width: 100%; - padding: 6px 12px 6px 35px; - background-color: #fff; - background-image: none; - border: 1px solid #9b9b9b; - border-radius: 4px; - font-size: 14px; - line-height: 1.42857143; - color: #555; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - - &:focus - outline: 0; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), - 0 0 8px rgba(102, 175, 233, 0.6); - - .wrapperText - white-space: nowrap; - cursor: pointer; - - .selectTreeBreadcrumb - .wrapperLabel - cursor: pointer; - padding: 0 12px; - height: 41px; - width: 100%; - line-height: 41px; - - .backIcon - padding-right: 10px; - - svg - width: 14px; - height: 14px; - position: relative; - top: 2px; - color: #457fb0; - - .treeOptions - overflow: auto; - height: 100%; - - .selectTreeBreadcrumb + .treeInputsWrapper .treeInputs .treeLeaf - border: none; - height: initial; - line-height: 26px; - - & > .treeInputsWrapper > .treeInputs .treeLeaf - border-bottom: 1px solid #ccc; - height: 41px; - line-height: 41px; - - .treeNode, .treeLeaf - cursor: pointer; - display: block; - overflow: hidden; - font-weight: normal; - box-shadow: 0 0 0 200px transparent; - padding: 0 12px; - - .treeNode - border-bottom: 1px solid #ccc; - height: 41px; - line-height: 41px; - - .radioLabel .radioInput - display: none; diff --git a/platform/ui/src/components/selectTree/SelectTreeBreadcrumb.js b/platform/ui/src/components/selectTree/SelectTreeBreadcrumb.js deleted file mode 100644 index 1bcb5ea20..000000000 --- a/platform/ui/src/components/selectTree/SelectTreeBreadcrumb.js +++ /dev/null @@ -1,37 +0,0 @@ -import { Component } from 'react'; -import React from 'react'; -import PropTypes from 'prop-types'; -import { Icon } from './../../elements/Icon'; - -export default class SelectTreeBreadcrumb extends Component { - static propTypes = { - label: PropTypes.string.isRequired, - value: PropTypes.string.isRequired, - onSelected: PropTypes.func.isRequired, - }; - - render() { - return ( -
    - -
    - ); - } -} diff --git a/platform/ui/src/components/selectTree/__docs__/selectTree.mdx b/platform/ui/src/components/selectTree/__docs__/selectTree.mdx deleted file mode 100644 index 68ee9882e..000000000 --- a/platform/ui/src/components/selectTree/__docs__/selectTree.mdx +++ /dev/null @@ -1,42 +0,0 @@ ---- -name: Select Tree -menu: Components -route: /components/select-tree ---- - -import { Playground, Props } from 'docz' -import { State } from 'react-powerplug' -import { SelectTree } from './../index.js' - -import selectTreeItems from './selectTreeItems.js' - -# SelectTree - -## Basic usage - - - - {({ state, setState }) => ( - -
    -                {JSON.stringify(state.items, null, 2)}
    -            
    - - setState({ itemLabelSelected: item.label }) } - selectTreeFirstTitle="Select Tree Example Header" - autoFocus={false} - /> -
    - )} - -
    - -
    - -## API - - diff --git a/platform/ui/src/components/selectTree/__docs__/selectTreeItems.js b/platform/ui/src/components/selectTree/__docs__/selectTreeItems.js deleted file mode 100644 index 0c7466966..000000000 --- a/platform/ui/src/components/selectTree/__docs__/selectTreeItems.js +++ /dev/null @@ -1,30 +0,0 @@ -export default [ - { - label: 'A', - value: 'A', - items: [ - { - label: 'Abdominal Wall', - value: 'AbdominalWall', - }, - { - label: 'Adrenal Left', - value: 'AdrenalLeft', - }, - ], - }, - { - label: 'B', - value: 'B', - items: [ - { - label: 'Brain', - value: 'Brain', - }, - { - label: 'Breast', - value: 'Breast', - }, - ], - }, -]; diff --git a/platform/ui/src/components/selectTree/index.js b/platform/ui/src/components/selectTree/index.js deleted file mode 100644 index 58dad4997..000000000 --- a/platform/ui/src/components/selectTree/index.js +++ /dev/null @@ -1 +0,0 @@ -export { SelectTree } from './SelectTree'; diff --git a/platform/ui/src/components/simpleDialog/SimpleDialog.js b/platform/ui/src/components/simpleDialog/SimpleDialog.js deleted file mode 100644 index 8a8561769..000000000 --- a/platform/ui/src/components/simpleDialog/SimpleDialog.js +++ /dev/null @@ -1,95 +0,0 @@ -import React, { Component, useState } from 'react'; -import PropTypes from 'prop-types'; -import { TextInput } from '@ohif/ui'; - -import './SimpleDialog.styl'; - -class SimpleDialog extends Component { - static propTypes = { - children: PropTypes.node, - componentRef: PropTypes.any, - componentStyle: PropTypes.object, - rootClass: PropTypes.string, - isOpen: PropTypes.bool, - headerTitle: PropTypes.string.isRequired, - onClose: PropTypes.func.isRequired, - onConfirm: PropTypes.func.isRequired, - }; - - static defaultProps = { - isOpen: true, - componentStyle: {}, - rootClass: '', - }; - - static InputDialog = ({ onSubmit, defaultValue, title, label, onClose }) => { - const [value, setValue] = useState(defaultValue); - - const onSubmitHandler = () => { - onSubmit(value); - }; - - return ( -
    - - setValue(event.target.value)} - label={label} - /> - -
    - ); - }; - - render() { - return ( - - {this.props.isOpen && ( -
    -
    -
    - - x - -

    {this.props.headerTitle}

    -
    -
    {this.props.children}
    -
    - - -
    -
    -
    - )} -
    - ); - } - - onClose = event => { - event.preventDefault(); - event.stopPropagation(); - this.props.onClose(); - }; - - onConfirm = event => { - event.preventDefault(); - event.stopPropagation(); - this.props.onConfirm(); - }; -} - -export { SimpleDialog }; diff --git a/platform/ui/src/components/simpleDialog/SimpleDialog.styl b/platform/ui/src/components/simpleDialog/SimpleDialog.styl deleted file mode 100644 index 5df1de18a..000000000 --- a/platform/ui/src/components/simpleDialog/SimpleDialog.styl +++ /dev/null @@ -1,110 +0,0 @@ -@import './../../design/styles/common/button.styl' -@import './../../design/styles/common/global.styl' - -.InputDialog - .simpleDialog - position: relative - -.simpleDialog - position: relative; - z-index: 1000; - border: 0; - border-radius: 6px; - background-color: var(--ui-gray-darker); - - .header - border-bottom: 3px solid var(--primary-background-color); - padding: 19px 22px 17px; - position: relative; - - .title - font-size: 20px; - font-weight: 600; - line-height: 24px; - padding-right: 40px; - color: var(--text-secondary-color); - margin: 0; - - .closeBtn - -webkit-transform: translateY(-50%); - color: var(--text-secondary-color); - height: 20px; - opacity: 1; - overflow: hidden; - padding: 2px; - position: absolute; - right: 21px; - text-align: center; - text-shadow: none; - top: 50%; - transform: translateY(-50%); - transition: color 0.3s ease; - width: 20px; - - .closeIcon - color: transparent; - display: block; - font-size: 0; - height: 100%; - line-height: 0; - overflow: hidden; - position: relative; - width: 100%; - - &:after, &:before - content: ' '; - display: block; - height: 2px; - transition: background-color 0.3s ease; - width: 19px; - background-color: var(--text-secondary-color); - - &:before - left: 1px; - position: absolute; - top: 1px; - -webkit-transform: rotate(45deg); - transform: rotate(45deg); - -webkit-transform-origin: 1px 50%; - transform-origin: 1px 50%; - - &:after - right: 1px; - position: absolute; - top: 1px; - -webkit-transform: rotate(-45deg); - transform: rotate(-45deg); - -webkit-transform-origin: calc(100% - 1px) 50%; - transform-origin: calc(100% - 1px) 50%; - - .content - padding: 16px 22px 25px; - position: relative; - color: var(--text-primary-color); - - .simpleDialogSelect, .simpleDialogInput - background-color: var(--input-background-color); - color: var(--text-primary-color); - border: 0; - border-radius: 2px; - font-size: 14px; - height: 30px; - width: 100%; - line-height: 16px; - padding: 8px 9px 6px; - margin-top: 10px; - display: block; - - .simpleDialogLabelFor - font-size: 14px; - font-weight: 700; - line-height: 16px; - margin: 10px 0 0 0; - color: var(--text-primary-color); - - .footer - padding: 15px; - text-align: right; - - .btn - margin-left: 5px; diff --git a/platform/ui/src/components/simpleDialog/__docs__/simpleDialog.mdx b/platform/ui/src/components/simpleDialog/__docs__/simpleDialog.mdx deleted file mode 100644 index 764074b10..000000000 --- a/platform/ui/src/components/simpleDialog/__docs__/simpleDialog.mdx +++ /dev/null @@ -1,83 +0,0 @@ ---- -name: Simple Dialog -menu: Components -route: /components/simple-dialog ---- - -import { Playground, Props } from 'docz' -import { State } from 'react-powerplug' -import { SimpleDialog } from './../index.js' - -# Simple Dialog - -Its similar to a modal but we can pass its style as props and manipulate it as -we want. Initially used to display tool data changes in our Viewport. - -## Basic usage - - - - {({ state, setState }) => ( - -
    {JSON.stringify(state, null, 2) }
    - - {/* Toggle Dialog */} - - - setState({ isDialogOpen: false })} - onConfirm={() => setState({ - isDialogOpen: false, - // If you don't want to update external state until complete, - // This is where you could grab current field values and update parent - // With setState - // - // inputValue: this.input.value, - // selectValue: this.select.value - })} - componentStyle={state.dialogStyle} - onValueChanged={(value) => setState({value}) } - > - - setState({inputValue: e.target.value})} - /> - - - -
    - )} -
    - -
    - -## API - - diff --git a/platform/ui/src/components/simpleDialog/index.js b/platform/ui/src/components/simpleDialog/index.js deleted file mode 100644 index df8327865..000000000 --- a/platform/ui/src/components/simpleDialog/index.js +++ /dev/null @@ -1 +0,0 @@ -export { SimpleDialog } from './SimpleDialog.js'; diff --git a/platform/ui/src/components/snackbar/SnackbarContainer.js b/platform/ui/src/components/snackbar/SnackbarContainer.js deleted file mode 100644 index e49d1c73e..000000000 --- a/platform/ui/src/components/snackbar/SnackbarContainer.js +++ /dev/null @@ -1,53 +0,0 @@ -import React from 'react'; -import SnackbarItem from './SnackbarItem'; -import './Snackbar.css'; -import { useSnackbarContext } from '../../contextProviders'; - -const SnackbarContainer = () => { - const { snackbarItems, hide } = useSnackbarContext(); - - const renderItem = item => { - return ; - }; - - if (!snackbarItems) { - return null; - } - - const renderItems = () => { - const items = { - topLeft: [], - topCenter: [], - topRight: [], - bottomLeft: [], - bottomCenter: [], - bottomRight: [], - }; - - snackbarItems.map(item => { - items[item.position].push(item); - }); - - return ( -
    - {Object.keys(items).map(pos => { - if (!items[pos].length) { - return null; - } - - return ( -
    - {items[pos].map((item, index) => ( -
    {renderItem(item)}
    - ))} -
    - ); - })} -
    - ); - }; - - return <>{renderItems()}; -}; - -export default SnackbarContainer; diff --git a/platform/ui/src/components/snackbar/SnackbarItem.js b/platform/ui/src/components/snackbar/SnackbarItem.js deleted file mode 100644 index 40c43697e..000000000 --- a/platform/ui/src/components/snackbar/SnackbarItem.js +++ /dev/null @@ -1,31 +0,0 @@ -import React, { useState, useEffect } from 'react'; - -const SnackbarItem = ({ options, onClose }) => { - const handleClose = () => { - onClose(options.id); - }; - - useEffect(() => { - if (options.autoClose) { - setTimeout(() => { - handleClose(); - }, options.duration); - } - }, []); - - return ( -
    - - x - - {options.title &&
    {options.title}
    } - {options.message &&
    {options.message}
    } -
    - ); -}; - -export default SnackbarItem; diff --git a/platform/ui/src/components/snackbar/SnackbarTypes.js b/platform/ui/src/components/snackbar/SnackbarTypes.js deleted file mode 100644 index 3dffcb5c9..000000000 --- a/platform/ui/src/components/snackbar/SnackbarTypes.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - INFO: 'info', - WARNING: 'warning', - SUCCESS: 'success', - ERROR: 'error', -}; diff --git a/platform/ui/src/components/studyBrowser/ImageThumbnail.styl b/platform/ui/src/components/studyBrowser/ImageThumbnail.styl deleted file mode 100644 index dce5c7d41..000000000 --- a/platform/ui/src/components/studyBrowser/ImageThumbnail.styl +++ /dev/null @@ -1,99 +0,0 @@ -:root { - --text-secondary-color: #91B9CD; - --active-color: #20A5D6; - --primary-background-color: black; - --ui-border-color-dark: #3C5D80 - --sidebar-transition: all 0.3s ease; -} - -.ThumbnailEntry.active .ImageThumbnail - border-color: var(--active-color); - box-shadow: none - transition: var(--sidebar-transition); - -.ImageThumbnail - background-color: var(--primary-background-color); - box-shadow: inset 0 0 0 1px var(--ui-border-color-dark); - border: 5px solid transparent - border-radius: 12px - height: 135px - margin: 0 auto - padding 5px - position: relative - transition: var(--sidebar-transition); - width: 217px - -moz-background-clip: padding - -webkit-background-clip: padding - background-clip: padding-box - - // Thumbnail Loading Indicator - - .image-thumbnail-loading-indicator - position: absolute - left: 50% - top: 50% - margin: -22px 0 0 -22px - display: block - width: 44px - height: 44px - - &:after - content: " " - display: block - width: 32px - height: 32px - margin: 1px - border-radius: 50% - border: 5px solid var(--ui-border-color-dark) - border-color: var(--ui-border-color-dark) transparent var(--ui-border-color-dark) transparent - animation: image-thumbnail-loading-indicator 1.2s linear infinite - - @keyframes image-thumbnail-loading-indicator - 0% - transform: rotate(0deg) - 100% - transform: rotate(360deg) - - // The End... - -.image-thumbnail-canvas - height: 100% - overflow: hidden - display: flex - justify-content: center - - img - -webkit-user-drag: none - pointer-events: none - -.thumbnailLoadingIndicator - display: none - pointer-events: none - color: var(--text-secondary-color); - height: 20px - width: 100% - top: 0 - left: 0 - right: 0 - bottom: 0 - margin: auto - position: absolute - - &.d-block - display: block; - - p - text-align: center - font-size: 10pt - -.image-thumbnail-progress-bar - position: relative - width: 100% - height: 3px - top: -5px - - .image-thumbnail-progress-bar-inner - height: 100% - width: 0 - border-radius: 5px - background-color: var(--active-color); diff --git a/platform/ui/src/components/studyBrowser/StudyBrowser.styl b/platform/ui/src/components/studyBrowser/StudyBrowser.styl deleted file mode 100644 index 5a105afeb..000000000 --- a/platform/ui/src/components/studyBrowser/StudyBrowser.styl +++ /dev/null @@ -1,40 +0,0 @@ -.study-browser - float: left - height: 100% - width: 100% - overflow: hidden - background-color: black - padding-bottom: 20px - padding-top: 10px - - .scrollable-study-thumbnails - height: 100% - overflow-y: auto - overflow-x: hidden - padding-bottom: 50px - padding-right: 16px - padding-left: 4px - margin-right: -16px - - display: flex; - flex-direction: column; - - &::-webkit-scrollbar - display: none - - .thumbnail-container - margin: 0 auto; - padding-bottom: 1.5rem; - - .noselect - -moz-user-select: none; /* Firefox */ - -ms-user-select: none; /* Internet Explorer */ - -khtml-user-select: none; /* KHTML browsers (e.g. Konqueror) */ - -webkit-user-select: none; /* Chrome, Safari, and Opera */ - -webkit-touch-callout: none; /* Disable Android and iOS callouts*/ - - -.draggable - cursor: copy - cursor: -webkit-grab - cursor: -moz-grab diff --git a/platform/ui/src/components/studyBrowser/Thumbnail.styl b/platform/ui/src/components/studyBrowser/Thumbnail.styl deleted file mode 100644 index 47e6ecb8e..000000000 --- a/platform/ui/src/components/studyBrowser/Thumbnail.styl +++ /dev/null @@ -1,98 +0,0 @@ -@import './../../design/styles/common/global.styl' - -:root { - --series-count-background-color: #678696; -} - -.thumbnail - cursor: pointer - display: table - margin: 0 auto; - min-width: 90%; - padding-bottom: 1.5rem; - - .alt-image-text - align-items: center; - justify-content: center; - background-color: var(--primary-background-color); - box-shadow: inset 0 0 0 1px var(--ui-border-color-dark); - border: 5px solid transparent; - border-radius: 12px; - height: 135px; - margin: 0 auto; - padding: 5px; - position: relative; - transition: var(--sidebar-transition); - width: 217px; - display: flex; - - h1 - text-align: center - color: var(--text-primary-color); - - .series-details - display: flex; - flex-direction: column - color: var(--text-primary-color); - font-size: 14px - line-height: 1.3em - margin-top: 5px - margin-left: 1rem - margin-right: 0.5rem - max-width: 217px - position: relative - word-wrap: break-word - - .series-description - flex-grow: 1 - - &.info-only .series-description - display: none - - .series-information - display: flex - flex-direction: row - justify-content: space-between - - .item-frames .icon - height: 18px - - .item-series.image-frames .icon - background-color: var(--series-count-background-color); - margin-top: 6px - position: relative - - &:after - content: '' - background-color: var(--active-color); - box-shadow: 1px 1px rgba(0, 0, 0, .115) - left: -4px - position: absolute - top: -4px - - & - &:after - content: '' - border: 0px solid var(--series-count-background-color) - display: inline-block - height: 11px - width: 11px - - .value - color: var(--text-secondary-color); - display: inline-block - font-size: 12px - margin-left: 4px - overflow: hidden - text-overflow: ellipsis - white-space: nowrap - width: calc(100% - 15px) - vertical-align: middle - - .icon - color: var(--active-color); - display: inline-block - font-size: 10px - font-weight: 900 - text-align: right - width: 11px diff --git a/platform/ui/src/components/studyBrowser/__docs__/ExampleDropTarget.css b/platform/ui/src/components/studyBrowser/__docs__/ExampleDropTarget.css deleted file mode 100644 index 3d5fc34c6..000000000 --- a/platform/ui/src/components/studyBrowser/__docs__/ExampleDropTarget.css +++ /dev/null @@ -1,30 +0,0 @@ -.ExampleDropTarget { - display: flex; - justify-content: center; - flex-direction: column; - - min-height: 100px; - - border: 2px dashed black; - padding: 20px; - transition: 0.2s all ease; -} - -.ExampleDropTarget h4, -.ExampleDropTarger p { - text-align: center; - word-break: break-word; -} - -.ExampleDropTarget.can-drop { - border: 2px dashed #20a5d6; - background-color: #fafafa; - color: black; -} - -.ExampleDropTarget.hovered { - border: 2px dashed #20a5d6; - background-color: black; - color: #91b9cd; - cursor: copy; -} diff --git a/platform/ui/src/components/studyBrowser/__docs__/studyBrowser.mdx b/platform/ui/src/components/studyBrowser/__docs__/studyBrowser.mdx deleted file mode 100644 index f9606fe84..000000000 --- a/platform/ui/src/components/studyBrowser/__docs__/studyBrowser.mdx +++ /dev/null @@ -1,22 +0,0 @@ ---- -name: Study Browser -menu: Components -route: /components/study-browser ---- - -import { Playground, Props } from 'docz' -import { State } from 'react-powerplug' -import { WrappedStudyBrowser } from './wrappedStudyBrowser.js' -import { StudyBrowser } from './../index.js' - -# Study Browser - -## Basic usage - - - - - -## API - - diff --git a/platform/ui/src/components/studyBrowser/__docs__/wrappedStudyBrowser.js b/platform/ui/src/components/studyBrowser/__docs__/wrappedStudyBrowser.js deleted file mode 100644 index d7fa76f54..000000000 --- a/platform/ui/src/components/studyBrowser/__docs__/wrappedStudyBrowser.js +++ /dev/null @@ -1,41 +0,0 @@ -import React, { Component } from 'react'; -import { DragDropContext } from 'react-dnd'; -import TouchBackend from 'react-dnd-touch-backend'; - -// -import { - studies, - onThumbnailClick, - onThumbnailDoubleClick, -} from './exampleStudies.js'; -import ExampleDropTarget from './ExampleDropTarget.js'; -import { StudyBrowser } from './../index.js'; - -class StudyBrowserContainer extends Component { - render() { - //const viewportData = [null, null, null, null]; - - return ( - - - - - ); - } -} - -// Note: -// Normally, the top level APP component is wrapped with the DragDropContext -// We wrap this component to create a simple/local example. -const WrappedStudyBrowser = DragDropContext( - TouchBackend({ enableMouseEvents: true }), - null, - true -)(StudyBrowserContainer); - -// http://react-dnd.github.io/react-dnd/docs/api/drag-drop-context -export { WrappedStudyBrowser }; diff --git a/platform/ui/src/components/studyBrowser/index.js b/platform/ui/src/components/studyBrowser/index.js deleted file mode 100644 index fd9b43275..000000000 --- a/platform/ui/src/components/studyBrowser/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { StudyBrowser } from './StudyBrowser.js'; -export { Thumbnail } from './Thumbnail.js'; diff --git a/platform/ui/src/components/studyList/CustomDateRangePicker.css b/platform/ui/src/components/studyList/CustomDateRangePicker.css deleted file mode 100644 index 6b2b07845..000000000 --- a/platform/ui/src/components/studyList/CustomDateRangePicker.css +++ /dev/null @@ -1,119 +0,0 @@ -/* NOTE: the order of these styles DO matter */ - -/* Will edit everything selected including everything between a range of dates */ -.CalendarDay__selected_span { - background: var(--datePicker-picker-background); - color: var(--datePicker-picker-text); - border-color: #e4e7e7; -} - -/* Will edit selected date or the endpoints of a range of dates */ -.CalendarDay__selected { - background: var(--datePicker-picker-background); - color: var(--datePicker-picker-text); - border-color: #e4e7e7; -} - -/* Will edit when hovered over. _span style also has this property */ -.CalendarDay__selected:hover, -.CalendarDay__default:hover { - background: var(--datePicker-picker-background); - color: var(--datePicker-picker-text); - border-color: #e4e7e7; -} - -/* Will edit when the second date (end date) in a range of dates -is not yet selected. Edits the dates between your mouse and said date */ -.CalendarDay__hovered_span:hover, -.CalendarDay__hovered_span { - background: var(--datePicker-picker-background); - color: var(--datePicker-picker-text); - border-color: #e4e7e7; -} - -/* EXTERIOR INPUT STYLE */ -/* Container - placement */ -.DateRangePicker { - height: 40px; - margin: 0 5px 20px 5px; - cursor: pointer; - border: none; - width: 100%; -} -/* Container - visual */ -.DateRangePickerInput { - width: calc(100% - 10px); /* Just use padding? */ - background-color: var(--datePicker-input-background); - border-color: var(--datePicker-input-background); - color: var(--datePicker-picker-text-input); - height: 40px; -} - -.DateRangePickerInput.DateRangePickerInput__withBorder { - border-radius: 4px; - background-color: var(--datePicker-input-background); -} - -/* Input Container */ -.DateInput { - width: 97px; - height: 38px; - border-radius: 4px; - background-color: var(--datePicker-input-background); -} - -/* Actual Input Element */ -.DateInput > .DateInput_input { - border-color: transparent; - background-color: transparent; - color: var(--datePicker-picker-text-input); - height: 38px; - font-size: 10pt; - padding: 0; -} - -/* PRESETS */ -.PresetDateRangePicker_panel { - display: flex; - justify-content: space-between; -} - -.PresetDateRangePicker_button { - margin: 0; - padding: 4px 8px; - color: #00a699; - background: var(--datePicker-picker-text-input); -} - -.PresetDateRangePicker_button:hover { - background: #00a699; - color: var(--datePicker-picker-text-input); -} - -.CalendarDay__blocked_out_of_range:hover { - background: #fff; - cursor: not-allowed; - color: var(--datePicker-picker-text-disabled); -} - -.DateRangePicker_select { - background-color: white; - color: var(--datePicker-picker-text); - border: 1px solid #e4e7e7; - border-radius: 4px; - display: inline-block; - padding: 3px 20px 3px 10px; - font-size: 14px; - cursor: pointer; - appearance: none; - - background-image: linear-gradient(45deg, transparent 50%, gray 50%), - linear-gradient(135deg, gray 50%, transparent 50%); - background-position: calc(100% - 11px) 11px, calc(100% - 6px) calc(11px); - background-size: 5px 5px, 5px 5px; - background-repeat: no-repeat; -} - -.DateRangePicker_select:hover { - border-color: #c4c4c4; -} diff --git a/platform/ui/src/components/studyList/CustomDateRangePicker.js b/platform/ui/src/components/studyList/CustomDateRangePicker.js deleted file mode 100644 index dc82d5f32..000000000 --- a/platform/ui/src/components/studyList/CustomDateRangePicker.js +++ /dev/null @@ -1,140 +0,0 @@ -// If you want to continue using CSS stylesheets and classes... -// https://github.com/airbnb/react-dates#initialize -import 'react-dates/initialize'; -import 'react-dates/lib/css/_datepicker.css'; -import './CustomDateRangePicker.css'; - -import React from 'react'; -import PropTypes from 'prop-types'; -import { DateRangePicker } from 'react-dates'; -import moment from 'moment'; -import i18n from '@ohif/i18n'; -import { useTranslation } from 'react-i18next'; - -function CustomDateRangePicker(props) { - moment.locale(i18n.language); // using i18n in the date picker - - const { t } = useTranslation('DatePicker'); - - const { - onDatesChange, - startDate, - endDate, - presets, - ...dateRangePickerProps - } = props; - - const renderDatePresets = () => { - const { presets } = props; - - return ( -
    - {presets.map(({ text, start, end }) => { - const isSelected = startDate === start && endDate === end; - - return ( - - ); - })} -
    - ); - }; - const renderMonthElement = ({ month, onMonthSelect, onYearSelect }) => { - const containerStyle = { - margin: '0 5px', - }; - - const renderYearsOptions = () => { - const yearsRange = 20; - const options = []; - - for (let i = 0; i < yearsRange; i++) { - const year = moment().year() - i; - options.push(); - } - - return options; - }; - - renderMonthElement.propTypes = { - onMonthSelect: PropTypes.func, - onYearSelect: PropTypes.func, - }; - - return ( -
    -
    - -
    -
    - {} - -
    -
    - ); - }; - - return ( - - ); -} - -CustomDateRangePicker.propTypes = { - presets: PropTypes.arrayOf( - PropTypes.shape({ - text: PropTypes.string, - start: PropTypes.required, - end: PropTypes.required, - }) - ), - onDatesChange: PropTypes.func.isRequired, - startDate: PropTypes.instanceOf(Date), - endDate: PropTypes.instanceOf(Date), - month: PropTypes.instanceOf(Date), -}; - -export default CustomDateRangePicker; diff --git a/platform/ui/src/components/studyList/PageToolbar.js b/platform/ui/src/components/studyList/PageToolbar.js deleted file mode 100644 index d0f445800..000000000 --- a/platform/ui/src/components/studyList/PageToolbar.js +++ /dev/null @@ -1,38 +0,0 @@ -import React, { PureComponent } from 'react'; - -import { Icon } from './../../elements/Icon'; -import PropTypes from 'prop-types'; - -class PageToolbar extends PureComponent { - static propTypes = { - onImport: PropTypes.func, - }; - - onImport = event => { - if (this.props.onImport) { - this.props.onImport(event); - } - }; - - getImportTool() { - if (this.props.onImport) { - return ( -
    - -
    - ); - } - } - - render() { - return
    {this.getImportTool()}
    ; - } -} - -export { PageToolbar }; diff --git a/platform/ui/src/components/studyList/PaginationArea.styl b/platform/ui/src/components/studyList/PaginationArea.styl deleted file mode 100644 index bfab2fe05..000000000 --- a/platform/ui/src/components/studyList/PaginationArea.styl +++ /dev/null @@ -1,63 +0,0 @@ -.pagination-area - display: flex; - color: var(--text-secondary-color); - font-size: 13px - font-weight: normal !important - - label - font-weight: normal - - select - margin: 5px - background-color: var(--primary-background-color) - color: white - - - .rows-dropdown - width: 25%; - padding-right: 15px; - padding-left: 15px; - - .pagination-buttons - width: 75%; - padding-right: 15px; - padding-left: 15px; - - .form-group - margin-bottom: 15px; - -.rows-per-page label.wrapperLabel - display: inline-table !important - margin: 0 4px - - select - margin: 0px 4px 0px 4px - width: 42px - -.page-buttons - margin: 0 - text-align: right - font-weight: normal - ul.pagination-control - margin: 0 - - li - display: table-cell - padding: 5px 2px - - button - padding: 4px 8px - background-color: var(--primary-background-color) - border-color: var(--ui-gray) - color: var(--ui-gray-darkest) - color: white - text-decoration: none - - &:hover:enabled - color: var(--active-color) - - .active - button - background-color: var(--ui-gray) - border-color: #ddd - color: white diff --git a/platform/ui/src/components/studyList/StudyListLoadingText.js b/platform/ui/src/components/studyList/StudyListLoadingText.js deleted file mode 100644 index b1c404d3c..000000000 --- a/platform/ui/src/components/studyList/StudyListLoadingText.js +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import { Icon } from './../../elements/Icon'; -// TODO: useTranslation -import { withTranslation } from '../../contextProviders'; - -function StudyListLoadingText({ t: translate }) { - return ( -
    - {translate('Loading')}... -
    - ); -} - -const connectedComponent = withTranslation('StudyListLoadingText')( - StudyListLoadingText -); - -export { connectedComponent as StudyListLoadingText }; diff --git a/platform/ui/src/components/studyList/TableSearchFilter.js b/platform/ui/src/components/studyList/TableSearchFilter.js deleted file mode 100644 index ca9874e5a..000000000 --- a/platform/ui/src/components/studyList/TableSearchFilter.js +++ /dev/null @@ -1,150 +0,0 @@ -import React, { useState } from 'react'; -import PropTypes from 'prop-types'; -import moment from 'moment'; -import { isInclusivelyBeforeDay } from 'react-dates'; -import CustomDateRangePicker from './CustomDateRangePicker.js'; -import { Icon } from './../../elements/Icon'; -import { useTranslation } from 'react-i18next'; - -const getDateEntry = (datePicked, rangeDatePicked) => { - return rangeDatePicked || datePicked || null; -}; - -const getDateEntryFromRange = (today, numOfDays, edge = 'start') => { - if (typeof numOfDays !== 'number') { - return; - } - - if (edge === 'end') { - return today; - } else { - today.subtract(numOfDays, 'days'); - } -}; - -function TableSearchFilter(props) { - const { - meta, - values, - onSort, - onValueChange, - sortFieldName, - sortDirection, - // TODO: Rename - studyListDateFilterNumDays, - } = props; - - const { studyDateTo, studyDateFrom } = values || {}; - const [focusedInput, setFocusedInput] = useState(null); - const { t, ready: translationsAreReady } = useTranslation('Common'); - - const sortIcons = ['sort', 'sort-up', 'sort-down']; - const sortIconForSortField = - sortDirection === 'asc' ? sortIcons[1] : sortIcons[2]; - - const today = moment(); - const lastWeek = moment().subtract(7, 'day'); - const lastMonth = moment().subtract(1, 'month'); - - const defaultStartDate = getDateEntryFromRange( - today, - studyListDateFilterNumDays, - 'start' - ); - const defaultEndDate = getDateEntryFromRange( - today, - studyListDateFilterNumDays, - 'end' - ); - - const studyDatePresets = [ - { - text: t('Today'), - start: today, - end: today, - }, - { - text: t('Last 7 days'), - start: lastWeek, - end: today, - }, - { - text: t('Last 30 days'), - start: lastMonth, - end: today, - }, - ]; - - return translationsAreReady - ? meta.map((field, i) => { - const { displayText, fieldName, inputType } = field; - const isSortField = sortFieldName === fieldName; - const sortIcon = isSortField ? sortIconForSortField : sortIcons[0]; - - return ( - - - {inputType === 'text' && ( - onValueChange(fieldName, e.target.value)} - /> - )} - {inputType === 'date-range' && ( - // https://github.com/airbnb/react-dates - { - onValueChange('studyDateFrom', startDate); - onValueChange('studyDateTo', endDate); - }} - focusedInput={focusedInput} - onFocusChange={updatedVal => setFocusedInput(updatedVal)} - // Optional - numberOfMonths={1} // For med and small screens? 2 for large? - showClearDates={true} - anchorDirection="left" - presets={studyDatePresets} - hideKeyboardShortcutsPanel={true} - isOutsideRange={day => !isInclusivelyBeforeDay(day, moment())} - /> - )} - - ); - }) - : null; -} - -TableSearchFilter.propTypes = { - meta: PropTypes.arrayOf( - PropTypes.shape({ - displayText: PropTypes.string.isRequired, - fieldName: PropTypes.string.isRequired, - inputType: PropTypes.oneOf(['text', 'date-range']).isRequired, - size: PropTypes.number.isRequired, - }) - ).isRequired, - values: PropTypes.object.isRequired, - onSort: PropTypes.func.isRequired, - sortFieldName: PropTypes.string, - sortDirection: PropTypes.oneOf([null, 'asc', 'desc']), -}; - -TableSearchFilter.defaultProps = {}; - -export { TableSearchFilter }; -export default TableSearchFilter; diff --git a/platform/ui/src/components/studyList/index.js b/platform/ui/src/components/studyList/index.js deleted file mode 100644 index af9078927..000000000 --- a/platform/ui/src/components/studyList/index.js +++ /dev/null @@ -1,4 +0,0 @@ -export { StudyList } from './StudyList.js'; -export { TableSearchFilter } from './TableSearchFilter.js'; -export { TablePagination } from './TablePagination.js'; -export { PageToolbar } from './PageToolbar.js'; diff --git a/platform/ui/src/components/tableList/TableList.styl b/platform/ui/src/components/tableList/TableList.styl deleted file mode 100644 index 4c0c0d88d..000000000 --- a/platform/ui/src/components/tableList/TableList.styl +++ /dev/null @@ -1,50 +0,0 @@ - -$headerRowHeight = 63px - -.tableList - background-color: var(--primary-background-color) - height: 100%; - width: 100%; - - .tableListHeader - background-color: var(--ui-gray-darker) - color: var(--text-secondary-color) - display: flex - height: $headerRowHeight - line-height: $headerRowHeight - margin-top: 2px - overflow: hidden - width: 100% - - .tableListHeaderTitle - color: var(--text-secondary-color) - font-size: 22px - font-weight: 300 - line-height: $headerRowHeight - padding: 0 10px - text-align: left - flex: 1; - - .tableListHeaderSelector - cursor: pointer - max-width: 30px - padding-left: 2px - align-items: stretch - flex: 1 - justify-content: space-around - text-align: center - - svg - fill: #c1d8e3 - height: 63px - max-width: 11px - - .numberOfItems - color: var(--ui-sky-blue) - float: right - font-weight: 300 - font-size: 40px - max-width: 54px - height: $headerRowHeight - line-height: 66px - flex: 1; diff --git a/platform/ui/src/components/tableList/TableListItem.styl b/platform/ui/src/components/tableList/TableListItem.styl deleted file mode 100644 index c6e8e4d29..000000000 --- a/platform/ui/src/components/tableList/TableListItem.styl +++ /dev/null @@ -1,46 +0,0 @@ -.tableListItem - display: flex - margin-left: -6px - margin-top: 2px - padding-left: 6px - opacity: 0.7 - cursor: pointer; - width: calc(100% + 6px) - - &:hover - opacity 1 - - &.selected - opacity 1 - .itemIndex - color: $activeColor - - &.hasWarning - .warning - display: block - - .itemIndex - background-color: var(--ui-gray) - color: var(--text-secondary-color) - cursor: pointer - flex: 1 - max-width: 25px - transition(all 0.3s ease) - font-size: 14px - font-weight: 400 - margin-right: 6px - padding: 10px - text-align: center - -webkit-box-sizing: initial; - -moz-box-sizing: initial; - box-sizing: initial; - - .itemContent - flex: 1 - color: var(--text-secondary-color) - width: calc(100% - 51px); - font-weight: 400 - margin-top: 9px; - - .warning-icon - display: none diff --git a/platform/ui/src/components/tableList/__docs__/tableList.mdx b/platform/ui/src/components/tableList/__docs__/tableList.mdx deleted file mode 100644 index bea1c7db5..000000000 --- a/platform/ui/src/components/tableList/__docs__/tableList.mdx +++ /dev/null @@ -1,48 +0,0 @@ ---- -name: Table List -menu: Components -route: /components/table-list ---- - -import { Playground, Props } from 'docz' -import { State } from 'react-powerplug' -import { TableList, TableListItem } from './../index.js' - -# Table List - -## Basic usage - - - - {({ state, setState }) => ( - - {state.listItems.map( (item, index) => { - return ( - alert('item clicked')} - > - - - )} - )} - - )} - - - - - -## API - - diff --git a/platform/ui/src/components/tableList/index.js b/platform/ui/src/components/tableList/index.js deleted file mode 100644 index 5a19d8d71..000000000 --- a/platform/ui/src/components/tableList/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { TableList } from './TableList'; -export { TableListItem } from './TableListItem'; diff --git a/platform/ui/src/components/toolbarSection/ToolbarSection.js b/platform/ui/src/components/toolbarSection/ToolbarSection.js deleted file mode 100644 index e1fdbf213..000000000 --- a/platform/ui/src/components/toolbarSection/ToolbarSection.js +++ /dev/null @@ -1,65 +0,0 @@ -import './ToolbarSection.styl'; - -import React, { PureComponent } from 'react'; - -import ExpandableToolMenu from '../../viewer/ExpandableToolMenu'; -import PropTypes from 'prop-types'; -import ToolbarButton from '../../viewer/ToolbarButton'; -import classnames from 'classnames'; - -class ToolbarSection extends PureComponent { - static defaultProps = { - className: '', - }; - - static propTypes = { - buttons: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string, - label: PropTypes.string.isRequired, - icon: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.shape({ - name: PropTypes.string.isRequired, - }), - ]), - /** Optional: Expandable Tool Menu */ - buttons: PropTypes.arrayOf(PropTypes.shape({})), - }) - ).isRequired, - /** Array of string button ids that should show as active */ - activeButtons: PropTypes.arrayOf(PropTypes.string).isRequired, - /** Class for toolbar section container */ - className: PropTypes.string, - }; - - render() { - const items = this.props.buttons.map((button, index) => { - if (button.buttons && Array.isArray(button.buttons)) { - return ( - - ); - } else { - return ( - - ); - } - }); - - return ( -
    - {items} -
    - ); - } -} - -export { ToolbarSection }; diff --git a/platform/ui/src/components/toolbarSection/ToolbarSection.styl b/platform/ui/src/components/toolbarSection/ToolbarSection.styl deleted file mode 100644 index 1e008acca..000000000 --- a/platform/ui/src/components/toolbarSection/ToolbarSection.styl +++ /dev/null @@ -1,4 +0,0 @@ -.ToolbarSection - float: left; - background-color: var(--primary-background-color); - border-radius: 8px; diff --git a/platform/ui/src/components/toolbarSection/__docs__/exampleButtons.js b/platform/ui/src/components/toolbarSection/__docs__/exampleButtons.js deleted file mode 100644 index 74e08b6a2..000000000 --- a/platform/ui/src/components/toolbarSection/__docs__/exampleButtons.js +++ /dev/null @@ -1,41 +0,0 @@ -export default [ - { - id: 'Pan', - label: 'Pan', - icon: 'arrows', - }, - { - label: 'Zoom', - icon: 'search', - }, - { - label: 'Bidirectional', - icon: 'measure-target', - }, - { - label: 'Stack Scroll', - icon: 'bars', - }, - { - label: 'Reset', - icon: 'reset', - }, - { - label: 'Manual', - icon: 'level', - }, - { - label: 'More', - icon: 'ellipse-circle', - buttons: [ - { - label: 'Reset 2', - icon: 'reset', - }, - { - label: 'Manual 2', - icon: 'adjust', - }, - ], - }, -]; diff --git a/platform/ui/src/components/toolbarSection/__docs__/toolbarSection.docs.mdx b/platform/ui/src/components/toolbarSection/__docs__/toolbarSection.docs.mdx deleted file mode 100644 index a246a2dd5..000000000 --- a/platform/ui/src/components/toolbarSection/__docs__/toolbarSection.docs.mdx +++ /dev/null @@ -1,39 +0,0 @@ ---- -name: Toolbar Section -menu: Components -route: /components/toolbar-section ---- - -import { Playground, Props } from 'docz'; -import { State } from 'react-powerplug'; -import { ToolbarSection } from './../index.js'; -import exampleButtons from './exampleButtons.js'; -import NameSpace from '../../../__docs__/NameSpace'; - -# ToolbarSection - -A basic row of buttons for a toolbar. Active command is `WwwcTool` - -## Basic usage - - - { - alert('pressed'); - }, - }} - > - {({ state, setState }) => } - - - -## API - - - -## Translation Namespace - - diff --git a/platform/ui/src/components/toolbarSection/index.js b/platform/ui/src/components/toolbarSection/index.js deleted file mode 100644 index 5dad83951..000000000 --- a/platform/ui/src/components/toolbarSection/index.js +++ /dev/null @@ -1 +0,0 @@ -export { ToolbarSection } from './ToolbarSection.js'; diff --git a/platform/ui/src/components/tooltip/Tooltip.js b/platform/ui/src/components/tooltip/Tooltip.js deleted file mode 100644 index 237d2cb22..000000000 --- a/platform/ui/src/components/tooltip/Tooltip.js +++ /dev/null @@ -1,66 +0,0 @@ -import './Tooltip.styl'; - -import classNames from 'classnames'; -import React from 'react'; -import PropTypes from 'prop-types'; - -const propTypes = { - /** Sets the direction the Tooltip is positioned towards. */ - placement: PropTypes.oneOf(['top', 'right', 'bottom', 'left']), - - /** The "top" position value for the Tooltip. */ - positionTop: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - /** The "left" position value for the Tooltip. */ - positionLeft: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - - /** The "top" position value for the Tooltip arrow. */ - arrowOffsetTop: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - /** The "left" position value for the Tooltip arrow. */ - arrowOffsetLeft: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), -}; - -const defaultProps = { - placement: 'right', -}; - -class Tooltip extends React.Component { - render() { - const { - placement, - positionTop, - positionLeft, - arrowOffsetTop, - arrowOffsetLeft, - className, - style, - children, - } = this.props; - - const outerStyle = { - top: positionTop, - left: positionLeft, - ...style, - }; - - const arrowStyle = { - top: arrowOffsetTop, - left: arrowOffsetLeft, - }; - - return ( -
    -
    -
    {children}
    -
    - ); - } -} - -Tooltip.propTypes = propTypes; -Tooltip.defaultProps = defaultProps; - -export { Tooltip }; diff --git a/platform/ui/src/components/tooltip/Tooltip.styl b/platform/ui/src/components/tooltip/Tooltip.styl deleted file mode 100644 index ab0822ab9..000000000 --- a/platform/ui/src/components/tooltip/Tooltip.styl +++ /dev/null @@ -1,92 +0,0 @@ -@import './../../design/styles/common/global.styl' - -.tooltip - position: absolute; - z-index: 1070; - display: block; - font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; - font-size: 12px; - font-style: normal; - font-weight: 400; - line-height: 1.42857143; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - letter-spacing: normal; - word-break: normal; - word-spacing: normal; - word-wrap: normal; - white-space: normal; - opacity: 0; - line-break: auto; - - &.in - opacity: .9; - - &.top - margin-top: -3px; - padding: 5px 0; - - &.right - margin-left: 3px; - padding: 0 5px; - - &.bottom - margin-top: 3px; - padding: 5px 0; - - &.left - margin-left: -3px; - padding: 0 5px; - - &.top .tooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -5px; - border-width: 5px 5px 0; - border-top-color: #000; - } - - &.right .tooltip-arrow { - top: 50%; - left: 0; - margin-top: -5px; - border-width: 5px 5px 5px 0; - border-right-color: #000; - } - &.left .tooltip-arrow { - top: 50%; - right: 0; - margin-top: -5px; - border-width: 5px 0 5px 5px; - border-left-color: #000; - } - &.bottom .tooltip-arrow { - top: 0; - left: 50%; - margin-left: -5px; - border-width: 0 5px 5px; - border-bottom-color: #000; - } - -.tooltip-inner { - max-width: 200px; - padding: 3px 8px; - color: #fff; - text-align: center; - background-color: #000; - border-radius: 4px; -} - -.tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} - -.tooltip.in - opacity: .9; diff --git a/platform/ui/src/components/tooltip/__docs__/tooltip.noshow-mdx b/platform/ui/src/components/tooltip/__docs__/tooltip.noshow-mdx deleted file mode 100644 index e5adad984..000000000 --- a/platform/ui/src/components/tooltip/__docs__/tooltip.noshow-mdx +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Tooltip -menu: Components -route: /components/tooltip ---- - -import { Playground, Props } from 'docz' -import { Tooltip } from './../index.js' - -# Tooltip - -## Basic usage - - - - - -## API - - diff --git a/platform/ui/src/components/tooltip/__tests__/.githold b/platform/ui/src/components/tooltip/__tests__/.githold deleted file mode 100644 index e69de29bb..000000000 diff --git a/platform/ui/src/components/tooltip/index.js b/platform/ui/src/components/tooltip/index.js deleted file mode 100644 index 40ede0d67..000000000 --- a/platform/ui/src/components/tooltip/index.js +++ /dev/null @@ -1 +0,0 @@ -export { Tooltip } from './Tooltip.js'; diff --git a/platform/ui/src/contextProviders/DialogProvider.js b/platform/ui/src/contextProviders/DialogProvider.js deleted file mode 100644 index 74e7c1419..000000000 --- a/platform/ui/src/contextProviders/DialogProvider.js +++ /dev/null @@ -1,291 +0,0 @@ -import React, { - useState, - createContext, - useContext, - useCallback, - useEffect, -} from 'react'; -import PropTypes from 'prop-types'; -import Draggable from 'react-draggable'; -import classNames from 'classnames'; - -import { utils } from '@ohif/core'; - -import './DialogProvider.styl'; - -const DialogContext = createContext(null); - -export const useDialog = () => useContext(DialogContext); - -const DialogProvider = ({ children, service }) => { - const [isDragging, setIsDragging] = useState(false); - const [dialogs, setDialogs] = useState([]); - const [lastDialogId, setLastDialogId] = useState(null); - const [lastDialogPosition, setLastDialogPosition] = useState(null); - const [centerPositions, setCenterPositions] = useState([]); - - useEffect(() => { - setCenterPositions( - dialogs.map(dialog => ({ - id: dialog.id, - ...getCenterPosition(dialog.id), - })) - ); - }, [dialogs]); - - const getCenterPosition = id => { - const root = document.querySelector('#root'); - const centerX = root.offsetLeft + root.offsetWidth / 2; - const centerY = root.offsetTop + root.offsetHeight / 2; - const item = document.querySelector(`#draggableItem-${id}`); - const itemBounds = item.getBoundingClientRect(); - return { - x: centerX - itemBounds.width / 2, - y: centerY - itemBounds.height / 2, - }; - }; - - /** - * Sets the implementation of a dialog service that can be used by extensions. - * - * @returns void - */ - useEffect(() => { - if (service) { - service.setServiceImplementation({ create, dismiss, dismissAll }); - } - }, [create, dismiss, service]); - - /** - * UI Dialog - * - * @typedef {Object} DialogProps - * @property {string} id The dialog id. - * @property {DialogContent} content The dialog content. - * @property {Object} contentProps The dialog content props. - * @property {boolean} isDraggable Controls if dialog content is draggable or not. - * @property {boolean} showOverlay Controls dialog overlay. - * @property {boolean} centralize Center the dialog on the screen. - * @property {boolean} preservePosition Use last position instead of default. - * @property {ElementPosition} defaultPosition Specifies the `x` and `y` that the dragged item should start at. - * @property {Function} onStart Called when dragging starts. If `false` is returned any handler, the action will cancel. - * @property {Function} onStop Called when dragging stops. - * @property {Function} onDrag Called while dragging. - */ - - useEffect(() => _bringToFront(lastDialogId), [_bringToFront, lastDialogId]); - - /** - * Creates a new dialog and return its id. - * - * @param {DialogProps} props The dialog props. - * @returns The new dialog id. - */ - const create = useCallback(props => { - const { id } = props; - - let dialogId = id; - if (!dialogId) { - dialogId = utils.guid(); - } - - setDialogs(dialogs => [...dialogs, { ...props, id: dialogId }]); - setLastDialogId(dialogId); - - return dialogId; - }, []); - - /** - * Dismisses the dialog with a given id. - * - * @param {Object} props - - * @property {string} props.id The dialog id. - * @returns void - */ - const dismiss = useCallback( - ({ id }) => - setDialogs(dialogs => dialogs.filter(dialog => dialog.id !== id)), - [] - ); - - /** - * Dismisses all dialogs. - * - * @returns void - */ - const dismissAll = () => { - setDialogs([]); - }; - - /** - * Indicate if there are no dialogs present. - * - * @returns True if no dialogs are present. - */ - const isEmpty = () => dialogs && dialogs.length < 1; - - /** - * Moves the dialog to the foreground if clicked. - * - * @param {string} id The dialog id. - * @returns void - */ - const _bringToFront = useCallback(id => { - setDialogs(dialogs => { - const topDialog = dialogs.find(dialog => dialog.id === id); - return topDialog - ? [...dialogs.filter(dialog => dialog.id !== id), topDialog] - : dialogs; - }); - }, []); - - const renderDialogs = () => - dialogs.map(dialog => { - const { - id, - content: DialogContent, - contentProps, - defaultPosition, - centralize = false, - preservePosition = true, - isDraggable = true, - onStart, - onStop, - onDrag, - showOverlay, - } = dialog; - - let position = - (preservePosition && lastDialogPosition) || defaultPosition; - if (centralize) { - position = centerPositions.find(position => position.id === id); - } - - const dragableItem = () => ( - { - const e = event || window.event; - const target = e.target || e.srcElement; - const BLACKLIST = [ - 'SVG', - 'BUTTON', - 'PATH', - 'INPUT', - 'SPAN', - 'LABEL', - ]; - if (BLACKLIST.includes(target.tagName.toUpperCase())) { - return false; - } - - if (validCallback(onStart)) { - return onStart(event); - } - }} - onStop={event => { - setIsDragging(false); - - if (validCallback(onStop)) { - return onStop(event); - } - }} - onDrag={event => { - setIsDragging(true); - _bringToFront(id); - _updateLastDialogPosition(id); - - if (validCallback(onDrag)) { - return onDrag(event); - } - }} - > -
    _bringToFront(id)} - > - -
    -
    - ); - - return ( - showOverlay ? ( -
    - {dragableItem()} -
    - ) : ( - dragableItem() - ) - ); - }); - - /** - * Update the last dialog position to be used as the new default position. - * - * @returns void - */ - const _updateLastDialogPosition = dialogId => { - const draggableItemBounds = document - .querySelector(`#draggableItem-${dialogId}`) - .getBoundingClientRect(); - setLastDialogPosition({ - x: draggableItemBounds.x, - y: draggableItemBounds.y, - }); - }; - - const validCallback = callback => callback && typeof callback === 'function'; - - return ( - - {!isEmpty() && -
    - {renderDialogs()} -
    - } - {children} -
    - ); -}; - -/** - * - * High Order Component to use the dialog methods through a Class Component - * - */ -export const withDialog = Component => { - return function WrappedComponent(props) { - const { create, dismiss, dismissAll, isEmpty } = useDialog(); - return ( - - ); - }; -}; - -DialogProvider.defaultProps = { - service: null, -}; - -DialogProvider.propTypes = { - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.node), - PropTypes.node, - PropTypes.func, - ]).isRequired, - service: PropTypes.shape({ - setServiceImplementation: PropTypes.func, - }), -}; - -export default DialogProvider; diff --git a/platform/ui/src/contextProviders/DialogProvider.styl b/platform/ui/src/contextProviders/DialogProvider.styl deleted file mode 100644 index f4e576f62..000000000 --- a/platform/ui/src/contextProviders/DialogProvider.styl +++ /dev/null @@ -1,21 +0,0 @@ -.DraggableItem.draggable - div - cursor: grab !important - -.DraggableItem.draggable.dragging - div - cursor: grabbing !important - -.DraggableArea - width: 100% - height: 100% - position: absolute - .Overlay - position: fixed - z-index: 999 - left: 0 - top: 0 - width: 100% - height: 100% - overflow: auto - background: rgba(0,0,0,.1) diff --git a/platform/ui/src/contextProviders/LanguageProvider.js b/platform/ui/src/contextProviders/LanguageProvider.js deleted file mode 100644 index f5e42847b..000000000 --- a/platform/ui/src/contextProviders/LanguageProvider.js +++ /dev/null @@ -1,28 +0,0 @@ -// Reference > https://reactjs.org/docs/context.html -import React from 'react'; -import { - withTranslation as I18NextWithTranslation, - I18nextProvider, -} from 'react-i18next'; -import i18n from '@ohif/i18n'; - -const WrapperI18n = Component => { - const WrapperComponent = props => ( - - - - ); - - return WrapperComponent; -}; - -const withTranslation = namespace => Component => { - const TranslatedComponent = props => { - return ; - }; - - return WrapperI18n(I18NextWithTranslation(namespace)(TranslatedComponent)); -}; - -export { withTranslation }; -export default withTranslation; diff --git a/platform/ui/src/contextProviders/ModalProvider.js b/platform/ui/src/contextProviders/ModalProvider.js deleted file mode 100644 index e8d65635d..000000000 --- a/platform/ui/src/contextProviders/ModalProvider.js +++ /dev/null @@ -1,134 +0,0 @@ -import React, { - useState, - createContext, - useContext, - useEffect, - useCallback, -} from 'react'; -import PropTypes from 'prop-types'; -import classNames from 'classnames'; - -const ModalContext = createContext(null); -const { Provider } = ModalContext; - -export const useModal = () => useContext(ModalContext); - -/** - * UI Modal - * - * @typedef {Object} ModalProps - * @property {ReactElement|HTMLElement} [content=null] Modal content. - * @property {Object} [contentProps=null] Modal content props. - * @property {boolean} [shouldCloseOnEsc=false] Modal is dismissible via the esc key. - * @property {boolean} [isOpen=true] Make the Modal visible or hidden. - * @property {boolean} [closeButton=true] Should the modal body render the close button. - * @property {string} [title=null] Should the modal render the title independently of the body content. - * @property {string} [customClassName=null] The custom class to style the modal. - */ - -const ModalProvider = ({ children, modal: Modal, service }) => { - const DEFAULT_OPTIONS = { - content: null, - contentProps: null, - shouldCloseOnEsc: false, - isOpen: true, - closeButton: true, - title: null, - customClassName: '', - }; - - const [options, setOptions] = useState(DEFAULT_OPTIONS); - - /** - * Sets the implementation of a modal service that can be used by extensions. - * - * @returns void - */ - useEffect(() => { - if (service) { - service.setServiceImplementation({ hide, show }); - } - }, [hide, service, show]); - - /** - * Show the modal and override its configuration props. - * - * @param {ModalProps} props { content, contentProps, shouldCloseOnEsc, isOpen, closeButton, title, customClassName } - * @returns void - */ - const show = useCallback(props => setOptions({ ...options, ...props }), [ - options, - ]); - - /** - * Hide the modal and set its properties to default. - * - * @returns void - */ - const hide = useCallback(() => setOptions(DEFAULT_OPTIONS), [ - DEFAULT_OPTIONS, - ]); - - const { - content: ModalContent, - contentProps, - isOpen, - title, - customClassName, - shouldCloseOnEsc, - closeButton, - } = options; - - return ( - - {ModalContent && ( - - - - )} - {children} - - ); -}; - -/** - * Higher Order Component to use the modal methods through a Class Component. - * - * @returns - */ -export const withModal = Component => { - return function WrappedComponent(props) { - const { show, hide } = useModal(); - return ; - }; -}; - -ModalProvider.defaultProps = { - service: null, -}; - -ModalProvider.propTypes = { - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.node), - PropTypes.node, - ]).isRequired, - modal: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.node), - PropTypes.node, - PropTypes.func, - ]).isRequired, - service: PropTypes.shape({ - setServiceImplementation: PropTypes.func, - }), -}; - -export default ModalProvider; - -export const ModalConsumer = ModalContext.Consumer; diff --git a/platform/ui/src/contextProviders/SnackbarProvider.js b/platform/ui/src/contextProviders/SnackbarProvider.js deleted file mode 100644 index cd8f3b1e0..000000000 --- a/platform/ui/src/contextProviders/SnackbarProvider.js +++ /dev/null @@ -1,142 +0,0 @@ -import React, { - useState, - createContext, - useContext, - useCallback, - useEffect, -} from 'react'; -import PropTypes from 'prop-types'; - -import SnackbarContainer from '../components/snackbar/SnackbarContainer'; -import SnackbarTypes from '../components/snackbar/SnackbarTypes'; - -const SnackbarContext = createContext(null); - -export const useSnackbarContext = () => useContext(SnackbarContext); - -const SnackbarProvider = ({ children, service }) => { - const DEFAULT_OPTIONS = { - title: '', - message: '', - duration: 5000, - autoClose: true, - position: 'bottomRight', - type: SnackbarTypes.INFO, - }; - - const [count, setCount] = useState(1); - const [snackbarItems, setSnackbarItems] = useState([]); - - /** - * Sets the implementation of a notification service that can be used by extensions. - * - * @returns void - */ - useEffect(() => { - if (service) { - service.setServiceImplementation({ hide, show }); - } - }, [service, hide, show]); - - const show = useCallback( - options => { - if (!options || (!options.title && !options.message)) { - console.warn( - 'Snackbar cannot be rendered without required parameters: title | message' - ); - - return null; - } - - const newItem = { - ...DEFAULT_OPTIONS, - ...options, - id: count, - visible: true, - }; - - setSnackbarItems(state => [...state, newItem]); - setCount(count + 1); - }, - [count, DEFAULT_OPTIONS] - ); - - const hide = useCallback( - id => { - const hideItem = items => { - const newItems = items.map(item => { - if (item.id === id) { - item.visible = false; - } - - return item; - }); - - return newItems; - }; - - setSnackbarItems(state => hideItem(state)); - - setTimeout(() => { - setSnackbarItems(state => [...state.filter(item => item.id !== id)]); - }, 1000); - }, - [setSnackbarItems] - ); - - const hideAll = () => { - // reset count - setCount(1); - - // remove all items from array - setSnackbarItems(() => []); - }; - - /** - * expose snackbar methods to window for debug purposes - * TODO: Check if it's really necessary - */ - window.snackbar = { - show, - hide, - hideAll, - }; - - return ( - - {!!snackbarItems && } - {children} - - ); -}; - -SnackbarProvider.defaultProps = { - service: null, -}; - -SnackbarProvider.propTypes = { - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.node), - PropTypes.node, - PropTypes.func, - ]).isRequired, - service: PropTypes.shape({ - setServiceImplementation: PropTypes.func, - }), -}; - -/** - * - * High Order Component to use the snackbar methods through a Class Component - * - */ -export const withSnackbar = Component => { - return function WrappedComponent(props) { - const snackbarContext = { - ...useSnackbarContext(), - }; - return ; - }; -}; - -export default SnackbarProvider; diff --git a/platform/ui/src/contextProviders/index.js b/platform/ui/src/contextProviders/index.js deleted file mode 100644 index e4ca06143..000000000 --- a/platform/ui/src/contextProviders/index.js +++ /dev/null @@ -1,20 +0,0 @@ -export { - default as ModalProvider, - useModal, - withModal, - ModalConsumer, -} from './ModalProvider.js'; -export { - default as SnackbarProvider, - useSnackbarContext, - withSnackbar, -} from './SnackbarProvider.js'; -export { - default as LanguageProvider, - withTranslation, -} from './LanguageProvider.js'; -export { - default as DialogProvider, - withDialog, - useDialog, -} from './DialogProvider.js'; diff --git a/platform/ui/src/design/styles/common/button.styl b/platform/ui/src/design/styles/common/button.styl deleted file mode 100644 index ea3f0b1eb..000000000 --- a/platform/ui/src/design/styles/common/button.styl +++ /dev/null @@ -1,53 +0,0 @@ -.btn-danger - color: #fff; - background-color: #d9534f; - border-color: #d43f3a; - -.btn-primary - color: #fff; - background-color: #337ab7; - border-color: #2e6da4; - -.btn-default - color: #333; - background-color: #fff; - border-color: #ccc; - -.btn - display: inline-block; - padding: 6px 12px; - margin-bottom: 0; - font-size: 14px; - font-weight: 400; - line-height: 1.42857143; - text-align: center; - white-space: nowrap; - vertical-align: middle; - -ms-touch-action: manipulation; - touch-action: manipulation; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - background-image: none; - border: 1px solid transparent; - border-radius: 4px; - -.btn.disabled, .btn[disabled], fieldset[disabled] .btn - cursor: not-allowed; - -webkit-box-shadow: none; - box-shadow: none; - opacity: .65; - -button.close - -webkit-appearance: none; - padding: 0; - cursor: pointer; - background: 0 0; - border: 0; - -.btn-group, .btn-group-vertical - position: relative; - display: inline-block; - vertical-align: middle; diff --git a/platform/ui/src/design/styles/common/form.styl b/platform/ui/src/design/styles/common/form.styl deleted file mode 100644 index 230c7b4d4..000000000 --- a/platform/ui/src/design/styles/common/form.styl +++ /dev/null @@ -1,121 +0,0 @@ -.form-themed - - table - color: var(--text-primary-color) - - th, td - font-size: 15px - font-weight: normal - - th - line-height: 60px - - td - line-height: 18px - padding: 0; - - // TODO: imported this from merged-styles.css - .p-r-1 - padding-right: 1rem !important; - - label - margin-bottom: 5px - // end TODO - - label.wrapperLabel - cursor: pointer - - label.wrapperLabel:not(.checkboxLabel) - cursor: pointer - display: flex - flex-direction: column - - .wrapperText - display: block - order: -1 - transition(color 0.3s ease) - - .btn, input[type=text], input[type=password], input[type=number] - &[disabled], &.disabled - &, &:hover, &:active - background-color: var(--ui-gray-darker) - border-color: var(--ui-gray-light) - color: var(--text-primary-color) - - & + .wrapperText - color: var(--text-primary-color) - cursor: auto - - input[type=text], input[type=password], input[type=number] - background-color: var(--ui-gray) - border-color: var(--ui-border-color) - color: var(--text-primary-color) - font-weight: normal - transition(background-color 0.3s ease\, border-color 0.3s ease) - - &:active, &:focus - background-color: var(--ui-gray-dark) - border: 2px solid var(--active-color) - box-shadow: none - - & + .wrapperText - color: var(--active-color) - - .btn-primary - background-color: var(--active-color) - border-collapse: var(--ui-border-color-active) - color: var(--ui-text-color-active) - transition(background-color 0.3s ease\, border-color 0.3s ease) - - &:hover, &:active, &:focus, &:focus:active - // TODO: 0.8 opacity - background-color: var(--ui-active-color) - border-collapse: var(--ui-border-color-active) - color: var(--ui-text-color-active) - - .form-control - background-color: #FFFFFF - border: 0 - border-radius(2px) - font-size: 14px - height: 30px - line-height: 16px - padding: 8px 9px 6px - -.form-control - display: block; - width: 100%; - height: 34px; - padding: 6px 12px; - font-size: 14px; - line-height: 1.42857143; - color: #555; - background-color: #fff; - background-image: none; - border: 1px solid #ccc; - border-radius: 4px; - box-shadow: inset 0 1px 1px rgba(0,0,0,.075); - - &:focus - border-color: #66afe9; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102,175,233,.6); - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102,175,233,.6); - - &::-ms-expand - border: 0; - background-color: transparent; - - &[disabled], - &[readonly], - fieldset[disabled] & - background-color: @input-bg-disabled; - opacity: 1; - - &[disabled], - fieldset[disabled] & - cursor: @cursor-disabled; - -input[type=range] - display: block; - width: 100%; diff --git a/platform/ui/src/design/styles/common/global.styl b/platform/ui/src/design/styles/common/global.styl deleted file mode 100644 index af81a0882..000000000 --- a/platform/ui/src/design/styles/common/global.styl +++ /dev/null @@ -1,71 +0,0 @@ -* - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - -.full-width - width: 100% - -.full-height - height: 100% - -.flex-h - display: flex - flex-direction: row - -.flex-v - display: flex - flex-direction: column - -.flex-grow - flex-grow: 1 - -.nowrap - white-space: nowrap - -.text-right - text-align: right; - -.text-center - text-align: center; - -.text-left - text-align: left; - -h1 - font-size: 36px; - -h3, h1 - font-family: inherit; - font-weight: 500; - line-height: 1.1; - margin-top: 20px; - margin-bottom: 10px; - -button, input, select, textarea - font-family: inherit; - font-size: inherit; - line-height: inherit; - -.row - margin-right: -15px; - margin-left: -15px; - -.pull-left - float: left!important; - -.pull-right - float: right!important; - -.fade - opacity: 0; - -webkit-transition: opacity .15s linear; - -o-transition: opacity .15s linear; - transition: opacity .15s linear; - -.fade.in - opacity: 1; - -a - color: #337ab7; - text-decoration: none; diff --git a/platform/ui/src/design/styles/common/modal.styl b/platform/ui/src/design/styles/common/modal.styl deleted file mode 100644 index ad0e80603..000000000 --- a/platform/ui/src/design/styles/common/modal.styl +++ /dev/null @@ -1,203 +0,0 @@ - -.modal-open - overflow: hidden; - -.modal - overflow: hidden; - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1050; - -webkit-overflow-scrolling: touch; - outline: 0; - background: rgba(0,0,0,0.5); - - .modal-dialog - - .modal-content - background-color: var(--ui-gray-darker) - border-color: var(--ui-border-color) - color: var(--text-secondary-color) - border-radius(6px) - border: 0 - - .modal-header, .modal-footer - border-color: var(--ui-border-color) - - .dialog-separator, - .dialog-separator-before, - .dialog-separator-after - position: relative - height: 40px; - - .dialog-separator:before, - .dialog-separator:after, - .dialog-separator-before:before, - .dialog-separator-after:after - background-color: #000000 - box-shadow(-50px 0 0 #000000\, 50px 0 0 #000000) - content: ' ' - display: block - height: 3px - left: 0 - position: absolute - width: 100% - - .dialog-separator:before, - .dialog-separator-before:before - top: -3px - - .dialog-separator:after, - .dialog-separator-after:after - bottom: -3px - - .modal-body - color: var(--text-primary-color) - padding: 16px 22px 0px - position: relative - - ::-webkit-scrollbar { - width: 6px; - background-color: var(--ui-gray-dark); - } - - ::-webkit-scrollbar-thumb { - background-color: var(--ui-gray-light); - border-radius: 5px; - } - - .modal-header - border-bottom-width: 3px - border-bottom-style: solid - border-bottom-color: #000000 - padding: 19px 22px 17px - position: relative - - h4 - color: var(--text-secondary-color) - font-size: 20px - font-weight: 500 - line-height: 24px - padding-right: 24px - - .modal-footer - border-top: 0 - padding-top: 0 - - .card-round - background-color: var(--ui-gray-dark) - border-radius(5px) - padding: 10px - - .modal-header - position: relative - - // When fading in the modal, animate it to slide down - &.fade .modal-dialog - -webkit-transition: transform .3s ease-out; - -o-transition: transform .3s ease-out; - transition: transform .3s ease-out; - -webkit-transform: translate(0,-25%); - -ms-transform: translate(0,-25%); - -o-transform: translate(0,-25%); - transform: translate(0,-25%); - - &.in .modal-dialog - transform: translate(0,0) - -.modal-open .modal - overflow-x: hidden; - overflow-y: auto; - -.modal-dialog - position: relative; - width: auto; - margin: 10px; - -.modal-content - position: relative; - background-color: #fff; - border: 1px solid rgba(0,0,0,.2); - border-radius: 6px; - -webkit-box-shadow: 0 3px 9px rgba(0,0,0,.5); - box-shadow: 0 3px 9px rgba(0,0,0,.5); - background-clip: padding-box; - outline: 0; - -.modal-backdrop - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1050; - background-color: #fff; - - &.fade - opacity: 0; - - &.in - opacity: 0; - -.modal-header - padding: 15px; - border-bottom: 1px solid #e5e5e5; - -.modal-header .close - margin-top: -2px; - -.modal-title - margin: 0; - line-height: 1.42857143; - -.modal-body - position: relative; - padding: 15px; - -.modal-footer - padding: 15px; - text-align: right; - border-top: 1px solid #e5e5e5; - - .btn+.btn - margin-left: 5px; - margin-bottom: 0; - - .btn-group .btn+.btn - margin-left: -1px; - - .btn-block+.btn-block - margin-left: 0; - -.modal-scrollbar-measure - position: absolute; - top: -9999px; - width: 50px; - height: 50px; - overflow: scroll; - -@media (min-width: 768px) - .modal-dialog - width: 600px; - margin: 30px auto; - - .modal-content - -webkit-box-shadow: 0 5px 15px rgba(0,0,0,.5); - box-shadow: 0 5px 15px rgba(0,0,0,.5); - -@media (min-width: 992px) - .modal-lg - width: 900px; - -.button-close, .modal-dialog button.close - color: var(--text-secondary-color) - height: 25px - opacity: 1 - overflow: hidden - text-align: center - text-shadow: none - width: 25px - font-size:25px - font-weight: lighter diff --git a/platform/ui/src/design/styles/common/navbar.styl b/platform/ui/src/design/styles/common/navbar.styl deleted file mode 100644 index dda831789..000000000 --- a/platform/ui/src/design/styles/common/navbar.styl +++ /dev/null @@ -1,57 +0,0 @@ -.nav-tabs - border-bottom: 0 - margin-bottom: 3px - position: relative - z-index: 1 - - :hover - cursor: pointer - - &>li - font-size: 14px - font-weight: normal - height: 40px - line-height: 40px - margin-bottom: 0 - - &>button - display: block - width: 100% - line-height: inherit - margin: 0 - height: inherit - padding: 0 10px 0 10px - outline: none - - &:after - background-color: transparent - bottom: -3px - content: ' ' - display: block - height: 3px - transition(background-color 0.3s ease) - width: 100% - - &>button, &.active>button - &, &:hover, &:active, &:focus - color: var(--active-color) - background-color: transparent - border: 0 - - &.active>button - font-weight: bold - - &:after - background-color: var(--active-color) - -.nav - padding-left: 0; - list-style: none; - - > li - position: relative; - display: block; - - > li - float: left; - margin-bottom: -1px; diff --git a/platform/ui/src/design/styles/common/state.styl b/platform/ui/src/design/styles/common/state.styl deleted file mode 100644 index 8c438f741..000000000 --- a/platform/ui/src/design/styles/common/state.styl +++ /dev/null @@ -1,25 +0,0 @@ -.form-themed .state-error, .state-error - - &.wrapperLabel input + .wrapperText - color: var(--state-error-text) - - &+.tooltip - - .tooltip-inner - color: white - background-color: var(--state-error-border) - - &.top .tooltip-arrow - border-top-color: var(--state-error-border) - &.right .tooltip-arrow - border-right-color: var(--state-error-border) - &.bottom .tooltip-arrow - border-bottom-color: var(--state-error-border) - &.left .tooltip-arrow - border-left-color: var(--state-error-border) - - - &:not(.component-group) - &.form-control, .form-control - background-color: var(--state-error-border) - border-color: var(--state-error-border) diff --git a/platform/ui/src/design/styles/common/table.styl b/platform/ui/src/design/styles/common/table.styl deleted file mode 100644 index 26485d4e7..000000000 --- a/platform/ui/src/design/styles/common/table.styl +++ /dev/null @@ -1,15 +0,0 @@ -.table-responsive - min-height: .01%; - overflow-x: auto; - -.table - width: 100%; - max-width: 100%; - margin-bottom: 20px; - -table - border-spacing: 0; - border-collapse: collapse; - -th - text-align: left; diff --git a/platform/ui/src/elements/Icon/Icon.js b/platform/ui/src/elements/Icon/Icon.js deleted file mode 100644 index 5791fee68..000000000 --- a/platform/ui/src/elements/Icon/Icon.js +++ /dev/null @@ -1,15 +0,0 @@ -import './Icon.styl'; - -import PropTypes from 'prop-types'; -import getIcon from './getIcon.js'; - -const Icon = props => { - return getIcon(props.name, props); -}; - -Icon.propTypes = { - /** The string name of the icon to display */ - name: PropTypes.string.isRequired, -}; - -export default Icon; diff --git a/platform/ui/src/elements/Icon/Icon.styl b/platform/ui/src/elements/Icon/Icon.styl deleted file mode 100644 index 12ded599c..000000000 --- a/platform/ui/src/elements/Icon/Icon.styl +++ /dev/null @@ -1,11 +0,0 @@ -.icon-pulse - fa-spin 1s infinite steps(8) - -.icon-spin { - animation: spin 2s linear infinite; -} - -@keyframes fa-spin{ - 0%{ transform:rotate(0deg) } - to{ transform:rotate(1turn) } -} diff --git a/platform/ui/src/elements/Icon/__docs__/icon.mdx b/platform/ui/src/elements/Icon/__docs__/icon.mdx deleted file mode 100644 index c5b8f07a3..000000000 --- a/platform/ui/src/elements/Icon/__docs__/icon.mdx +++ /dev/null @@ -1,84 +0,0 @@ ---- -name: Icon -menu: Elements -route: /elements/icon ---- - -import { Playground, Props } from 'docz'; -import { State } from 'react-powerplug'; -import { Icon, ICONS } from './../index.js'; - -# Icon - -## Basic usage - - -
    - {Object.keys(ICONS) - .sort() - .map((name, i) => { - return ( - -
    - -
    - {name} -
    -
    -
    - ); - })} -
    -
    - -The `` component inherits the color of its parent, and sizing is based -on its parent's `font-size`. Each icon has an `aria-labelledby` to assist screen -readers. - -We use `airbnb`'s [`babel-plugin-inline-react-svg`][airbnb] to automate -optimizing SVG files with [SVGO][svgo] and to create animatable React SVG -components that can be requested asynchronously. You can configure SVGO's -plugins [by following the advice laid out here][svgo-configure] - -## API - - - -The `Icon` component takes a single prop of `name`, which indicates which Icon -should be displayed. Again, the icon responds to contextual text/font styles. - -## Attribution - -A large number of these icons are from [Font Awesome 5's free set.][fa-license] -Some attribution is likely required, depending on your usage. Sometimes as -little as a comment included side-by-side with the accompanying SVG icon. - - - - -[fa-license]: https://fontawesome.com/license -[airbnb]: https://github.com/airbnb/babel-plugin-inline-react-svg -[svgo]: https://github.com/svg/svgo/ -[svgo-configure]: https://github.com/airbnb/babel-plugin-inline-react-svg/issues/9#issuecomment-310178317) - diff --git a/platform/ui/src/elements/Icon/icons/3d-rotate.svg b/platform/ui/src/elements/Icon/icons/3d-rotate.svg deleted file mode 100644 index f9d2daadb..000000000 --- a/platform/ui/src/elements/Icon/icons/3d-rotate.svg +++ /dev/null @@ -1,13 +0,0 @@ - - 3D Rotate - - - - diff --git a/platform/ui/src/elements/Icon/icons/adjust.svg b/platform/ui/src/elements/Icon/icons/adjust.svg deleted file mode 100644 index ae2747644..000000000 --- a/platform/ui/src/elements/Icon/icons/adjust.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Adjust - - diff --git a/platform/ui/src/elements/Icon/icons/angle-double-down.svg b/platform/ui/src/elements/Icon/icons/angle-double-down.svg deleted file mode 100644 index 04d9d9fcf..000000000 --- a/platform/ui/src/elements/Icon/icons/angle-double-down.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Angle Double Down - - diff --git a/platform/ui/src/elements/Icon/icons/angle-double-up.svg b/platform/ui/src/elements/Icon/icons/angle-double-up.svg deleted file mode 100644 index 07419bb65..000000000 --- a/platform/ui/src/elements/Icon/icons/angle-double-up.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Angle Double Up - - diff --git a/platform/ui/src/elements/Icon/icons/angle-left.svg b/platform/ui/src/elements/Icon/icons/angle-left.svg deleted file mode 100644 index 15fb36b07..000000000 --- a/platform/ui/src/elements/Icon/icons/angle-left.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Angle Left - - diff --git a/platform/ui/src/elements/Icon/icons/arrows-alt-h.svg b/platform/ui/src/elements/Icon/icons/arrows-alt-h.svg deleted file mode 100644 index c96cb738c..000000000 --- a/platform/ui/src/elements/Icon/icons/arrows-alt-h.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Arrows Alt H - - diff --git a/platform/ui/src/elements/Icon/icons/arrows-alt-v.svg b/platform/ui/src/elements/Icon/icons/arrows-alt-v.svg deleted file mode 100644 index f1e777ddd..000000000 --- a/platform/ui/src/elements/Icon/icons/arrows-alt-v.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Arrows Alt V - - diff --git a/platform/ui/src/elements/Icon/icons/arrows.svg b/platform/ui/src/elements/Icon/icons/arrows.svg deleted file mode 100644 index 4aca49cff..000000000 --- a/platform/ui/src/elements/Icon/icons/arrows.svg +++ /dev/null @@ -1,22 +0,0 @@ - - Arrows - - - - - - - - - diff --git a/platform/ui/src/elements/Icon/icons/bars.svg b/platform/ui/src/elements/Icon/icons/bars.svg deleted file mode 100644 index 3b735f90e..000000000 --- a/platform/ui/src/elements/Icon/icons/bars.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Bars - - diff --git a/platform/ui/src/elements/Icon/icons/brain.svg b/platform/ui/src/elements/Icon/icons/brain.svg deleted file mode 100644 index f03f67ace..000000000 --- a/platform/ui/src/elements/Icon/icons/brain.svg +++ /dev/null @@ -1,24 +0,0 @@ - - Brain - - - - - - - - - - diff --git a/platform/ui/src/elements/Icon/icons/caret-down.svg b/platform/ui/src/elements/Icon/icons/caret-down.svg deleted file mode 100644 index cdebbd8f5..000000000 --- a/platform/ui/src/elements/Icon/icons/caret-down.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Caret Down - - diff --git a/platform/ui/src/elements/Icon/icons/caret-up.svg b/platform/ui/src/elements/Icon/icons/caret-up.svg deleted file mode 100644 index 611ca870e..000000000 --- a/platform/ui/src/elements/Icon/icons/caret-up.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Caret Up - - diff --git a/platform/ui/src/elements/Icon/icons/check-circle-o.svg b/platform/ui/src/elements/Icon/icons/check-circle-o.svg deleted file mode 100644 index 98b247319..000000000 --- a/platform/ui/src/elements/Icon/icons/check-circle-o.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Check Circle - - diff --git a/platform/ui/src/elements/Icon/icons/check-circle.svg b/platform/ui/src/elements/Icon/icons/check-circle.svg deleted file mode 100644 index 7f54493fe..000000000 --- a/platform/ui/src/elements/Icon/icons/check-circle.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Check Circle - - diff --git a/platform/ui/src/elements/Icon/icons/check.svg b/platform/ui/src/elements/Icon/icons/check.svg deleted file mode 100644 index 22d93a1fb..000000000 --- a/platform/ui/src/elements/Icon/icons/check.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Check - - diff --git a/platform/ui/src/elements/Icon/icons/chevron-down.svg b/platform/ui/src/elements/Icon/icons/chevron-down.svg deleted file mode 100644 index 1c28b0512..000000000 --- a/platform/ui/src/elements/Icon/icons/chevron-down.svg +++ /dev/null @@ -1,14 +0,0 @@ - - Chevron Down - - diff --git a/platform/ui/src/elements/Icon/icons/circle-notch.svg b/platform/ui/src/elements/Icon/icons/circle-notch.svg deleted file mode 100644 index 1a9429bda..000000000 --- a/platform/ui/src/elements/Icon/icons/circle-notch.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Circle Notch - - diff --git a/platform/ui/src/elements/Icon/icons/circle-o.svg b/platform/ui/src/elements/Icon/icons/circle-o.svg deleted file mode 100644 index c921f1534..000000000 --- a/platform/ui/src/elements/Icon/icons/circle-o.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Circle Outline - - diff --git a/platform/ui/src/elements/Icon/icons/circle.svg b/platform/ui/src/elements/Icon/icons/circle.svg deleted file mode 100644 index 99b9995b3..000000000 --- a/platform/ui/src/elements/Icon/icons/circle.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Circle - - diff --git a/platform/ui/src/elements/Icon/icons/cog.svg b/platform/ui/src/elements/Icon/icons/cog.svg deleted file mode 100644 index 017fc0e6d..000000000 --- a/platform/ui/src/elements/Icon/icons/cog.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Cog - - diff --git a/platform/ui/src/elements/Icon/icons/create-comment.svg b/platform/ui/src/elements/Icon/icons/create-comment.svg deleted file mode 100644 index aec47a3ae..000000000 --- a/platform/ui/src/elements/Icon/icons/create-comment.svg +++ /dev/null @@ -1,12 +0,0 @@ - - Create Comment - - - diff --git a/platform/ui/src/elements/Icon/icons/create-screen-capture.svg b/platform/ui/src/elements/Icon/icons/create-screen-capture.svg deleted file mode 100644 index cf7d8433d..000000000 --- a/platform/ui/src/elements/Icon/icons/create-screen-capture.svg +++ /dev/null @@ -1,15 +0,0 @@ - - Create Screen Capture - - - - - - diff --git a/platform/ui/src/elements/Icon/icons/crosshairs.svg b/platform/ui/src/elements/Icon/icons/crosshairs.svg deleted file mode 100644 index 4d53a1042..000000000 --- a/platform/ui/src/elements/Icon/icons/crosshairs.svg +++ /dev/null @@ -1,15 +0,0 @@ - - Crosshairs - - - diff --git a/platform/ui/src/elements/Icon/icons/cube.svg b/platform/ui/src/elements/Icon/icons/cube.svg deleted file mode 100644 index 6026cdf63..000000000 --- a/platform/ui/src/elements/Icon/icons/cube.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - Cube - - diff --git a/platform/ui/src/elements/Icon/icons/database.svg b/platform/ui/src/elements/Icon/icons/database.svg deleted file mode 100644 index 323d566e2..000000000 --- a/platform/ui/src/elements/Icon/icons/database.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Database - - diff --git a/platform/ui/src/elements/Icon/icons/dot-circle.svg b/platform/ui/src/elements/Icon/icons/dot-circle.svg deleted file mode 100644 index 3533dde76..000000000 --- a/platform/ui/src/elements/Icon/icons/dot-circle.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Dot Circle - - diff --git a/platform/ui/src/elements/Icon/icons/edit.svg b/platform/ui/src/elements/Icon/icons/edit.svg deleted file mode 100644 index c7554488d..000000000 --- a/platform/ui/src/elements/Icon/icons/edit.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Edit - - diff --git a/platform/ui/src/elements/Icon/icons/ellipse-circle.svg b/platform/ui/src/elements/Icon/icons/ellipse-circle.svg deleted file mode 100644 index a0c591c2b..000000000 --- a/platform/ui/src/elements/Icon/icons/ellipse-circle.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Ellipse Circle - - diff --git a/platform/ui/src/elements/Icon/icons/ellipse-h.svg b/platform/ui/src/elements/Icon/icons/ellipse-h.svg deleted file mode 100644 index 1dbb78331..000000000 --- a/platform/ui/src/elements/Icon/icons/ellipse-h.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Ellipse Horizontal - - diff --git a/platform/ui/src/elements/Icon/icons/ellipse-v.svg b/platform/ui/src/elements/Icon/icons/ellipse-v.svg deleted file mode 100644 index 01a0d719a..000000000 --- a/platform/ui/src/elements/Icon/icons/ellipse-v.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Ellipse Vertical - - diff --git a/platform/ui/src/elements/Icon/icons/eraser.svg b/platform/ui/src/elements/Icon/icons/eraser.svg deleted file mode 100644 index 7e9361f9b..000000000 --- a/platform/ui/src/elements/Icon/icons/eraser.svg +++ /dev/null @@ -1,15 +0,0 @@ - - Eraser - - diff --git a/platform/ui/src/elements/Icon/icons/exclamation-circle.svg b/platform/ui/src/elements/Icon/icons/exclamation-circle.svg deleted file mode 100644 index f3a1d4146..000000000 --- a/platform/ui/src/elements/Icon/icons/exclamation-circle.svg +++ /dev/null @@ -1,13 +0,0 @@ - - Exclamation Circle - - diff --git a/platform/ui/src/elements/Icon/icons/exclamation-triangle.svg b/platform/ui/src/elements/Icon/icons/exclamation-triangle.svg deleted file mode 100644 index 65da6f8e8..000000000 --- a/platform/ui/src/elements/Icon/icons/exclamation-triangle.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Exclamation Triangle - - diff --git a/platform/ui/src/elements/Icon/icons/fast-backward.svg b/platform/ui/src/elements/Icon/icons/fast-backward.svg deleted file mode 100644 index c1696b98f..000000000 --- a/platform/ui/src/elements/Icon/icons/fast-backward.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/platform/ui/src/elements/Icon/icons/fast-forward.svg b/platform/ui/src/elements/Icon/icons/fast-forward.svg deleted file mode 100644 index cd6bb9b7c..000000000 --- a/platform/ui/src/elements/Icon/icons/fast-forward.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/platform/ui/src/elements/Icon/icons/info.svg b/platform/ui/src/elements/Icon/icons/info.svg deleted file mode 100644 index 9e802a69f..000000000 --- a/platform/ui/src/elements/Icon/icons/info.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Info - - diff --git a/platform/ui/src/elements/Icon/icons/inline-edit.svg b/platform/ui/src/elements/Icon/icons/inline-edit.svg deleted file mode 100644 index 12c111b2c..000000000 --- a/platform/ui/src/elements/Icon/icons/inline-edit.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Inline Edit - - diff --git a/platform/ui/src/elements/Icon/icons/level.svg b/platform/ui/src/elements/Icon/icons/level.svg deleted file mode 100644 index c79ffc2f6..000000000 --- a/platform/ui/src/elements/Icon/icons/level.svg +++ /dev/null @@ -1,13 +0,0 @@ - - Level - - - diff --git a/platform/ui/src/elements/Icon/icons/link-circles.svg b/platform/ui/src/elements/Icon/icons/link-circles.svg deleted file mode 100644 index fd980320a..000000000 --- a/platform/ui/src/elements/Icon/icons/link-circles.svg +++ /dev/null @@ -1,15 +0,0 @@ - - Link Circles - - - - - diff --git a/platform/ui/src/elements/Icon/icons/link.svg b/platform/ui/src/elements/Icon/icons/link.svg deleted file mode 100644 index 28faa4853..000000000 --- a/platform/ui/src/elements/Icon/icons/link.svg +++ /dev/null @@ -1,12 +0,0 @@ - - Link - - - diff --git a/platform/ui/src/elements/Icon/icons/list.svg b/platform/ui/src/elements/Icon/icons/list.svg deleted file mode 100644 index 15e7a6c95..000000000 --- a/platform/ui/src/elements/Icon/icons/list.svg +++ /dev/null @@ -1,11 +0,0 @@ - - List - - diff --git a/platform/ui/src/elements/Icon/icons/liver.svg b/platform/ui/src/elements/Icon/icons/liver.svg deleted file mode 100644 index a099709f4..000000000 --- a/platform/ui/src/elements/Icon/icons/liver.svg +++ /dev/null @@ -1,16 +0,0 @@ - - Liver - - - - diff --git a/platform/ui/src/elements/Icon/icons/lock-alt.svg b/platform/ui/src/elements/Icon/icons/lock-alt.svg deleted file mode 100644 index 570a16de6..000000000 --- a/platform/ui/src/elements/Icon/icons/lock-alt.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Lock - - diff --git a/platform/ui/src/elements/Icon/icons/lock.svg b/platform/ui/src/elements/Icon/icons/lock.svg deleted file mode 100644 index 6a43ae317..000000000 --- a/platform/ui/src/elements/Icon/icons/lock.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Lock - - diff --git a/platform/ui/src/elements/Icon/icons/lung.svg b/platform/ui/src/elements/Icon/icons/lung.svg deleted file mode 100644 index 2de91333c..000000000 --- a/platform/ui/src/elements/Icon/icons/lung.svg +++ /dev/null @@ -1,25 +0,0 @@ - - Lung - - - - - - - diff --git a/platform/ui/src/elements/Icon/icons/measure-non-target.svg b/platform/ui/src/elements/Icon/icons/measure-non-target.svg deleted file mode 100644 index 6c6c55f61..000000000 --- a/platform/ui/src/elements/Icon/icons/measure-non-target.svg +++ /dev/null @@ -1,29 +0,0 @@ - - Measure Non-Target - - - - diff --git a/platform/ui/src/elements/Icon/icons/measure-target-cr.svg b/platform/ui/src/elements/Icon/icons/measure-target-cr.svg deleted file mode 100644 index 474136ac7..000000000 --- a/platform/ui/src/elements/Icon/icons/measure-target-cr.svg +++ /dev/null @@ -1,23 +0,0 @@ - - Measure Target CR - - CR - - - diff --git a/platform/ui/src/elements/Icon/icons/measure-target-ne.svg b/platform/ui/src/elements/Icon/icons/measure-target-ne.svg deleted file mode 100644 index 492a880e7..000000000 --- a/platform/ui/src/elements/Icon/icons/measure-target-ne.svg +++ /dev/null @@ -1,16 +0,0 @@ - - Measure Target NE - NE - - diff --git a/platform/ui/src/elements/Icon/icons/measure-target-un.svg b/platform/ui/src/elements/Icon/icons/measure-target-un.svg deleted file mode 100644 index 5ba5eb223..000000000 --- a/platform/ui/src/elements/Icon/icons/measure-target-un.svg +++ /dev/null @@ -1,23 +0,0 @@ - - Measure Target UN - - UN - - - diff --git a/platform/ui/src/elements/Icon/icons/measure-target.svg b/platform/ui/src/elements/Icon/icons/measure-target.svg deleted file mode 100644 index 19596906a..000000000 --- a/platform/ui/src/elements/Icon/icons/measure-target.svg +++ /dev/null @@ -1,13 +0,0 @@ - - Measure Target - - - diff --git a/platform/ui/src/elements/Icon/icons/measure-temp.svg b/platform/ui/src/elements/Icon/icons/measure-temp.svg deleted file mode 100644 index fb2e2b98b..000000000 --- a/platform/ui/src/elements/Icon/icons/measure-temp.svg +++ /dev/null @@ -1,16 +0,0 @@ - - Measure Temp - - - - - - diff --git a/platform/ui/src/elements/Icon/icons/object-group.svg b/platform/ui/src/elements/Icon/icons/object-group.svg deleted file mode 100644 index edd4bc189..000000000 --- a/platform/ui/src/elements/Icon/icons/object-group.svg +++ /dev/null @@ -1,20 +0,0 @@ - - Object Group - - - - - diff --git a/platform/ui/src/elements/Icon/icons/ohif-logo.svg b/platform/ui/src/elements/Icon/icons/ohif-logo.svg deleted file mode 100644 index f6525ab90..000000000 --- a/platform/ui/src/elements/Icon/icons/ohif-logo.svg +++ /dev/null @@ -1,17 +0,0 @@ - - OHIF Logo - - - - - diff --git a/platform/ui/src/elements/Icon/icons/ohif-text-logo.svg b/platform/ui/src/elements/Icon/icons/ohif-text-logo.svg deleted file mode 100644 index f06a067b5..000000000 --- a/platform/ui/src/elements/Icon/icons/ohif-text-logo.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/platform/ui/src/elements/Icon/icons/oval.svg b/platform/ui/src/elements/Icon/icons/oval.svg deleted file mode 100644 index 0a69e6b11..000000000 --- a/platform/ui/src/elements/Icon/icons/oval.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Oval - - diff --git a/platform/ui/src/elements/Icon/icons/palette.svg b/platform/ui/src/elements/Icon/icons/palette.svg deleted file mode 100644 index 04f596ba1..000000000 --- a/platform/ui/src/elements/Icon/icons/palette.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Pallete - - diff --git a/platform/ui/src/elements/Icon/icons/play.svg b/platform/ui/src/elements/Icon/icons/play.svg deleted file mode 100644 index 64ca7a5e3..000000000 --- a/platform/ui/src/elements/Icon/icons/play.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/platform/ui/src/elements/Icon/icons/plus.svg b/platform/ui/src/elements/Icon/icons/plus.svg deleted file mode 100644 index 6512e1116..000000000 --- a/platform/ui/src/elements/Icon/icons/plus.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Add - - diff --git a/platform/ui/src/elements/Icon/icons/power-off.svg b/platform/ui/src/elements/Icon/icons/power-off.svg deleted file mode 100644 index 3dd5dcf20..000000000 --- a/platform/ui/src/elements/Icon/icons/power-off.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Power Off - - diff --git a/platform/ui/src/elements/Icon/icons/reset.svg b/platform/ui/src/elements/Icon/icons/reset.svg deleted file mode 100644 index 8b2c9aa53..000000000 --- a/platform/ui/src/elements/Icon/icons/reset.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Reset - - diff --git a/platform/ui/src/elements/Icon/icons/rotate-right.svg b/platform/ui/src/elements/Icon/icons/rotate-right.svg deleted file mode 100644 index 106284fa0..000000000 --- a/platform/ui/src/elements/Icon/icons/rotate-right.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Rotate Right - - diff --git a/platform/ui/src/elements/Icon/icons/rotate.svg b/platform/ui/src/elements/Icon/icons/rotate.svg deleted file mode 100644 index 2dded38c4..000000000 --- a/platform/ui/src/elements/Icon/icons/rotate.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Rotate - - diff --git a/platform/ui/src/elements/Icon/icons/save-regular.svg b/platform/ui/src/elements/Icon/icons/save-regular.svg deleted file mode 100644 index cd3eb9592..000000000 --- a/platform/ui/src/elements/Icon/icons/save-regular.svg +++ /dev/null @@ -1,11 +0,0 @@ - diff --git a/platform/ui/src/elements/Icon/icons/search-plus.svg b/platform/ui/src/elements/Icon/icons/search-plus.svg deleted file mode 100644 index f130654c5..000000000 --- a/platform/ui/src/elements/Icon/icons/search-plus.svg +++ /dev/null @@ -1,14 +0,0 @@ - - Search Plus - - - - - diff --git a/platform/ui/src/elements/Icon/icons/search.svg b/platform/ui/src/elements/Icon/icons/search.svg deleted file mode 100644 index a313de17d..000000000 --- a/platform/ui/src/elements/Icon/icons/search.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Search - - diff --git a/platform/ui/src/elements/Icon/icons/soft-tissue.svg b/platform/ui/src/elements/Icon/icons/soft-tissue.svg deleted file mode 100644 index 730c69450..000000000 --- a/platform/ui/src/elements/Icon/icons/soft-tissue.svg +++ /dev/null @@ -1,16 +0,0 @@ - - Soft Tissue - - diff --git a/platform/ui/src/elements/Icon/icons/sort-down.svg b/platform/ui/src/elements/Icon/icons/sort-down.svg deleted file mode 100644 index 6306b4884..000000000 --- a/platform/ui/src/elements/Icon/icons/sort-down.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Sort Down - - diff --git a/platform/ui/src/elements/Icon/icons/sort-up.svg b/platform/ui/src/elements/Icon/icons/sort-up.svg deleted file mode 100644 index ab5e0a836..000000000 --- a/platform/ui/src/elements/Icon/icons/sort-up.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Sort Up - - diff --git a/platform/ui/src/elements/Icon/icons/sort.svg b/platform/ui/src/elements/Icon/icons/sort.svg deleted file mode 100644 index 1ade70182..000000000 --- a/platform/ui/src/elements/Icon/icons/sort.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Sort - - diff --git a/platform/ui/src/elements/Icon/icons/square-o.svg b/platform/ui/src/elements/Icon/icons/square-o.svg deleted file mode 100644 index 16d36444c..000000000 --- a/platform/ui/src/elements/Icon/icons/square-o.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Square Outline - - diff --git a/platform/ui/src/elements/Icon/icons/star.svg b/platform/ui/src/elements/Icon/icons/star.svg deleted file mode 100644 index 265a0e6bb..000000000 --- a/platform/ui/src/elements/Icon/icons/star.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Star - - diff --git a/platform/ui/src/elements/Icon/icons/step-backward.svg b/platform/ui/src/elements/Icon/icons/step-backward.svg deleted file mode 100644 index 78a15fa7d..000000000 --- a/platform/ui/src/elements/Icon/icons/step-backward.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/platform/ui/src/elements/Icon/icons/step-forward.svg b/platform/ui/src/elements/Icon/icons/step-forward.svg deleted file mode 100644 index c42eabf65..000000000 --- a/platform/ui/src/elements/Icon/icons/step-forward.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/platform/ui/src/elements/Icon/icons/stop.svg b/platform/ui/src/elements/Icon/icons/stop.svg deleted file mode 100644 index 9d124d325..000000000 --- a/platform/ui/src/elements/Icon/icons/stop.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Stop - - diff --git a/platform/ui/src/elements/Icon/icons/sun.svg b/platform/ui/src/elements/Icon/icons/sun.svg deleted file mode 100644 index 08158098d..000000000 --- a/platform/ui/src/elements/Icon/icons/sun.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Sun - - diff --git a/platform/ui/src/elements/Icon/icons/th-large.svg b/platform/ui/src/elements/Icon/icons/th-large.svg deleted file mode 100644 index 876289bc4..000000000 --- a/platform/ui/src/elements/Icon/icons/th-large.svg +++ /dev/null @@ -1,12 +0,0 @@ - - TH Large - - diff --git a/platform/ui/src/elements/Icon/icons/th-list.svg b/platform/ui/src/elements/Icon/icons/th-list.svg deleted file mode 100644 index e69919bf8..000000000 --- a/platform/ui/src/elements/Icon/icons/th-list.svg +++ /dev/null @@ -1,11 +0,0 @@ - - TH List - - diff --git a/platform/ui/src/elements/Icon/icons/th.svg b/platform/ui/src/elements/Icon/icons/th.svg deleted file mode 100644 index b1df15afa..000000000 --- a/platform/ui/src/elements/Icon/icons/th.svg +++ /dev/null @@ -1,11 +0,0 @@ - - TH - - diff --git a/platform/ui/src/elements/Icon/icons/times.svg b/platform/ui/src/elements/Icon/icons/times.svg deleted file mode 100644 index 27f875dce..000000000 --- a/platform/ui/src/elements/Icon/icons/times.svg +++ /dev/null @@ -1,12 +0,0 @@ - - Times - - diff --git a/platform/ui/src/elements/Icon/icons/trash.svg b/platform/ui/src/elements/Icon/icons/trash.svg deleted file mode 100644 index 20bca7e22..000000000 --- a/platform/ui/src/elements/Icon/icons/trash.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Trash - - diff --git a/platform/ui/src/elements/Icon/icons/unlink.svg b/platform/ui/src/elements/Icon/icons/unlink.svg deleted file mode 100644 index 37c53bbb9..000000000 --- a/platform/ui/src/elements/Icon/icons/unlink.svg +++ /dev/null @@ -1,11 +0,0 @@ - - Unlink - - diff --git a/platform/ui/src/elements/Icon/icons/user.svg b/platform/ui/src/elements/Icon/icons/user.svg deleted file mode 100644 index c55700132..000000000 --- a/platform/ui/src/elements/Icon/icons/user.svg +++ /dev/null @@ -1,11 +0,0 @@ - - User - - diff --git a/platform/ui/src/elements/Icon/icons/youtube.svg b/platform/ui/src/elements/Icon/icons/youtube.svg deleted file mode 100644 index 00db81c23..000000000 --- a/platform/ui/src/elements/Icon/icons/youtube.svg +++ /dev/null @@ -1,11 +0,0 @@ - - YouTube Logo - - diff --git a/platform/ui/src/elements/Icon/index.js b/platform/ui/src/elements/Icon/index.js deleted file mode 100644 index 3d83dbf3e..000000000 --- a/platform/ui/src/elements/Icon/index.js +++ /dev/null @@ -1,4 +0,0 @@ -import { ICONS } from './getIcon.js'; -import Icon from './Icon.js'; - -export { Icon, ICONS }; diff --git a/platform/ui/src/elements/Svg/Svg.js b/platform/ui/src/elements/Svg/Svg.js deleted file mode 100644 index 41ea577f5..000000000 --- a/platform/ui/src/elements/Svg/Svg.js +++ /dev/null @@ -1,14 +0,0 @@ -import './Svg.styl'; - -import PropTypes from 'prop-types'; -import getSvg from './getSvg.js'; - -const Svg = props => { - return getSvg(props.name, props); -}; - -Svg.propTypes = { - name: PropTypes.string.isRequired, -}; - -export { Svg }; diff --git a/platform/ui/src/elements/Svg/Svg.styl b/platform/ui/src/elements/Svg/Svg.styl deleted file mode 100644 index e69de29bb..000000000 diff --git a/platform/ui/src/elements/Svg/__docs__/svg.mdx b/platform/ui/src/elements/Svg/__docs__/svg.mdx deleted file mode 100644 index 6fe66a7ee..000000000 --- a/platform/ui/src/elements/Svg/__docs__/svg.mdx +++ /dev/null @@ -1,57 +0,0 @@ ---- -name: Svg -menu: Elements -route: /elements/svg ---- - -import { Playground, Props } from 'docz'; -import { State } from 'react-powerplug'; -import { Svg, SVGS } from './../index.js'; - -# Svg - -## Basic usage - - -
    - {Object.keys(SVGS) - .sort() - .map((name, i) => { - return ( - -
    - -
    - {name} -
    -
    -
    - ); - })} -
    -
    - -## API - - diff --git a/platform/ui/src/elements/Svg/getSvg.js b/platform/ui/src/elements/Svg/getSvg.js deleted file mode 100644 index 4933fc121..000000000 --- a/platform/ui/src/elements/Svg/getSvg.js +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react'; -// Svgs -import ohifLogoText from './svgs/ohif-logo-text.svg'; -import ohifLogoWrappedText from './svgs/ohif-logo-wrapped-text.svg'; - -const SVGS = { - 'ohif-logo-wrapped-text': ohifLogoWrappedText, - 'ohif-logo-text': ohifLogoText, -}; - -/** - * Return the matching SVG as a React Component. - * Results in an inlined SVG Element. If there's no match, - * return `null` - */ -export default function getSvg(key, props) { - if (!key || !SVGS[key]) { - return React.createElement('div', null, 'Missing SVG'); - } - - return React.createElement(SVGS[key], props); -} - -export { SVGS }; diff --git a/platform/ui/src/elements/Svg/index.js b/platform/ui/src/elements/Svg/index.js deleted file mode 100644 index 54a598b17..000000000 --- a/platform/ui/src/elements/Svg/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { Svg } from './Svg.js'; -export { SVGS } from './getSvg.js'; diff --git a/platform/ui/src/elements/Svg/svgs/ohif-logo-text.svg b/platform/ui/src/elements/Svg/svgs/ohif-logo-text.svg deleted file mode 100644 index f06a067b5..000000000 --- a/platform/ui/src/elements/Svg/svgs/ohif-logo-text.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/platform/ui/src/elements/Svg/svgs/ohif-logo-wrapped-text.svg b/platform/ui/src/elements/Svg/svgs/ohif-logo-wrapped-text.svg deleted file mode 100644 index d9c2cb6b6..000000000 --- a/platform/ui/src/elements/Svg/svgs/ohif-logo-wrapped-text.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/platform/ui/src/elements/form/DropdownMenu.css b/platform/ui/src/elements/form/DropdownMenu.css deleted file mode 100644 index cc02defe1..000000000 --- a/platform/ui/src/elements/form/DropdownMenu.css +++ /dev/null @@ -1,86 +0,0 @@ -.dd-menu { - float: left; - margin-right: 10px; - cursor: pointer; - position: relative; -} - -.dd-title { - font-size: 13px; -} - -.dd-menu-toggle { - display: inline-block; -} - -.dd-caret-down { - display: inline-block; - width: 0; - height: 0; - margin-top: 0.5rem; - margin-left: 0.5rem; - border-top: 5px solid; - border-right: 5px solid transparent; - border-left: 5px solid transparent; -} - -.dd-menu-list { - position: absolute; - top: 100%; - margin-top: 10px; - background: white; - z-index: 999; - border-radius: 5px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - -ms-border-radius: 5px; - -o-border-radius: 5px; - overflow: hidden; - transition: all 300ms ease; - -webkit-transition: all 300ms ease; - -moz-transition: all 300ms ease; - -ms-transition: all 300ms ease; - -o-transition: all 300ms ease; -} - -.dd-menu-list.open { - display: inline-block; -} - -.dd-menu-list.left { - left: 0; -} - -.dd-menu-list.right { - right: 0; -} - -.dd-menu-list.center { - left: 50%; - transform: translateX(-50%); - -webkit-transform: translateX(-50%); - -moz-transform: translateX(-50%); - -ms-transform: translateX(-50%); - -o-transform: translateX(-50%); -} - -.dd-item { - display: flex; - color: var(--text-color-active); - padding: 10px 15px; - border-bottom: 1px solid #ccc; -} - -.dd-item:hover { - text-decoration: none; - background: #eee; -} - -.dd-item:last-child { - border-bottom: none; -} - -.dd-item-icon { - margin-right: 10px; - margin-top: 2px; -} diff --git a/platform/ui/src/elements/form/DropdownMenu.js b/platform/ui/src/elements/form/DropdownMenu.js deleted file mode 100644 index e0562370a..000000000 --- a/platform/ui/src/elements/form/DropdownMenu.js +++ /dev/null @@ -1,138 +0,0 @@ -import './DropdownMenu.css'; - -import React, { Component } from 'react'; - -import { Icon } from '../Icon'; -import PropTypes from 'prop-types'; - -class DropdownMenu extends Component { - state = { - open: false, - }; - - static propTypes = { - titleElement: PropTypes.node, - title: PropTypes.string, - align: PropTypes.oneOf(['left', 'center', 'right']), - /** Items to render in the select's drop down */ - list: PropTypes.arrayOf( - PropTypes.shape({ - title: PropTypes.string.isRequired, - icon: PropTypes.object, - onClick: PropTypes.func, - link: PropTypes.string, - }) - ), - }; - - getListItems = () => { - const { list, align } = this.props; - - return list.map(({ icon, title, link, onClick }, key) => { - if (link) { - return ( - this.handleOnClick(onClick)} - > - {icon && } - {title} - - ); - } else { - return ( - - ); - } - }); - }; - - renderList = () => { - const { align } = this.props; - - if (!this.state.open) { - return null; - } - - return ( -
    - {this.getListItems()} -
    - ); - }; - - handleOnClick = onClick => { - this.toggleList(); - - if (onClick) { - onClick(); - } - }; - - handleMouseClick = e => { - if (this.node.contains(e.target)) { - return; - } - - this.toggleList(); - }; - - renderTitleElement = () => { - const { titleElement, title } = this.props; - - if (titleElement) { - return titleElement; - } - - return ( - - {title} - - - ); - }; - - toggleList = () => { - const { open } = this.state; - let state = true; - - document.addEventListener('mousedown', this.handleMouseClick, false); - - if (open) { - document.removeEventListener('mousedown', this.handleMouseClick, false); - state = false; - } - - this.setState({ - open: state, - }); - }; - - render() { - return ( -
    (this.node = node)} - > -
    - {this.renderTitleElement()} -
    - - {this.renderList()} -
    - ); - } -} - -export { DropdownMenu }; diff --git a/platform/ui/src/elements/form/Label.css b/platform/ui/src/elements/form/Label.css deleted file mode 100644 index 6d0a170b1..000000000 --- a/platform/ui/src/elements/form/Label.css +++ /dev/null @@ -1,8 +0,0 @@ -.label-ohif { - font-size: 1em; - color: #ffffff; -} - -.label-example { - background-color: var(--ui-gray-darker); -} diff --git a/platform/ui/src/elements/form/Label.js b/platform/ui/src/elements/form/Label.js deleted file mode 100644 index 06086fbd6..000000000 --- a/platform/ui/src/elements/form/Label.js +++ /dev/null @@ -1,27 +0,0 @@ -import './Label.css'; - -import React from 'react'; - -import PropTypes from 'prop-types'; - -class Label extends React.Component { - constructor(props) { - super(props); - this.state = { value: this.props.text }; - } - - render() { - return ( - - ); - } -} - -Label.propTypes = { - text: PropTypes.string.isRequired, - for: PropTypes.string, -}; - -export { Label }; diff --git a/platform/ui/src/elements/form/OldSelect.js b/platform/ui/src/elements/form/OldSelect.js deleted file mode 100644 index 3a59f70fc..000000000 --- a/platform/ui/src/elements/form/OldSelect.js +++ /dev/null @@ -1,49 +0,0 @@ -import './Select.css'; -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; - -class Select extends Component { - constructor(props) { - super(props); - this.state = { - value: this.props.value, - }; - } - - handleChange = event => { - const value = event.target.value; - this.setState({ value }); - if (this.props.onChange) this.props.onChange(value); - }; - - render() { - return ( - - ); - } -} - -Select.propTypes = { - options: PropTypes.arrayOf( - PropTypes.shape({ - key: PropTypes.string.isRequired, - value: PropTypes.string.isRequired, - }) - ), - value: PropTypes.string, - onChange: PropTypes.func, -}; - -export default Select; diff --git a/platform/ui/src/elements/form/Range.css b/platform/ui/src/elements/form/Range.css deleted file mode 100644 index 3bdaa94c2..000000000 --- a/platform/ui/src/elements/form/Range.css +++ /dev/null @@ -1,65 +0,0 @@ -.range { - margin: 0; - width: 100%; - -webkit-appearance: none; - background-color: transparent; -} - -.range:focus { - outline: none; -} - -.range::-webkit-slider-runnable-track { - width: 100%; - height: 2px; - cursor: pointer; - box-shadow: none; - background-color: var(--ui-border-color-dark); - border-radius: 0px; - border: 0px solid var(--ui-border-color-dark); -} - -.range::-moz-range-track { - width: 100%; - height: 2px; - cursor: pointer; - box-shadow: none; - background-color: var(--ui-border-color-dark); - border-radius: 0px; - border: 0px solid var(--ui-border-color-dark); -} - -.range::-webkit-slider-thumb { - box-shadow: none; - border: 0px solid var(--active-color); - box-shadow: 0px 10px 10px rgba(0, 0, 0, 0.25); - height: 21px; - width: 11px; - border-radius: 11px; - background: var(--active-color); - cursor: pointer; - -webkit-appearance: none; - margin-top: -10px; -} - -.range::-moz-range-thumb { - box-shadow: none; - border: 0px solid var(--active-color); - box-shadow: 0px 10px 10px rgba(0, 0, 0, 0.25); - height: 21px; - width: 11px; - border-radius: 11px; - background: var(--active-color); - cursor: pointer; - -webkit-appearance: none; - margin-top: -10px; -} - -.range::-moz-focus-outer { - border: 0; -} - -.range-example { - background: black; - height: 2em; -} diff --git a/platform/ui/src/elements/form/Select.css b/platform/ui/src/elements/form/Select.css deleted file mode 100644 index 58c9357c1..000000000 --- a/platform/ui/src/elements/form/Select.css +++ /dev/null @@ -1,63 +0,0 @@ -.select-ohif-container .select-ohif { - display: inline-block; - font-size: 10pt; - box-sizing: border-box; - width: auto; - transition: all 0.15s ease; - background-color: var(--input-background-color); - line-height: 16px; - color: var(--input-placeholder-color); - height: 40px; - margin: 0 5px 20px 5px; - padding: 0 20px; - placeholder-color: var(--input-placeholder-color); - cursor: pointer; - border: none; - font-weight: normal; - border-radius: 4px; - background-image: none; -} - -.select-ohif-container .select-ohif::-ms-expand { - display: none; -} - -.select-ohif-container .select-ohif-label { - padding: 5px; -} - -.select-ohif:focus { - outline: none; -} - -.select-ohif-container .select-ohif option { - font-weight: normal; -} - -/** Compatibility styles for MIP */ - -.select-ohif { - display: block; - font-family: Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', - sans-serif; - font-size: 0.8em; - font-weight: 600; - color: #444; - line-height: 1.3; - padding: 0.6em 1.4em 0.5em 0.8em; - width: 100%; - max-width: 100%; - margin: 0; - border: 1px solid #aaa; - box-shadow: 0 1px 0 1px rgba(0, 0, 0, 0.04); - border-radius: 0.5em; - -moz-appearance: none; - -webkit-appearance: none; - appearance: none; - background-color: #fff; - background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23007CB2%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E'), - linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%); - background-repeat: no-repeat, repeat; - background-position: right 0.7em top 50%, 0 0; - background-size: 0.65em auto, 100%; -} diff --git a/platform/ui/src/elements/form/Select.js b/platform/ui/src/elements/form/Select.js deleted file mode 100644 index 28008701f..000000000 --- a/platform/ui/src/elements/form/Select.js +++ /dev/null @@ -1,49 +0,0 @@ -import './Select.css'; - -import React, { Component } from 'react'; - -import PropTypes from 'prop-types'; - -class Select extends Component { - constructor(props) { - super(props); - } - - static propTypes = { - options: PropTypes.arrayOf( - PropTypes.shape({ - key: PropTypes.string.isRequired, - value: PropTypes.string.isRequired, - }) - ), - value: PropTypes.string, - onChange: PropTypes.func, - }; - - handleChange = event => { - const value = event.target.value; - this.setState({ value }); - if (this.props.onChange) this.props.onChange(value); - }; - - render() { - return ( -
    - {this.props.label && ( - - )} - -
    - ); - } -} - -export { Select }; diff --git a/platform/ui/src/elements/form/TextArea.css b/platform/ui/src/elements/form/TextArea.css deleted file mode 100644 index 72e8b2860..000000000 --- a/platform/ui/src/elements/form/TextArea.css +++ /dev/null @@ -1,7 +0,0 @@ -.textarea-ohif { - background-color: #b6b6b6; - border-color: #b6b6b6; - font-family: Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', - sans-serif; - font-size: 1em; -} diff --git a/platform/ui/src/elements/form/TextInput.css b/platform/ui/src/elements/form/TextInput.css deleted file mode 100644 index e05510529..000000000 --- a/platform/ui/src/elements/form/TextInput.css +++ /dev/null @@ -1,34 +0,0 @@ -.input-ohif-container { - font-size: 1em; - color: var(--text-primary-color); - font-weight: 400; -} - -.input-ohif-container .input-ohif { - display: inline-block; - height: 40px; - margin: 0 10px 20px; - padding: 0 20px; - cursor: pointer; - border: none; - background-color: var(--input-background-color); - color: var(--input-placeholder-color); - font-size: 10pt; - font-weight: normal; - width: auto; - border-radius: 4px; - transition: all 0.15s ease; -} - -.input-ohif-container .input-ohif-label { - padding: 5px; -} - -.input-ohif-container .input-ohif:active, -.input-ohif-container .input-ohif:focus { - background-color: var(--input-background-color); -} - -.input-ohif-container .input-ohif.invisible { - visibility: hidden; -} diff --git a/platform/ui/src/elements/form/TextInput.js b/platform/ui/src/elements/form/TextInput.js deleted file mode 100644 index 430d4320a..000000000 --- a/platform/ui/src/elements/form/TextInput.js +++ /dev/null @@ -1,45 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -import './TextInput.css'; - -class TextInput extends React.Component { - constructor(props) { - super(props); - } - - static propTypes = { - value: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.number - ]), - id: PropTypes.string, - label: PropTypes.string, - type: PropTypes.string, - }; - - static defaultProps = { - value: '', - id: `TextInput-${new Date().toTimeString()}`, - label: undefined, - type: 'text', - }; - - render() { - return ( -
    - {this.props.label && ( - - )} - -
    - ); - } -} - -export { TextInput }; diff --git a/platform/ui/src/elements/form/__docs__/dropdownMenu.doc.mdx b/platform/ui/src/elements/form/__docs__/dropdownMenu.doc.mdx deleted file mode 100644 index 82be20cb6..000000000 --- a/platform/ui/src/elements/form/__docs__/dropdownMenu.doc.mdx +++ /dev/null @@ -1,42 +0,0 @@ ---- -name: Form / Dropdown Menu -menu: Elements -route: /elements/form-ddMenu ---- - -import { Playground, Props } from 'docz'; -import { State } from 'react-powerplug'; -import { DropdownMenu } from './../index.js'; - -# Select - -## Basic usage - - - - {({ state, setState }) => } - - - -## API - - diff --git a/platform/ui/src/elements/form/__docs__/label.doc.mdx b/platform/ui/src/elements/form/__docs__/label.doc.mdx deleted file mode 100644 index cac3a1652..000000000 --- a/platform/ui/src/elements/form/__docs__/label.doc.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: Form / Label -menu: Elements -route: /elements/form-label ---- - -import { Playground, Props } from 'docz'; -import { State } from 'react-powerplug'; -import { Label } from './../index.js'; - -# Label - -## Basic usage - - - - {({ state, setState }) => ( -
    -
    - )} -
    -
    - -## API - - diff --git a/platform/ui/src/elements/form/__docs__/range.doc.mdx b/platform/ui/src/elements/form/__docs__/range.doc.mdx deleted file mode 100644 index 33eda0d66..000000000 --- a/platform/ui/src/elements/form/__docs__/range.doc.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -name: Form / Range -menu: Elements -route: /elements/form-range ---- - -import { Playground, Props } from 'docz'; -import { State } from 'react-powerplug'; -import { Range } from './../index.js'; - -# Range - -## Basic usage - - - - {({ state, setState }) => ( -
    - -
    - )} -
    -
    - -## API - - diff --git a/platform/ui/src/elements/form/__docs__/select.docs.mdx b/platform/ui/src/elements/form/__docs__/select.docs.mdx deleted file mode 100644 index dd810bb4c..000000000 --- a/platform/ui/src/elements/form/__docs__/select.docs.mdx +++ /dev/null @@ -1,39 +0,0 @@ ---- -name: Form / Select -menu: Elements -route: /elements/form-select ---- - -import { Playground, Props } from 'docz'; -import { State } from 'react-powerplug'; -import { Select } from './../index.js'; - -# Select - -## Basic usage - - - - - {({ state, setState }) =>