diff --git a/src/lib/LoadingIcon.tsx b/src/lib/LoadingIcon.tsx
new file mode 100644
index 000000000..4b7b7eb14
--- /dev/null
+++ b/src/lib/LoadingIcon.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import { PreviewLoading } from 'box-ui-elements/es/components/preview';
+
+export type Options = {
+ containerEl: HTMLElement;
+};
+
+export default class LoadingIcon {
+ containerEl: HTMLElement;
+
+ constructor({ containerEl }: Options) {
+ this.containerEl = containerEl;
+ }
+
+ destroy(): void {
+ ReactDOM.unmountComponentAtNode(this.containerEl);
+ }
+
+ render(extension: string): void {
+ ReactDOM.render(, this.containerEl);
+ }
+}
diff --git a/src/lib/Notification.js b/src/lib/Notification.js
index adf7d9249..29251c4e9 100644
--- a/src/lib/Notification.js
+++ b/src/lib/Notification.js
@@ -1,5 +1,5 @@
import { CLASS_HIDDEN, CLASS_BOX_PREVIEW_NOTIFICATION, CLASS_BOX_PREVIEW_NOTIFICATION_WRAPPER } from './constants';
-import { ICON_CLOSE } from './icons/icons';
+import { ICON_CLOSE } from './icons';
const HIDE_TIMEOUT_MS = 5000; // 5s
diff --git a/src/lib/Popup.js b/src/lib/Popup.js
index 829086716..77e79380f 100644
--- a/src/lib/Popup.js
+++ b/src/lib/Popup.js
@@ -1,5 +1,5 @@
import { CLASS_HIDDEN } from './constants';
-import { ICON_CLOSE } from './icons/icons';
+import { ICON_CLOSE } from './icons';
import { decodeKeydown } from './util';
class Popup {
diff --git a/src/lib/Preview.js b/src/lib/Preview.js
index 76f5b1b2e..3c5a82c4b 100644
--- a/src/lib/Preview.js
+++ b/src/lib/Preview.js
@@ -871,6 +871,7 @@ class Preview extends EventEmitter {
this.ui.showNavigation(this.file.id, this.collection);
// Setup loading UI and progress bar
+ this.ui.showLoadingIcon(this.file.extension);
this.ui.showLoadingIndicator();
this.ui.startProgressBar();
@@ -1170,11 +1171,6 @@ class Preview extends EventEmitter {
throw new PreviewError(ERROR_CODE.PERMISSIONS_PREVIEW, __('error_permissions'));
}
- // Show loading download button if user can download
- if (canDownload(this.file, this.options)) {
- this.ui.showLoadingDownloadButton(this.download);
- }
-
// Determine the asset loader to use
const loader = this.getLoader(this.file);
diff --git a/src/lib/PreviewUI.js b/src/lib/PreviewUI.js
index 6e2e6448f..000985470 100644
--- a/src/lib/PreviewUI.js
+++ b/src/lib/PreviewUI.js
@@ -1,6 +1,7 @@
+import LoadingIcon from './LoadingIcon';
+import Notification from './Notification';
import ProgressBar from './ProgressBar';
import shellTemplate from './shell.html';
-import Notification from './Notification';
import {
CLASS_BOX_PREVIEW_BASE_HEADER,
CLASS_BOX_PREVIEW_HAS_HEADER,
@@ -8,25 +9,19 @@ import {
CLASS_BOX_PREVIEW_HEADER,
CLASS_BOX_PREVIEW_THEME_DARK,
CLASS_HIDDEN,
- CLASS_INVISIBLE,
CLASS_PREVIEW_LOADED,
SELECTOR_BOX_PREVIEW_BTN_DOWNLOAD,
- SELECTOR_BOX_PREVIEW_BTN_LOADING_DOWNLOAD,
SELECTOR_BOX_PREVIEW_BTN_PRINT,
SELECTOR_BOX_PREVIEW_CONTAINER,
- SELECTOR_BOX_PREVIEW_CRAWLER_WRAPPER,
SELECTOR_BOX_PREVIEW_HEADER_CONTAINER,
- SELECTOR_BOX_PREVIEW_LOADING_TEXT,
- SELECTOR_BOX_PREVIEW_LOADING_WRAPPER,
SELECTOR_BOX_PREVIEW_LOGO_CUSTOM,
SELECTOR_BOX_PREVIEW_LOGO_DEFAULT,
SELECTOR_BOX_PREVIEW,
- SELECTOR_NAVIGATION_LEFT,
- SELECTOR_NAVIGATION_RIGHT,
SELECTOR_BOX_PREVIEW_CONTENT,
SELECTOR_BOX_PREVIEW_ICON,
+ SELECTOR_NAVIGATION_LEFT,
+ SELECTOR_NAVIGATION_RIGHT,
} from './constants';
-import { getIconFromName, getIconFromExtension } from './icons/icons';
import { insertTemplate } from './util';
class PreviewUI {
@@ -48,6 +43,9 @@ class PreviewUI {
/** @property {Function} - Keydown handler */
keydownHandler;
+ /** @property {LoadingIcon} - Loading icon instance */
+ loadingIcon;
+
/** @property {HTMLElement} - Preview container element which houses the sidebar and content */
previewContainer;
@@ -69,6 +67,11 @@ class PreviewUI {
this.previewContainer.removeEventListener('mousemove', this.mousemoveHandler);
}
+ if (this.loadingIcon) {
+ this.loadingIcon.destroy();
+ this.loadingIcon = null;
+ }
+
if (this.container) {
this.container.innerHTML = '';
}
@@ -123,18 +126,16 @@ class PreviewUI {
this.setupHeader(options.header, options.logoUrl);
}
+ // Destroy the loading icon if disabled
+ if (options.showLoading === false) {
+ this.destroyLoading();
+ }
+
// Setup progress bar
if (options.showProgress) {
this.progressBar = new ProgressBar(this.container);
}
- // Setup loading indicator
- if (options.showLoading) {
- this.setupLoading();
- } else {
- this.destroyLoading();
- }
-
// Attach keyboard events
document.addEventListener('keydown', this.keydownHandler);
@@ -248,25 +249,7 @@ class PreviewUI {
}
/**
- * Shows the loading download button if the viewers implement download
- *
- * @public
- * @param {Function} handler - Download click handler
- * @return {void}
- */
- showLoadingDownloadButton(handler) {
- const downloadButtonEl = this.container.querySelector(SELECTOR_BOX_PREVIEW_BTN_LOADING_DOWNLOAD);
- if (!downloadButtonEl) {
- return;
- }
-
- downloadButtonEl.title = __('download');
- downloadButtonEl.classList.remove(CLASS_INVISIBLE);
- downloadButtonEl.addEventListener('click', handler);
- }
-
- /**
- * Shows the loading indicator.
+ * Shows the loading indicator
*
* @public
* @return {void}
@@ -289,47 +272,6 @@ class PreviewUI {
}
this.previewContainer.classList.add(CLASS_PREVIEW_LOADED);
- this.showCrawler();
- }
-
- /**
- * Hides the loading crawler.
- *
- * @public
- * @return {void}
- */
- hideCrawler() {
- const crawler = this.previewContainer.querySelector(SELECTOR_BOX_PREVIEW_CRAWLER_WRAPPER);
- if (crawler) {
- crawler.classList.add(CLASS_HIDDEN);
- }
- }
-
- /**
- * Shows the loading crawler.
- *
- * @public
- * @return {void}
- */
- showCrawler() {
- const crawler = this.previewContainer.querySelector(SELECTOR_BOX_PREVIEW_CRAWLER_WRAPPER);
- if (crawler) {
- crawler.classList.remove(CLASS_HIDDEN);
- }
- }
-
- /**
- * Set the icon for the loading indicator based on the file extension.
- *
- * @public
- * @param {string} extension - File extension
- * @return {void}
- */
- setLoadingIcon(extension) {
- const iconWrapperEl = this.container.querySelector(SELECTOR_BOX_PREVIEW_ICON);
- if (iconWrapperEl) {
- iconWrapperEl.innerHTML = getIconFromExtension(extension) || getIconFromName('FILE_DEFAULT');
- }
}
/**
@@ -420,22 +362,38 @@ class PreviewUI {
headerToShow.classList.remove(CLASS_HIDDEN);
}
+ /**
+ * Sets the preview loading icon
+ *
+ * @public
+ * @param {string} extension - File extension to use for loading icon
+ * @return {void}
+ */
+ showLoadingIcon(extension) {
+ const iconEl = this.container.querySelector(SELECTOR_BOX_PREVIEW_ICON);
+
+ if (iconEl) {
+ this.loadingIcon = this.loadingIcon || new LoadingIcon({ containerEl: iconEl });
+ this.loadingIcon.render(extension);
+ }
+ }
+
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
- * Remove global loading indicators from the shell
+ * Remove global loading indicator from the shell
*
* @private
* @return {void}
*/
destroyLoading() {
- const loadingWrapperEl = this.container.querySelector(SELECTOR_BOX_PREVIEW_LOADING_WRAPPER);
- if (!loadingWrapperEl) {
+ const loadingIconEl = this.container.querySelector(SELECTOR_BOX_PREVIEW_ICON);
+ if (!loadingIconEl) {
return;
}
- loadingWrapperEl.parentElement.removeChild(loadingWrapperEl);
+ loadingIconEl.parentElement.removeChild(loadingIconEl);
}
/**
@@ -469,25 +427,6 @@ class PreviewUI {
customLogoEl.classList.remove(CLASS_HIDDEN);
}
}
-
- /**
- * Sets up preview loading indicator.
- *
- * @private
- * @return {void}
- */
- setupLoading() {
- const loadingWrapperEl = this.container.querySelector(SELECTOR_BOX_PREVIEW_LOADING_WRAPPER);
- if (!loadingWrapperEl) {
- return;
- }
-
- const loadingTextEl = loadingWrapperEl.querySelector(SELECTOR_BOX_PREVIEW_LOADING_TEXT);
- loadingTextEl.textContent = __('loading_preview');
-
- const loadingDownloadButtonEl = loadingWrapperEl.querySelector(SELECTOR_BOX_PREVIEW_BTN_LOADING_DOWNLOAD);
- loadingDownloadButtonEl.textContent = __('download_file');
- }
}
export default PreviewUI;
diff --git a/src/lib/__tests__/Preview-test.js b/src/lib/__tests__/Preview-test.js
index 7aa89a313..8952a4009 100644
--- a/src/lib/__tests__/Preview-test.js
+++ b/src/lib/__tests__/Preview-test.js
@@ -1216,6 +1216,7 @@ describe('lib/Preview', () => {
test('should setup the shell, update navigation, and show loading/start progress', () => {
const previewUIMock = sandbox.mock(preview.ui);
previewUIMock.expects('setup');
+ previewUIMock.expects('showLoadingIcon');
previewUIMock.expects('showLoadingIndicator');
previewUIMock.expects('startProgressBar');
previewUIMock.expects('showNavigation');
@@ -1666,7 +1667,6 @@ describe('lib/Preview', () => {
stubs.destroy = jest.spyOn(preview, 'destroy');
stubs.checkPermission = jest.spyOn(file, 'checkPermission').mockReturnValue(true);
stubs.canDownload = jest.spyOn(file, 'canDownload').mockReturnValue(false);
- stubs.showLoadingDownloadButton = jest.spyOn(preview.ui, 'showLoadingDownloadButton').mockImplementation();
stubs.loadPromiseResolve = Promise.resolve();
stubs.determineRepresentationStatusPromise = Promise.resolve();
stubs.loader = {
@@ -1711,18 +1711,6 @@ describe('lib/Preview', () => {
expect(() => preview.loadViewer()).toThrowError(PreviewError);
});
- test('should show the loading download button if file can be downloaded', () => {
- stubs.canDownload.mockReturnValue(true);
- preview.loadViewer({});
- expect(stubs.showLoadingDownloadButton).toBeCalled();
- });
-
- test("should not show the loading download button if file can't be downloaded", () => {
- stubs.canDownload.mockReturnValue(false);
- preview.loadViewer({});
- expect(stubs.showLoadingDownloadButton).not.toBeCalled();
- });
-
test('should throw an unsupported error if there is no loader for general file types', () => {
stubs.getLoader.mockReturnValue(undefined);
diff --git a/src/lib/__tests__/PreviewUI-test.js b/src/lib/__tests__/PreviewUI-test.js
index a5d49ac9d..382dd6be8 100644
--- a/src/lib/__tests__/PreviewUI-test.js
+++ b/src/lib/__tests__/PreviewUI-test.js
@@ -1,7 +1,9 @@
/* eslint-disable no-unused-expressions */
import * as constants from '../constants';
+import LoadingIcon from '../LoadingIcon';
import PreviewUI from '../PreviewUI';
-import { getIconFromExtension } from '../icons/icons';
+
+jest.mock('../LoadingIcon');
const sandbox = sinon.createSandbox();
let ui;
@@ -61,21 +63,13 @@ describe('lib/PreviewUI', () => {
expect(resultEl).toContainSelector(constants.SELECTOR_BOX_PREVIEW_PROGRESS_BAR);
// Check loading state
- const loadingWrapperEl = resultEl.querySelector(constants.SELECTOR_BOX_PREVIEW_LOADING_WRAPPER);
- expect(loadingWrapperEl).toContainSelector(constants.SELECTOR_BOX_PREVIEW_ICON);
- expect(loadingWrapperEl).toContainHTML('Loading Preview...');
- expect(loadingWrapperEl).toContainHTML('Download File');
+ expect(resultEl).toContainSelector(constants.SELECTOR_BOX_PREVIEW_ICON);
});
test('should not setup the progress bar or loading state if their respective option is false', () => {
const resultEl = ui.setup({ container: containerEl, showLoading: false, showProgress: false });
expect(resultEl).not.toContainSelector(constants.SELECTOR_BOX_PREVIEW_PROGRESS_BAR);
-
- // Check loading state
- expect(resultEl).not.toContainSelector(constants.SELECTOR_BOX_PREVIEW_LOADING_WRAPPER);
expect(resultEl).not.toContainSelector(constants.SELECTOR_BOX_PREVIEW_ICON);
- expect(resultEl).not.toContainHTML('Loading Preview...');
- expect(resultEl).not.toContainHTML('Download File');
});
test('should setup logo if option specifies', () => {
@@ -201,40 +195,8 @@ describe('lib/PreviewUI', () => {
});
});
- describe('showDownloadButton()', () => {
- test('should set up and show download button', () => {
- const buttonEl = containerEl.querySelector(constants.SELECTOR_BOX_PREVIEW_BTN_DOWNLOAD);
- buttonEl.classList.add(constants.CLASS_HIDDEN);
- sandbox
- .mock(buttonEl)
- .expects('addEventListener')
- .withArgs('click', handler);
-
- ui.showDownloadButton(handler);
-
- expect(buttonEl.title).toBe('Download');
- expect(buttonEl.classList.contains(constants.CLASS_HIDDEN)).toBe(false);
- });
- });
-
- describe('showLoadingDownloadButton()', () => {
- test('should set up and show loading download button', () => {
- const buttonEl = containerEl.querySelector(constants.SELECTOR_BOX_PREVIEW_BTN_LOADING_DOWNLOAD);
- buttonEl.classList.add(constants.CLASS_INVISIBLE);
- sandbox
- .mock(buttonEl)
- .expects('addEventListener')
- .withArgs('click', handler);
-
- ui.showLoadingDownloadButton(handler);
-
- expect(buttonEl.title).toBe('Download');
- expect(buttonEl.classList.contains(constants.CLASS_INVISIBLE)).toBe(false);
- });
- });
-
describe('showLoadingIndicator()', () => {
- test('should show loading indicator', () => {
+ test('should update the container classes', () => {
const contentContainerEl = containerEl.querySelector(constants.SELECTOR_BOX_PREVIEW);
contentContainerEl.classList.add(constants.CLASS_PREVIEW_LOADED);
@@ -245,36 +207,11 @@ describe('lib/PreviewUI', () => {
});
describe('hideLoadingIndicator()', () => {
- beforeEach(() => {
- jest.spyOn(ui, 'showCrawler');
- });
-
- test('should hide loading indicator', () => {
+ test('should update the container classes', () => {
const contentContainerEl = containerEl.querySelector(constants.SELECTOR_BOX_PREVIEW);
ui.hideLoadingIndicator();
expect(contentContainerEl).toHaveClass(constants.CLASS_PREVIEW_LOADED);
});
-
- test('should show the crawler', () => {
- ui.hideLoadingIndicator();
- expect(ui.showCrawler).toBeCalled();
- });
- });
-
- describe('showCrawler()', () => {
- test('should remove the hidden class from the crawler', () => {
- const crawlerEl = containerEl.querySelector(constants.SELECTOR_BOX_PREVIEW_CRAWLER_WRAPPER);
- ui.showCrawler();
- expect(crawlerEl).not.toHaveClass(constants.CLASS_HIDDEN);
- });
- });
-
- describe('hideCrawler()', () => {
- test('should add the hidden class to the crawler', () => {
- const crawlerEl = containerEl.querySelector(constants.SELECTOR_BOX_PREVIEW_CRAWLER_WRAPPER);
- ui.hideCrawler();
- expect(crawlerEl).toHaveClass(constants.CLASS_HIDDEN);
- });
});
describe('setupNotification()', () => {
@@ -285,15 +222,13 @@ describe('lib/PreviewUI', () => {
});
});
- describe('setLoadingIcon()', () => {
- test('should hide the crawler and set the file icon into the icon element', () => {
- const iconEl = document.createElement('div');
- iconEl.innerHTML = getIconFromExtension('pdf');
-
+ describe('showLoadingIcon()', () => {
+ test('should render the loading icon based on the file extension', () => {
ui.setup(options);
- ui.setLoadingIcon('pdf');
+ ui.showLoadingIcon('pdf');
- expect(containerEl.querySelector(constants.SELECTOR_BOX_PREVIEW_ICON).innerHTML).toEqual(iconEl.innerHTML);
+ expect(ui.loadingIcon).toBeInstanceOf(LoadingIcon);
+ expect(ui.loadingIcon.render).toBeCalledWith('pdf');
});
});
diff --git a/src/lib/_common.scss b/src/lib/_common.scss
index b7fc83d08..816c1f266 100644
--- a/src/lib/_common.scss
+++ b/src/lib/_common.scss
@@ -76,17 +76,6 @@ $header-height: 48px;
}
}
-.bp-icon-file {
- width: 160px;
- height: 160px;
- margin: 0 auto;
-
- svg {
- width: 100%;
- height: 100%;
- }
-}
-
// Dark theme for header
.bp-theme-dark {
.bp-header {
@@ -112,9 +101,7 @@ $header-height: 48px;
background-color: $sunset-grey;
}
- .bp-error,
- .bp-loading-text,
- .bp-btn-loading-download {
+ .bp-error {
color: $white;
}
diff --git a/src/lib/_loading.scss b/src/lib/_loading.scss
index 47d322090..0e7824821 100644
--- a/src/lib/_loading.scss
+++ b/src/lib/_loading.scss
@@ -41,10 +41,7 @@ $spinner-size: 15px;
display: flex;
flex-direction: column;
justify-content: center;
- transition: .25s opacity, .25s transform;
- animation-name: fadeIn;
- animation-duration: 1s;
- animation-iteration-count: 1;
+ transition: .25s opacity;
.bp-loaded & {
display: none;
@@ -62,25 +59,14 @@ $spinner-size: 15px;
.bp-loading {
position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: center;
color: $twos;
- text-align: center;
}
-.bp-loading-btn-container {
- padding: 15px 0 27px; // Same height as error viewer
- text-align: center;
-}
-
-.bp-btn-loading-download {
- color: $better-black;
- font-size: 12px;
-}
-
-// This crawler wrapper is used during preview loading
.bp-crawler-wrapper {
- position: absolute;
- top: 72px;
- width: 100%;
+ display: none;
.bp-crawler {
transform: scale(1.5);
@@ -91,7 +77,6 @@ $spinner-size: 15px;
}
}
-// Crawler is 3 short lines pulsing
.bp-crawler {
text-align: center;
@@ -101,7 +86,7 @@ $spinner-size: 15px;
height: 10px;
background-color: $box-blue;
border-radius: 4px;
- animation: box-crawler .66s infinite ease-in-out;
+ animation: box-crawler .66s infinite ease-in-out; // Crawler is 3 short lines pulsing
}
div:nth-child(2) {
diff --git a/src/lib/constants.js b/src/lib/constants.js
index 34fff22ab..cff9c9ecd 100644
--- a/src/lib/constants.js
+++ b/src/lib/constants.js
@@ -18,11 +18,8 @@ export const CLASS_BOX_PREVIEW_HAS_NAVIGATION = 'bp-has-navigation';
export const CLASS_BOX_PREVIEW_HEADER = 'bp-header';
export const CLASS_BOX_PREVIEW_HEADER_CONTAINER = 'bp-header-container';
export const CLASS_BOX_PREVIEW_BASE_HEADER = 'bp-base-header';
-export const CLASS_BOX_PREVIEW_HEADER_BTNS = 'bp-header-btns';
export const CLASS_BOX_PREVIEW_ICON = 'bp-icon';
export const CLASS_BOX_PREVIEW_LINK = 'bp-link';
-export const CLASS_BOX_PREVIEW_LOADING_TEXT = 'bp-loading-text';
-export const CLASS_BOX_PREVIEW_LOADING_WRAPPER = 'bp-loading-wrapper';
export const CLASS_BOX_PREVIEW_LOGO_CUSTOM = 'bp-custom-logo';
export const CLASS_BOX_PREVIEW_LOGO_DEFAULT = 'bp-default-logo';
export const CLASS_BOX_PREVIEW_MENU = 'bp-menu';
@@ -65,20 +62,15 @@ export const DISCOVERABILITY_ATTRIBUTE = 'data-resin-discoverability';
export const SELECTOR_BOX_PREVIEW_CONTAINER = `.${CLASS_BOX_PREVIEW_CONTAINER}`;
export const SELECTOR_BOX_PREVIEW = `.${CLASS_BOX_PREVIEW}`;
export const SELECTOR_BOX_PREVIEW_CONTENT = `.${CLASS_BOX_PREVIEW_CONTENT}`;
-export const SELECTOR_BOX_PREVIEW_CRAWLER_WRAPPER = '.bp-crawler-wrapper';
-export const SELECTOR_BOX_PREVIEW_HEADER_BTNS = `.${CLASS_BOX_PREVIEW_HEADER_BTNS}`;
export const SELECTOR_NAVIGATION_LEFT = '.bp-navigate-left';
export const SELECTOR_NAVIGATION_RIGHT = '.bp-navigate-right';
export const SELECTOR_BOX_PREVIEW_BTN_ANNOTATE_POINT = '.bp-btn-annotate-point';
export const SELECTOR_BOX_PREVIEW_BTN_ANNOTATE_DRAW = '.bp-btn-annotate-draw';
export const SELECTOR_BOX_PREVIEW_BTN_PRINT = '.bp-btn-print';
export const SELECTOR_BOX_PREVIEW_BTN_DOWNLOAD = '.bp-btn-download';
-export const SELECTOR_BOX_PREVIEW_BTN_LOADING_DOWNLOAD = '.bp-btn-loading-download';
export const SELECTOR_BOX_PREVIEW_HEADER = `.${CLASS_BOX_PREVIEW_HEADER}`;
export const SELECTOR_BOX_PREVIEW_HEADER_CONTAINER = `.${CLASS_BOX_PREVIEW_HEADER_CONTAINER}`;
export const SELECTOR_BOX_PREVIEW_ICON = `.${CLASS_BOX_PREVIEW_ICON}`;
-export const SELECTOR_BOX_PREVIEW_LOADING_TEXT = `.${CLASS_BOX_PREVIEW_LOADING_TEXT}`;
-export const SELECTOR_BOX_PREVIEW_LOADING_WRAPPER = `.${CLASS_BOX_PREVIEW_LOADING_WRAPPER}`;
export const SELECTOR_BOX_PREVIEW_LOGO_CUSTOM = `.${CLASS_BOX_PREVIEW_LOGO_CUSTOM}`;
export const SELECTOR_BOX_PREVIEW_LOGO_DEFAULT = `.${CLASS_BOX_PREVIEW_LOGO_DEFAULT}`;
export const SELECTOR_BOX_PREVIEW_PROGRESS_BAR = `.${CLASS_BOX_PREVIEW_PROGRESS_BAR}`;
diff --git a/src/lib/icons/IconFileAudio32.svg b/src/lib/icons/IconFileAudio32.svg
deleted file mode 100644
index 3c129e61f..000000000
--- a/src/lib/icons/IconFileAudio32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileBoxNote32.svg b/src/lib/icons/IconFileBoxNote32.svg
deleted file mode 100644
index 5fc8b1f06..000000000
--- a/src/lib/icons/IconFileBoxNote32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileCode32.svg b/src/lib/icons/IconFileCode32.svg
deleted file mode 100644
index 063c08a8c..000000000
--- a/src/lib/icons/IconFileCode32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileDefault32.svg b/src/lib/icons/IconFileDefault32.svg
deleted file mode 100644
index a28a8be19..000000000
--- a/src/lib/icons/IconFileDefault32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileDocs32.svg b/src/lib/icons/IconFileDocs32.svg
deleted file mode 100644
index 915fa7b64..000000000
--- a/src/lib/icons/IconFileDocs32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileDwg32.svg b/src/lib/icons/IconFileDwg32.svg
deleted file mode 100644
index 09bf25add..000000000
--- a/src/lib/icons/IconFileDwg32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileExcel32.svg b/src/lib/icons/IconFileExcel32.svg
deleted file mode 100644
index 4ef81d862..000000000
--- a/src/lib/icons/IconFileExcel32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileIllustrator32.svg b/src/lib/icons/IconFileIllustrator32.svg
deleted file mode 100644
index 0f84ca826..000000000
--- a/src/lib/icons/IconFileIllustrator32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileImage32.svg b/src/lib/icons/IconFileImage32.svg
deleted file mode 100644
index c27451909..000000000
--- a/src/lib/icons/IconFileImage32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileIndesign32.svg b/src/lib/icons/IconFileIndesign32.svg
deleted file mode 100644
index 92fd3dc76..000000000
--- a/src/lib/icons/IconFileIndesign32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileKeynote32.svg b/src/lib/icons/IconFileKeynote32.svg
deleted file mode 100644
index 0037e4ea6..000000000
--- a/src/lib/icons/IconFileKeynote32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileNumbers32.svg b/src/lib/icons/IconFileNumbers32.svg
deleted file mode 100644
index 30f69fb9f..000000000
--- a/src/lib/icons/IconFileNumbers32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFilePDF32.svg b/src/lib/icons/IconFilePDF32.svg
deleted file mode 100644
index 4acb407c9..000000000
--- a/src/lib/icons/IconFilePDF32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFilePages32.svg b/src/lib/icons/IconFilePages32.svg
deleted file mode 100644
index f678e5e0d..000000000
--- a/src/lib/icons/IconFilePages32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFilePhotoshop32.svg b/src/lib/icons/IconFilePhotoshop32.svg
deleted file mode 100644
index 1b554549f..000000000
--- a/src/lib/icons/IconFilePhotoshop32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFilePowerpoint32.svg b/src/lib/icons/IconFilePowerpoint32.svg
deleted file mode 100644
index e9f2cd6cb..000000000
--- a/src/lib/icons/IconFilePowerpoint32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFilePresentation32.svg b/src/lib/icons/IconFilePresentation32.svg
deleted file mode 100644
index c738c3eec..000000000
--- a/src/lib/icons/IconFilePresentation32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileSheets32.svg b/src/lib/icons/IconFileSheets32.svg
deleted file mode 100644
index 8ab331e23..000000000
--- a/src/lib/icons/IconFileSheets32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileSlides32.svg b/src/lib/icons/IconFileSlides32.svg
deleted file mode 100644
index 69f57717a..000000000
--- a/src/lib/icons/IconFileSlides32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileSpreadsheet32.svg b/src/lib/icons/IconFileSpreadsheet32.svg
deleted file mode 100644
index 511ac66c6..000000000
--- a/src/lib/icons/IconFileSpreadsheet32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileText32.svg b/src/lib/icons/IconFileText32.svg
deleted file mode 100644
index 5109421e2..000000000
--- a/src/lib/icons/IconFileText32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileThreeD32.svg b/src/lib/icons/IconFileThreeD32.svg
deleted file mode 100644
index 7837a0f3f..000000000
--- a/src/lib/icons/IconFileThreeD32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileVector32.svg b/src/lib/icons/IconFileVector32.svg
deleted file mode 100644
index 841c87e75..000000000
--- a/src/lib/icons/IconFileVector32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileVideo32.svg b/src/lib/icons/IconFileVideo32.svg
deleted file mode 100644
index fc1f3eb33..000000000
--- a/src/lib/icons/IconFileVideo32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileWord32.svg b/src/lib/icons/IconFileWord32.svg
deleted file mode 100644
index d4b731924..000000000
--- a/src/lib/icons/IconFileWord32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/IconFileZip32.svg b/src/lib/icons/IconFileZip32.svg
deleted file mode 100644
index 7289b797b..000000000
--- a/src/lib/icons/IconFileZip32.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/icons/icons.js b/src/lib/icons/icons.js
deleted file mode 100644
index d468c3e52..000000000
--- a/src/lib/icons/icons.js
+++ /dev/null
@@ -1,311 +0,0 @@
-import FULLSCREEN_IN from './full_screen_in_24px.svg';
-import FULLSCREEN_OUT from './full_screen_out_24px.svg';
-import ARROW_LEFT from './arrow_left_24px.svg';
-import ARROW_RIGHT from './arrow_right_24px.svg';
-import CHECK_MARK from './checkmark_24px.svg';
-import GEAR from './gear_24px.svg';
-import FILE_AUDIO from './IconFileAudio32.svg';
-import FILE_AUTOCAD from './IconFileDwg32.svg';
-import FILE_BOX_NOTE from './IconFileBoxNote32.svg';
-import FILE_CODE from './IconFileCode32.svg';
-import FILE_DEFAULT from './IconFileDefault32.svg';
-import FILE_DOCUMENT from './IconFileText32.svg';
-import FILE_EXCEL from './IconFileExcel32.svg';
-import FILE_GOOGLE_DOC from './IconFileDocs32.svg';
-import FILE_GOOGLE_SHEET from './IconFileSheets32.svg';
-import FILE_GOOGLE_SLIDE from './IconFileSlides32.svg';
-import FILE_ILLUSTRATOR from './IconFileIllustrator32.svg';
-import FILE_IMAGE from './IconFileImage32.svg';
-import FILE_KEYNOTE from './IconFileKeynote32.svg';
-import FILE_MEDIA from './IconFileVideo32.svg';
-import FILE_NUMBERS from './IconFileNumbers32.svg';
-import FILE_OBJ from './IconFileThreeD32.svg';
-import FILE_PAGES from './IconFilePages32.svg';
-import FILE_PDF from './IconFilePDF32.svg';
-import FILE_POWERPOINT from './IconFilePowerpoint32.svg';
-import FILE_PRESENTATION from './IconFilePresentation32.svg';
-import FILE_SPREADSHEET from './IconFileSpreadsheet32.svg';
-import FILE_VECTOR from './IconFileVector32.svg';
-import FILE_WORD from './IconFileWord32.svg';
-import FILE_ZIP from './IconFileZip32.svg';
-import ANIMATION from './animation_24px.svg';
-import PAUSE from './pause_24px.svg';
-import PLAY from './play_24px.svg';
-import PLAY_LARGE from './play_48px.svg';
-import RESET from './3D_reset_24px.svg';
-import VR from './3D_vr_24px.svg';
-import FIND_DROP_DOWN from './arrow_drop_down.svg';
-import FIND_DROP_UP from './arrow_drop_up.svg';
-import CLOSE from './close.svg';
-import SEARCH from './search.svg';
-import PRINT_CHECKMARK from './print_checkmark.svg';
-
-export const ICON_FULLSCREEN_IN = FULLSCREEN_IN;
-export const ICON_FULLSCREEN_OUT = FULLSCREEN_OUT;
-export const ICON_ARROW_LEFT = ARROW_LEFT;
-export const ICON_ARROW_RIGHT = ARROW_RIGHT;
-export const ICON_CHECK_MARK = CHECK_MARK;
-export const ICON_GEAR = GEAR;
-export const ICON_ANIMATION = ANIMATION;
-export const ICON_PAUSE = PAUSE;
-export const ICON_PLAY = PLAY;
-export const ICON_PLAY_LARGE = PLAY_LARGE;
-export const ICON_3D_RESET = RESET;
-export const ICON_3D_VR = VR;
-export const ICON_FIND_DROP_DOWN = FIND_DROP_DOWN;
-export const ICON_FIND_DROP_UP = FIND_DROP_UP;
-export const ICON_CLOSE = CLOSE;
-export const ICON_SEARCH = SEARCH;
-export const ICON_PRINT_CHECKMARK = PRINT_CHECKMARK;
-
-const FILE_LOADING_ICONS = {
- FILE_AUDIO,
- FILE_AUTOCAD,
- FILE_BOX_NOTE,
- FILE_CODE,
- FILE_DEFAULT,
- FILE_DOCUMENT,
- FILE_EXCEL,
- FILE_GOOGLE_DOC,
- FILE_GOOGLE_SHEET,
- FILE_GOOGLE_SLIDE,
- FILE_ILLUSTRATOR,
- FILE_IMAGE,
- FILE_KEYNOTE,
- FILE_MEDIA,
- FILE_NUMBERS,
- FILE_OBJ,
- FILE_PAGES,
- FILE_PDF,
- FILE_POWERPOINT,
- FILE_PRESENTATION,
- FILE_SPREADSHEET,
- FILE_VECTOR,
- FILE_WORD,
- FILE_ZIP,
-};
-
-export const ICON_FILE_MAP = {};
-
-// AUDIO ICON EXTENSIONS
-['aac', 'aif', 'aifc', 'aiff', 'amr', 'au', 'flac', 'm4a', 'mp3', 'ra', 'wav', 'wma'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_AUDIO';
-});
-
-// BOXNOTE ICON EXTENSIONS
-['boxnote'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_BOX_NOTE';
-});
-
-// CODE ICON EXTENSIONS
-[
- 'as',
- 'as3',
- 'asm',
- 'bat',
- 'c',
- 'cc',
- 'cmake',
- 'cpp',
- 'cs',
- 'css',
- 'cxx',
- 'diff',
- 'erb',
- 'groovy',
- 'h',
- 'haml',
- 'hh',
- 'htm',
- 'html',
- 'java',
- 'js',
- 'json',
- 'less',
- 'm',
- 'make',
- 'md',
- 'ml',
- 'mm',
- 'php',
- 'pl',
- 'plist',
- 'properties',
- 'py',
- 'rb',
- 'rst',
- 'sass',
- 'scala',
- 'script',
- 'scm',
- 'sml',
- 'sql',
- 'sh',
- 'vi',
- 'vim',
- 'webdoc',
- 'xml',
- 'xsd',
- 'xsl',
- 'yaml',
-].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_CODE';
-});
-
-// EXCEL ICON EXTENSIONS
-['xls', 'xlsm', 'xlsx', 'xlsb'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_EXCEL';
-});
-
-// DOCUMENT ICON EXTENSIONS
-['log', 'msg', 'ods', 'rtf', 'txt', 'wpd'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_DOCUMENT';
-});
-
-// GOOGLE DOC ICON EXTENSIONS
-['gdoc'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_GOOGLE_DOC';
-});
-
-// GOOGLE SHEET ICON EXTENSIONS
-['gsheet'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_GOOGLE_SHEET';
-});
-
-// GOOGLE SLIDE ICON EXTENSIONS
-['gslide'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_GOOGLE_SLIDE';
-});
-
-// IMAGE ICON EXTENSIONS
-[
- 'ai',
- 'bmp',
- 'cr2',
- 'crw',
- 'dcm',
- 'dng',
- 'gif',
- 'heic',
- 'jpeg',
- 'jpg',
- 'nef',
- 'png',
- 'ps',
- 'psd',
- 'raf',
- 'raw',
- 'svg',
- 'swf',
- 'tga',
- 'tif',
- 'tiff',
-].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_IMAGE';
-});
-
-// VECTOR ICON EXTENSIONS
-['eps'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_VECTOR';
-});
-
-// KEYNOTE ICON EXTENSIONS
-['key'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_KEYNOTE';
-});
-
-// MEDIA ICON EXTENSIONS
-[
- '3g2',
- '3gp',
- 'avi',
- 'flv',
- 'm2v',
- 'm2ts',
- 'm4v',
- 'mkv',
- 'mov',
- 'mp4',
- 'mpeg',
- 'mpg',
- 'mts',
- 'ogg',
- 'qt',
- 'ts',
- 'wmv',
-].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_MEDIA';
-});
-
-// NUMBERS ICON EXTENSIONS
-['numbers'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_NUMBERS';
-});
-
-// OBJ ICON EXTENSIONS
-['3ds', 'box3d', 'dae', 'fbx', 'obj', 'ply', 'stl'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_OBJ';
-});
-
-// PAGES ICON EXTENSIONS
-['pages'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_PAGES';
-});
-
-// PDF ICON EXTENSIONS
-['pdf'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_PDF';
-});
-
-// POWERPOINT ICON EXTENSIONS
-['ppt', 'pptx'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_POWERPOINT';
-});
-
-// PRESENTATION ICON EXTENSIONS
-['odp'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_PRESENTATION';
-});
-
-// SPREADSHEET ICON EXTENSIONS
-['csv', 'tsv'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_SPREADSHEET';
-});
-
-// WORD ICON EXTENSIONS
-['doc', 'docx'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_WORD';
-});
-
-// ZIP ICON EXTENSIONS
-['tgz', 'zip'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_ZIP';
-});
-
-// AUTOCAD ICON EXTENSIONS
-['dwg'].forEach(extension => {
- ICON_FILE_MAP[extension] = 'FILE_AUTOCAD';
-});
-
-/**
- * Map from file extension to svg.
- *
- * @public
- * @param {string} fileExtension - The extension of the file
- * @return {HTMLElement} The SVG of the requested file icon
- */
-export function getIconFromExtension(fileExtension) {
- const iconName = ICON_FILE_MAP[fileExtension];
- return FILE_LOADING_ICONS[iconName];
-}
-
-/**
- * Map from icon file name to svg.
- *
- * @public
- * @param {string} iconName - The name of the icon
- * @return {HTMLElement} The SVG of the requested file icon
- */
-export function getIconFromName(iconName) {
- return FILE_LOADING_ICONS[iconName];
-}
diff --git a/src/lib/icons/index.js b/src/lib/icons/index.js
new file mode 100644
index 000000000..7071f790c
--- /dev/null
+++ b/src/lib/icons/index.js
@@ -0,0 +1,17 @@
+export { default as ICON_3D_RESET } from './3D_reset_24px.svg';
+export { default as ICON_3D_VR } from './3D_vr_24px.svg';
+export { default as ICON_ANIMATION } from './animation_24px.svg';
+export { default as ICON_ARROW_LEFT } from './arrow_left_24px.svg';
+export { default as ICON_ARROW_RIGHT } from './arrow_right_24px.svg';
+export { default as ICON_CHECK_MARK } from './checkmark_24px.svg';
+export { default as ICON_CLOSE } from './close.svg';
+export { default as ICON_FIND_DROP_DOWN } from './arrow_drop_down.svg';
+export { default as ICON_FIND_DROP_UP } from './arrow_drop_up.svg';
+export { default as ICON_FULLSCREEN_IN } from './full_screen_in_24px.svg';
+export { default as ICON_FULLSCREEN_OUT } from './full_screen_out_24px.svg';
+export { default as ICON_GEAR } from './gear_24px.svg';
+export { default as ICON_PAUSE } from './pause_24px.svg';
+export { default as ICON_PLAY } from './play_24px.svg';
+export { default as ICON_PLAY_LARGE } from './play_48px.svg';
+export { default as ICON_PRINT_CHECKMARK } from './print_checkmark.svg';
+export { default as ICON_SEARCH } from './search.svg';
diff --git a/src/lib/shell.html b/src/lib/shell.html
index a1ef972aa..2653271b0 100644
--- a/src/lib/shell.html
+++ b/src/lib/shell.html
@@ -70,10 +70,6 @@
-
-
-
-