@enact/sandstone
Version:
Large-screen/TV support library for Enact, containing a variety of UI components.
255 lines (242 loc) • 7.93 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.TimePicker = void 0;
Object.defineProperty(exports, "TimePickerBase", {
enumerable: true,
get: function get() {
return _TimePickerBase["default"];
}
});
exports.timeToLocaleString = exports["default"] = void 0;
var _Pure = _interopRequireDefault(require("@enact/ui/internal/Pure"));
var _DateFactory = _interopRequireDefault(require("ilib/lib/DateFactory"));
var _DateFmt = _interopRequireDefault(require("ilib/lib/DateFmt"));
var _LocaleInfo = _interopRequireDefault(require("ilib/lib/LocaleInfo"));
var _DateTime = require("../internal/DateTime");
var _Skinnable = _interopRequireDefault(require("../Skinnable"));
var _TimePickerBase = _interopRequireDefault(require("./TimePickerBase"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
/**
* Provides a Sandstone-themed time selection component.
*
* @example
* <TimePicker value={new Date()} />
*
* @module sandstone/TimePicker
* @exports TimePicker
* @exports TimePickerBase
* @exports timeToLocaleString
*/
/*
* Converts a string representation of time into minutes
*
* @param {String} time Time in the format `HH:mm`
*
* @returns {Number} Time in minute
* @private
*/
var toMinutes = function toMinutes(time) {
var colon = time.indexOf(':');
var hour = parseInt(time.substring(0, colon));
var minute = parseInt(time.substring(colon + 1));
return hour * 60 + minute;
};
/*
* Converts the `start` and `end` string representations (e.g. '12:00') into a numerical
* representation.
*
* @param {Object} options Time options
* @param {String} options.start Start time of meridiem
* @param {String} options.end End time of meridiem
*
* @returns {Object} Contains start and end time in minutes
* @private
*/
var calcMeridiemRange = function calcMeridiemRange(_ref) {
var start = _ref.start,
end = _ref.end;
return {
start: toMinutes(start),
end: toMinutes(end)
};
};
/*
* Finds the index of the meridiem which contains `time`
*
* @param {Number} time Time in minutes
* @param {Object[]} meridiems Array of meridiems with `start` and `end` members in minutes
*
* @returns {Number} Index of `time` in `meridiems`
* @private
*/
var indexOfMeridiem = function indexOfMeridiem(time, meridiems) {
var minutes = time.getHours() * 60 + time.getMinutes();
for (var i = 0; i < meridiems.length; i++) {
var m = meridiems[i];
if (minutes >= m.start && minutes <= m.end) {
return i;
}
}
return -1;
};
var getLabelFormatter = function getLabelFormatter() {
return new _DateFmt["default"]({
type: 'time',
useNative: false,
timezone: 'local',
length: 'full',
date: 'dmwy'
});
};
var dateTimeConfig = {
customProps: function customProps(i18n, value, _ref2) {
var meridiemLabel = _ref2.meridiemLabel;
var values = {
// i18n props
meridiems: i18n.meridiemLabels,
meridiemLabel: meridiemLabel,
// date components
hour: 12,
minute: 0,
meridiem: 0
};
if (i18n.meridiemEnabled && meridiemLabel == null) {
if (values.meridiems.length > 2) {
values.meridiemLabel = "".concat(values.meridiems[0], " / ").concat(values.meridiems[1], " ...");
} else {
values.meridiemLabel = values.meridiems.join(' / ');
}
}
if (value) {
if (i18n.meridiemEnabled) {
values.meridiem = indexOfMeridiem(value, i18n.meridiemRanges);
}
values.hour = value.getHours();
values.minute = value.getMinutes();
}
return values;
},
defaultOrder: ['h', 'm', 'a'],
handlers: {
onChangeHour: function onChangeHour(ev, value) {
var currentTime = (0, _DateFactory["default"])(value).getTimeExtended();
var currentHour = value.hour;
value.hour = ev.value;
// In the case of navigating onto the skipped hour of DST, ilib will return the same
// value so we skip that hour and update the value again.
var newTime = (0, _DateFactory["default"])(value).getTimeExtended();
if (newTime === currentTime) {
value.hour = ev.value * 2 - currentHour;
}
return value;
},
onChangeMinute: function onChangeMinute(ev, value) {
value.minute = ev.value;
return value;
},
onChangeMeridiem: function onChangeMeridiem(ev, value, i18n) {
var meridiemRanges = i18n.meridiemRanges;
var meridiem = meridiemRanges[ev.value];
if (meridiemRanges.length === 2) {
// In the common case of 2 meridiems, we'll offset hours by 12 so that picker stays
// the same.
value.hour = (value.getHours() + 12) % 24;
} else {
// In the rarer case of > 2 meridiems (e.g. am-ET), try to set hours only first
var hours = Math.floor(meridiem.start / 60);
value.hour = hours;
// but check if it is still out of bounds and update the minutes as well
var minutes = hours * 60 + value.getMinutes();
if (minutes > meridiem.end) {
value.minute = meridiem.end % 60;
} else if (minutes < meridiem.start) {
value.minute = meridiem.start % 60;
}
}
return value;
}
},
i18n: function i18n() {
// Filters used to extract the order of pickers from the ilib template
var includeMeridiem = /([khma])(?!\1)/ig;
var excludeMeridiem = /([khm])(?!\1)/ig;
// Meridiem localization
var merFormatter = new _DateFmt["default"]({
template: 'a',
useNative: false,
timezone: 'local'
});
var meridiems = merFormatter.getMeridiemsRange();
var meridiemRanges = meridiems.map(calcMeridiemRange);
var meridiemLabels = meridiems.map(function (obj) {
return obj.name;
});
// Picker ordering
var li = new _LocaleInfo["default"]();
var clockPref = li.getClock();
var meridiemEnabled = clockPref === '12';
var filter = meridiemEnabled ? includeMeridiem : excludeMeridiem;
var order = getLabelFormatter().getTemplate().replace(/'.*?'/g, '').match(filter).map(function (s) {
return s[0].toLowerCase();
});
return {
formatter: getLabelFormatter(),
meridiemEnabled: meridiemEnabled,
meridiemLabels: meridiemLabels,
meridiemRanges: meridiemRanges,
order: order
};
}
};
/**
* A component that allows displaying or selecting time.
*
* Set the {@link sandstone/TimePicker.TimePicker.value|value} property to a standard JavaScript
* {@link /docs/developer-guide/glossary/#date|Date} object to initialize the picker.
*
* By default, `TimePicker` maintains the state of its `value` property. Supply the
* `defaultValue` property to control its initial value. If you wish to directly control updates
* to the component, supply a value to `value` at creation time and update it in response to
* `onChange` events.
*
* @class TimePicker
* @memberof sandstone/TimePicker
* @mixes ui/Changeable.Changeable
* @ui
* @public
*/
/**
* Default value
*
* @name defaultValue
* @memberof sandstone/TimePicker.TimePicker.prototype
* @type {Number}
* @public
*/
var TimePicker = exports.TimePicker = (0, _Pure["default"])((0, _Skinnable["default"])((0, _DateTime.DateTimeDecorator)(dateTimeConfig, _TimePickerBase["default"])));
/**
* The selected date.
*
* @name value
* @memberof sandstone/TimePicker.TimePicker
* @instance
* @type {Date}
* @public
*/
/**
* Converts a standard `Date` object into a locale-specific string.
*
* @function
* @memberof sandstone/TimePicker
* @param {Date} time `Date` to convert
* @returns {String?} Converted date or `null` if `date` is invalid
*/
var timeToLocaleString = exports.timeToLocaleString = function timeToLocaleString(time) {
if (!time) {
return null;
}
return getLabelFormatter().format(time);
};
var _default = exports["default"] = TimePicker;