From 98fa5c9ae2e926d609444d7195d09604ada7c013 Mon Sep 17 00:00:00 2001 From: Aman Agrawal Date: Wed, 8 Dec 2021 06:54:28 +0000 Subject: [PATCH] flatpickr: Move `show_flatpickr` function in a new module. This would avoid cyclic imports to access `show_flatpickr` function. --- static/js/compose.js | 4 +- static/js/composebox_typeahead.js | 118 +----------------------------- static/js/flatpickr.js | 118 ++++++++++++++++++++++++++++++ tools/test-js-with-node | 1 + 4 files changed, 123 insertions(+), 118 deletions(-) create mode 100644 static/js/flatpickr.js diff --git a/static/js/compose.js b/static/js/compose.js index 42ab16c587..0c6ba3ed46 100644 --- a/static/js/compose.js +++ b/static/js/compose.js @@ -12,8 +12,8 @@ import * as compose_fade from "./compose_fade"; import * as compose_state from "./compose_state"; import * as compose_ui from "./compose_ui"; import * as compose_validate from "./compose_validate"; -import * as composebox_typeahead from "./composebox_typeahead"; import * as echo from "./echo"; +import * as flatpickr from "./flatpickr"; import * as giphy from "./giphy"; import {$t, $t_html} from "./i18n"; import * as loading from "./loading"; @@ -637,7 +637,7 @@ export function initialize() { compose_ui.insert_syntax_and_focus(timestr, target_textarea); }; - composebox_typeahead.show_flatpickr( + flatpickr.show_flatpickr( $(compose_click_target)[0], on_timestamp_selection, new Date(), diff --git a/static/js/composebox_typeahead.js b/static/js/composebox_typeahead.js index 3acb1e0197..a6993c3f0a 100644 --- a/static/js/composebox_typeahead.js +++ b/static/js/composebox_typeahead.js @@ -1,5 +1,3 @@ -import {formatISO} from "date-fns"; -import ConfirmDatePlugin from "flatpickr/dist/plugins/confirmDate/confirmDate"; import $ from "jquery"; import _ from "lodash"; @@ -12,7 +10,7 @@ import * as compose_pm_pill from "./compose_pm_pill"; import * as compose_state from "./compose_state"; import * as compose_ui from "./compose_ui"; import * as compose_validate from "./compose_validate"; -import {get_keydown_hotkey} from "./hotkey"; +import * as flatpickr from "./flatpickr"; import {$t} from "./i18n"; import * as message_store from "./message_store"; import * as muted_users from "./muted_users"; @@ -768,118 +766,6 @@ export function content_highlighter(item) { } } -function is_numeric_key(key) { - return ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"].includes(key); -} - -export function show_flatpickr(element, callback, default_timestamp, options = {}) { - const flatpickr_input = $(""); - - const instance = flatpickr_input.flatpickr({ - mode: "single", - enableTime: true, - clickOpens: false, - defaultDate: default_timestamp, - plugins: [ - new ConfirmDatePlugin({ - showAlways: true, - confirmText: $t({defaultMessage: "Confirm"}), - confirmIcon: "", - }), - ], - positionElement: element, - dateFormat: "Z", - formatDate: (date) => formatISO(date), - disableMobile: true, - onKeyDown: (selectedDates, dateStr, instance, event) => { - if (is_numeric_key(event.key)) { - // Don't attempt to get_keydown_hotkey for numeric inputs - // as it would return undefined. - return; - } - - const hotkey = get_keydown_hotkey(event); - - if (["tab", "shift_tab"].includes(hotkey.name)) { - const elems = [ - instance.selectedDateElem, - instance.hourElement, - instance.minuteElement, - instance.amPM, - $(".flatpickr-confirm")[0], - ]; - const i = elems.indexOf(event.target); - const n = elems.length; - const remain = (i + (event.shiftKey ? -1 : 1)) % n; - const target = elems[Math.floor(remain >= 0 ? remain : remain + n)]; - event.preventDefault(); - event.stopPropagation(); - target.focus(); - } - - event.stopPropagation(); - }, - ...options, - }); - - const container = $($(instance.innerContainer).parent()); - - container.on("keydown", (e) => { - if (is_numeric_key(e.key)) { - // Let users type numeric values - return true; - } - - const hotkey = get_keydown_hotkey(e); - - if (!hotkey) { - return false; - } - - if (hotkey.name === "backspace" || hotkey.name === "delete") { - // Let backspace or delete be handled normally - return true; - } - - if (hotkey.name === "enter") { - if (e.target.classList[0] === "flatpickr-day") { - return true; // use flatpickr default implementation - } - $(element).toggleClass("has_popover"); - container.find(".flatpickr-confirm").trigger("click"); - } - - if (hotkey.name === "escape") { - $(element).toggleClass("has_popover"); - instance.close(); - instance.destroy(); - } - - if (["tab", "shift_tab"].includes(hotkey.name)) { - return true; // use flatpickr default implementation - } - - if (["right_arrow", "up_arrow", "left_arrow", "down_arrow"].includes(hotkey.name)) { - return true; // use flatpickr default implementation - } - - e.stopPropagation(); - e.preventDefault(); - - return true; - }); - - container.on("click", ".flatpickr-confirm", () => { - callback(flatpickr_input.val()); - instance.close(); - instance.destroy(); - }); - instance.open(); - instance.selectedDateElem.focus(); - - return instance; -} - export function content_typeahead_selected(item, event) { const pieces = split_at_cursor(this.query, this.$element); let beginning = pieces[0]; @@ -1016,7 +902,7 @@ export function content_typeahead_selected(item, event) { textbox.caret(beginning.length, beginning.length); compose_ui.autosize_textarea(textbox); }; - show_flatpickr(this.$element[0], on_timestamp_selection, timestamp); + flatpickr.show_flatpickr(this.$element[0], on_timestamp_selection, timestamp); return beginning + rest; } } diff --git a/static/js/flatpickr.js b/static/js/flatpickr.js new file mode 100644 index 0000000000..8b7b95e89e --- /dev/null +++ b/static/js/flatpickr.js @@ -0,0 +1,118 @@ +import {formatISO} from "date-fns"; +import ConfirmDatePlugin from "flatpickr/dist/plugins/confirmDate/confirmDate"; +import $ from "jquery"; + +import {get_keydown_hotkey} from "./hotkey"; +import {$t} from "./i18n"; + +function is_numeric_key(key) { + return ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"].includes(key); +} + +export function show_flatpickr(element, callback, default_timestamp, options = {}) { + const flatpickr_input = $(""); + + const instance = flatpickr_input.flatpickr({ + mode: "single", + enableTime: true, + clickOpens: false, + defaultDate: default_timestamp, + plugins: [ + new ConfirmDatePlugin({ + showAlways: true, + confirmText: $t({defaultMessage: "Confirm"}), + confirmIcon: "", + }), + ], + positionElement: element, + dateFormat: "Z", + formatDate: (date) => formatISO(date), + disableMobile: true, + onKeyDown: (selectedDates, dateStr, instance, event) => { + if (is_numeric_key(event.key)) { + // Don't attempt to get_keydown_hotkey for numeric inputs + // as it would return undefined. + return; + } + + const hotkey = get_keydown_hotkey(event); + + if (["tab", "shift_tab"].includes(hotkey.name)) { + const elems = [ + instance.selectedDateElem, + instance.hourElement, + instance.minuteElement, + instance.amPM, + $(".flatpickr-confirm")[0], + ]; + const i = elems.indexOf(event.target); + const n = elems.length; + const remain = (i + (event.shiftKey ? -1 : 1)) % n; + const target = elems[Math.floor(remain >= 0 ? remain : remain + n)]; + event.preventDefault(); + event.stopPropagation(); + target.focus(); + } + + event.stopPropagation(); + }, + ...options, + }); + + const container = $($(instance.innerContainer).parent()); + + container.on("keydown", (e) => { + if (is_numeric_key(e.key)) { + // Let users type numeric values + return true; + } + + const hotkey = get_keydown_hotkey(e); + + if (!hotkey) { + return false; + } + + if (hotkey.name === "backspace" || hotkey.name === "delete") { + // Let backspace or delete be handled normally + return true; + } + + if (hotkey.name === "enter") { + if (e.target.classList[0] === "flatpickr-day") { + return true; // use flatpickr default implementation + } + $(element).toggleClass("has_popover"); + container.find(".flatpickr-confirm").trigger("click"); + } + + if (hotkey.name === "escape") { + $(element).toggleClass("has_popover"); + instance.close(); + instance.destroy(); + } + + if (["tab", "shift_tab"].includes(hotkey.name)) { + return true; // use flatpickr default implementation + } + + if (["right_arrow", "up_arrow", "left_arrow", "down_arrow"].includes(hotkey.name)) { + return true; // use flatpickr default implementation + } + + e.stopPropagation(); + e.preventDefault(); + + return true; + }); + + container.on("click", ".flatpickr-confirm", () => { + callback(flatpickr_input.val()); + instance.close(); + instance.destroy(); + }); + instance.open(); + instance.selectedDateElem.focus(); + + return instance; +} \ No newline at end of file diff --git a/tools/test-js-with-node b/tools/test-js-with-node index c777d2d3e9..b2260bd1e2 100755 --- a/tools/test-js-with-node +++ b/tools/test-js-with-node @@ -81,6 +81,7 @@ EXEMPT_FILES = make_set( "static/js/emojisets.js", "static/js/favicon.js", "static/js/feedback_widget.js", + "static/js/flatpickr.js", "static/js/floating_recipient_bar.js", "static/js/gear_menu.js", "static/js/giphy.js",