Browse Source

feat: update component DatePicker

yhhu 6 years ago
parent
commit
6fbcd64a6e

+ 3 - 0
package.json

@@ -12,6 +12,8 @@
   "author": "ryn",
   "license": "ISC",
   "dependencies": {
+    "classnames": "^2.2.6",
+    "prop-types": "^15.6.2",
     "react": "^16.5.2",
     "react-dom": "^16.5.2"
   },
@@ -28,6 +30,7 @@
     "eslint-plugin-import": "^2.14.0",
     "eslint-plugin-jsx-a11y": "^6.1.1",
     "eslint-plugin-react": "^7.11.1",
+    "file-loader": "^2.0.0",
     "html-webpack-plugin": "^3.2.0",
     "mini-css-extract-plugin": "^0.4.3",
     "pre-commit": "^1.2.2",

+ 66 - 0
src/components/index/DatePicker.js

@@ -0,0 +1,66 @@
+import React, { Component } from 'react'
+import PropTypes from 'prop-types'
+import classNames from 'classnames'
+import Styles from './picker.css'
+import { getDateFormatFromSepecificDate } from '../../utils'
+
+class DatePicker extends Component {
+  constructor(props) {
+    super(props)
+    this.state = {
+      inputFocus: false,
+    }
+
+    this.onInputFocus = this.onInputFocus.bind(this)
+    this.onInputBlur = this.onInputBlur.bind(this)
+    this.onInputChange = this.onInputChange.bind(this)
+  }
+
+  onInputFocus() {
+    this.setState({ inputFocus: true })
+  }
+
+  onInputChange() {
+    console.log('change')
+  }
+
+  onInputBlur() {
+    this.setState({ inputFocus: false })
+  }
+
+  render() {
+    const { inline, defaultDate } = this.props
+    const { inputFocus } = this.state
+
+    return (
+      <div
+        className={Styles.container}
+        style={inline ? { display: 'inline-block' } : {}}
+      >
+        <input
+          type="text"
+          className={Styles.input}
+          value={defaultDate}
+          onFocus={this.onInputFocus}
+          onBlur={this.onInputBlur}
+          onChange={this.onInputChange}
+        />
+        <i className={Styles.calendar} />
+        <i className={Styles.close} />
+        <div className={classNames(Styles.line, { [Styles.inputFocus]: inputFocus })} />
+      </div>
+    )
+  }
+}
+
+DatePicker.defaultProps = {
+  inline: false,
+  defaultDate: getDateFormatFromSepecificDate(),
+}
+
+DatePicker.propTypes = {
+  inline: PropTypes.bool,
+  defaultDate: PropTypes.string,
+}
+
+export default DatePicker

+ 44 - 0
src/components/index/picker.css

@@ -0,0 +1,44 @@
+.container {
+  min-width: 170px;
+  cursor: text;
+  position: relative;
+  font-size: 14px;
+  overflow: hidden;
+}
+.input {
+  font-family: "Chinese Quote", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+  width: 100%;
+  height: 32px;
+  margin: 0;
+  padding: 4px 11px;
+  outline: none;
+  line-height: 1.5;
+  box-sizing: border-box;
+  font-size: 14px;
+  color: rgba(0, 0, 0, 0.65);
+  border: none;
+  border-bottom: 1px solid #ccc;
+}
+.line {
+  width: 100%;
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  border-bottom: 1px solid #1890ff;
+  transform: translateX(-100%);
+  transition: transform .15s cubic-bezier(0.17, 1.05, 0.9,-0.15);
+}
+.input-focus {
+  transform: translateX(0);
+}
+.calendar {
+  position: absolute;
+  margin-top: 8px;
+  right: 11px;
+  display: inline-block;
+  width: 16px;
+  height: 16px;
+  background-image: url('../../static/icon-calendar.svg');
+  background-position: center; 
+  background-size: 16px 16px;
+}

+ 3 - 1
src/index.js

@@ -1,8 +1,10 @@
 
 import React from 'react'
 import ReactDOM from 'react-dom'
+import DatePicker from './components/index/DatePicker'
+import './styles/index.css'
 
-const App = () => <div>Hello React!</div>
+const App = () => <DatePicker />
 
 /* eslint-disable no-undef */
 ReactDOM.render(<App />, document.getElementById('container'))

File diff suppressed because it is too large
+ 1 - 0
src/static/icon-calendar.svg


+ 3 - 0
src/styles/index.css

@@ -0,0 +1,3 @@
+:global(.container) {
+  width: 170px;
+}

+ 15 - 24
src/utils/date.js

@@ -11,7 +11,7 @@ export const isLeapYear = year => (year % 4 === 0 && year % 100 !== 0) || (year
  * 去掉字符串首尾空格
  * @param {String} str 字符串
  */
-export const trimStr = str => str.replace(/^\s*/).replace(/\s*$/)
+export const trimStr = str => str.replace(/^\s*/, '').replace(/\s*$/, '')
 
 /**
  * 获取当前年份
@@ -31,7 +31,7 @@ export const getCurrentDay = () => new Date().getDate()
 /**
  * 获取当前年份格式
  */
-export const getCurrentDate = () => `${getCurrentYear()}-${getCurrentMonth()}-${getCurrentDate()}`
+export const getCurrentDate = () => `${getCurrentYear()}-${getCurrentMonth()}-${getCurrentDay()}`
 
 /**
  * 格式化月份或者天数
@@ -50,29 +50,20 @@ const formatMonthOrDay = dateStr => {
  * @param {String} date 日期
  */
 export const formatDate = date => {
-  const currentDate = getCurrentDate()
-
-  if (!date) {
-    return currentDate
-  }
-
-  if (typeof date !== 'string') {
-    warnning('date should be string')
-    return currentDate
-  }
-
-  if (date.split('-').length > 0) {
-    return currentDate
-  }
-
   const regexp = /^(\d{4})(\s*[/\-\\:]?\s*)?(\d{1,2})(\s*[/\-\\:]?\s*)?(\d{1,2})/
   const strArr = trimStr(date).match(regexp)
   const year = strArr[1]
   let month = strArr[3]
   let day = strArr[5]
+
   if (+month > 12) {
-    warnning('cannot recognition the date string, please offer a separator, like: 2019-09-18')
-    return currentDate
+    warnning('month exceed max month number 12')
+    month = 12
+  }
+
+  if (+day > 31) {
+    warnning('day exceed max day number 31')
+    day = 31
   }
 
   month = formatMonthOrDay(month)
@@ -99,25 +90,25 @@ const specificDateAdapter = date => {
  * 获取指定日期的年份
  * @param {String} date 日期格式
  */
-export const getYearFromSpecificDate = date => specificDateAdapter(date)('year')
+export const getYearFromSpecificDate = (date = getCurrentDate()) => specificDateAdapter(date)('year')
 
 /**
  * 获取指定日期的月份
  * @param {String} date 日期格式
  */
-export const getMonthFromSpecificDate = date => specificDateAdapter(date)('month')
+export const getMonthFromSpecificDate = (date = getCurrentDate()) => specificDateAdapter(date)('month')
 
 /**
  * 获取指定日期的天数
  * @param {String} date 日期格式
  */
-export const getDayFromSepecificDate = date => specificDateAdapter(date)('day')
+export const getDayFromSepecificDate = (date = getCurrentDate()) => specificDateAdapter(date)('day')
 
 /**
  * 获取指定日期的年份格式
  * @param {String} date 日期格式
  */
-export const getDateFormatFromSepecificDate = date => specificDateAdapter(date)('format')
+export const getDateFormatFromSepecificDate = (date = getCurrentDate()) => specificDateAdapter(date)('format')
 
 /**
  * 获取指定月份的天数
@@ -125,7 +116,7 @@ export const getDateFormatFromSepecificDate = date => specificDateAdapter(date)(
  * @param {String} month 月份
  */
 export const getDaysCountOfMonth = (month = getCurrentMonth(),
-  year = getCurrentYear()) => new Date(year, month, 0)
+  year = getCurrentYear()) => new Date(year, month, 0).getDate()
 
 /**
  * 获取一月中的第一天是星期几

+ 8 - 1
webpack/webpack.config.dev.js

@@ -6,6 +6,7 @@ const projectPath = path.resolve(__dirname, '../')
 
 module.exports = {
   mode: 'development',
+  devtool: 'eval-source-map',
   entry: path.resolve(projectPath, 'src/index.js'),
   output: {
     path: path.resolve(__dirname, 'dist'),
@@ -29,7 +30,6 @@ module.exports = {
       {
         test: /\.js$/,
         loader: 'babel-loader',
-        // include: path.resolve(projectPath, './src/**/*.js'),
         exclude: /node_modules/,
       },
       {
@@ -46,6 +46,13 @@ module.exports = {
           },
         ],
       },
+      {
+        test: /\.(jpe?g|png|svg|bmp)$/,
+        loader: 'file-loader',
+        options: {
+          name: '[name].[ext]',
+        },
+      },
     ],
   },
   plugins: [

+ 6 - 1
webpack/webpack.config.prod.js

@@ -16,7 +16,6 @@ module.exports = {
       {
         test: /\.js$/,
         loader: 'babel-loader',
-        include: path.resolve(projectPath, 'src'),
         exclude: /node_modules/,
       },
       {
@@ -38,6 +37,12 @@ module.exports = {
           },
         ],
       },
+      {
+        loader: 'file-loader',
+        options: {
+          outputPath: path.resolve(projectPath, 'dist/images'),
+        },
+      },
     ],
   },
   plugins: [

+ 11 - 0
yarn.lock

@@ -1272,6 +1272,10 @@ class-utils@^0.3.5:
     isobject "^3.0.0"
     static-extend "^0.1.1"
 
+classnames@^2.2.6:
+  version "2.2.6"
+  resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
+
 clean-css@4.2.x:
   version "4.2.1"
   resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17"
@@ -2205,6 +2209,13 @@ file-entry-cache@^2.0.0:
     flat-cache "^1.2.1"
     object-assign "^4.0.1"
 
+file-loader@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-2.0.0.tgz#39749c82f020b9e85901dcff98e8004e6401cfde"
+  dependencies:
+    loader-utils "^1.0.2"
+    schema-utils "^1.0.0"
+
 fill-range@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7"