Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-time-picker

Package Overview
Dependencies
Maintainers
1
Versions
86
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-time-picker - npm Package Compare versions

Comparing version 3.0.0 to 3.1.0

11

dist/shared/dateFormatter.js

@@ -6,3 +6,3 @@ 'use strict';

});
exports.formatTime = undefined;
exports.getFormatter = undefined;

@@ -17,2 +17,4 @@ var _getUserLocale = require('get-user-locale');

/* eslint-disable import/prefer-default-export */
/**

@@ -22,3 +24,3 @@ * Gets Intl-based date formatter from formatter cache. If it doesn't exist in cache

*/
var getFormatter = function getFormatter(options, locale) {
var getFormatter = exports.getFormatter = function getFormatter(options, locale) {
if (!locale) {

@@ -41,7 +43,2 @@ // Default parameter is not enough as it does not protect us from null values

return formatterCache[locale][stringifiedOptions];
};
// eslint-disable-next-line import/prefer-default-export
var formatTime = exports.formatTime = function formatTime(date, locale) {
return getFormatter({ hour: 'numeric', minute: 'numeric', second: 'numeric' }, locale)(date);
};

@@ -6,3 +6,8 @@ 'use strict';

});
exports.getAmPmLabels = exports.updateInputWidth = exports.max = exports.min = undefined;
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _dateFormatter = require('./dateFormatter');
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

@@ -13,2 +18,3 @@

};
var min = exports.min = function min() {

@@ -40,5 +46,36 @@ for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {

element.style.width = width + 'px';
element.style.width = Math.ceil(width) + 'px';
container.removeChild(span);
};
var getAmPmLabels = exports.getAmPmLabels = function getAmPmLabels(locale) {
var amPmFormatter = (0, _dateFormatter.getFormatter)({ hour: 'numeric' }, locale);
var amString = amPmFormatter(new Date(2017, 0, 1, 9));
var pmString = amPmFormatter(new Date(2017, 0, 1, 21));
var _amString$split = amString.split('9'),
_amString$split2 = _slicedToArray(_amString$split, 2),
am1 = _amString$split2[0],
am2 = _amString$split2[1];
var _pmString$split = pmString.split('9'),
_pmString$split2 = _slicedToArray(_pmString$split, 2),
pm1 = _pmString$split2[0],
pm2 = _pmString$split2[1];
if (am1 !== pm1) {
return [am1, pm1].map(function (el) {
return el.trim();
});
}
if (am2 !== pm2) {
return [am2, pm2].map(function (el) {
return el.trim();
});
}
// Fallback
return ['am', 'pm'];
};

@@ -7,6 +7,6 @@ 'use strict';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

@@ -58,2 +58,4 @@

var _utils = require('./shared/utils');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -69,2 +71,4 @@

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
var allViews = ['hour', 'minute', 'second'];

@@ -97,13 +101,19 @@

var removeUnwantedCharacters = function removeUnwantedCharacters(str) {
return str.split('').filter(function (a) {
return (
// We don't want spaces in dates
a.charCodeAt(0) !== 32
// Internet Explorer specific
&& a.charCodeAt(0) !== 8206
// Remove non-ASCII characters
&& /^[\x20-\x7F]*$/.test(a)
var _renderCustomInputs = function _renderCustomInputs(placeholder, elementFunctions) {
var pattern = new RegExp(Object.keys(elementFunctions).join('|'), 'gi');
var matches = placeholder.match(pattern);
return placeholder.split(pattern).reduce(function (arr, element, index) {
var divider = element &&
// eslint-disable-next-line react/no-array-index-key
_react2.default.createElement(
_Divider2.default,
{ key: 'separator_' + index },
element
);
}).join('');
var res = [].concat(_toConsumableArray(arr), [divider]);
if (matches[index]) {
res.push(elementFunctions[matches[index]]());
}
return res;
}, []);
};

@@ -130,2 +140,10 @@

second: null
}, _this.onClick = function (event) {
if (event.target === event.currentTarget) {
// Wrapper was directly clicked
var _event$target$childre = _slicedToArray(event.target.children, 2),
firstInput = _event$target$childre[1];
focus(firstInput);
}
}, _this.onKeyDown = function (event) {

@@ -197,3 +215,3 @@ switch (event.key) {

onChange(processedValue);
onChange(processedValue, false);
}, _this.onChangeAmPm = function (event) {

@@ -224,3 +242,3 @@ var value = event.target.value;

})) {
onChange(null);
onChange(null, false);
} else if (formElements.every(function (formElement) {

@@ -234,41 +252,15 @@ return formElement.value && formElement.checkValidity();

var processedValue = _this.getProcessedValue(timeString);
onChange(processedValue);
onChange(processedValue, false);
}
}, _temp), _possibleConstructorReturn(_this, _ret);
}
}, _this.renderHour12 = function () {
var hour = _this.state.hour;
_createClass(TimeInput, [{
key: 'getProcessedValue',
/**
* Gets current value in a desired format.
*/
value: function getProcessedValue(value) {
var nativeValueParser = this.nativeValueParser;
return nativeValueParser(value);
}
/**
* Returns value type that can be returned with currently applied settings.
*/
}, {
key: 'renderHour12',
value: function renderHour12() {
var hour = this.state.hour;
return _react2.default.createElement(_Hour12Input2.default, _extends({
key: 'hour12'
}, this.commonInputProps, {
}, _this.commonInputProps, {
value: hour
}));
}
}, {
key: 'renderHour24',
value: function renderHour24() {
var hour = this.state.hour;
}, _this.renderHour24 = function () {
var hour = _this.state.hour;

@@ -278,25 +270,15 @@

key: 'hour24'
}, this.commonInputProps, {
}, _this.commonInputProps, {
value: hour
}));
}
}, {
key: 'renderMinute',
value: function renderMinute() {
var maxDetail = this.props.maxDetail;
}, _this.renderMinute = function () {
var maxDetail = _this.props.maxDetail;
var _this$state = _this.state,
hour = _this$state.hour,
minute = _this$state.minute;
// Do not display if maxDetail is "hour" or less
if (allViews.indexOf(maxDetail) < 1) {
return null;
}
var _state = this.state,
hour = _state.hour,
minute = _state.minute;
return _react2.default.createElement(_MinuteInput2.default, _extends({
key: 'minute'
}, this.commonInputProps, {
}, _this.commonInputProps, {
hour: hour,

@@ -306,23 +288,13 @@ maxDetail: maxDetail,

}));
}
}, {
key: 'renderSecond',
value: function renderSecond() {
var maxDetail = this.props.maxDetail;
}, _this.renderSecond = function () {
var maxDetail = _this.props.maxDetail;
var _this$state2 = _this.state,
hour = _this$state2.hour,
minute = _this$state2.minute,
second = _this$state2.second;
// Do not display if maxDetail is "minute" or less
if (allViews.indexOf(maxDetail) < 2) {
return null;
}
var _state2 = this.state,
hour = _state2.hour,
minute = _state2.minute,
second = _state2.second;
return _react2.default.createElement(_SecondInput2.default, _extends({
key: 'second'
}, this.commonInputProps, {
}, _this.commonInputProps, {
hour: hour,

@@ -333,7 +305,5 @@ maxDetail: maxDetail,

}));
}
}, {
key: 'renderAmPm',
value: function renderAmPm() {
var amPm = this.state.amPm;
}, _this.renderAmPm = function () {
var amPm = _this.state.amPm;
var locale = _this.props.locale;

@@ -343,46 +313,42 @@

key: 'ampm'
}, this.commonInputProps, {
value: amPm,
onChange: this.onChangeAmPm
}, _this.commonInputProps, {
locale: locale,
onChange: _this.onChangeAmPm,
value: amPm
}));
}, _temp), _possibleConstructorReturn(_this, _ret);
}
_createClass(TimeInput, [{
key: 'getProcessedValue',
/**
* Gets current value in a desired format.
*/
value: function getProcessedValue(value) {
var nativeValueParser = this.nativeValueParser;
return nativeValueParser(value);
}
/**
* Returns value type that can be returned with currently applied settings.
*/
}, {
key: 'renderCustomInputs',
value: function renderCustomInputs() {
var _this2 = this;
var placeholder = this.placeholder;
var divider = this.divider,
placeholder = this.placeholder;
var elementFunctions = {
'hour-12': this.renderHour12,
'hour-24': this.renderHour24,
minute: this.renderMinute,
second: this.renderSecond,
ampm: this.renderAmPm
};
return placeholder.split(divider).map(function (part) {
switch (part) {
case 'hour-12':
return _this2.renderHour12();
case 'hour-24':
return _this2.renderHour24();
case 'minute':
return _this2.renderMinute();
case 'second':
return _this2.renderSecond();
case 'ampm':
return _this2.renderAmPm();
default:
return null;
}
}).filter(Boolean).reduce(function (result, element, index) {
if (index && element.key !== 'ampm') {
result.push(
// eslint-disable-next-line react/no-array-index-key
_react2.default.createElement(
_Divider2.default,
{ key: 'separator_' + index },
divider
));
}
result.push(element);
return result;
}, []);
return _renderCustomInputs(placeholder, elementFunctions);
}

@@ -421,3 +387,7 @@ }, {

'div',
{ className: className },
{
className: className,
onClick: this.onClick,
role: 'presentation'
},
this.renderNativeInput(),

@@ -428,2 +398,21 @@ this.renderCustomInputs()

}, {
key: 'formatTime',
get: function get() {
var _props2 = this.props,
locale = _props2.locale,
maxDetail = _props2.maxDetail;
var options = { hour: 'numeric' };
var level = allViews.indexOf(maxDetail);
if (level >= 1) {
options.minute = 'numeric';
}
if (level >= 2) {
options.second = 'numeric';
}
return (0, _dateFormatter.getFormatter)(options, locale);
}
}, {
key: 'valueType',

@@ -449,17 +438,9 @@ get: function get() {

}
// eslint-disable-next-line class-methods-use-this
}, {
key: 'divider',
get: function get() {
var locale = this.props.locale;
var date = new Date(2017, 0, 1, 21, 12, 13);
return removeUnwantedCharacters((0, _dateFormatter.formatTime)(date, locale)).match(/[^0-9]/)[0];
return this.formatTime(date).match(/[^0-9a-z]/i)[0];
}
// eslint-disable-next-line class-methods-use-this
}, {

@@ -472,3 +453,3 @@ key: 'placeholder',

return removeUnwantedCharacters((0, _dateFormatter.formatTime)(date, locale)).replace('21', 'hour-24').replace('9', 'hour-12').replace('13', 'minute').replace('14', 'second').replace(/AM|PM/i, this.divider + 'ampm');
return this.formatTime(date).replace('21', 'hour-24').replace('9', 'hour-12').replace('13', 'minute').replace('14', 'second').replace(new RegExp((0, _utils.getAmPmLabels)(locale).join('|')), 'ampm');
}

@@ -478,11 +459,11 @@ }, {

get: function get() {
var _this3 = this;
var _this2 = this;
var _props2 = this.props,
className = _props2.className,
disabled = _props2.disabled,
isClockOpen = _props2.isClockOpen,
maxTime = _props2.maxTime,
minTime = _props2.minTime,
required = _props2.required;
var _props3 = this.props,
className = _props3.className,
disabled = _props3.disabled,
isClockOpen = _props3.isClockOpen,
maxTime = _props3.maxTime,
minTime = _props3.minTime,
required = _props3.required;

@@ -502,3 +483,3 @@

// Save a reference to each input field
_this3[name + 'Input'] = ref;
_this2[name + 'Input'] = ref;
}

@@ -505,0 +486,0 @@ };

@@ -7,2 +7,4 @@ 'use strict';

var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

@@ -26,2 +28,4 @@

var _utils = require('../shared/utils');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -51,2 +55,3 @@

itemRef = _props.itemRef,
locale = _props.locale,
onChange = _props.onChange,

@@ -59,2 +64,7 @@ required = _props.required,

var _getAmPmLabels = (0, _utils.getAmPmLabels)(locale),
_getAmPmLabels2 = _slicedToArray(_getAmPmLabels, 2),
amLabel = _getAmPmLabels2[0],
pmLabel = _getAmPmLabels2[1];
return _react2.default.createElement(

@@ -83,3 +93,3 @@ 'select',

{ disabled: this.amDisabled, value: 'am' },
'am'
amLabel
),

@@ -89,3 +99,3 @@ _react2.default.createElement(

{ disabled: this.pmDisabled, value: 'pm' },
'pm'
pmLabel
)

@@ -119,2 +129,3 @@ );

itemRef: _propTypes2.default.func,
locale: _propTypes2.default.string,
maxTime: _propTypes3.isTime,

@@ -121,0 +132,0 @@ minTime: _propTypes3.isTime,

@@ -70,7 +70,3 @@ 'use strict';

return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = TimePicker.__proto__ || Object.getPrototypeOf(TimePicker)).call.apply(_ref, [this].concat(args))), _this), _this.state = {}, _this.onClick = function (event) {
if (_this.wrapper && !_this.wrapper.contains(event.target)) {
_this.closeClock();
}
}, _this.openClock = function () {
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = TimePicker.__proto__ || Object.getPrototypeOf(TimePicker)).call.apply(_ref, [this].concat(args))), _this), _this.state = {}, _this.openClock = function () {
_this.setState({ isOpen: true });

@@ -117,2 +113,11 @@ }, _this.closeClock = function () {

_this.openClock();
}, _this.onBlur = function () {
var onBlur = _this.props.onBlur;
if (onBlur) {
onBlur(event);
}
_this.closeClock();
}, _this.stopPropagation = function (event) {

@@ -126,12 +131,2 @@ return event.stopPropagation();

_createClass(TimePicker, [{
key: 'componentDidMount',
value: function componentDidMount() {
document.addEventListener('mousedown', this.onClick);
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
document.removeEventListener('mousedown', this.onClick);
}
}, {
key: 'renderInputs',

@@ -199,2 +194,4 @@ value: function renderInputs() {

value: function renderClock() {
var _this2 = this;
var disableClock = this.props.disableClock;

@@ -224,3 +221,3 @@ var isOpen = this.state.isOpen;

ref: function ref(_ref2) {
if (!_ref2) {
if (!_ref2 || !isOpen) {
return;

@@ -234,3 +231,8 @@ }

if (collisions.collidedBottom) {
_ref2.classList.add(className + '--above-label');
var overflowTopAfterChange = collisions.overflowTop + _ref2.clientHeight + _this2.wrapper.clientHeight;
// If it's going to make situation any better, display the calendar above the input
if (overflowTopAfterChange < collisions.overflowBottom) {
_ref2.classList.add(className + '--above-label');
}
}

@@ -249,3 +251,3 @@ }

value: function render() {
var _this2 = this;
var _this3 = this;

@@ -264,4 +266,9 @@ var _props3 = this.props,

onFocus: this.onFocus,
onBlur: this.onBlur,
ref: function ref(_ref3) {
_this2.wrapper = _ref3;
if (!_ref3) {
return;
}
_this3.wrapper = _ref3;
}

@@ -268,0 +275,0 @@ }),

{
"name": "react-time-picker",
"version": "3.0.0",
"version": "3.1.0",
"description": "A time picker for your React app.",

@@ -5,0 +5,0 @@ "main": "dist/entry.js",

@@ -213,4 +213,6 @@ import React from 'react';

expect(separators).toHaveLength(2);
expect(separators).toHaveLength(3);
expect(separators.at(0).text()).toBe(':');
expect(separators.at(1).text()).toBe(':');
expect(separators.at(2).text()).toBe(' ');
});

@@ -225,4 +227,5 @@

const customInputs = component.find('input[type="number"]');
const ampm = component.find('select');
expect(separators).toHaveLength(customInputs.length - 1);
expect(separators).toHaveLength(customInputs.length + ampm.length - 1);
});

@@ -282,12 +285,11 @@

const customInputs = component.find('input[type="number"]');
const secondInput = customInputs.at(2);
const select = component.find('select');
secondInput.getDOMNode().focus();
select.getDOMNode().focus();
expect(document.activeElement).toBe(secondInput.getDOMNode());
expect(document.activeElement).toBe(select.getDOMNode());
secondInput.simulate('keydown', getKey('ArrowRight'));
select.simulate('keydown', getKey('ArrowRight'));
expect(document.activeElement).toBe(secondInput.getDOMNode());
expect(document.activeElement).toBe(select.getDOMNode());
});

@@ -316,3 +318,3 @@

it('does not jump to the next field when right arrow is pressed when the last input is focused', () => {
it('does not jump to the previous field when left arrow is pressed when the first input is focused', () => {
const component = mount(

@@ -356,3 +358,3 @@ <TimeInput

expect(onChange).toHaveBeenCalled();
expect(onChange).toHaveBeenCalledWith('20:17:00');
expect(onChange).toHaveBeenCalledWith('20:17:00', false);
});

@@ -381,3 +383,3 @@

expect(onChange).toHaveBeenCalledTimes(1);
expect(onChange).toHaveBeenCalledWith(null);
expect(onChange).toHaveBeenCalledWith(null, false);
});

@@ -404,3 +406,3 @@

expect(onChange).toHaveBeenCalled();
expect(onChange).toHaveBeenCalledWith('20:17:00');
expect(onChange).toHaveBeenCalledWith('20:17:00', false);
});

@@ -427,4 +429,4 @@

expect(onChange).toHaveBeenCalled();
expect(onChange).toHaveBeenCalledWith(null);
expect(onChange).toHaveBeenCalledWith(null, false);
});
});

@@ -8,18 +8,2 @@ import React from 'react';

const mockDocumentListeners = () => {
const eventMap = {};
document.addEventListener = jest.fn((method, cb) => {
if (!eventMap[method]) {
eventMap[method] = [];
}
eventMap[method].push(cb);
});
return {
simulate: (method, args) => {
eventMap[method].forEach(cb => cb(args));
},
};
};
describe('TimePicker', () => {

@@ -183,5 +167,3 @@ it('passes default name to TimeInput', () => {

it('closes Calendar component when clicked outside', () => {
const { simulate } = mockDocumentListeners();
it('closes Calendar component when focused outside', () => {
const component = mount(

@@ -191,5 +173,6 @@ <TimePicker isOpen />

simulate('mousedown', {
target: document,
});
const customInputs = component.find('input[type="number"]');
const hourInput = customInputs.at(0);
hourInput.simulate('blur');
component.update();

@@ -200,5 +183,3 @@

it('does not close Calendar component when clicked inside', () => {
const { simulate } = mockDocumentListeners();
it('does not close Calendar component when focused inside', () => {
const component = mount(

@@ -208,5 +189,8 @@ <TimePicker isOpen />

simulate('mousedown', {
target: component.getDOMNode(),
});
const customInputs = component.find('input[type="number"]');
const hourInput = customInputs.at(0);
const minuteInput = customInputs.at(1);
hourInput.simulate('blur');
minuteInput.simulate('focus');
component.update();

@@ -213,0 +197,0 @@

@@ -5,2 +5,4 @@ import getUserLocale from 'get-user-locale';

/* eslint-disable import/prefer-default-export */
/**

@@ -10,3 +12,3 @@ * Gets Intl-based date formatter from formatter cache. If it doesn't exist in cache

*/
const getFormatter = (options, locale) => {
export const getFormatter = (options, locale) => {
if (!locale) {

@@ -30,7 +32,1 @@ // Default parameter is not enough as it does not protect us from null values

};
// eslint-disable-next-line import/prefer-default-export
export const formatTime = (date, locale) => getFormatter(
{ hour: 'numeric', minute: 'numeric', second: 'numeric' },
locale,
)(date);

@@ -0,2 +1,5 @@

import { getFormatter } from './dateFormatter';
const isValidNumber = a => typeof a === 'number' && !isNaN(a);
export const min = (...args) => Math.min(...args.filter(isValidNumber));

@@ -14,5 +17,25 @@ export const max = (...args) => Math.max(...args.filter(isValidNumber));

const { width } = span.getBoundingClientRect();
element.style.width = `${width}px`;
element.style.width = `${Math.ceil(width)}px`;
container.removeChild(span);
};
export const getAmPmLabels = (locale) => {
const amPmFormatter = getFormatter({ hour: 'numeric' }, locale);
const amString = amPmFormatter(new Date(2017, 0, 1, 9));
const pmString = amPmFormatter(new Date(2017, 0, 1, 21));
const [am1, am2] = amString.split('9');
const [pm1, pm2] = pmString.split('9');
if (am1 !== pm1) {
return [am1, pm1].map(el => el.trim());
}
if (am2 !== pm2) {
return [am2, pm2].map(el => el.trim());
}
// Fallback
return ['am', 'pm'];
};

@@ -13,3 +13,3 @@ import React, { PureComponent } from 'react';

import { formatTime } from './shared/dateFormatter';
import { getFormatter } from './shared/dateFormatter';
import {

@@ -25,2 +25,3 @@ getHours,

import { isTime } from './shared/propTypes';
import { getAmPmLabels } from './shared/utils';

@@ -53,13 +54,20 @@ const allViews = ['hour', 'minute', 'second'];

const removeUnwantedCharacters = str => str
.split('')
.filter(a => (
// We don't want spaces in dates
a.charCodeAt(0) !== 32
// Internet Explorer specific
&& a.charCodeAt(0) !== 8206
// Remove non-ASCII characters
&& /^[\x20-\x7F]*$/.test(a)
))
.join('');
const renderCustomInputs = (placeholder, elementFunctions) => {
const pattern = new RegExp(Object.keys(elementFunctions).join('|'), 'gi');
const matches = placeholder.match(pattern);
return placeholder.split(pattern)
.reduce((arr, element, index) => {
const divider = element && (
// eslint-disable-next-line react/no-array-index-key
<Divider key={`separator_${index}`}>
{element}
</Divider>
);
const res = [...arr, divider];
if (matches[index]) {
res.push(elementFunctions[matches[index]]());
}
return res;
}, []);
};

@@ -113,2 +121,17 @@ export default class TimeInput extends PureComponent {

get formatTime() {
const { locale, maxDetail } = this.props;
const options = { hour: 'numeric' };
const level = allViews.indexOf(maxDetail);
if (level >= 1) {
options.minute = 'numeric';
}
if (level >= 2) {
options.second = 'numeric';
}
return getFormatter(options, locale);
}
/**

@@ -144,14 +167,8 @@ * Gets current value in a desired format.

// eslint-disable-next-line class-methods-use-this
get divider() {
const { locale } = this.props;
const date = new Date(2017, 0, 1, 21, 12, 13);
return (
removeUnwantedCharacters(formatTime(date, locale))
.match(/[^0-9]/)[0]
);
return this.formatTime(date).match(/[^0-9a-z]/i)[0];
}
// eslint-disable-next-line class-methods-use-this
get placeholder() {

@@ -162,3 +179,3 @@ const { locale } = this.props;

return (
removeUnwantedCharacters(formatTime(date, locale))
this.formatTime(date)
.replace('21', 'hour-24')

@@ -168,3 +185,3 @@ .replace('9', 'hour-12')

.replace('14', 'second')
.replace(/AM|PM/i, `${this.divider}ampm`)
.replace(new RegExp(getAmPmLabels(locale).join('|')), 'ampm')
);

@@ -200,2 +217,10 @@ }

onClick = (event) => {
if (event.target === event.currentTarget) {
// Wrapper was directly clicked
const [/* nativeInput */, firstInput] = event.target.children;
focus(firstInput);
}
}
onKeyDown = (event) => {

@@ -275,3 +300,3 @@ switch (event.key) {

onChange(processedValue);
onChange(processedValue, false);
}

@@ -315,3 +340,3 @@

if (formElementsWithoutSelect.every(formElement => !formElement.value)) {
onChange(null);
onChange(null, false);
} else if (

@@ -325,7 +350,7 @@ formElements.every(formElement => formElement.value && formElement.checkValidity())

const processedValue = this.getProcessedValue(timeString);
onChange(processedValue);
onChange(processedValue, false);
}
}
renderHour12() {
renderHour12 = () => {
const { hour } = this.state;

@@ -342,3 +367,3 @@

renderHour24() {
renderHour24 = () => {
const { hour } = this.state;

@@ -355,10 +380,4 @@

renderMinute() {
renderMinute = () => {
const { maxDetail } = this.props;
// Do not display if maxDetail is "hour" or less
if (allViews.indexOf(maxDetail) < 1) {
return null;
}
const { hour, minute } = this.state;

@@ -377,10 +396,4 @@

renderSecond() {
renderSecond = () => {
const { maxDetail } = this.props;
// Do not display if maxDetail is "minute" or less
if (allViews.indexOf(maxDetail) < 2) {
return null;
}
const { hour, minute, second } = this.state;

@@ -400,4 +413,5 @@

renderAmPm() {
renderAmPm = () => {
const { amPm } = this.state;
const { locale } = this.props;

@@ -408,4 +422,5 @@ return (

{...this.commonInputProps}
locale={locale}
onChange={this.onChangeAmPm}
value={amPm}
onChange={this.onChangeAmPm}
/>

@@ -416,33 +431,12 @@ );

renderCustomInputs() {
const { divider, placeholder } = this;
const { placeholder } = this;
const elementFunctions = {
'hour-12': this.renderHour12,
'hour-24': this.renderHour24,
minute: this.renderMinute,
second: this.renderSecond,
ampm: this.renderAmPm,
};
return (
placeholder
.split(divider)
.map((part) => {
switch (part) {
case 'hour-12': return this.renderHour12();
case 'hour-24': return this.renderHour24();
case 'minute': return this.renderMinute();
case 'second': return this.renderSecond();
case 'ampm': return this.renderAmPm();
default: return null;
}
})
.filter(Boolean)
.reduce((result, element, index) => {
if (index && element.key !== 'ampm') {
result.push(
// eslint-disable-next-line react/no-array-index-key
<Divider key={`separator_${index}`}>
{divider}
</Divider>,
);
}
result.push(element);
return result;
}, [])
);
return renderCustomInputs(placeholder, elementFunctions);
}

@@ -479,3 +473,7 @@

return (
<div className={className}>
<div
className={className}
onClick={this.onClick}
role="presentation"
>
{this.renderNativeInput()}

@@ -482,0 +480,0 @@ {this.renderCustomInputs()}

@@ -10,2 +10,3 @@ import React, { PureComponent } from 'react';

import { isTime } from '../shared/propTypes';
import { getAmPmLabels } from '../shared/utils';

@@ -27,6 +28,7 @@ class AmPm extends PureComponent {

const {
className, disabled, itemRef, onChange, required, value,
className, disabled, itemRef, locale, onChange, required, value,
} = this.props;
const name = 'amPm';
const [amLabel, pmLabel] = getAmPmLabels(locale);

@@ -56,6 +58,6 @@ return (

<option disabled={this.amDisabled} value="am">
am
{amLabel}
</option>
<option disabled={this.pmDisabled} value="pm">
pm
{pmLabel}
</option>

@@ -71,2 +73,3 @@ </select>

itemRef: PropTypes.func,
locale: PropTypes.string,
maxTime: isTime,

@@ -73,0 +76,0 @@ minTime: isTime,

@@ -35,16 +35,2 @@ import React, { PureComponent } from 'react';

componentDidMount() {
document.addEventListener('mousedown', this.onClick);
}
componentWillUnmount() {
document.removeEventListener('mousedown', this.onClick);
}
onClick = (event) => {
if (this.wrapper && !this.wrapper.contains(event.target)) {
this.closeClock();
}
}
openClock = () => {

@@ -94,2 +80,12 @@ this.setState({ isOpen: true });

onBlur = () => {
const { onBlur } = this.props;
if (onBlur) {
onBlur(event);
}
this.closeClock();
}
stopPropagation = event => event.stopPropagation();

@@ -185,3 +181,3 @@

ref={(ref) => {
if (!ref) {
if (!ref || !isOpen) {
return;

@@ -195,3 +191,10 @@ }

if (collisions.collidedBottom) {
ref.classList.add(`${className}--above-label`);
const overflowTopAfterChange = (
collisions.overflowTop + ref.clientHeight + this.wrapper.clientHeight
);
// If it's going to make situation any better, display the calendar above the input
if (overflowTopAfterChange < collisions.overflowBottom) {
ref.classList.add(`${className}--above-label`);
}
}

@@ -224,3 +227,10 @@ }}

onFocus={this.onFocus}
ref={(ref) => { this.wrapper = ref; }}
onBlur={this.onBlur}
ref={(ref) => {
if (!ref) {
return;
}
this.wrapper = ref;
}}
>

@@ -227,0 +237,0 @@ {this.renderInputs()}

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc