From 3220af737c3a72bd6a2a3c5ccc87e81c983a1efd Mon Sep 17 00:00:00 2001 From: Erik Ziegler Date: Mon, 26 Jul 2021 13:22:25 +0200 Subject: [PATCH] fix(tailwind): Ensure tailwind properly purges unused utility classes (#2485) --- .webpack/rules/cssToJavaScript.js | 16 +- .webpack/webpack.base.js | 16 +- .../src/ViewportLoadingIndicator.js | 6 +- extensions/cornerstone/src/ViewportOverlay.js | 28 +- .../dicom-sr/src/viewports/ViewportOverlay.js | 8 +- .../src/viewports/ViewportLoadingIndicator.js | 6 +- .../src/viewports/ViewportOverlay.js | 28 +- package.json | 10 +- .../components/ExpandableToolbarButton.mdx | 2 +- .../component-library/components/ListMenu.mdx | 2 +- platform/docs/pluginOHIFWebpackConfig.js | 4 +- platform/docs/tailwind.config.js | 12 +- platform/ui/.webpack/webpack.prod.js | 18 +- platform/ui/package.json | 1 + platform/ui/postcss.config.js | 7 - .../ui/src/components/DateRange/DateRange.css | 4 +- .../src/components/InputGroup/InputGroup.jsx | 3 +- .../ui/src/components/SidePanel/SidePanel.jsx | 8 +- .../StudyListTable/StudyListTableRow.js | 4 +- .../WindowLevelMenuItem.jsx | 2 +- platform/ui/src/tailwind.css | 8 +- platform/ui/src/utils/getGridWidthClass.js | 35 + platform/ui/tailwind.config.js | 12 +- platform/viewer/.webpack/webpack.pwa.js | 22 +- platform/viewer/package.json | 9 +- .../viewer/public/html-templates/index.html | 4 +- .../viewer/public/html-templates/rollbar.html | 4 +- .../public/html-templates/script-tag.html | 42 - platform/viewer/src/index.js | 1 - .../viewer/src/routes/DataSourceWrapper.jsx | 9 +- platform/viewer/tailwind.config.js | 838 ++++++++++++++++++ platform/viewer/tailwind.css | 4 + yarn.lock | 98 +- 33 files changed, 1028 insertions(+), 243 deletions(-) delete mode 100644 platform/ui/postcss.config.js create mode 100644 platform/ui/src/utils/getGridWidthClass.js delete mode 100644 platform/viewer/public/html-templates/script-tag.html create mode 100644 platform/viewer/tailwind.config.js create mode 100644 platform/viewer/tailwind.css diff --git a/.webpack/rules/cssToJavaScript.js b/.webpack/rules/cssToJavaScript.js index 5d4d55d33..24d44e803 100644 --- a/.webpack/rules/cssToJavaScript.js +++ b/.webpack/rules/cssToJavaScript.js @@ -1,14 +1,26 @@ const autoprefixer = require('autoprefixer'); +const path = require('path'); +const tailwindcss = require('tailwindcss'); +const tailwindConfigPath = path.resolve('tailwind.config.js'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const devMode = process.env.NODE_ENV !== 'production'; const cssToJavaScript = { test: /\.css$/, use: [ - 'style-loader', + //'style-loader', + devMode ? 'style-loader' : MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { importLoaders: 1 } }, { loader: 'postcss-loader', options: { - plugins: () => [autoprefixer('last 2 version', 'ie >= 11')], + postcssOptions: { + verbose: true, + plugins: [ + [tailwindcss(tailwindConfigPath)], + [autoprefixer('last 2 version', 'ie >= 11')], + ], + }, }, }, ], diff --git a/.webpack/webpack.base.js b/.webpack/webpack.base.js index 9f960dbfc..b37f3405d 100644 --- a/.webpack/webpack.base.js +++ b/.webpack/webpack.base.js @@ -8,10 +8,13 @@ const PACKAGE = require('../platform/viewer/package.json'); const loadShadersRule = require('./rules/loadShaders.js'); const loadWebWorkersRule = require('./rules/loadWebWorkers.js'); const transpileJavaScriptRule = require('./rules/transpileJavaScript.js'); +const cssToJavaScript = require('./rules/cssToJavaScript.js'); // ~~ PLUGINS const BundleAnalyzerPlugin = require('webpack-bundle-analyzer') .BundleAnalyzerPlugin; const TerserJSPlugin = require('terser-webpack-plugin'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); + // ~~ ENV VARS const NODE_ENV = process.env.NODE_ENV; const QUICK_BUILD = process.env.QUICK_BUILD; @@ -62,6 +65,7 @@ module.exports = (env, argv, { SRC_DIR, DIST_DIR }) => { fullySpecified: false, }, }, + cssToJavaScript, ], }, resolve: { @@ -117,11 +121,6 @@ module.exports = (env, argv, { SRC_DIR, DIST_DIR }) => { // Uncomment to generate bundle analyzer // new BundleAnalyzerPlugin(), ], - // Fix: https://github.com/webpack-contrib/css-loader/issues/447#issuecomment-285598881 - // For issue in cornerstone-wado-image-loader - /*node: { - fs: 'empty', - },*/ }; if (isProdBuild) { @@ -131,6 +130,13 @@ module.exports = (env, argv, { SRC_DIR, DIST_DIR }) => { terserOptions: {}, }), ]; + + /*config.plugins.push( + new MiniCssExtractPlugin({ + filename: 'dist/[name].bundle.css', + chunkFilename: 'dist/[id].css', + }) + );*/ } if (isQuickBuild) { diff --git a/extensions/cornerstone/src/ViewportLoadingIndicator.js b/extensions/cornerstone/src/ViewportLoadingIndicator.js index 46b6c7f72..2030d0d23 100644 --- a/extensions/cornerstone/src/ViewportLoadingIndicator.js +++ b/extensions/cornerstone/src/ViewportLoadingIndicator.js @@ -7,7 +7,7 @@ const ViewportLoadingIndicator = ({ error }) => { return ( <>
-
+

Error Loading Image

An error has occurred.

{error.message}

@@ -20,9 +20,7 @@ const ViewportLoadingIndicator = ({ error }) => { <>
-

- Loading... -

+

Loading...

); diff --git a/extensions/cornerstone/src/ViewportOverlay.js b/extensions/cornerstone/src/ViewportOverlay.js index af93a2dd7..b3f7e31de 100644 --- a/extensions/cornerstone/src/ViewportOverlay.js +++ b/extensions/cornerstone/src/ViewportOverlay.js @@ -32,36 +32,48 @@ const ViewportOverlay = ({ return (
-
+
{isZoomActive && (
Zoom: - {scale.toFixed(2)}x + {scale.toFixed(2)}x
)} {isWwwcActive && (
W: - + {windowWidth.toFixed(0)} L: - {windowCenter.toFixed(0)} + {windowCenter.toFixed(0)}
)}
-
+
{stackSize > 1 && (
I: - + {`${instanceNumber} (${imageIndex}/${stackSize})`}
)}
-
-
+
+
); }; diff --git a/extensions/dicom-sr/src/viewports/ViewportOverlay.js b/extensions/dicom-sr/src/viewports/ViewportOverlay.js index 8ca11f8c8..045770d90 100644 --- a/extensions/dicom-sr/src/viewports/ViewportOverlay.js +++ b/extensions/dicom-sr/src/viewports/ViewportOverlay.js @@ -35,17 +35,17 @@ const ViewportOverlay = ({ {isZoomActive && (
Zoom: - {scale.toFixed(2)}x + {scale.toFixed(2)}x
)} {isWwwcActive && (
W: - + {windowWidth.toFixed(0)} L: - {windowCenter.toFixed(0)} + {windowCenter.toFixed(0)}
)}
@@ -53,7 +53,7 @@ const ViewportOverlay = ({ {stackSize > 1 && (
I: - + {`${instanceNumber} (${imageIndex}/${stackSize})`}
diff --git a/extensions/measurement-tracking/src/viewports/ViewportLoadingIndicator.js b/extensions/measurement-tracking/src/viewports/ViewportLoadingIndicator.js index 46b6c7f72..2030d0d23 100644 --- a/extensions/measurement-tracking/src/viewports/ViewportLoadingIndicator.js +++ b/extensions/measurement-tracking/src/viewports/ViewportLoadingIndicator.js @@ -7,7 +7,7 @@ const ViewportLoadingIndicator = ({ error }) => { return ( <>
-
+

Error Loading Image

An error has occurred.

{error.message}

@@ -20,9 +20,7 @@ const ViewportLoadingIndicator = ({ error }) => { <>
-

- Loading... -

+

Loading...

); diff --git a/extensions/measurement-tracking/src/viewports/ViewportOverlay.js b/extensions/measurement-tracking/src/viewports/ViewportOverlay.js index af93a2dd7..b3f7e31de 100644 --- a/extensions/measurement-tracking/src/viewports/ViewportOverlay.js +++ b/extensions/measurement-tracking/src/viewports/ViewportOverlay.js @@ -32,36 +32,48 @@ const ViewportOverlay = ({ return (
-
+
{isZoomActive && (
Zoom: - {scale.toFixed(2)}x + {scale.toFixed(2)}x
)} {isWwwcActive && (
W: - + {windowWidth.toFixed(0)} L: - {windowCenter.toFixed(0)} + {windowCenter.toFixed(0)}
)}
-
+
{stackSize > 1 && (
I: - + {`${instanceNumber} (${imageIndex}/${stackSize})`}
)}
-
-
+
+
); }; diff --git a/package.json b/package.json index e896687f8..b14301514 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,6 @@ "eslint-plugin-promise": "^4.2.1", "eslint-plugin-react": "7.x", "eslint-plugin-react-hooks": "4.2.0", - "extract-css-chunks-webpack-plugin": "^4.9.0", "html-webpack-plugin": "^5.3.2", "husky": "^3.0.0", "jest": "^24.8.0", @@ -99,11 +98,12 @@ "jest-junit": "^6.4.0", "lerna": "^3.15.0", "lint-staged": "^9.0.2", + "mini-css-extract-plugin": "^2.1.0", "optimize-css-assets-webpack-plugin": "^5.0.3", - "postcss": "^8.2.15", - "postcss-import": "^12.0.1", - "postcss-loader": "^4.0.3", - "postcss-preset-env": "^6.6.0", + "postcss": "^8.3.5", + "postcss-import": "^14.0.2", + "postcss-loader": "^6.1.1", + "postcss-preset-env": "^6.7.0", "prettier": "^1.18.2", "react-hot-loader": "^4.13.0", "serve": "^11.1.0", diff --git a/platform/docs/docs/platform/component-library/components/ExpandableToolbarButton.mdx b/platform/docs/docs/platform/component-library/components/ExpandableToolbarButton.mdx index c410d512f..44c3728a0 100644 --- a/platform/docs/docs/platform/component-library/components/ExpandableToolbarButton.mdx +++ b/platform/docs/docs/platform/component-library/components/ExpandableToolbarButton.mdx @@ -56,7 +56,7 @@ function() { {subtitle} diff --git a/platform/docs/docs/platform/component-library/components/ListMenu.mdx b/platform/docs/docs/platform/component-library/components/ListMenu.mdx index 518c29947..0e44cc95d 100644 --- a/platform/docs/docs/platform/component-library/components/ListMenu.mdx +++ b/platform/docs/docs/platform/component-library/components/ListMenu.mdx @@ -56,7 +56,7 @@ function() { {subtitle} diff --git a/platform/docs/pluginOHIFWebpackConfig.js b/platform/docs/pluginOHIFWebpackConfig.js index e1ec7ae4c..ef8138917 100644 --- a/platform/docs/pluginOHIFWebpackConfig.js +++ b/platform/docs/pluginOHIFWebpackConfig.js @@ -21,7 +21,7 @@ module.exports = function(context, options) { }, }; }, - /*configurePostCss(postcssOptions) { + configurePostCss(postcssOptions) { postcssOptions.plugins.push( require('postcss-import'), require('tailwindcss'), @@ -33,6 +33,6 @@ module.exports = function(context, options) { }) ); return postcssOptions; - },*/ + }, }; }; diff --git a/platform/docs/tailwind.config.js b/platform/docs/tailwind.config.js index 6c4d20d6a..7d6f035ba 100644 --- a/platform/docs/tailwind.config.js +++ b/platform/docs/tailwind.config.js @@ -2,8 +2,14 @@ module.exports = { prefix: '', important: false, separator: ':', - purge: false, - //purge: ['./docs/**/*.jsx', './docs/**/*.mdx'], + purge: { + content: [ + './docs/**/*.jsx', + './docs/**/*.mdx', + './node_modules/@ohif/ui/src/**/*.{js,jsx,css}', + '../../node_modules/@ohif/ui/src/**/*.{js,jsx,css}', + ], + }, theme: { screens: { sm: '640px', @@ -749,7 +755,7 @@ module.exports = { ], borderRadius: ['responsive', 'focus', 'first', 'last'], borderStyle: ['responsive', 'focus'], - //borderWidth: ['responsive', 'focus', 'first', 'last'], + borderWidth: ['responsive', 'focus', 'first', 'last'], boxShadow: ['responsive', 'hover', 'focus'], boxSizing: ['responsive'], cursor: ['responsive'], diff --git a/platform/ui/.webpack/webpack.prod.js b/platform/ui/.webpack/webpack.prod.js index 4d4be6d1a..32d99604c 100644 --- a/platform/ui/.webpack/webpack.prod.js +++ b/platform/ui/.webpack/webpack.prod.js @@ -24,8 +24,8 @@ module.exports = (env, argv) => { warnings: true, }, optimization: { - minimize: true, - sideEffects: true, + minimize: false, + sideEffects: false, }, output: { path: ROOT_DIR, @@ -34,22 +34,8 @@ module.exports = (env, argv) => { filename: pkg.main, }, externals: { - '@ohif/core': { - commonjs: '@ohif/core', - commonjs2: '@ohif/core', - amd: '@ohif/core', - root: '@ohif/core', - }, react: 'React', 'react-dom': 'ReactDOM', }, - module: { - rules: [ - { - test: /\.css$/i, - use: ['style-loader', 'css-loader', 'postcss-loader'], - }, - ], - }, }); }; diff --git a/platform/ui/package.json b/platform/ui/package.json index 7ae7aa8b4..db9f6361c 100644 --- a/platform/ui/package.json +++ b/platform/ui/package.json @@ -45,6 +45,7 @@ }, "devDependencies": { "autoprefixer": "9.7.4", + "mini-css-extract-plugin": "^2.1.0", "postcss": "^8.3.5", "postcss-loader": "^6.1.1", "prop-types": "15.7.2", diff --git a/platform/ui/postcss.config.js b/platform/ui/postcss.config.js deleted file mode 100644 index fdc99eb8c..000000000 --- a/platform/ui/postcss.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const tailwindcss = require('tailwindcss'); -const tailwindConfigPath = path.join(__dirname, 'tailwind.config.js'); - -module.exports = { - plugins: [tailwindcss(tailwindConfigPath), require('autoprefixer')], -}; diff --git a/platform/ui/src/components/DateRange/DateRange.css b/platform/ui/src/components/DateRange/DateRange.css index af8768f73..f310fb167 100644 --- a/platform/ui/src/components/DateRange/DateRange.css +++ b/platform/ui/src/components/DateRange/DateRange.css @@ -1,5 +1,5 @@ -.DateRangePicker { -} +/*@tailwind base; +@tailwind utilities;*/ /** CONTAINER STYLES **/ diff --git a/platform/ui/src/components/InputGroup/InputGroup.jsx b/platform/ui/src/components/InputGroup/InputGroup.jsx index 850120ee5..5a14eb78f 100644 --- a/platform/ui/src/components/InputGroup/InputGroup.jsx +++ b/platform/ui/src/components/InputGroup/InputGroup.jsx @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; +import getGridWidthClass from '../../utils/getGridWidthClass' import { InputText, @@ -132,7 +133,7 @@ const InputGroup = ({ key={inputMeta.name} className={classnames( 'pl-4 first:pl-12', - `w-${inputMeta.gridCol}/24` + getGridWidthClass(inputMeta.gridCol) )} > {renderFieldInputComponent(inputMeta)} diff --git a/platform/ui/src/components/SidePanel/SidePanel.jsx b/platform/ui/src/components/SidePanel/SidePanel.jsx index e2d0966e1..35a7e82f9 100644 --- a/platform/ui/src/components/SidePanel/SidePanel.jsx +++ b/platform/ui/src/components/SidePanel/SidePanel.jsx @@ -31,12 +31,12 @@ const baseClasses = const classesMap = { open: { - left: `border-r-${borderSize}`, - right: `border-l-${borderSize}`, + left: `border-r-4`, + right: `border-l-4`, }, closed: { - left: `border-r-${borderSize} items-end`, - right: `border-l-${borderSize} items-start`, + left: `border-r-4 items-end`, + right: `border-l-4 items-start`, }, }; diff --git a/platform/ui/src/components/StudyListTable/StudyListTableRow.js b/platform/ui/src/components/StudyListTable/StudyListTableRow.js index 786cc2539..ed900c7f7 100644 --- a/platform/ui/src/components/StudyListTable/StudyListTableRow.js +++ b/platform/ui/src/components/StudyListTable/StudyListTableRow.js @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import { Icon } from '../'; +import getGridWidthClass from '../../utils/getGridWidthClass'; const StudyListTableRow = props => { const { tableData } = props; @@ -36,14 +37,13 @@ const StudyListTableRow = props => { > {row.map((cell, index) => { const { content, title, gridCol } = cell; - return ( ( {title} - + {subtitle} {index + 1} diff --git a/platform/ui/src/tailwind.css b/platform/ui/src/tailwind.css index 4772a6cf1..d4441ed9a 100644 --- a/platform/ui/src/tailwind.css +++ b/platform/ui/src/tailwind.css @@ -1,11 +1,11 @@ +/* IMPORT CUSTOM FONT */ +@import url('https://fonts.googleapis.com/css?family=Lato:100,300,400,500,700&display=swap'); + @tailwind base; @tailwind components; @tailwind utilities; -/* IMPORT CUSTOM FONT */ -@import url('https://fonts.googleapis.com/css?family=Lato:100,300,400,500,700&display=swap'); - -/* Trincate 2 lines utility */ +/* Truncate 2 lines utility */ .truncate-2-lines { overflow: hidden; display: -webkit-box; diff --git a/platform/ui/src/utils/getGridWidthClass.js b/platform/ui/src/utils/getGridWidthClass.js new file mode 100644 index 000000000..bc1e00c9a --- /dev/null +++ b/platform/ui/src/utils/getGridWidthClass.js @@ -0,0 +1,35 @@ +// This is really annoying, but we can't use string concatenation to produce names +// or the purger will purge stuff we need. This is a lazy workaground. +// The alternative would be to use the safelist, but then we would have to remember +// which components which entry in the safelist are used for. +// https://tailwindcss.com/docs/optimizing-for-production +export default function getGridWidthClass(gridCol) { + const widthClasses = { + 1: 'w-1-24', + 2: 'w-2-24', + 3: 'w-3-24', + 4: 'w-4-24', + 5: 'w-5-24', + 6: 'w-6-24', + 7: 'w-7-24', + 8: 'w-8-24', + 9: 'w-9-24', + 10: 'w-10-24', + 11: 'w-11-24', + 12: 'w-12-24', + 13: 'w-13-24', + 14: 'w-14-24', + 15: 'w-15-24', + 16: 'w-16-24', + 17: 'w-17-24', + 18: 'w-18-24', + 19: 'w-19-24', + 20: 'w-20-24', + 21: 'w-21-24', + 22: 'w-22-24', + 23: 'w-23-24', + 24: 'w-24-24', + }; + + return widthClasses[gridCol]; +} diff --git a/platform/ui/tailwind.config.js b/platform/ui/tailwind.config.js index 6e61bd204..c85ca4d19 100644 --- a/platform/ui/tailwind.config.js +++ b/platform/ui/tailwind.config.js @@ -2,8 +2,10 @@ module.exports = { prefix: '', important: false, separator: ':', - purge: false, // TODO: unclear how we should purge when using a component library in another app - //purge: ['./src/**/*.jsx', './src/**/*.js'], + purge: { + content: ['./src/**/*.{jsx,js,css}'], + safelist: [], + }, theme: { screens: { sm: '640px', @@ -749,7 +751,7 @@ module.exports = { ], borderRadius: ['responsive', 'focus', 'first', 'last'], borderStyle: ['responsive', 'focus'], - //borderWidth: ['responsive', 'focus', 'first', 'last'], + borderWidth: ['responsive', 'focus', 'first', 'last'], boxShadow: ['responsive', 'hover', 'focus'], boxSizing: ['responsive'], cursor: ['responsive'], @@ -826,4 +828,8 @@ module.exports = { }, corePlugins: {}, plugins: [], + future: { + purgeLayersByDefault: true, + standardFontWeights: true, + }, }; diff --git a/platform/viewer/.webpack/webpack.pwa.js b/platform/viewer/.webpack/webpack.pwa.js index 9561f7134..3271de51a 100644 --- a/platform/viewer/.webpack/webpack.pwa.js +++ b/platform/viewer/.webpack/webpack.pwa.js @@ -7,11 +7,9 @@ const webpackBase = require('./../../../.webpack/webpack.base.js'); // ~~ Plugins const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); -const ExtractCssChunksPlugin = require('extract-css-chunks-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const { InjectManifest } = require('workbox-webpack-plugin'); -// ~~ Rules -const extractStyleChunksRule = require('./rules/extractStyleChunks.js'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // ~~ Directories const SRC_DIR = path.join(__dirname, '../src'); const DIST_DIR = path.join(__dirname, '../dist'); @@ -39,9 +37,6 @@ module.exports = (env, argv) => { filename: isProdBuild ? '[name].bundle.[chunkhash].js' : '[name].js', publicPath: PUBLIC_URL, // Used by HtmlWebPackPlugin for asset prefix }, - module: { - rules: [...extractStyleChunksRule(isProdBuild)], - }, resolve: { modules: [ // Modules specific to this package @@ -81,12 +76,6 @@ module.exports = (env, argv) => { }, ], }), - // https://github.com/faceyspacey/extract-css-chunks-webpack-plugin#webpack-4-standalone-installation - new ExtractCssChunksPlugin({ - filename: isProdBuild ? '[name].[hash].css' : '[name].css', - chunkFilename: isProdBuild ? '[id].[hash].css' : '[id].css', - ignoreOrder: false, // Enable to remove warnings about conflicting order - }), // Generate "index.html" w/ correct includes/imports new HtmlWebpackPlugin({ template: `${PUBLIC_DIR}/html-templates/${HTML_TEMPLATE}`, @@ -131,7 +120,14 @@ module.exports = (env, argv) => { mergedConfig.devServer.proxy[PROXY_TARGET] = PROXY_DOMAIN; } - if (!isProdBuild) { + if (isProdBuild) { + mergedConfig.plugins.push( + new MiniCssExtractPlugin({ + filename: '[name].bundle.css', + chunkFilename: '[id].css', + }) + ); + } else { mergedConfig.plugins.push(new webpack.HotModuleReplacementPlugin()); } diff --git a/platform/viewer/package.json b/platform/viewer/package.json index b02a825d2..a12c1733a 100644 --- a/platform/viewer/package.json +++ b/platform/viewer/package.json @@ -17,10 +17,11 @@ }, "proxy": "http://localhost:8042", "scripts": { - "build:viewer": "cross-env NODE_ENV=production node --max_old_space_size=4096 ./../../node_modules/webpack/bin/webpack.js --config .webpack/webpack.pwa.js --progress", - "build:viewer:ci": "cross-env NODE_ENV=production PUBLIC_URL=/ APP_CONFIG=config/netlify.js QUICK_BUILD=true node --max_old_space_size=4096 ./../../node_modules/webpack/bin/webpack.js --config .webpack/webpack.pwa.js", - "build:viewer:qa": "cross-env NODE_ENV=production APP_CONFIG=config/google.js node --max_old_space_size=4096 ./../../node_modules/webpack/bin/webpack.js --config .webpack/webpack.pwa.js --progress", - "build:viewer:demo": "cross-env NODE_ENV=production APP_CONFIG=config/demo.js HTML_TEMPLATE=rollbar.html QUICK_BUILD=true node --max_old_space_size=4096 ./../../node_modules/webpack/bin/webpack.js --progress --config .webpack/webpack.pwa.js", + "build:viewer": "cross-env NODE_ENV=production yarn run build", + "build:viewer:ci": "cross-env NODE_ENV=production PUBLIC_URL=/ APP_CONFIG=config/netlify.js QUICK_BUILD=true yarn run build", + "build:viewer:qa": "cross-env NODE_ENV=production APP_CONFIG=config/google.js yarn run build", + "build:viewer:demo": "cross-env NODE_ENV=production APP_CONFIG=config/demo.js HTML_TEMPLATE=rollbar.html QUICK_BUILD=true yarn run build", + "build": "node --max_old_space_size=4096 ./../../node_modules/webpack/bin/webpack.js --progress --config .webpack/webpack.pwa.js", "dev": "cross-env NODE_ENV=development webpack serve --config .webpack/webpack.pwa.js", "dev:orthanc": "cross-env NODE_ENV=development PROXY_TARGET=/dicom-web PROXY_DOMAIN=http://localhost:8042 APP_CONFIG=config/docker_nginx-orthanc.js webpack serve --config .webpack/webpack.pwa.js", "dev:viewer": "yarn run dev", diff --git a/platform/viewer/public/html-templates/index.html b/platform/viewer/public/html-templates/index.html index 1dce0e233..9374a43f8 100644 --- a/platform/viewer/public/html-templates/index.html +++ b/platform/viewer/public/html-templates/index.html @@ -64,8 +64,8 @@ - + diff --git a/platform/viewer/public/html-templates/rollbar.html b/platform/viewer/public/html-templates/rollbar.html index ae8e9c695..e8899fe74 100644 --- a/platform/viewer/public/html-templates/rollbar.html +++ b/platform/viewer/public/html-templates/rollbar.html @@ -64,8 +64,8 @@ - + diff --git a/platform/viewer/public/html-templates/script-tag.html b/platform/viewer/public/html-templates/script-tag.html deleted file mode 100644 index 455b63493..000000000 --- a/platform/viewer/public/html-templates/script-tag.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - OHIF Standalone Viewer - - - - - -
- - - - - - - diff --git a/platform/viewer/src/index.js b/platform/viewer/src/index.js index 437b9ddf4..12a6d1caa 100644 --- a/platform/viewer/src/index.js +++ b/platform/viewer/src/index.js @@ -6,7 +6,6 @@ import 'regenerator-runtime/runtime'; import App from './App.jsx'; import React from 'react'; import ReactDOM from 'react-dom'; -// test /** * EXTENSIONS diff --git a/platform/viewer/src/routes/DataSourceWrapper.jsx b/platform/viewer/src/routes/DataSourceWrapper.jsx index 769f097b9..69ce49f5e 100644 --- a/platform/viewer/src/routes/DataSourceWrapper.jsx +++ b/platform/viewer/src/routes/DataSourceWrapper.jsx @@ -63,20 +63,21 @@ function DataSourceWrapper(props) { setIsLoading(true); const studies = await dataSource.query.studies.search(queryFilterValues); - setIsLoading(false); setData({ studies: studies || [], total: studies.length, resultsPerPage: queryFilterValues.resultsPerPage, pageNumber: queryFilterValues.pageNumber, }); + + setIsLoading(false); } try { // Cache invalidation :thinking: // - Anytime change is not just next/previous page // - And we didn't cross a result offset range - const isFirstLoad = data.studies.length === 0; + const isFirstLoad = data.studies.length === 0 && !isLoading; const isSamePage = data.pageNumber === queryFilterValues.pageNumber; const previousOffset = Math.floor((data.pageNumber * data.resultsPerPage) / STUDIES_LIMIT) * @@ -88,7 +89,7 @@ function DataSourceWrapper(props) { ) * (STUDIES_LIMIT - 1); const isDataInvalid = - isFirstLoad || isSamePage || newOffset !== previousOffset; + isFirstLoad || !isSamePage || newOffset !== previousOffset; if (isDataInvalid) { getData(); @@ -97,7 +98,7 @@ function DataSourceWrapper(props) { console.warn(ex); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [location, params]); + }, [data, location, params, isLoading, setIsLoading]); // queryFilterValues // TODO: Better way to pass DataSource? diff --git a/platform/viewer/tailwind.config.js b/platform/viewer/tailwind.config.js new file mode 100644 index 000000000..68618f287 --- /dev/null +++ b/platform/viewer/tailwind.config.js @@ -0,0 +1,838 @@ +module.exports = { + prefix: '', + important: false, + separator: ':', + purge: { + // Note: if you are writing an extension that uses Tailwind classes, + // you need to put it here so they are not purged in the production build + content: [ + './src/**/*.{jsx,js,css}', + './node_modules/@ohif/ui/src/**/*.{js,jsx,css}', + '../../node_modules/@ohif/ui/src/**/*.{js,jsx,css}', + '../../node_modules/@ohif/ui/src/**/*.{js,jsx,css}', + '../../node_modules/@ohif/extension-*/src/**/*.{js,jsx,css}', + ], + }, + theme: { + screens: { + sm: '640px', + md: '768px', + lg: '1024px', + xl: '1280px', + }, + colors: { + overlay: 'rgba(0, 0, 0, 0.8)', + transparent: 'transparent', + black: '#000', + white: '#fff', + initial: 'initial', + inherit: 'inherit', + + indigo: { + dark: '#0b1a42', + }, + aqua: { + pale: '#7bb2ce', + }, + + primary: { + light: '#5acce6', + main: '#0944b3', + dark: '#090c29', + active: '#348cfd', + }, + + secondary: { + light: '#3a3f99', + main: '#2b166b', + dark: '#041c4a', + active: '#1f1f27', + }, + + common: { + bright: '#e1e1e1', + light: '#a19fad', + main: '#fff', + dark: '#726f7e', + active: '#2c3074', + }, + + customgreen: { + 100: '#05D97C', + }, + + customblue: { + 100: '#c4fdff', + 200: '#38daff', + }, + + gray: { + 100: '#f7fafc', + 200: '#edf2f7', + 300: '#e2e8f0', + 400: '#cbd5e0', + 500: '#a0aec0', + 600: '#718096', + 700: '#4a5568', + 800: '#2d3748', + 900: '#1a202c', + }, + red: { + 100: '#fff5f5', + 200: '#fed7d7', + 300: '#feb2b2', + 400: '#fc8181', + 500: '#f56565', + 600: '#e53e3e', + 700: '#c53030', + 800: '#9b2c2c', + 900: '#742a2a', + }, + orange: { + 100: '#fffaf0', + 200: '#feebc8', + 300: '#fbd38d', + 400: '#f6ad55', + 500: '#ed8936', + 600: '#dd6b20', + 700: '#c05621', + 800: '#9c4221', + 900: '#7b341e', + }, + yellow: { + 100: '#fffff0', + 200: '#fefcbf', + 300: '#faf089', + 400: '#f6e05e', + 500: '#ecc94b', + 600: '#d69e2e', + 700: '#b7791f', + 800: '#975a16', + 900: '#744210', + }, + green: { + 100: '#f0fff4', + 200: '#c6f6d5', + 300: '#9ae6b4', + 400: '#68d391', + 500: '#48bb78', + 600: '#38a169', + 700: '#2f855a', + 800: '#276749', + 900: '#22543d', + }, + teal: { + 100: '#e6fffa', + 200: '#b2f5ea', + 300: '#81e6d9', + 400: '#4fd1c5', + 500: '#38b2ac', + 600: '#319795', + 700: '#2c7a7b', + 800: '#285e61', + 900: '#234e52', + }, + blue: { + 100: '#ebf8ff', + 200: '#bee3f8', + 300: '#90cdf4', + 400: '#63b3ed', + 500: '#4299e1', + 600: '#3182ce', + 700: '#2b6cb0', + 800: '#2c5282', + 900: '#2a4365', + }, + indigo: { + 100: '#ebf4ff', + 200: '#c3dafe', + 300: '#a3bffa', + 400: '#7f9cf5', + 500: '#667eea', + 600: '#5a67d8', + 700: '#4c51bf', + 800: '#434190', + 900: '#3c366b', + }, + purple: { + 100: '#faf5ff', + 200: '#e9d8fd', + 300: '#d6bcfa', + 400: '#b794f4', + 500: '#9f7aea', + 600: '#805ad5', + 700: '#6b46c1', + 800: '#553c9a', + 900: '#44337a', + }, + pink: { + 100: '#fff5f7', + 200: '#fed7e2', + 300: '#fbb6ce', + 400: '#f687b3', + 500: '#ed64a6', + 600: '#d53f8c', + 700: '#b83280', + 800: '#97266d', + 900: '#702459', + }, + }, + spacing: { + px: '1px', + '0': '0', + '1': '0.15rem', + '2': '0.5rem', + '3': '0.75rem', + '4': '1rem', + '5': '1.25rem', + '6': '1.5rem', + '8': '2rem', + '10': '2.5rem', + '12': '3rem', + '14': '3.5rem', + '16': '4rem', + '18': '4.5rem', + '20': '5rem', + '24': '6rem', + '32': '8rem', + '40': '10rem', + '48': '12rem', + '56': '14rem', + '64': '16rem', + '72': '18rem', + '80': '20rem', + '88': '22rem', + '96': '24rem', + '104': '26rem', + '112': '28rem', + '250px': '250px', + }, + backgroundColor: theme => theme('colors'), + backgroundPosition: { + bottom: 'bottom', + center: 'center', + left: 'left', + 'left-bottom': 'left bottom', + 'left-top': 'left top', + right: 'right', + 'right-bottom': 'right bottom', + 'right-top': 'right top', + top: 'top', + }, + backgroundSize: { + auto: 'auto', + cover: 'cover', + contain: 'contain', + }, + borderColor: theme => ({ + ...theme('colors'), + DEFAULT: theme('colors.gray.300', 'currentColor'), + }), + borderRadius: { + none: '0', + sm: '0.125rem', + DEFAULT: '0.25rem', + md: '0.375rem', + lg: '0.5rem', + full: '9999px', + }, + borderWidth: { + DEFAULT: '1px', + '0': '0', + '2': '2px', + '4': '4px', + '8': '8px', + }, + boxShadow: { + xs: '0 0 0 1px rgba(0, 0, 0, 0.05)', + sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)', + DEFAULT: + '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', + md: + '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', + lg: + '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', + xl: + '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', + '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)', + outline: '0 0 0 3px rgba(66, 153, 225, 0.5)', + none: 'none', + }, + container: {}, + cursor: { + auto: 'auto', + default: 'default', + pointer: 'pointer', + wait: 'wait', + text: 'text', + move: 'move', + 'not-allowed': 'not-allowed', + }, + fill: { + current: 'currentColor', + }, + flex: { + '1': '1 1 0%', + '0.3': '0.3 0.3 0%', + '0.5': '0.5 0.5 0%', + auto: '1 1 auto', + initial: '0 1 auto', + none: 'none', + }, + flexGrow: { + '0': '0', + DEFAULT: '1', + }, + flexShrink: { + '0': '0', + DEFAULT: '1', + }, + fontFamily: { + sans: [ + 'Lato', + 'system-ui', + '-apple-system', + 'BlinkMacSystemFont', + '"Segoe UI"', + 'Roboto', + '"Helvetica Neue"', + 'Arial', + '"Noto Sans"', + 'sans-serif', + '"Apple Color Emoji"', + '"Segoe UI Emoji"', + '"Segoe UI Symbol"', + '"Noto Color Emoji"', + ], + serif: ['Georgia', 'Cambria', '"Times New Roman"', 'Times', 'serif'], + mono: [ + 'Menlo', + 'Monaco', + 'Consolas', + '"Liberation Mono"', + '"Courier New"', + 'monospace', + ], + }, + fontSize: { + xs: '0.65rem', + sm: '0.75rem', + base: '0.875rem', + lg: '1rem', + xl: '1.25rem', + '2xl': '1.5rem', + '3xl': '1.875rem', + '4xl': '2.25rem', + '5xl': '3rem', + '6xl': '4rem', + }, + fontWeight: { + hairline: '100', + thin: '200', + light: '300', + normal: '400', + medium: '500', + semibold: '600', + bold: '700', + extrabold: '800', + black: '900', + }, + height: theme => ({ + auto: 'auto', + ...theme('spacing'), + full: '100%', + screen: '100vh', + }), + inset: { + '0': '0', + auto: 'auto', + full: '100%', + viewport: '0.5rem', + '1/2': '50%', + 'viewport-scrollbar': '1.3rem', + }, + letterSpacing: { + tighter: '-0.05em', + tight: '-0.025em', + normal: '0', + wide: '0.025em', + wider: '0.05em', + widest: '0.1em', + }, + lineHeight: { + none: '1', + tight: '1.25', + snug: '1.375', + normal: '1.5', + relaxed: '1.625', + loose: '2', + '3': '.75rem', + '4': '1rem', + '5': '1.25rem', + '6': '1.5rem', + '7': '1.75rem', + '8': '2rem', + '9': '2.25rem', + '10': '2.5rem', + }, + listStyleType: { + none: 'none', + disc: 'disc', + decimal: 'decimal', + }, + margin: (theme, { negative }) => ({ + auto: 'auto', + ...theme('spacing'), + ...negative(theme('spacing')), + }), + maxHeight: theme => ({ + full: '100%', + screen: '100vh', + ...theme('spacing'), + }), + maxWidth: (theme, { breakpoints }) => ({ + none: 'none', + xs: '20rem', + sm: '24rem', + md: '28rem', + lg: '32rem', + xl: '36rem', + '2xl': '42rem', + '3xl': '48rem', + '4xl': '56rem', + '5xl': '64rem', + '6xl': '72rem', + full: '100%', + ...breakpoints(theme('screens')), + ...theme('spacing'), + }), + minHeight: theme => ({ + ...theme('spacing'), + '0': '0', + full: '100%', + screen: '100vh', + }), + minWidth: theme => ({ + ...theme('spacing'), + '0': '0', + xs: '2rem', + sm: '4rem', + md: '6rem', + lg: '8rem', + xl: '10rem', + full: '100%', + }), + objectPosition: { + bottom: 'bottom', + center: 'center', + left: 'left', + 'left-bottom': 'left bottom', + 'left-top': 'left top', + right: 'right', + 'right-bottom': 'right bottom', + 'right-top': 'right top', + top: 'top', + }, + opacity: { + '0': '0', + '5': '.5', + '10': '.10', + '15': '.15', + '20': '.20', + '25': '.25', + '30': '.30', + '35': '.35', + '40': '.40', + '45': '.45', + '50': '.50', + '55': '.55', + '60': '.60', + '65': '.65', + '70': '.70', + '75': '.75', + '80': '.80', + '85': '.85', + '90': '.90', + '95': '.95', + '100': '1', + }, + order: { + first: '-9999', + last: '9999', + none: '0', + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + '8': '8', + '9': '9', + '10': '10', + '11': '11', + '12': '12', + }, + padding: theme => theme('spacing'), + placeholderColor: theme => theme('colors'), + stroke: theme => ({ + ...theme('colors'), + current: 'currentColor', + }), + strokeWidth: { + '0': '0', + '1': '1', + '2': '2', + }, + textColor: theme => theme('colors'), + width: theme => ({ + auto: 'auto', + ...theme('spacing'), + '1/2': '50%', + '1/3': '33.333333%', + '2/3': '66.666667%', + '1/4': '25%', + '2/4': '50%', + '3/4': '75%', + '1/5': '20%', + '2/5': '40%', + '3/5': '60%', + '4/5': '80%', + '1/6': '16.666667%', + '2/6': '33.333333%', + '3/6': '50%', + '4/6': '66.666667%', + '5/6': '83.333333%', + '1/12': '8.333333%', + '2/12': '16.666667%', + '3/12': '25%', + '4/12': '33.333333%', + '5/12': '41.666667%', + '6/12': '50%', + '7/12': '58.333333%', + '8/12': '66.666667%', + '9/12': '75%', + '10/12': '83.333333%', + '11/12': '91.666667%', + '1/24': '4.166666667%', + '2/24': '8.333333333%', + '3/24': '12.5%', + '4/24': '16.66666667%', + '5/24': '20.83333333%', + '6/24': '25%', + '7/24': '29.16666667%', + '8/24': '33.33333333%', + '9/24': '37.5%', + '10/24': '41.66666667%', + '11/24': '45.83333333%', + '12/24': '50%', + '13/24': '54.16666667%', + '14/24': '58.33333333%', + '15/24': '62.5%', + '16/24': '66.66666667%', + '17/24': '70.83333333%', + '18/24': '75%', + '19/24': '79.16666667%', + '20/24': '83.33333333%', + '21/24': '87.5%', + '22/24': '91.66666667%', + '23/24': '95.83333333%', + full: '100%', + screen: '100vw', + 'max-content': 'max-content', + }), + zIndex: { + auto: 'auto', + '0': '0', + '10': '10', + '20': '20', + '30': '30', + '40': '40', + '50': '50', + }, + gap: theme => theme('spacing'), + gridTemplateColumns: { + none: 'none', + '1': 'repeat(1, minmax(0, 1fr))', + '2': 'repeat(2, minmax(0, 1fr))', + '3': 'repeat(3, minmax(0, 1fr))', + '4': 'repeat(4, minmax(0, 1fr))', + '5': 'repeat(5, minmax(0, 1fr))', + '6': 'repeat(6, minmax(0, 1fr))', + '7': 'repeat(7, minmax(0, 1fr))', + '8': 'repeat(8, minmax(0, 1fr))', + '9': 'repeat(9, minmax(0, 1fr))', + '10': 'repeat(10, minmax(0, 1fr))', + '11': 'repeat(11, minmax(0, 1fr))', + '12': 'repeat(12, minmax(0, 1fr))', + }, + gridColumn: { + auto: 'auto', + 'span-1': 'span 1 / span 1', + 'span-2': 'span 2 / span 2', + 'span-3': 'span 3 / span 3', + 'span-4': 'span 4 / span 4', + 'span-5': 'span 5 / span 5', + 'span-6': 'span 6 / span 6', + 'span-7': 'span 7 / span 7', + 'span-8': 'span 8 / span 8', + 'span-9': 'span 9 / span 9', + 'span-10': 'span 10 / span 10', + 'span-11': 'span 11 / span 11', + 'span-12': 'span 12 / span 12', + }, + gridColumnStart: { + auto: 'auto', + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + '8': '8', + '9': '9', + '10': '10', + '11': '11', + '12': '12', + '13': '13', + }, + gridColumnEnd: { + auto: 'auto', + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + '8': '8', + '9': '9', + '10': '10', + '11': '11', + '12': '12', + '13': '13', + }, + gridTemplateRows: { + none: 'none', + '1': 'repeat(1, minmax(0, 1fr))', + '2': 'repeat(2, minmax(0, 1fr))', + '3': 'repeat(3, minmax(0, 1fr))', + '4': 'repeat(4, minmax(0, 1fr))', + '5': 'repeat(5, minmax(0, 1fr))', + '6': 'repeat(6, minmax(0, 1fr))', + }, + gridRow: { + auto: 'auto', + 'span-1': 'span 1 / span 1', + 'span-2': 'span 2 / span 2', + 'span-3': 'span 3 / span 3', + 'span-4': 'span 4 / span 4', + 'span-5': 'span 5 / span 5', + 'span-6': 'span 6 / span 6', + }, + gridRowStart: { + auto: 'auto', + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + }, + gridRowEnd: { + auto: 'auto', + '1': '1', + '2': '2', + '3': '3', + '4': '4', + '5': '5', + '6': '6', + '7': '7', + }, + transformOrigin: { + center: 'center', + top: 'top', + 'top-right': 'top right', + right: 'right', + 'bottom-right': 'bottom right', + bottom: 'bottom', + 'bottom-left': 'bottom left', + left: 'left', + 'top-left': 'top left', + }, + scale: { + '0': '0', + '50': '.5', + '75': '.75', + '90': '.9', + '95': '.95', + '100': '1', + '105': '1.05', + '110': '1.1', + '125': '1.25', + '150': '1.5', + }, + rotate: { + '-180': '-180deg', + '-90': '-90deg', + '-45': '-45deg', + '0': '0', + '45': '45deg', + '90': '90deg', + '180': '180deg', + }, + translate: (theme, { negative }) => ({ + ...theme('spacing'), + ...negative(theme('spacing')), + '-full': '-100%', + '-1/2': '-50%', + '1/2': '50%', + full: '100%', + }), + skew: { + '-12': '-12deg', + '-6': '-6deg', + '-3': '-3deg', + '0': '0', + '3': '3deg', + '6': '6deg', + '12': '12deg', + }, + transitionProperty: { + none: 'none', + all: 'all', + height: 'height', + DEFAULT: + 'background-color, border-color, color, fill, stroke, opacity, box-shadow, transform', + colors: 'background-color, border-color, color, fill, stroke', + opacity: 'opacity', + shadow: 'box-shadow', + transform: 'transform', + }, + transitionTimingFunction: { + linear: 'linear', + in: 'cubic-bezier(0.4, 0, 1, 1)', + out: 'cubic-bezier(0, 0, 0.2, 1)', + 'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)', + }, + transitionDuration: { + '75': '75ms', + '100': '100ms', + '150': '150ms', + '200': '200ms', + '300': '300ms', + '500': '500ms', + '700': '700ms', + '1000': '1000ms', + }, + }, + variants: { + accessibility: ['responsive', 'focus'], + alignContent: ['responsive'], + alignItems: ['responsive'], + alignSelf: ['responsive'], + appearance: ['responsive'], + backgroundAttachment: ['responsive'], + backgroundColor: [ + 'responsive', + 'hover', + 'focus', + 'active', + 'group-focus', + 'group-hover', + ], + backgroundPosition: ['responsive'], + backgroundRepeat: ['responsive'], + backgroundSize: ['responsive'], + borderCollapse: ['responsive'], + borderColor: [ + 'responsive', + 'hover', + 'focus', + 'active', + 'group-focus', + 'group-hover', + ], + borderRadius: ['responsive', 'focus', 'first', 'last'], + borderStyle: ['responsive', 'focus'], + borderWidth: ['responsive', 'focus', 'first', 'last'], + boxShadow: ['responsive', 'hover', 'focus'], + boxSizing: ['responsive'], + cursor: ['responsive'], + display: ['responsive'], + fill: ['responsive'], + flex: ['responsive'], + flexDirection: ['responsive'], + flexGrow: ['responsive'], + flexShrink: ['responsive'], + flexWrap: ['responsive'], + float: ['responsive'], + clear: ['responsive'], + fontFamily: ['responsive'], + fontSize: ['responsive'], + fontSmoothing: ['responsive'], + fontStyle: ['responsive'], + fontWeight: ['responsive', 'hover', 'focus'], + height: ['responsive'], + inset: ['responsive'], + justifyContent: ['responsive'], + letterSpacing: ['responsive'], + lineHeight: ['responsive'], + listStylePosition: ['responsive'], + listStyleType: ['responsive'], + margin: ['responsive'], + maxHeight: ['responsive'], + maxWidth: ['responsive'], + minHeight: ['responsive'], + minWidth: ['responsive'], + objectFit: ['responsive'], + objectPosition: ['responsive'], + opacity: ['responsive', 'hover', 'focus', 'active'], + order: ['responsive'], + outline: ['responsive', 'focus'], + overflow: ['responsive'], + padding: ['responsive', 'first'], + placeholderColor: ['responsive', 'focus'], + pointerEvents: ['responsive'], + position: ['responsive'], + resize: ['responsive'], + stroke: ['responsive'], + strokeWidth: ['responsive'], + tableLayout: ['responsive'], + textAlign: ['responsive'], + textColor: ['responsive', 'hover', 'focus', 'active', 'group-hover'], + textDecoration: ['responsive', 'hover', 'focus'], + textTransform: ['responsive'], + userSelect: ['responsive'], + verticalAlign: ['responsive'], + visibility: ['responsive'], + whitespace: ['responsive'], + width: ['responsive'], + wordBreak: ['responsive'], + zIndex: ['responsive'], + gap: ['responsive'], + gridAutoFlow: ['responsive'], + gridTemplateColumns: ['responsive'], + gridColumn: ['responsive'], + gridColumnStart: ['responsive'], + gridColumnEnd: ['responsive'], + gridTemplateRows: ['responsive'], + gridRow: ['responsive'], + gridRowStart: ['responsive'], + gridRowEnd: ['responsive'], + transform: ['responsive'], + transformOrigin: ['responsive'], + scale: ['responsive', 'hover', 'focus'], + rotate: ['responsive', 'hover', 'focus'], + translate: ['responsive', 'hover', 'focus'], + skew: ['responsive', 'hover', 'focus'], + transitionProperty: ['responsive'], + transitionTimingFunction: ['responsive'], + transitionDuration: ['responsive'], + }, + corePlugins: {}, + plugins: [], +}; diff --git a/platform/viewer/tailwind.css b/platform/viewer/tailwind.css new file mode 100644 index 000000000..492349705 --- /dev/null +++ b/platform/viewer/tailwind.css @@ -0,0 +1,4 @@ +/* IMPORT CUSTOM FONT */ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/yarn.lock b/yarn.lock index f26bc17c3..ba2e469ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1114,27 +1114,13 @@ core-js-pure "^3.15.0" regenerator-runtime "^0.13.4" -"@babel/runtime@7.1.2": - version "7.1.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.1.2.tgz#81c89935f4647706fc54541145e6b4ecfef4b8e3" - integrity sha512-Y3SCjmhSupzFB6wcv1KmmFucH6gDVnI30WjOcicV10ju0cZjak3Jcs67YLIXBrmZYw1xCrVeJPbycFwrqNyxpg== - dependencies: - regenerator-runtime "^0.12.0" - -"@babel/runtime@7.7.6", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.4", "@babel/runtime@^7.7.6": +"@babel/runtime@7.1.2", "@babel/runtime@7.7.6", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.4", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.7.6" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.6.tgz#d18c511121aff1b4f2cd1d452f1bac9601dd830f" integrity sha512-BWAJxpNVa0QlE5gZdWjSxXtemZyZ9RmrmVozxt3NUXeZhVIJ5ANyqmMc0JDrivBZyxUuQvFxlvH4OWWOogGfUw== dependencies: regenerator-runtime "^0.13.2" -"@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.8.tgz#7119a56f421018852694290b9f9148097391b446" - integrity sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg== - dependencies: - regenerator-runtime "^0.13.4" - "@babel/template@^7.12.7", "@babel/template@^7.14.5", "@babel/template@^7.4.0": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4" @@ -8098,16 +8084,6 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -extract-css-chunks-webpack-plugin@^4.9.0: - version "4.9.0" - resolved "https://registry.yarnpkg.com/extract-css-chunks-webpack-plugin/-/extract-css-chunks-webpack-plugin-4.9.0.tgz#da5e6b1d8b39a398c817ffc98550f4ccb6d795e1" - integrity sha512-HNuNPCXRMqJDQ1OHAUehoY+0JVCnw9Y/H22FQzYVwo8Ulgew98AGDu0grnY5c7xwiXHjQa6yJ/1dxLCI/xqTyQ== - dependencies: - loader-utils "^2.0.0" - normalize-url "1.9.1" - schema-utils "^1.0.0" - webpack-sources "^1.1.0" - extract-stack@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/extract-stack/-/extract-stack-1.0.0.tgz#b97acaf9441eea2332529624b732fc5a1c8165fa" @@ -12021,6 +11997,13 @@ mini-css-extract-plugin@^1.6.0: schema-utils "^3.0.0" webpack-sources "^1.1.0" +mini-css-extract-plugin@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.1.0.tgz#4aa6558b527ad4c168fee4a20b6092ebe9f98309" + integrity sha512-SV1GgjMcfqy6hW07rAniUbQE4qS3inh3v4rZEUySkPRWy3vMbS3jUCjMOvNI4lUnDlQYJEmuUqKktTCNY5koFQ== + dependencies: + schema-utils "^3.0.0" + minimalistic-assert@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -12443,16 +12426,6 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= -normalize-url@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" - integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= - dependencies: - object-assign "^4.0.1" - prepend-http "^1.0.0" - query-string "^4.1.0" - sort-keys "^1.0.0" - normalize-url@^3.0.0: version "3.3.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" @@ -13652,16 +13625,6 @@ postcss-image-set-function@^3.0.1: postcss "^7.0.2" postcss-values-parser "^2.0.0" -postcss-import@^12.0.1: - version "12.0.1" - resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-12.0.1.tgz#cf8c7ab0b5ccab5649024536e565f841928b7153" - integrity sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw== - dependencies: - postcss "^7.0.1" - postcss-value-parser "^3.2.3" - read-cache "^1.0.0" - resolve "^1.1.7" - postcss-import@^14.0.2: version "14.0.2" resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-14.0.2.tgz#60eff77e6be92e7b67fe469ec797d9424cae1aa1" @@ -13704,17 +13667,6 @@ postcss-load-config@^3.1.0: lilconfig "^2.0.3" yaml "^1.10.2" -postcss-loader@^4.0.3: - version "4.3.0" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-4.3.0.tgz#2c4de9657cd4f07af5ab42bd60a673004da1b8cc" - integrity sha512-M/dSoIiNDOo8Rk0mUqoj4kpGq91gcxCfb9PoyZVdZ76/AuhxylHDYZblNE8o+EQ9AMSASeMFEKxZf5aU6wlx1Q== - dependencies: - cosmiconfig "^7.0.0" - klona "^2.0.4" - loader-utils "^2.0.0" - schema-utils "^3.0.0" - semver "^7.3.4" - postcss-loader@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-5.3.0.tgz#1657f869e48d4fdb018a40771c235e499ee26244" @@ -14134,7 +14086,7 @@ postcss-place@^4.0.1: postcss "^7.0.2" postcss-values-parser "^2.0.0" -postcss-preset-env@^6.6.0, postcss-preset-env@^6.7.0: +postcss-preset-env@^6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz#c34ddacf8f902383b35ad1e030f178f4cdf118a5" integrity sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg== @@ -14319,7 +14271,7 @@ postcss-unique-selectors@^5.0.1: postcss-selector-parser "^6.0.5" uniqs "^2.0.0" -postcss-value-parser@^3.0.0, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0: +postcss-value-parser@^3.0.0, postcss-value-parser@^3.3.0: version "3.3.1" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== @@ -14385,11 +14337,6 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prepend-http@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= - prepend-http@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" @@ -14703,14 +14650,6 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== -query-string@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" - integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s= - dependencies: - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - query-string@^6.12.1, query-string@^6.13.8, query-string@^6.14.0: version "6.14.1" resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a" @@ -15604,11 +15543,6 @@ regenerate@^1.4.0: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.12.0: - version "0.12.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" - integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== - regenerator-runtime@^0.13.1, regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4: version "0.13.7" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" @@ -16614,13 +16548,6 @@ sort-css-media-queries@1.5.4: resolved "https://registry.yarnpkg.com/sort-css-media-queries/-/sort-css-media-queries-1.5.4.tgz#24182b12002a13d01ba943ddf74f5098d7c244ce" integrity sha512-YP5W/h4Sid/YP7Lp87ejJ5jP13/Mtqt2vx33XyhO+IAugKlufRPbOrPlIiEUuxmpNBSBd3EeeQpFhdu3RfI2Ag== -sort-keys@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" - integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= - dependencies: - is-plain-obj "^1.0.0" - sort-keys@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" @@ -16890,11 +16817,6 @@ stream-shift@^1.0.0: resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= - strict-uri-encode@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546"