UNPKG

devextreme

Version:

JavaScript/TypeScript Component Suite for Responsive Web Development

324 lines (323 loc) • 11.3 kB
/** * DevExtreme (esm/__internal/ui/date_box/time_view.js) * Version: 25.2.7 * Build date: Tue May 05 2026 * * Copyright (c) 2012 - 2026 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ import dateLocalization from "../../../common/core/localization/date"; import registerComponent from "../../../core/component_registrator"; import $ from "../../../core/renderer"; import Box from "../../ui/box"; import Editor from "../../ui/editor/editor"; import SelectBox from "../../ui/m_select_box"; import NumberBox from "../../ui/number_box/m_number_box"; import dateUtils from "./date_utils"; const TIMEVIEW_CLASS = "dx-timeview"; const TIMEVIEW_CLOCK_CLASS = "dx-timeview-clock"; const TIMEVIEW_FIELD_CLASS = "dx-timeview-field"; const TIMEVIEW_HOURARROW_CLASS = "dx-timeview-hourarrow"; const TIMEVIEW_TIME_SEPARATOR_CLASS = "dx-timeview-time-separator"; const TIMEVIEW_FORMAT12_CLASS = "dx-timeview-format12"; const TIMEVIEW_FORMAT12_AM = -1; const TIMEVIEW_FORMAT12_PM = 1; const TIMEVIEW_MINUTEARROW_CLASS = "dx-timeview-minutearrow"; const cssRotate = function($arrow, angle) { let offset = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : 0; $arrow.css("transform", `rotate(${angle}deg) translate(0,${offset}px)`) }; const rotateArrow = ($arrow, angle, offset) => { if (!$arrow) { return } cssRotate($arrow, angle, offset) }; class TimeView extends Editor { _getDefaultOptions() { return Object.assign({}, super._getDefaultOptions(), { value: new Date(Date.now()), use24HourFormat: true, _showClock: true, _arrowOffset: 5 }) } _getValue() { const { value: value } = this.option(); return value || new Date } _init() { super._init(); this.$element().addClass("dx-timeview") } _render() { super._render(); this._renderBox(); this._updateTime() } _renderBox() { const { _showClock: _showClock } = this.option(); const $box = $("<div>").appendTo(this.$element()); const items = []; if (_showClock) { items.push({ ratio: 1, shrink: 0, baseSize: "auto", template: this._renderClock.bind(this) }) } items.push({ ratio: 0, shrink: 0, baseSize: "auto", template: this._renderField.bind(this) }); this._createComponent($box, Box, { height: "100%", width: "100%", direction: "col", items: items }) } _renderClock(_, __, container) { this._$hourArrow = $("<div>").addClass("dx-timeview-hourarrow"); this._$minuteArrow = $("<div>").addClass("dx-timeview-minutearrow"); const $container = $(container); $container.addClass("dx-timeview-clock").append(this._$hourArrow).append(this._$minuteArrow); this.setAria("role", "presentation", $container) } _updateClock() { const { _arrowOffset: _arrowOffset } = this.option(); const time = this._getValue(); const hourArrowAngle = time.getHours() / 12 * 360 + time.getMinutes() / 60 * 30; const minuteArrowAngle = time.getMinutes() / 60 * 360; rotateArrow(this._$hourArrow, hourArrowAngle, _arrowOffset); rotateArrow(this._$minuteArrow, minuteArrowAngle, _arrowOffset) } _getBoxItems(is12HourFormat) { const items = [{ ratio: 0, shrink: 0, baseSize: "auto", template: () => this._hourBox.$element() }, { ratio: 0, shrink: 0, baseSize: "auto", template: () => $("<div>").addClass("dx-timeview-time-separator").text(dateLocalization.getTimeSeparator()) }, { ratio: 0, shrink: 0, baseSize: "auto", template: () => this._minuteBox.$element() }]; if (is12HourFormat) { items.push({ ratio: 0, shrink: 0, baseSize: "auto", template: () => { var _this$_format; return null === (_this$_format = this._format12) || void 0 === _this$_format ? void 0 : _this$_format.$element() } }) } return items } _renderField() { const { use24HourFormat: use24HourFormat } = this.option(); const is12HourFormat = !use24HourFormat; this._createHourBox(is12HourFormat); this._createMinuteBox(); if (is12HourFormat) { this._createFormat12Box() } return this._createComponent($("<div>").addClass("dx-timeview-field"), Box, { direction: "row", align: "center", crossAlign: "center", items: this._getBoxItems(is12HourFormat) }).$element() } _createHourBox(is12HourFormat) { this._hourBox = this._createComponent($("<div>"), NumberBox, Object.assign({ min: -1, max: is12HourFormat ? 13 : 24, value: this._getValue().getHours(), onValueChanged: this._onHourBoxValueChanged.bind(this), onKeyboardHandled: opts => this._keyboardHandler(opts) }, this._getNumberBoxConfig())); this._hourBox.setAria("label", "hours") } _isPM() { var _this$_format2; const { use24HourFormat: use24HourFormat } = this.option(); const format12Value = null === (_this$_format2 = this._format12) || void 0 === _this$_format2 ? void 0 : _this$_format2.option().value; return !use24HourFormat && 1 === format12Value } _onHourBoxValueChanged(_ref) { let { value: value, component: component } = _ref; const currentValue = this._getValue(); const newValue = new Date(currentValue); let newHours = this._convertMaxHourToMin(value); component.option("value", newHours); if (this._isPM()) { newHours += 12 } newValue.setHours(newHours); dateUtils.normalizeTime(newValue); this.option("value", newValue) } _convertMaxHourToMin(hours) { const { use24HourFormat: use24HourFormat } = this.option(); const maxHoursValue = use24HourFormat ? 24 : 12; return (maxHoursValue + hours) % maxHoursValue } _createMinuteBox() { this._minuteBox = this._createComponent($("<div>"), NumberBox, Object.assign({ min: -1, max: 60, value: this._getValue().getMinutes(), onKeyboardHandled: opts => this._keyboardHandler(opts), onValueChanged: _ref2 => { let { value: value, component: component } = _ref2; const newMinutes = (60 + value) % 60; component.option("value", newMinutes); const time = new Date(this._getValue()); time.setMinutes(newMinutes); dateUtils.normalizeTime(time); this.option("value", time) } }, this._getNumberBoxConfig())); this._minuteBox.setAria("label", "minutes") } _createFormat12Box() { const periodNames = dateLocalization.getPeriodNames(); const { stylingMode: stylingMode } = this.option(); this._format12 = this._createComponent($("<div>").addClass("dx-timeview-format12"), SelectBox, { items: [{ value: -1, text: periodNames[0] }, { value: 1, text: periodNames[1] }], valueExpr: "value", displayExpr: "text", onKeyboardHandled: opts => this._keyboardHandler(opts), onValueChanged: _ref3 => { let { value: value } = _ref3; const hours = this._getValue().getHours(); const time = new Date(this._getValue()); const newHours = (hours + 12 * value) % 24; time.setHours(newHours); this.option("value", time) }, dropDownOptions: { container: this.$element() }, value: this._getValue().getHours() >= 12 ? 1 : -1, stylingMode: stylingMode }); this._format12.setAria("label", "type") } _refreshFormat12() { const { use24HourFormat: use24HourFormat } = this.option(); if (use24HourFormat) { return } const value = this._getValue(); const hours = value.getHours(); const isPM = hours >= 12; const newValue = isPM ? 1 : -1; this._silentEditorValueUpdate(this._format12, newValue) } _silentEditorValueUpdate(editor, value) { if (!editor) { return } editor._suppressValueChangeAction(); editor.option("value", value); editor._resumeValueChangeAction() } _getNumberBoxConfig() { const { stylingMode: stylingMode } = this.option(); return { showSpinButtons: true, displayValueFormatter: value => (value < 10 ? "0" : "") + value, stylingMode: stylingMode } } _normalizeHours(hours) { const { use24HourFormat: use24HourFormat } = this.option(); return use24HourFormat ? hours : hours % 12 || 12 } _updateField() { const hours = this._normalizeHours(this._getValue().getHours()); this._silentEditorValueUpdate(this._hourBox, hours); this._silentEditorValueUpdate(this._minuteBox, this._getValue().getMinutes()); this._refreshFormat12() } _updateTime() { const { _showClock: _showClock } = this.option(); if (_showClock) { this._updateClock() } this._updateField() } _visibilityChanged(visible) { if (visible) { this._updateTime() } } _optionChanged(args) { switch (args.name) { case "value": this._updateTime(); super._optionChanged(args); break; case "_arrowOffset": break; case "use24HourFormat": case "_showClock": case "stylingMode": this._invalidate(); break; default: super._optionChanged(args) } } } registerComponent("dxTimeView", TimeView); export default TimeView;