diff --git a/services/web/.storybook/default-theme.js b/services/web/.storybook/default-theme.js
deleted file mode 100644
index f854bc8a9c..0000000000
--- a/services/web/.storybook/default-theme.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import React from 'react'
-import '../frontend/stylesheets/style.less'
-
-const DefaultTheme = () =>
-
-export default DefaultTheme
diff --git a/services/web/.storybook/global.css b/services/web/.storybook/global.css
new file mode 100644
index 0000000000..7a99a82e64
--- /dev/null
+++ b/services/web/.storybook/global.css
@@ -0,0 +1,3 @@
+.sidebar-container a[title='Overleaf'] {
+ max-width: 100px;
+}
diff --git a/services/web/.storybook/ieee-theme.js b/services/web/.storybook/ieee-theme.js
deleted file mode 100644
index 57f8e03d05..0000000000
--- a/services/web/.storybook/ieee-theme.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import React from 'react'
-import '../frontend/stylesheets/ieee-style.less'
-
-const IEEETheme = () =>
-
-export default IEEETheme
diff --git a/services/web/.storybook/light-theme.js b/services/web/.storybook/light-theme.js
deleted file mode 100644
index 6d0a08fa5f..0000000000
--- a/services/web/.storybook/light-theme.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import React from 'react'
-import '../frontend/stylesheets/light-style.less'
-
-const LightTheme = () =>
-
-export default LightTheme
diff --git a/services/web/.storybook/main.js b/services/web/.storybook/main.js
index 345f50471e..d406d3bfca 100644
--- a/services/web/.storybook/main.js
+++ b/services/web/.storybook/main.js
@@ -11,7 +11,14 @@ module.exports = {
...storybookConfig.module.rules.filter(
rule => !rule.test.toString().includes('woff')
),
- ...customConfig.module.rules
+ // Replace the less rule, adding to-string-loader
+ ...customConfig.module.rules.filter(
+ rule => !rule.test.toString().includes('less')
+ ),
+ {
+ test: /\.less$/,
+ use: ['to-string-loader', 'css-loader', 'less-loader']
+ }
]
// Combine Storybook's webpack plugins with our webpack plugins
diff --git a/services/web/.storybook/manager.js b/services/web/.storybook/manager.js
index dafdf1bb71..9d4d33ad6a 100644
--- a/services/web/.storybook/manager.js
+++ b/services/web/.storybook/manager.js
@@ -1,6 +1,15 @@
import { addons } from '@storybook/addons'
-import { themes } from '@storybook/theming'
+import { create } from '@storybook/theming'
-addons.setConfig({
- theme: themes.dark
+import './global.css'
+
+import brandImage from '../public/img/ol-brand/overleaf.svg'
+
+const theme = create({
+ base: 'light',
+ brandTitle: 'Overleaf',
+ brandUrl: 'https://www.overleaf.com',
+ brandImage
})
+
+addons.setConfig({ theme })
diff --git a/services/web/.storybook/preview-body.html b/services/web/.storybook/preview-body.html
deleted file mode 100644
index 5e82b90a54..0000000000
--- a/services/web/.storybook/preview-body.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/services/web/.storybook/preview.css b/services/web/.storybook/preview.css
new file mode 100644
index 0000000000..9a39b51ac5
--- /dev/null
+++ b/services/web/.storybook/preview.css
@@ -0,0 +1,7 @@
+.sb-show-main .modal-backdrop {
+ display: none;
+}
+
+.sb-show-main .modal {
+ position: relative;
+}
diff --git a/services/web/.storybook/preview.js b/services/web/.storybook/preview.js
index 8b7fc75214..ffe06d9a91 100644
--- a/services/web/.storybook/preview.js
+++ b/services/web/.storybook/preview.js
@@ -1,8 +1,6 @@
import React from 'react'
-const DefaultTheme = React.lazy(() => import('./default-theme'))
-const LightTheme = React.lazy(() => import('./light-theme'))
-const IEEETheme = React.lazy(() => import('./ieee-theme'))
+import './preview.css'
// Storybook does not (currently) support async loading of "stories". Therefore
// the strategy in frontend/js/i18n.js does not work (because we cannot wait on
@@ -46,26 +44,43 @@ export const globalTypes = {
theme: {
name: 'Theme',
description: 'Editor theme',
- defaultValue: 'default',
+ defaultValue: 'default-',
toolbar: {
icon: 'circlehollow',
- items: ['default', 'light', 'IEEE']
+ items: [
+ { value: 'default-', title: 'Default' },
+ { value: 'light-', title: 'Light' },
+ { value: 'ieee-', title: 'IEEE' }
+ ]
}
}
}
+export const loaders = [
+ async ({ globals }) => {
+ const { theme } = globals
+
+ return {
+ // NOTE: this uses `${theme}style.less` rather than `${theme}.less`
+ // so that webpack only bundles files ending with "style.less"
+ activeStyle: await import(
+ `../frontend/stylesheets/${theme === 'default-' ? '' : theme}style.less`
+ )
+ }
+ }
+]
+
const withTheme = (Story, context) => {
+ const { activeStyle } = context.loaded
+
return (
<>
- >}>
- {context.globals.theme === 'default' && }
- {context.globals.theme === 'light' && }
- {context.globals.theme === 'IEEE' && }
-
+ {activeStyle && }
>
)
}
+
export const decorators = [withTheme]
window.ExposedSettings = {}
diff --git a/services/web/package-lock.json b/services/web/package-lock.json
index 88ad50c7f4..87e3f659c9 100644
--- a/services/web/package-lock.json
+++ b/services/web/package-lock.json
@@ -29328,6 +29328,14 @@
"to-no-case": "^1.0.0"
}
},
+ "to-string-loader": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/to-string-loader/-/to-string-loader-1.1.6.tgz",
+ "integrity": "sha512-VNg62//PS1WfNwrK3n7t6wtK5Vdtx/qeYLLEioW46VMlYUwAYT6wnfB+OwS2FMTCalIHu0tk79D3RXX8ttmZTQ==",
+ "requires": {
+ "loader-utils": "^1.0.0"
+ }
+ },
"toggle-selection": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
diff --git a/services/web/package.json b/services/web/package.json
index ef5eef4177..52b30643f6 100644
--- a/services/web/package.json
+++ b/services/web/package.json
@@ -229,6 +229,7 @@
"socket.io-mock": "^1.3.1",
"terser-webpack-plugin": "^2.3.6",
"timekeeper": "^2.2.0",
+ "to-string-loader": "^1.1.6",
"val-loader": "^1.1.1",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.11",