From 9a961130e887c9ac1afc99bb76fc81b47a0c9061 Mon Sep 17 00:00:00 2001
From: Alexandru Munteanu <alexandru.munteanu@thinslices.com>
Date: Wed, 7 Feb 2018 14:15:37 +0200
Subject: [PATCH] Refactor progress into separate Steps component

---
 .../src/components/Progress.js                | 41 -------------
 .../component-wizard/src/components/Wizard.js | 10 ++--
 .../component-wizard/src/components/index.js  |  7 +--
 .../src/components/Steps/Steps.js             | 48 +++++++++++++++
 .../src/components/Steps/Steps.local.scss}    |  0
 .../src/components/Steps/Steps.md             | 58 +++++++++++++++++++
 .../src/components/index.js                   |  1 +
 packages/xpub-faraday/app/routes.js           |  4 +-
 packages/xpub-faraday/config/default.js       |  2 +-
 9 files changed, 115 insertions(+), 56 deletions(-)
 delete mode 100644 packages/component-wizard/src/components/Progress.js
 create mode 100644 packages/components-faraday/src/components/Steps/Steps.js
 rename packages/{component-wizard/src/components/Progress.local.scss => components-faraday/src/components/Steps/Steps.local.scss} (100%)
 create mode 100644 packages/components-faraday/src/components/Steps/Steps.md

diff --git a/packages/component-wizard/src/components/Progress.js b/packages/component-wizard/src/components/Progress.js
deleted file mode 100644
index b22a07f8b..000000000
--- a/packages/component-wizard/src/components/Progress.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-import { compose, withHandlers, withContext, getContext } from 'recompose'
-
-import classes from './Progress.local.scss'
-
-const Separator = () => <div className={classes.separator} />
-
-const Step = ({ title, index, currentStep }) => (
-  <div className={classes.step}>
-    {index === currentStep && <div className={classes.bullet} />}
-    {index < currentStep && <div className={classes.success}>✓</div>}
-    <span className={classes.stepTitle}>{`${index + 1}. ${title}`}</span>
-  </div>
-)
-
-const Steps = ({ currentStep, children, renderSteps }) => (
-  <div className={classes.container}>{renderSteps()}</div>
-)
-
-const DecoratedSteps = compose(
-  withHandlers({
-    renderSteps: ({ children }) => () => {
-      const c = []
-      React.Children.forEach(children, (child, idx) => {
-        c.push(child)
-        if (idx !== React.Children.count(children) - 1) {
-          c.push(<Separator key={Math.random()} />)
-        }
-      })
-      return c
-    },
-  }),
-  withContext({ currentStep: PropTypes.number }, ({ currentStep }) => ({
-    currentStep,
-  })),
-)(Steps)
-
-DecoratedSteps.Step = getContext({ currentStep: PropTypes.number })(Step)
-
-export default DecoratedSteps
diff --git a/packages/component-wizard/src/components/Wizard.js b/packages/component-wizard/src/components/Wizard.js
index e13aaa0af..303a59f6d 100644
--- a/packages/component-wizard/src/components/Wizard.js
+++ b/packages/component-wizard/src/components/Wizard.js
@@ -1,11 +1,9 @@
 import React from 'react'
 import classnames from 'classnames'
+import { Steps } from 'pubsweet-components-faraday/src/components'
 
 import classes from './Wizard.local.scss'
 import WizardFormStep from './WizardFormStep'
-import Progress from './Progress'
-
-const { Step } = Progress
 
 export default ({
   journal: { wizard: { showProgress, steps } },
@@ -16,11 +14,11 @@ export default ({
 }) => (
   <div className={classnames(classes.container)}>
     {showProgress && (
-      <Progress currentStep={step}>
+      <Steps currentStep={step}>
         {getSteps().map((step, index) => (
-          <Step index={index} key={step} title={step} />
+          <Steps.Step key={step} title={step} />
         ))}
-      </Progress>
+      </Steps>
     )}
     <WizardFormStep {...steps[step]} nextStep={nextStep} prevStep={prevStep} />
   </div>
diff --git a/packages/component-wizard/src/components/index.js b/packages/component-wizard/src/components/index.js
index 276990a47..b24d781c5 100644
--- a/packages/component-wizard/src/components/index.js
+++ b/packages/component-wizard/src/components/index.js
@@ -1,6 +1 @@
-export { default as Wizard } from './Wizard'
-export { default as Progress } from './Progress'
-export { default as WizardPage } from './WizardPage'
-export { default as WizardStep } from './WizardStep'
-export { default as WizardFormStep } from './WizardFormStep'
-export { default as AutosaveIndicator } from './AutosaveIndicator'
+export { default as Wizard } from './WizardPage'
diff --git a/packages/components-faraday/src/components/Steps/Steps.js b/packages/components-faraday/src/components/Steps/Steps.js
new file mode 100644
index 000000000..e6d691713
--- /dev/null
+++ b/packages/components-faraday/src/components/Steps/Steps.js
@@ -0,0 +1,48 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import { compose, withHandlers, setDisplayName } from 'recompose'
+
+import classes from './Steps.local.scss'
+
+const Separator = () => <div className={classes.separator} />
+
+const Step = ({ title, index, currentStep }) => (
+  <div className={classes.step}>
+    {index === currentStep && <div className={classes.bullet} />}
+    {index < currentStep && <div className={classes.success}>✓</div>}
+    <span className={classes.stepTitle}>{`${index + 1}. ${title}`}</span>
+  </div>
+)
+
+const Steps = ({ currentStep, children, renderSteps }) => (
+  <div className={classes.container}>{renderSteps()}</div>
+)
+
+const DecoratedSteps = compose(
+  setDisplayName('Steps'),
+  withHandlers({
+    renderSteps: ({ children, renderSeparator, currentStep }) => () => {
+      const separator = renderSeparator || Separator
+      return React.Children.toArray(children).reduce(
+        (acc, el, index, arr) =>
+          index === arr.length - 1
+            ? [...acc, React.cloneElement(el, { index, currentStep })]
+            : [
+                ...acc,
+                React.cloneElement(el, { index, currentStep }),
+                React.createElement(separator, { key: `sep-${el.key}` }),
+              ],
+        [],
+      )
+    },
+  }),
+)(Steps)
+
+DecoratedSteps.Step = Step
+
+DecoratedSteps.propTypes = {
+  currentStep: PropTypes.number.isRequired,
+  renderSeparator: PropTypes.func,
+}
+
+export default DecoratedSteps
diff --git a/packages/component-wizard/src/components/Progress.local.scss b/packages/components-faraday/src/components/Steps/Steps.local.scss
similarity index 100%
rename from packages/component-wizard/src/components/Progress.local.scss
rename to packages/components-faraday/src/components/Steps/Steps.local.scss
diff --git a/packages/components-faraday/src/components/Steps/Steps.md b/packages/components-faraday/src/components/Steps/Steps.md
new file mode 100644
index 000000000..904db21d8
--- /dev/null
+++ b/packages/components-faraday/src/components/Steps/Steps.md
@@ -0,0 +1,58 @@
+# Steps
+
+`Steps` is a navigation bar that guides users through the steps of a task. Use it whenever there is a sequence of tasks or steps that need to be done.
+
+## Props
+
+|      Prop       |                            Description                            | Required | Default |      Type       |
+| :-------------: | :---------------------------------------------------------------: | :------: | :-----: | :-------------: |
+|   currentStep   |                  The current step of the wizard.                  |   true   |  null   |     number      |
+| renderSeparator | Separator component to be rendered between two adjacent children. |  false   |  null   | React component |
+
+## Examples
+
+1.Usage with the Step component.
+
+```js
+import { Steps } from 'pubsweet-components-faraday/src/components'
+const { Step } = Steps
+
+<Steps currentStep={1}>
+  <Step title="First step" />
+  <Step title="Second step" />
+  <Step title="Third step" />
+</Steps>
+```
+
+2.Usage with a custom step component
+
+```js
+const StepComponent = ({ index, currentStep, customProp }) => <div>
+  I am a custom component at step {index} / {currentStep} with a {customProp}.
+</div>
+
+<Steps currentStep={1}>
+  <StepComponent customProp="Hei" />
+  <StepComponent customProp="Ho" />
+  <StepComponent customProp="Let's go!" />
+</Steps>
+```
+
+Each child of the Steps component has access to the `currentStep` and also it's own `index`.
+
+3.Usage with a custom separator
+When the default separator is not what you want you can always pass a custom separator component. This custom separator will be placed between each two adjacent children.
+
+```js
+const Separator = () => (
+  <div style={{ backgroundColor: 'pink', flex: 1, height: 10 }}>
+    DIVIDER OF WORLDS
+  </div>
+)
+
+<Steps currentStep={1} renderSeparator={Separator}>
+  <StepComponent customProp="Hei" />
+  <StepComponent customProp="Ho" />
+  <StepComponent customProp="Let's go!" />
+</Steps>
+```
diff --git a/packages/components-faraday/src/components/index.js b/packages/components-faraday/src/components/index.js
index 210934a75..38c8a65a7 100644
--- a/packages/components-faraday/src/components/index.js
+++ b/packages/components-faraday/src/components/index.js
@@ -1,3 +1,4 @@
+export { default as Steps } from './Steps/Steps'
 export { default as Files } from './Files/Files'
 export { default as AuthorList } from './AuthorList/AuthorList'
 export { default as SortableList } from './SortableList/SortableList'
diff --git a/packages/xpub-faraday/app/routes.js b/packages/xpub-faraday/app/routes.js
index c9d5449e9..2f6b1b783 100644
--- a/packages/xpub-faraday/app/routes.js
+++ b/packages/xpub-faraday/app/routes.js
@@ -12,7 +12,7 @@ import {
 
 // import DashboardPage from 'pubsweet-component-xpub-dashboard/src/components/DashboardPage'
 import DashboardPage from 'pubsweet-components-faraday/src/components/Dashboard'
-import WizardPage from 'pubsweet-component-wizard/src/components/WizardPage'
+import { Wizard } from 'pubsweet-component-wizard/src/components'
 import ManuscriptPage from 'pubsweet-component-xpub-manuscript/src/components/ManuscriptPage'
 import ConfirmationPage from 'pubsweet-components-faraday/src/components/UIComponents/ConfirmationPage'
 import NotFound from 'pubsweet-components-faraday/src/components/UIComponents/NotFound'
@@ -30,7 +30,7 @@ const Routes = () => (
       />
       <PrivateRoute component={LogoutPage} exact path="/logout" />
       <PrivateRoute
-        component={WizardPage}
+        component={Wizard}
         exact
         path="/projects/:project/versions/:version/submit"
       />
diff --git a/packages/xpub-faraday/config/default.js b/packages/xpub-faraday/config/default.js
index 66110156b..e406244dd 100644
--- a/packages/xpub-faraday/config/default.js
+++ b/packages/xpub-faraday/config/default.js
@@ -24,7 +24,7 @@ module.exports = {
   'pubsweet-client': {
     API_ENDPOINT: '/api',
     'login-redirect': '/',
-    'redux-log': true,
+    'redux-log': false,
     theme: process.env.PUBSWEET_THEME,
   },
   'mail-transport': {
-- 
GitLab