Browse Source

chore: change props model to context model

yhhu 5 years ago
parent
commit
9e8816e0da

+ 1 - 1
.babelrc

@@ -1,3 +1,3 @@
 {
-  "presets": ["env", "react"]
+  "presets": ["env", "stage-2", "react"]
 }

+ 1 - 0
package.json

@@ -24,6 +24,7 @@
     "babel-loader": "7.1.5",
     "babel-preset-env": "^1.7.0",
     "babel-preset-react": "^6.24.1",
+    "babel-preset-stage-2": "^6.24.1",
     "css-loader": "^1.0.0",
     "eslint": "^5.6.0",
     "eslint-config-airbnb": "^17.1.0",

+ 53 - 46
src/components/calendar/Index.js

@@ -5,11 +5,13 @@ import Styles from './index.css'
 import {
   getDaysOfMonth,
   getWeekSort,
-  selectDayByIndex,
+  // selectDayByIndex,
+  setSelectedDays,
 } from '../../helper'
 import {
   PREV_DAY, NEXT_DAY, _,
 } from '../../const'
+import { DateContext } from '../../context'
 
 class Index extends React.Component {
   constructor(props) {
@@ -17,8 +19,8 @@ class Index extends React.Component {
 
     const { value } = this.props
     this.state = {
-      weekTags: [],
-      days: [],
+      // weekTags: [],
+      // days: [],
       /* eslint-disable react/no-unused-state */
       selectedDay: value,
     }
@@ -26,72 +28,77 @@ class Index extends React.Component {
 
   static getDerivedStateFromProps(props, state) {
     if (props.model !== state.prevModel) {
+      const changeModelDays = getDaysOfMonth(_, _, props.model)
+      const afterSetDays = setSelectedDays(changeModelDays, state.selectedDay)
       return {
         prevModel: props.model,
         weekTags: getWeekSort(props.model),
-        days: getDaysOfMonth(_, _, props.model),
+        days: afterSetDays,
       }
     }
 
     if (props.value !== state.selectedDay) {
-      return { ...state, selectedDay: props.selectedDay }
+      return { ...state, selectedDay: props.value }
     }
 
     return state
   }
 
-  selectDay(day, index) {
-    const { onSelectDay } = this.props
-    const { days } = this.state
-    const selectedDays = selectDayByIndex(days, index)
-    // console.log(days)
-    // console.log(index)
-    // console.log(selectedDays)
-    this.setState({ days: selectedDays }, () => {
-      onSelectDay(day)
-    })
-  }
+  // selectDay(day, index) {
+  // const { onSelectDay, onCloseModal } = this.props
+  // const { days } = this.state
+  // const selectedDays = selectDayByIndex(days, index)
+  // this.setState({ days: selectedDays }, () => {
+  //   onSelectDay(day)
+  //   onCloseModal()
+  // })
+  // }
 
   render() {
-    const { weekTags, days } = this.state
-
     return (
-      <div className={Styles.wrapper}>
-        { weekTags.map(weekName => (
-          <span
-            className={`${Styles.normal} ${Styles.week}`}
-            title={`星期${weekName}`}
-            key={weekName}
-          >
-            { weekName }
-          </span>
-        )) }
+      <DateContext.Consumer>
         {
-          days.map((day, index) => (
-            <span
-              className={classNames(Styles.normal, {
-                [Styles.prev]: day.tag === PREV_DAY,
-                [Styles.next]: day.tag === NEXT_DAY,
-                [Styles.current]: day.current,
-                [Styles.selected]: day.selected,
-              })}
-              title={day.full}
-              key={day.full}
-              onClick={() => this.selectDay(day, index)}
-              role="presentation"
-            >
-              { day.day }
-            </span>
-          ))
+          ({ weekTags, days, onSelectDay }) => (
+            <div className={Styles.wrapper}>
+              { weekTags.map(weekName => (
+                <span
+                  className={`${Styles.normal} ${Styles.week}`}
+                  title={`星期${weekName}`}
+                  key={weekName}
+                >
+                  { weekName }
+                </span>
+              )) }
+              {
+                days.map(day => (
+                  <span
+                    className={classNames(Styles.normal, {
+                      [Styles.prev]: day.tag === PREV_DAY,
+                      [Styles.next]: day.tag === NEXT_DAY,
+                      [Styles.current]: day.current,
+                      [Styles.selected]: day.selected,
+                    })}
+                    title={day.full}
+                    key={day.full}
+                    onClick={() => onSelectDay(day)}
+                    role="presentation"
+                  >
+                    { day.day }
+                  </span>
+                ))
+              }
+            </div>
+          )
         }
-      </div>
+      </DateContext.Consumer>
     )
   }
 }
 
 Index.propTypes = {
   value: PropTypes.string.isRequired,
-  onSelectDay: PropTypes.func.isRequired,
+  // onSelectDay: PropTypes.func.isRequired,
+  // onCloseModal: PropTypes.func.isRequired,
 }
 
 export default Index

+ 24 - 14
src/components/footer/Footer.js

@@ -1,21 +1,31 @@
 import React from 'react'
-import PropTypes from 'prop-types'
 import Styles from './footer.css'
+import { DateContext } from '../../context'
 import { CHINESE_MODEL } from '../../const'
+import { getDateFormatFromSepecificDate } from '../../utils'
 
-const Footer = ({ model, onChangeModel }) => (
-  <div className={Styles.wrapper}>
-    <div />
-    <div className={Styles.today}><span>今天</span></div>
-    <div role="presentation" className={Styles.lang} onClick={() => onChangeModel(model)}>
-      <span>{ model === CHINESE_MODEL ? '中' : '西' }</span>
-    </div>
-  </div>
+const Footer = () => (
+  <DateContext.Consumer>
+    {
+      ({ model, onChangeModel, onSelectDay }) => (
+        <div className={Styles.wrapper}>
+          <div />
+          <div
+            role="presentation"
+            className={Styles.today}
+            onClick={() => onSelectDay({
+              full: getDateFormatFromSepecificDate(),
+            })}
+          >
+            <span>今天</span>
+          </div>
+          <div role="presentation" className={Styles.lang} onClick={() => onChangeModel(model)}>
+            <span>{ model === CHINESE_MODEL ? '中' : '西' }</span>
+          </div>
+        </div>
+      )
+    }
+  </DateContext.Consumer>
 )
 
-Footer.propTypes = {
-  model: PropTypes.string.isRequired,
-  onChangeModel: PropTypes.func.isRequired,
-}
-
 export default Footer

+ 40 - 15
src/components/index/DatePicker.js

@@ -3,7 +3,9 @@ import PropTypes from 'prop-types'
 import Styles from './picker.css'
 import { getDateFormatFromSepecificDate } from '../../utils'
 import Modal from '../modal/Modal'
-import { CHINESE_MODEL, WESTERN_MODEL } from '../../const'
+import { CHINESE_MODEL, WESTERN_MODEL, _ } from '../../const'
+import { DateContext, initialData } from '../../context'
+import { setSelectedDays, getDaysOfMonth, getWeekSort } from '../../helper'
 
 class DatePicker extends Component {
   constructor(props) {
@@ -12,7 +14,7 @@ class DatePicker extends Component {
     this.state = {
       value: defaultDate,
       showModal: false,
-      model: CHINESE_MODEL,
+      ...initialData,
     }
 
     this.onModalOpen = this.onModalOpen.bind(this)
@@ -28,7 +30,7 @@ class DatePicker extends Component {
   }
 
   onModalClose() {
-    // this.setState({ showModal: false })
+    this.setState({ showModal: false })
   }
 
   onInputChange(event) {
@@ -40,15 +42,30 @@ class DatePicker extends Component {
   }
 
   onChangeModel(model) {
+    const { value } = this.state
+    let nextModel = model
     if (model === CHINESE_MODEL) {
-      this.setState({ model: WESTERN_MODEL })
+      nextModel = WESTERN_MODEL
     } else {
-      this.setState({ model: CHINESE_MODEL })
+      nextModel = CHINESE_MODEL
     }
+
+    const weekTags = getWeekSort(nextModel)
+    const changeModelDays = getDaysOfMonth(_, _, nextModel)
+    const afterSetDays = setSelectedDays(changeModelDays, value)
+    this.setState({
+      model: nextModel,
+      weekTags: weekTags,
+      days: afterSetDays,
+    })
   }
 
   onSelectDay(day) {
-    this.setState({ value: day.full })
+    const { days } = this.state
+    const afterSetDays = setSelectedDays(days, day.full)
+    this.setState({ value: day.full, days: afterSetDays }, () => {
+      // this.onModalClose()
+    })
   }
 
   render() {
@@ -68,7 +85,6 @@ class DatePicker extends Component {
             value={value}
             onChange={e => this.onInputChange(e)}
             onFocus={this.onModalOpen}
-            onBlur={this.onModalClose}
           />
           <i className={Styles.calendar} />
           <i
@@ -78,14 +94,23 @@ class DatePicker extends Component {
           />
           <div className={Styles.line} />
         </div>
-        <Modal
-          isMounted={showModal}
-          delayTime={200}
-          onInputChange={this.onInputChange}
-          onChangeModel={this.onChangeModel}
-          onSelectDay={this.onSelectDay}
-          {...this.state}
-        />
+        <DateContext.Provider
+          value={
+            {
+              ...this.state,
+              onSelectDay: this.onSelectDay,
+              onChangeModel: this.onChangeModel,
+            }
+          }
+        >
+          <Modal
+            isMounted={showModal}
+            delayTime={200}
+            onInputChange={this.onInputChange}
+            onCloseModal={this.onModalClose}
+            {...this.state}
+          />
+        </DateContext.Provider>
       </div>
     )
   }

+ 4 - 11
src/components/modal/Modal.js

@@ -11,11 +11,8 @@ import Footer from '../footer/Footer'
 const Modal = ({
   isMounted,
   value,
-  // showModal,
   onInputChange,
-  onChangeModel,
-  onSelectDay,
-  model,
+  onCloseModal,
 }) => (
   <React.Fragment>
     <div className={classNames(Styles.container, {
@@ -30,12 +27,11 @@ const Modal = ({
       <div className="calendar">
         <Header />
         <Body
-          model={model}
           value={value}
-          onSelectDay={onSelectDay}
+          onCloseModal={onCloseModal}
         />
       </div>
-      <Footer model={model} onChangeModel={onChangeModel} />
+      <Footer />
     </div>
   </React.Fragment>
 )
@@ -47,11 +43,8 @@ Modal.defaultProps = {
 Modal.propTypes = {
   isMounted: PropTypes.bool,
   value: PropTypes.string.isRequired,
-  // showModal: PropTypes.bool.isRequired,
   onInputChange: PropTypes.func.isRequired,
-  model: PropTypes.string.isRequired,
-  onChangeModel: PropTypes.func.isRequired,
-  onSelectDay: PropTypes.func.isRequired,
+  onCloseModal: PropTypes.func.isRequired,
 }
 
 export default delayUnmounting(Modal)

+ 17 - 0
src/context.js

@@ -0,0 +1,17 @@
+import React from 'react'
+import { CHINESE_MODEL, _ } from './const'
+import { getDaysOfMonth, getWeekSort } from './helper'
+
+const model = CHINESE_MODEL
+const days = getDaysOfMonth(_, _, model)
+const weekTags = getWeekSort(model)
+
+export const initialData = {
+  model: model,
+  days: days,
+  weekTags: weekTags,
+  onChangeModel: () => {},
+  onSelectDay: () => {},
+}
+
+export const DateContext = React.createContext(initialData)

+ 10 - 0
src/helper.js

@@ -8,6 +8,7 @@ import {
   getDaysCountOfMonth,
   formatMonthOrDay,
   isCurrentDay,
+  formatDate,
 } from './utils'
 
 export const getWeekSort = (model = CHINESE_MODEL) => {
@@ -105,3 +106,12 @@ export const selectDayByIndex = (days, index) => days.map((day, idx) => {
   tempDay.selected = index === idx
   return tempDay
 })
+
+export const setSelectedDays = (days, selectedDay) => {
+  const fDate = formatDate(selectedDay)
+  return days.map(day => {
+    const tempDay = day
+    tempDay.selected = day.full === fDate.format
+    return tempDay
+  })
+}

+ 92 - 2
yarn.lock

@@ -467,6 +467,14 @@ babel-generator@^6.26.0:
     source-map "^0.5.7"
     trim-right "^1.0.1"
 
+babel-helper-bindify-decorators@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz#14c19e5f142d7b47f19a52431e52b1ccbc40a330"
+  dependencies:
+    babel-runtime "^6.22.0"
+    babel-traverse "^6.24.1"
+    babel-types "^6.24.1"
+
 babel-helper-builder-binary-assignment-operator-visitor@^6.24.1:
   version "6.24.1"
   resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664"
@@ -509,6 +517,15 @@ babel-helper-explode-assignable-expression@^6.24.1:
     babel-traverse "^6.24.1"
     babel-types "^6.24.1"
 
+babel-helper-explode-class@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb"
+  dependencies:
+    babel-helper-bindify-decorators "^6.24.1"
+    babel-runtime "^6.22.0"
+    babel-traverse "^6.24.1"
+    babel-types "^6.24.1"
+
 babel-helper-function-name@^6.24.1:
   version "6.24.1"
   resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9"
@@ -600,6 +617,22 @@ babel-plugin-syntax-async-functions@^6.8.0:
   version "6.13.0"
   resolved "http://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95"
 
+babel-plugin-syntax-async-generators@^6.5.0:
+  version "6.13.0"
+  resolved "http://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a"
+
+babel-plugin-syntax-class-properties@^6.8.0:
+  version "6.13.0"
+  resolved "http://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de"
+
+babel-plugin-syntax-decorators@^6.13.0:
+  version "6.13.0"
+  resolved "http://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b"
+
+babel-plugin-syntax-dynamic-import@^6.18.0:
+  version "6.18.0"
+  resolved "http://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da"
+
 babel-plugin-syntax-exponentiation-operator@^6.8.0:
   version "6.13.0"
   resolved "http://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de"
@@ -612,11 +645,23 @@ babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0:
   version "6.18.0"
   resolved "http://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
 
+babel-plugin-syntax-object-rest-spread@^6.8.0:
+  version "6.13.0"
+  resolved "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5"
+
 babel-plugin-syntax-trailing-function-commas@^6.22.0:
   version "6.22.0"
   resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3"
 
-babel-plugin-transform-async-to-generator@^6.22.0:
+babel-plugin-transform-async-generator-functions@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db"
+  dependencies:
+    babel-helper-remap-async-to-generator "^6.24.1"
+    babel-plugin-syntax-async-generators "^6.5.0"
+    babel-runtime "^6.22.0"
+
+babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async-to-generator@^6.24.1:
   version "6.24.1"
   resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761"
   dependencies:
@@ -624,6 +669,25 @@ babel-plugin-transform-async-to-generator@^6.22.0:
     babel-plugin-syntax-async-functions "^6.8.0"
     babel-runtime "^6.22.0"
 
+babel-plugin-transform-class-properties@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac"
+  dependencies:
+    babel-helper-function-name "^6.24.1"
+    babel-plugin-syntax-class-properties "^6.8.0"
+    babel-runtime "^6.22.0"
+    babel-template "^6.24.1"
+
+babel-plugin-transform-decorators@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz#788013d8f8c6b5222bdf7b344390dfd77569e24d"
+  dependencies:
+    babel-helper-explode-class "^6.24.1"
+    babel-plugin-syntax-decorators "^6.13.0"
+    babel-runtime "^6.22.0"
+    babel-template "^6.24.1"
+    babel-types "^6.24.1"
+
 babel-plugin-transform-es2015-arrow-functions@^6.22.0:
   version "6.22.0"
   resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221"
@@ -792,7 +856,7 @@ babel-plugin-transform-es2015-unicode-regex@^6.22.0:
     babel-runtime "^6.22.0"
     regexpu-core "^2.0.0"
 
-babel-plugin-transform-exponentiation-operator@^6.22.0:
+babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-exponentiation-operator@^6.24.1:
   version "6.24.1"
   resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e"
   dependencies:
@@ -807,6 +871,13 @@ babel-plugin-transform-flow-strip-types@^6.22.0:
     babel-plugin-syntax-flow "^6.18.0"
     babel-runtime "^6.22.0"
 
+babel-plugin-transform-object-rest-spread@^6.22.0:
+  version "6.26.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06"
+  dependencies:
+    babel-plugin-syntax-object-rest-spread "^6.8.0"
+    babel-runtime "^6.26.0"
+
 babel-plugin-transform-react-display-name@^6.23.0:
   version "6.25.0"
   resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz#67e2bf1f1e9c93ab08db96792e05392bf2cc28d1"
@@ -900,6 +971,25 @@ babel-preset-react@^6.24.1:
     babel-plugin-transform-react-jsx-source "^6.22.0"
     babel-preset-flow "^6.23.0"
 
+babel-preset-stage-2@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz#d9e2960fb3d71187f0e64eec62bc07767219bdc1"
+  dependencies:
+    babel-plugin-syntax-dynamic-import "^6.18.0"
+    babel-plugin-transform-class-properties "^6.24.1"
+    babel-plugin-transform-decorators "^6.24.1"
+    babel-preset-stage-3 "^6.24.1"
+
+babel-preset-stage-3@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz#836ada0a9e7a7fa37cb138fb9326f87934a48395"
+  dependencies:
+    babel-plugin-syntax-trailing-function-commas "^6.22.0"
+    babel-plugin-transform-async-generator-functions "^6.24.1"
+    babel-plugin-transform-async-to-generator "^6.24.1"
+    babel-plugin-transform-exponentiation-operator "^6.24.1"
+    babel-plugin-transform-object-rest-spread "^6.22.0"
+
 babel-register@^6.26.0:
   version "6.26.0"
   resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071"