This is the 12th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021
TIP 👉 boohoo! Although chu three households can destroy qin, there is no open China! ____ Lu You “Golden Mistake Knife Trip”
preface
Web Component is an area that the front-end world has been very enthusiastic about. To implement it with third-party componentized frameworks, you need to rely on a lot of things in the framework itself. Most of the time we just have a few simple components, not too big, not too many, so in order to keep the components lightweight, Simple, we don’t really want to use a third party framework at this point.
Date picker component
import
import DatePicker from '@/components/DatePicker/DatePicker';
Copy the code
Props
1. onChange
- Type: func (required)
- Default value: none
- Note: Select the callback function after the date, input parameter:
- {my Moment | Date | String | Number} the value selected Date value (and valueType correspondence)
- MomentValue momentValue for the Moment value of the date
2. valueType
- Type: datepicker. VALUE_TYPE
- Default value: datepicker.value_type.string
- Description: Date value type
3. value
- Type: valueType Specifies the type
- Default value: none
- Description: Date value
<DatePicker value={'2019-12-12'}
valueType={DatePicker.VALUE_TYPE.string}
onChange={this.dateChange} />
Copy the code
<DatePicker value={new Date()}
valueType={DatePicker.VALUE_TYPE.date}
onChange={this.dateChange} />
Copy the code
<DatePicker value={1576049926055}
valueType={DatePicker.VALUE_TYPE.millisecond}
onChange={this.dateChange} />
Copy the code
<DatePicker value={moment()}
valueType={DatePicker.VALUE_TYPE.moment}
onChange={this.dateChange} />
Copy the code
4. format
- Type: string
- Default: ‘YYYY-MM-DD’ (‘YYYY-MM-DD HH: MM :ss’ when showTime is true)
- Description: Date string format
5. showTime
- Types: bool
- Default value: false
- Description: Whether to display the time (hour minute second)
6. defaultTime
- Type: string
- Default value: none (If this parameter is not set, the current time is used by default)
- Description: Default time (hour minute second), such as ’00:00:00′
7. minValue
- Type: any of datepicker. VALUE_TYPE, independent of valueType
- Default value: none
- Description: Minimum value of an optional date
8. maxValue
- Type: any of datepicker. VALUE_TYPE, independent of valueType
- Default value: none
- Description: Maximum number of available dates
9. placeholder
- Type: string
- Default: ‘Please select date’ (‘ Please select date and time ‘when showTime is true)
- Note: Enter a prompt message
10. showClear
- Types: bool
- Default value: true
- Note: Whether to display the empty button on the right side of the input box
11. disabled
- Types: bool
- Default value: false
- Description: Whether the date picker is unavailable, true indicates that the date picker is unavailable
12. disabledDate
- Type: func (required)
- Default value: none
- Note: Check whether the date is optional
- The arguments:
- {Moment} current Current date
- Returns:
- {Boolen} Whether this parameter is unavailable. True indicates that the current date is unavailable
- The arguments:
13. disabledHours
- Type: func (required)
- Default value: none
- Get an array of unavailable hours (valid if showTime is true)
- The arguments:
- {Moment} current Current date
- Returns:
- {Array} An unusable Array of hours
- The arguments:
14. disabledMinutes
- Type: func (required)
- Default value: none
- Get an array of unavailable minutes (valid if showTime is true)
- The arguments:
- {Number} selectedHour the currently selectedHour
- {Moment} current Current date
- Returns:
- {Array} An unusable minute Array
- The arguments:
15. disabledSeconds
- Type: func (required)
- Default value: none
- Get array of unusable seconds (valid if showTime is true)
- The arguments:
- {Number} selectedHour the currently selectedHour
- {Number} selectedMinute specifies the currently selectedMinute
- {Moment} current Current date
- Returns:
- {Array} An unusable Array of seconds
- The arguments:
Realize the DatePicker js
import React from 'react';
import PropTypes from 'prop-types';
import Calendar from 'rc-calendar';
import Picker from 'rc-calendar/lib/Picker';
import zhCN from 'rc-calendar/lib/locale/zh_CN';
import TimePickerPanel from 'rc-time-picker/lib/Panel';
import moment from 'moment';
import valueTypes from './utils/value-types';
import PickerPropTypes from './utils/picker-prop-types.js';
import valueConvertUtil from './utils/value-convert-util.js';
import 'moment/locale/zh-cn';
import './datePicker.scss';
/** * date picker */
export default class DatePicker extends React.Component {
// Value type constants
static VALUE_TYPE = valueTypes;
// Check the input type
static propTypes = {
/** * select the callback function * after the date@param {Moment | Date | String | Number} Value Select the date value (corresponding to valueType) *@param {Moment} MomentValue Select the Moment value of the date */
onChange: PropTypes.func.isRequired,
// Date value type: datepicker. VALUE_TYPE
valueType: PropTypes.oneOf(Object.keys(DatePicker.VALUE_TYPE).map( k= > DatePicker.VALUE_TYPE[k]) ),
// Date value (must be a value of type specified by valueType)
value: PickerPropTypes.dateValue,
// Format of the date string
format: PropTypes.string,
// Whether to display the time (hour minute second)
showTime: PropTypes.bool,
// Default time. This parameter is valid when showTime is true, such as '00:00:00', or the current time is null
defaultTime: PropTypes.string,
// The minimum value of the available dates (any of datepicker.value_type, independent of valueType)
minValue: PickerPropTypes.looseDateValue,
// Maximum number of available dates (any of datepicker. VALUE_TYPE, independent of valueType)
maxValue: PickerPropTypes.looseDateValue,
// Enter a prompt
placeholder: PropTypes.string,
// Whether to display the empty button
showClear: PropTypes.bool,
// Is not available
disabled: PropTypes.bool,
/** * Check whether the date is optional *@param {Moment} Current Current date *@return {Boolen} True indicates that the current date is not selectable. */
disabledDate: PropTypes.func,
/** * gets an array of unusable hours (valid if showTime is true) *@param {Moment} Current Current date *@return {Array<Number>} Unusable hour array */
disabledHours: PropTypes.func,
/** * Gets an array of unavailable minutes (valid if showTime is true) *@param {Number} SelectedHour the currently selectedHour *@param {Moment} Current Current date *@return {Array<Number>} An unusable minute array */
disabledMinutes: PropTypes.func,
/** * gets an array of unusable seconds (valid if showTime is true) *@param {Number} SelectedHour the currently selectedHour *@param {Number} SelectedMinute specifies the currently selectedMinute *@param {Moment} Current Current date *@return {Array<Number>} Unusable second array */
disabledSeconds: PropTypes.func
}
// Enter the default value
static defaultProps = {
// Date value type, default string
valueType: DatePicker.VALUE_TYPE.string,
// Whether to display the time (hour, minute, second)
showTime: false.// Whether to display the empty button
showClear: true.// Whether it is unavailable. The default value is yes
disabled: false
}
constructor(props) {
super(props);
const format = this.props.format || (this.props.showTime ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD');
const momentValue = valueConvertUtil.convertToMoment(this.props.value, this.props.valueType, this.props.showTime, format);
const minMomentValue = valueConvertUtil.convertToMoment(this.props.minValue, null.this.props.showTime, format);
const maxMomentValue = valueConvertUtil.convertToMoment(this.props.maxValue, null.this.props.showTime, format);
const defaultTimeValue = this.props.defaultTime ? moment(this.props.defaultTime, 'HH:mm:ss') : moment();
const placeholder = this.props.placeholder ? this.props.placeholder : (this.props.showTime ? 'Please select date and time' : 'Please select a date');
this.state = {
// Moment value
momentValue,
// Time is a string of characters
format,
// Optional moment object with minimum time
minMomentValue,
// Optional moment object for the maximum time
maxMomentValue,
// The default time is minute and second
defaultTimeValue,
// Enter a prompt
placeholder
};
}
componentDidUpdate(prevProps, prevState) {
this.receivePropsResetState(prevProps);
}
// Reset state based on the props changes
receivePropsResetState (prevProps) {
const format = this.props.format || (this.props.showTime ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD');
if(prevProps.format ! = =this.props.format || prevProps.showTime ! = =this.props.showTime) {
const momentValue = valueConvertUtil.convertToMoment(this.props.value, this.props.valueType, this.props.showTime, format);
const minMomentValue = valueConvertUtil.convertToMoment(this.props.minValue, null.this.props.showTime, format);
const maxMomentValue = valueConvertUtil.convertToMoment(this.props.maxValue, null.this.props.showTime, format);
const placeholder = this.props.placeholder ? this.props.placeholder : (this.props.showTime ? 'Please select date and time' : 'Please select a date');
this.setState({
// Moment value
momentValue,
// Time is a string of characters
format,
// Optional moment object with minimum time
minMomentValue,
// Optional moment object for the maximum time
maxMomentValue,
// Enter a prompt
placeholder
});
} else {
if(prevProps.valueType ! = =this.props.valueType) {
console.warn('The value of DatePicker component props. ValueType cannot be changed arbitrarily');
}
if(! valueConvertUtil.isSameValue(prevProps.value,this.props.value)) {
const momentValue = valueConvertUtil.convertToMoment(this.props.value, this.props.valueType, this.props.showTime, format);
this.setState({ momentValue });
}
if(prevProps.minValue ! = =this.props.minValue) {
const minMomentValue = valueConvertUtil.convertToMoment(this.props.minValue, null.this.props.showTime, format);
this.setState({ minMomentValue });
}
if(prevProps.maxValue ! = =this.props.maxValue) {
const maxMomentValue = valueConvertUtil.convertToMoment(this.props.maxValue, null.this.props.showTime, format);
this.setState({ maxMomentValue });
}
if(prevProps.defaultTime ! = =this.props.defaultTime) {
const defaultTimeValue = this.props.defaultTime ? moment(this.props.defaultTime, 'HH:mm:ss') : moment();
this.setState({ defaultTimeValue });
}
if(prevProps.placeholder ! = =this.props.placeholder) {
const placeholder = this.props.placeholder ? this.props.placeholder : (this.props.showTime ? 'Please select date and time' : 'Please select a date');
this.setState({ placeholder }); }}}/** * Convert other types to the moment object *@param Value Time value of other types */
convertToMoment (value) {
return valueConvertUtil.convertToMoment(value, this.props.valueType, this.props.showTime, this.state.format);
}
/** * Convert the moment object to another type *@param Obj moment object */
convertFromMoment (obj) {
return valueConvertUtil.convertFromMoment(obj, this.props.valueType, this.props.showTime, this.state.format);
}
// The event triggered after the date picker is selected
onPickerChange = (value) = > {
this.setState({ momentValue: value })
if (!this.props.showTime || value === null) {
this.props.onChange && this.props.onChange(this.convertFromMoment(value), value); }}// The event that is triggered when the date picker open state changes
onOpenChange = (open) = > {
if (this.props.showTime && ! open) {let value = this.state.momentValue;
this.props.onChange && this.props.onChange(this.convertFromMoment(value), value); }}/ / to empty
onClear = (event) = > {
this.props.onChange && this.props.onChange(null.null);
event.stopPropagation();
};
// Create time selector component (time minute second selector component)
createTimePicker = (value) = > {
if (this.props.showTime) {
return <TimePickerPanel value={value} defaultValue={this.state.defaultTimeValue}/>;
}
return null;
}
/** * Check whether the date is optional *@param {Moment} Current moment object *@returns {boolean}* /
disabledDate = (current) = > {
if (!this.props.showTime) { // Do not display the time (minutes, seconds)
let curValue = moment(current.format('YYYY-MM-DD'), 'YYYY-MM-DD');
let { minMomentValue, maxMomentValue } = this.state;
if (minMomentValue && curValue.isBefore(minMomentValue)) return true;
if (maxMomentValue && curValue.isAfter(maxMomentValue)) return true;
} else { // Display time (minutes, seconds)
let curValue = this.state.momentValue;
if ( curValue ) {
curValue = moment(`${current.format('YYYY-MM-DD')} The ${this.convertToMoment(curValue).format('HH:mm:ss')}`.'YYYY-MM-DD HH:mm:ss');
} else {
curValue = moment(`${current.format('YYYY-MM-DD')} The ${this.state.defaultTimeValue.format('HH:mm:ss')}`.'YYYY-MM-DD HH:mm:ss');
}
let { minMomentValue, maxMomentValue } = this.state;
let minVal, maxVal;
if (minMomentValue) {
minVal = moment(minMomentValue.format('YYYY-MM-DD'), 'YYYY-MM-DD')
if (curValue.valueOf() < minVal.valueOf()) return true;
}
if (maxMomentValue) {
if (maxMomentValue.format('HH:mm:ss') = = ='00:00:00') {
maxVal = maxMomentValue.clone();
} else {
maxVal = moment(maxMomentValue.format('YYYY-MM-DD'), 'YYYY-MM-DD').add(moment.duration({'day' : 1}));
}
if (curValue.valueOf() >= maxVal.valueOf()) return true; }}if (this.props.disabledDate) {
return this.props.disabledDate(current);
}
return false;
}
/** * Determine whether the time (hour, minute, second) is optional *@param {Moment} Current moment object *@returns {Object} Return the object */ that contains the disabledHours, disabledMinutes, and disabledSeconds functions
disabledTime = (current) = > {
// Create a continuous array of numbers based on the minimum and maximum values
function createNumArray (minNum, maxNum) {
let arr = [];
for (let i = minNum; i <= maxNum; i++) {
arr.push(i);
}
return arr;
}
// Maximum and minimum values for optional dates
let { minMomentValue, maxMomentValue } = this.state;
// If the date has been selected
if (current) {
// Get an array of unusable hours
let disabledHours = () = > {
let hours = [];
if (minMomentValue && current.isSame(minMomentValue, 'day')) {
hours = createNumArray(0, minMomentValue.hour() - 1);
}
if (maxMomentValue && current.isSame(maxMomentValue, 'day')) {
hours = hours.concat(createNumArray(maxMomentValue.hour() + 1.23));
}
if (this.props.disabledHours) {
hours = hours.concat(this.props.disabledHours(current));
}
return hours;
}
// The method to get the unusable minute array
let disabledMinutes = (selectedHour) = > {
let minutes = [];
if (minMomentValue && current.isSame(minMomentValue, 'day') && selectedHour === minMomentValue.hour()) {
minutes = createNumArray(0, minMomentValue.minute() - 1);
}
if (maxMomentValue && current.isSame(maxMomentValue, 'day') && selectedHour === maxMomentValue.hour()) {
minutes = minutes.concat(createNumArray(maxMomentValue.minute() + 1.59));
}
if (this.props.disabledMinutes) {
minutes = minutes.concat(this.props.disabledMinutes(selectedHour, current));
}
return minutes;
}
// Get the unusable second array method
let disabledSeconds = (selectedHour, selectedMinute) = > {
let seconds = [];
if (minMomentValue && current.isSame(minMomentValue, 'day') && selectedHour === minMomentValue.hour() && selectedMinute === minMomentValue.minute()) {
seconds = createNumArray(0, minMomentValue.second() - 1);
}
if (maxMomentValue && current.isSame(maxMomentValue, 'day') && selectedHour === maxMomentValue.hour() && selectedMinute === maxMomentValue.minute()) {
seconds = seconds.concat(createNumArray(maxMomentValue.second() + 1.59));
}
if (this.props.disabledSeconds) {
seconds = seconds.concat(this.props.disabledSeconds(selectedHour, selectedMinute, current));
}
return seconds;
}
return {
disabledHours,
disabledMinutes,
disabledSeconds
}
} else {
// If no date is selected and the date range is limited, the time and second cannot be selected
if (minMomentValue || maxMomentValue) {
return {
disabledHours: () = > createNumArray(0.23),
disabledMinutes: () = > createNumArray(0.59),
disabledSeconds: () = > createNumArray(0.59)}; }else { // If no date is selected and the date range is not limited, use the disabledHours, disabledMinutes, and disabledSeconds of the input parameters to filter
return {
disabledHours: () = > {
return this.props.disabledHours ? this.props.disabledHours(current) : [];
},
disabledMinutes: (selectedHour) = > {
return this.props.disabledMinutes ? this.props.disabledMinutes(selectedHour, current) : [];
},
disabledSeconds: (selectedHour, selectedMinute) = > {
return this.props.disabledSeconds ? this.props.disabledSeconds(selectedHour, selectedMinute, current) : []; }}; }}}render() {
const dateValue = this.state.momentValue;
const showClear = this.props.showClear && this.props.value;
const calendar = (<Calendar locale={ zhCN }
dateInputPlaceholder={this.state.placeholder}
format={this.state.format}
timePicker={this.createTimePicker(dateValue)}
showDateInput={false}
disabledDate={this.disabledDate}
disabledTime={this.disabledTime} />);
return (
<Picker animation="slide-up"
calendar={calendar}
value={dateValue}
onChange={this.onPickerChange}
onOpenChange={this.onOpenChange}
disabled={this.props.disabled}>
{
({ value }) => {
return (
<div className={'calendar-picker-box'+ (showClear ? ' calendar-picker-box-show-clear' :"')} >
<input placeholder={this.state.placeholder}
disabled={this.props.disabled}
className="date-picker-input"
value={value && value.format && value.format(this.state.format) || ''}
readOnly />
{showClear ?
<span className="date-picker-clear" onClick={this.onClear} title="Empty">
<i className="icon-guanbishibaimianxing clear-icon"></i>
</span>
: null}
<i className="icon icon-rili"></i>
</div>); }}</Picker>); }}Copy the code
I’m going to leave the styles out for now
“Feel free to discuss in the comments section.”