@steroidsjs/bootstrap 3.0.41 → 3.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -54,7 +54,7 @@ function TimeFieldView(props) {
54
54
  'is-invalid': !!props.errors
55
55
  }), props.className), style: props.style },
56
56
  React.createElement("div", { className: bem.element('body') },
57
- React.createElement("input", __assign({}, props.inputProps, { id: props.id, className: bem(bem.element('input'), props.inputProps.className), onChange: function (e) { return props.inputProps.onChange(e.target.value); } })),
57
+ React.createElement("input", __assign({}, props.inputProps, { id: props.id, ref: props.maskRef, className: bem(bem.element('input'), props.inputProps.className), onChange: function (e) { return props.inputProps.onChange(e.target.value); } })),
58
58
  React.createElement("div", { className: bem.element('icon-container') },
59
59
  !props.inputProps.value && props.icon && (React.createElement(Icon_1["default"], { className: bem.element('date-icon'), name: typeof props.icon === 'string' ? props.icon : 'calendar_range', tabIndex: -1 })),
60
60
  props.showRemove && props.inputProps.value && props.icon !== false && (React.createElement(Icon_1["default"], { className: bem.element('close-icon'), onClick: function (e) {
@@ -28,39 +28,40 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
28
28
  exports.__esModule = true;
29
29
  var React = __importStar(require("react"));
30
30
  var hooks_1 = require("@steroidsjs/core/hooks");
31
- var padStart_1 = __importDefault(require("lodash-es/padStart"));
32
31
  var TimePanelColumn_1 = __importDefault(require("./views/TimePanelColumn"));
33
- var getHours = function () {
34
- var result = [];
35
- for (var i = 0; i < 24; i += 1) {
36
- var hour = (0, padStart_1["default"])(i, 2, '0');
37
- result.push(hour);
38
- }
39
- return result;
40
- };
41
- var getMinutes = function () {
42
- var result = [];
43
- for (var i = 0; i < 60; i += 1) {
44
- var minute = (0, padStart_1["default"])(i, 2, '0');
45
- result.push(minute);
46
- }
47
- return result;
48
- };
32
+ var utils_1 = require("./utils");
49
33
  function TimePanelView(props) {
34
+ var _a;
50
35
  var bem = (0, hooks_1.useBem)('TimePanelView');
51
- var _a = props.value ? props.value.split(':') : ['00', '00'], hours = _a[0], minutes = _a[1];
36
+ var _b = props.value ? props.value.split(':') : ['00', '00'], hours = _b[0], minutes = _b[1];
37
+ var _c = props.availableTime || {}, from = _c.from, to = _c.to;
38
+ var minuteStep = (_a = props.minuteStep) !== null && _a !== void 0 ? _a : 1;
52
39
  var currentValues = {
53
40
  hours: hours,
54
41
  minutes: minutes
55
42
  };
43
+ var availableHours = (0, utils_1.getAvailableHours)(from, to);
44
+ // если текущий час невалиден — берём первый доступный
45
+ var minutesHour = (0, utils_1.isHourAvailable)(hours, from, to)
46
+ ? hours
47
+ : availableHours[0];
56
48
  var COLUMNS = [{
57
- values: getHours(),
49
+ values: (0, utils_1.getAvailableHours)(from, to),
58
50
  currentValueKey: 'hours',
59
51
  onUpdate: function (value) {
60
- props.onSelect(value + ':' + minutes);
52
+ var nextMinutes = (0, utils_1.normalizeMinutesForHour)(value, minutes, {
53
+ from: from,
54
+ to: to,
55
+ step: minuteStep
56
+ });
57
+ props.onSelect(value + ':' + nextMinutes);
61
58
  }
62
59
  }, {
63
- values: getMinutes(),
60
+ values: (0, utils_1.getAvailableMinutes)(minutesHour, {
61
+ from: from,
62
+ to: to,
63
+ step: minuteStep
64
+ }),
64
65
  currentValueKey: 'minutes',
65
66
  onUpdate: function (value) {
66
67
  props.onSelect(hours + ':' + value);
@@ -0,0 +1,15 @@
1
+ /** 'HH:mm' -> minutes from start of day */
2
+ export declare const timeToMinutes: (time: string) => number;
3
+ export declare const isHourAvailable: (hour: string, from?: string, to?: string) => boolean;
4
+ export declare const getMinuteRange: (fromMin: number, toMin: number, step?: number) => number[];
5
+ export declare const getAvailableHours: (from?: string, to?: string) => string[];
6
+ export declare const getAvailableMinutes: (hour: string, options?: {
7
+ from?: string;
8
+ to?: string;
9
+ step?: number;
10
+ }) => string[];
11
+ export declare const normalizeMinutesForHour: (hour: string, minute: string, options?: {
12
+ from?: string;
13
+ to?: string;
14
+ step?: number;
15
+ }) => string;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ exports.__esModule = true;
6
+ exports.normalizeMinutesForHour = exports.getAvailableMinutes = exports.getAvailableHours = exports.getMinuteRange = exports.isHourAvailable = exports.timeToMinutes = void 0;
7
+ var padStart_1 = __importDefault(require("lodash-es/padStart"));
8
+ /** 'HH:mm' -> minutes from start of day */
9
+ var timeToMinutes = function (time) {
10
+ var _a = time.split(':').map(Number), h = _a[0], m = _a[1];
11
+ return h * 60 + m;
12
+ };
13
+ exports.timeToMinutes = timeToMinutes;
14
+ var isHourAvailable = function (hour, from, to) {
15
+ var h = Number(hour);
16
+ var fromMin = from ? (0, exports.timeToMinutes)(from) : 0;
17
+ var toMin = to ? (0, exports.timeToMinutes)(to) : 24 * 60 - 1;
18
+ var hourStart = h * 60;
19
+ var hourEnd = h * 60 + 59;
20
+ return !(hourEnd < fromMin || hourStart > toMin);
21
+ };
22
+ exports.isHourAvailable = isHourAvailable;
23
+ /** clamp value into range */
24
+ var clamp = function (value, min, max) { return Math.min(Math.max(value, min), max); };
25
+ var getMinuteRange = function (fromMin, toMin, step) {
26
+ if (step === void 0) { step = 1; }
27
+ var result = [];
28
+ for (var m = fromMin; m <= toMin; m += step) {
29
+ result.push(m);
30
+ }
31
+ return result;
32
+ };
33
+ exports.getMinuteRange = getMinuteRange;
34
+ var getAvailableHours = function (from, to) {
35
+ var result = [];
36
+ var fromMin = from ? (0, exports.timeToMinutes)(from) : 0;
37
+ var toMin = to ? (0, exports.timeToMinutes)(to) : 24 * 60 - 1;
38
+ var startHour = Math.floor(fromMin / 60);
39
+ var endHour = Math.floor(toMin / 60);
40
+ for (var h = startHour; h <= endHour; h += 1) {
41
+ result.push((0, padStart_1["default"])(h, 2, '0'));
42
+ }
43
+ return result;
44
+ };
45
+ exports.getAvailableHours = getAvailableHours;
46
+ var getAvailableMinutes = function (hour, options) {
47
+ var _a;
48
+ var h = Number(hour);
49
+ var step = (_a = options === null || options === void 0 ? void 0 : options.step) !== null && _a !== void 0 ? _a : 1;
50
+ var fromMin = (options === null || options === void 0 ? void 0 : options.from) ? (0, exports.timeToMinutes)(options.from) : 0;
51
+ var toMin = (options === null || options === void 0 ? void 0 : options.to) ? (0, exports.timeToMinutes)(options.to) : 24 * 60 - 1;
52
+ var hourStart = h * 60;
53
+ var startMinute = clamp(fromMin - hourStart, 0, 59);
54
+ var endMinute = clamp(toMin - hourStart, 0, 59);
55
+ return (0, exports.getMinuteRange)(startMinute, endMinute, step)
56
+ .map(function (m) { return (0, padStart_1["default"])(m, 2, '0'); });
57
+ };
58
+ exports.getAvailableMinutes = getAvailableMinutes;
59
+ var normalizeMinutesForHour = function (hour, minute, options) {
60
+ var available = (0, exports.getAvailableMinutes)(hour, options);
61
+ // если минут вообще нет (на всякий случай)
62
+ if (!available.length) {
63
+ return minute;
64
+ }
65
+ // если текущая минута валидна — оставляем
66
+ if (available.includes(minute)) {
67
+ return minute;
68
+ }
69
+ // иначе берём ближайшую допустимую (обычно первую)
70
+ return available[0];
71
+ };
72
+ exports.normalizeMinutesForHour = normalizeMinutesForHour;
@@ -54,8 +54,8 @@ function TimeRangeFieldView(props) {
54
54
  'is-invalid': !!props.errors
55
55
  }), props.className), style: props.style },
56
56
  react_1["default"].createElement("div", { className: bem.element('body') },
57
- react_1["default"].createElement("input", __assign({}, props.inputPropsFrom, { id: props.id, className: bem(bem.element('input')), onChange: function (e) { return props.inputPropsFrom.onChange(e.target.value); } })),
58
- react_1["default"].createElement("input", __assign({}, props.inputPropsTo, { className: bem.element('input'), onChange: function (e) { return props.inputPropsTo.onChange(e.target.value); } })),
57
+ react_1["default"].createElement("input", __assign({}, props.inputPropsFrom, { ref: props.maskToRef, id: props.id, className: bem(bem.element('input')), onChange: function (e) { return props.inputPropsFrom.onChange(e.target.value); } })),
58
+ react_1["default"].createElement("input", __assign({}, props.inputPropsTo, { ref: props.maskFromRef, className: bem.element('input'), onChange: function (e) { return props.inputPropsTo.onChange(e.target.value); } })),
59
59
  react_1["default"].createElement("div", { className: bem.element('icon-container') },
60
60
  props.icon && !hasValue && (react_1["default"].createElement(content_1.Icon, { className: bem.element('date-icon'), name: typeof props.icon === 'string' ? props.icon : 'calendar_range', tabIndex: -1 })),
61
61
  props.showRemove && hasValue && (react_1["default"].createElement(content_1.Icon, { className: bem.element('close-icon'), onClick: function (e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steroidsjs/bootstrap",
3
- "version": "3.0.41",
3
+ "version": "3.0.42",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "author": "Vladimir Kozhin <hello@kozhindev.com>",
@@ -35,7 +35,7 @@
35
35
  "react-use": "^17.4.0"
36
36
  },
37
37
  "devDependencies": {
38
- "@steroidsjs/core": "^3.0.80",
38
+ "@steroidsjs/core": "3.0.83",
39
39
  "@steroidsjs/eslint-config": "^2.1.6",
40
40
  "@types/enzyme": "^3.10.8",
41
41
  "@types/googlemaps": "^3.43.3",