Sfoglia il codice sorgente

Merge pull request #3191 from overleaf/as-storybook

Set up Storybook and add Outline stories

GitOrigin-RevId: 2635ad142ef152a5ee8023c10cf31f344fbd7e8d
Alasdair Smith 5 anni fa
parent
commit
f5449dc4b0

+ 6 - 0
services/web/.storybook/default-theme.js

@@ -0,0 +1,6 @@
+import React from 'react'
+import '../frontend/stylesheets/style.less'
+
+const DefaultTheme = () => <React.Fragment />
+
+export default DefaultTheme

+ 6 - 0
services/web/.storybook/ieee-theme.js

@@ -0,0 +1,6 @@
+import React from 'react'
+import '../frontend/stylesheets/ieee-style.less'
+
+const IEEETheme = () => <React.Fragment />
+
+export default IEEETheme

+ 6 - 0
services/web/.storybook/light-theme.js

@@ -0,0 +1,6 @@
+import React from 'react'
+import '../frontend/stylesheets/light-style.less'
+
+const LightTheme = () => <React.Fragment />
+
+export default LightTheme

+ 29 - 0
services/web/.storybook/main.js

@@ -0,0 +1,29 @@
+const customConfig = require('../webpack.config.dev')
+
+module.exports = {
+  stories: ['../frontend/stories/**/*.stories.js'],
+  addons: ['@storybook/addon-essentials', '@storybook/addon-a11y'],
+  webpackFinal: storybookConfig => {
+    // Combine Storybook's webpack loaders with our webpack loaders
+    const rules = [
+      // Filter out the Storybook font file loader, which overrides our font
+      // file loader causing the font to fail to load
+      ...storybookConfig.module.rules.filter(
+        rule => !rule.test.toString().includes('woff')
+      ),
+      ...customConfig.module.rules
+    ]
+
+    // Combine Storybook's webpack plugins with our webpack plugins
+    const plugins = [...storybookConfig.plugins, ...customConfig.plugins]
+
+    return {
+      ...storybookConfig,
+      module: {
+        ...storybookConfig.module,
+        rules
+      },
+      plugins
+    }
+  }
+}

+ 6 - 0
services/web/.storybook/manager.js

@@ -0,0 +1,6 @@
+import { addons } from '@storybook/addons'
+import { themes } from '@storybook/theming'
+
+addons.setConfig({
+  theme: themes.dark
+})

+ 5 - 0
services/web/.storybook/preview-body.html

@@ -0,0 +1,5 @@
+<style>
+  body {
+    background: inherit; /* makes grid visible */
+  }
+</style>

+ 65 - 0
services/web/.storybook/preview.js

@@ -0,0 +1,65 @@
+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'))
+
+// 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
+// the promise to resolve).
+// Therefore we have to use the synchronous method for configuring
+// react-i18next. Because this, we can only hard-code a single language.
+import i18n from 'i18next'
+import { initReactI18next } from 'react-i18next'
+import en from '../locales/en.json'
+i18n.use(initReactI18next).init({
+  lng: 'en',
+
+  resources: {
+    en: { translation: en }
+  },
+
+  react: {
+    useSuspense: false
+  },
+
+  interpolation: {
+    prefix: '__',
+    suffix: '__',
+    unescapeSuffix: 'HTML',
+    skipOnVariables: true
+  }
+})
+
+export const parameters = {
+  // Automatically mark prop-types like onClick, onToggle, etc as Storybook
+  // "actions", so that they are logged in the Actions pane at the bottom of the
+  // viewer
+  actions: { argTypesRegex: '^on.*' }
+}
+
+export const globalTypes = {
+  theme: {
+    name: 'Theme',
+    description: 'Editor theme',
+    defaultValue: 'default',
+    toolbar: {
+      icon: 'circlehollow',
+      items: ['default', 'light', 'IEEE']
+    }
+  }
+}
+
+const withTheme = (Story, context) => {
+  return (
+    <>
+      <React.Suspense fallback={<></>}>
+        {context.globals.theme === 'default' && <DefaultTheme />}
+        {context.globals.theme === 'light' && <LightTheme />}
+        {context.globals.theme === 'IEEE' && <IEEETheme />}
+      </React.Suspense>
+      <Story {...context} />
+    </>
+  )
+}
+export const decorators = [withTheme]

+ 1 - 1
services/web/frontend/js/features/outline/components/outline-pane.js

@@ -104,7 +104,7 @@ OutlinePane.propTypes = {
   outline: PropTypes.array.isRequired,
   projectId: PropTypes.string.isRequired,
   jumpToLine: PropTypes.func.isRequired,
-  onToggle: PropTypes.func,
+  onToggle: PropTypes.func.isRequired,
   eventTracking: PropTypes.object.isRequired,
   highlightedLine: PropTypes.number
 }

+ 57 - 0
services/web/frontend/stories/outline.stories.js

@@ -0,0 +1,57 @@
+import React from 'react'
+
+import OutlinePane from '../js/features/outline/components/outline-pane'
+
+export const Basic = args => <OutlinePane {...args} />
+Basic.args = {
+  outline: [{ line: 1, title: 'Hello', level: 1 }]
+}
+
+export const Nested = args => <OutlinePane {...args} />
+Nested.args = {
+  outline: [
+    {
+      line: 1,
+      title: 'Section',
+      level: 1,
+      children: [
+        {
+          line: 2,
+          title: 'Subsection',
+          level: 2,
+          children: [
+            {
+              line: 3,
+              title: 'Subsubsection',
+              level: 3
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
+
+export const NoSections = args => <OutlinePane {...args} />
+NoSections.args = {}
+
+export const NonTexFile = args => <OutlinePane {...args} />
+NonTexFile.args = {
+  isTexFile: false
+}
+
+export default {
+  title: 'Outline',
+  component: OutlinePane,
+  argTypes: {
+    jumpToLine: { action: 'jumpToLine' }
+  },
+  args: {
+    projectId: '1234',
+    eventTracking: { sendMB: () => {} },
+    isTexFile: true,
+    outline: [],
+    jumpToLine: () => {},
+    onToggle: () => {}
+  }
+}

File diff suppressed because it is too large
+ 2365 - 1790
services/web/package-lock.json


+ 5 - 1
services/web/package.json

@@ -28,7 +28,8 @@
     "lint": "eslint --max-warnings 0 -f unix .",
     "format": "prettier-eslint '**/*.{js,less}' --list-different",
     "format:fix": "prettier-eslint '**/*.{js,less}' --write",
-    "migrations": "east"
+    "migrations": "east",
+    "storybook": "start-storybook -p 6006"
   },
   "browserslist": [
     "last 1 year",
@@ -148,6 +149,9 @@
   },
   "devDependencies": {
     "@babel/register": "^7.10.1",
+    "@storybook/addon-a11y": "^6.0.21",
+    "@storybook/addon-essentials": "^6.0.21",
+    "@storybook/react": "^6.0.21",
     "@testing-library/dom": "^7.7.3",
     "@testing-library/react": "^10.0.4",
     "acorn": "^7.1.1",

Some files were not shown because too many files changed in this diff