chuijs 4.0.3 → 4.0.4
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.
- package/CHANGELOG.md +536 -0
- package/framework/appLayout/default/chui_app_layout.js +361 -303
- package/framework/appLayout/default/global_style.css +243 -89
- package/framework/appLayout/default/main_theme_style.css +188 -101
- package/framework/components/chui_accordion/accordion.js +17 -17
- package/framework/components/chui_accordion/styles.css +7 -7
- package/framework/components/chui_action_sheet/action_sheet.js +35 -32
- package/framework/components/chui_action_sheet/styles.css +10 -4
- package/framework/components/chui_actions_bar/actions_bar.js +338 -0
- package/framework/components/chui_actions_bar/styles.css +139 -0
- package/framework/components/chui_affix/affix.js +4 -4
- package/framework/components/chui_affix/styles.css +5 -0
- package/framework/components/chui_alert/alert.js +11 -5
- package/framework/components/chui_alert/styles.css +7 -0
- package/framework/components/chui_avatar/avatar.js +13 -13
- package/framework/components/chui_avatar/styles.css +1 -1
- package/framework/components/chui_avatar_group/avatar_group.js +4 -4
- package/framework/components/chui_avatar_group/styles.css +1 -1
- package/framework/components/chui_backtop/backtop.js +25 -2
- package/framework/components/chui_backtop/styles.css +21 -0
- package/framework/components/chui_badge/badge.js +15 -15
- package/framework/components/chui_badge/styles.css +6 -6
- package/framework/components/chui_banner/banner.js +222 -0
- package/framework/components/chui_banner/styles.css +170 -0
- package/framework/components/chui_breadcrumb/styles.css +1 -1
- package/framework/components/chui_button/button.js +24 -28
- package/framework/components/chui_button/styles.css +5 -5
- package/framework/components/chui_calendar/calendar.js +6 -6
- package/framework/components/chui_card/card.js +14 -14
- package/framework/components/chui_card_scroll/card_scroll.js +169 -0
- package/framework/components/chui_card_scroll/styles.css +86 -0
- package/framework/components/chui_chat/chat.js +73 -51
- package/framework/components/chui_chat/styles.css +18 -7
- package/framework/components/chui_clipboard_history/clipboard_history.js +25 -20
- package/framework/components/chui_clipboard_history/styles.css +10 -8
- package/framework/components/chui_code/code.js +8 -8
- package/framework/components/chui_code/styles.css +2 -2
- package/framework/components/chui_code_editor/code_editor.js +26 -26
- package/framework/components/chui_code_editor/styles.css +3 -3
- package/framework/components/chui_command_palette/command_palette.js +29 -29
- package/framework/components/chui_command_palette/styles.css +5 -5
- package/framework/components/chui_console/console.js +9 -9
- package/framework/components/chui_console/styles.css +5 -2
- package/framework/components/chui_content_block/content_block.js +2 -2
- package/framework/components/chui_context_menu/context_menu.js +162 -54
- package/framework/components/chui_context_menu/styles.css +82 -8
- package/framework/components/chui_custom_element/custom_element.js +11 -11
- package/framework/components/chui_data_grid/data_grid.js +268 -268
- package/framework/components/chui_data_grid/styles.css +14 -14
- package/framework/components/chui_descriptions/styles.css +1 -1
- package/framework/components/chui_details/details.js +12 -12
- package/framework/components/chui_details/styles.css +7 -7
- package/framework/components/chui_diff_viewer/diff_viewer.js +88 -88
- package/framework/components/chui_diff_viewer/styles.css +9 -9
- package/framework/components/chui_divider/divider.js +6 -6
- package/framework/components/chui_divider/styles.css +2 -2
- package/framework/components/chui_drawer/drawer.js +37 -14
- package/framework/components/chui_drawer/styles.css +18 -4
- package/framework/components/chui_drop_zone/drop_zone.js +6 -6
- package/framework/components/chui_drop_zone/styles.css +10 -6
- package/framework/components/chui_fieldset/fieldset.js +6 -6
- package/framework/components/chui_fieldset/styles.css +5 -5
- package/framework/components/chui_file_explorer/file_explorer.js +115 -115
- package/framework/components/chui_file_explorer/styles.css +6 -6
- package/framework/components/chui_form/form.js +11 -11
- package/framework/components/chui_gantt/gantt.js +41 -41
- package/framework/components/chui_gantt/styles.css +5 -5
- package/framework/components/chui_graphs/graphs.js +82 -46
- package/framework/components/chui_graphs/styles.css +26 -5
- package/framework/components/chui_hero/hero.js +63 -20
- package/framework/components/chui_hero/styles.css +176 -7
- package/framework/components/chui_html_block/html_block.js +5 -5
- package/framework/components/chui_html_block/styles.css +1 -1
- package/framework/components/chui_hx/styles.css +2 -2
- package/framework/components/chui_icons/icons.js +7 -7
- package/framework/components/chui_icons/styles.css +2 -1
- package/framework/components/chui_inputs/chui_check_box/styles.css +12 -3
- package/framework/components/chui_inputs/chui_chips/chips.js +92 -31
- package/framework/components/chui_inputs/chui_chips/styles.css +28 -5
- package/framework/components/chui_inputs/chui_color_picker/color_picker.js +20 -15
- package/framework/components/chui_inputs/chui_color_picker/styles.css +7 -7
- package/framework/components/chui_inputs/chui_combo_box/combo_box.js +58 -58
- package/framework/components/chui_inputs/chui_combo_box/styles.css +9 -9
- package/framework/components/chui_inputs/chui_date/date.js +93 -95
- package/framework/components/chui_inputs/chui_date/styles.css +8 -8
- package/framework/components/chui_inputs/chui_date_range/date_range.js +22 -22
- package/framework/components/chui_inputs/chui_date_range/styles.css +3 -3
- package/framework/components/chui_inputs/chui_datetime/datetime.js +12 -12
- package/framework/components/chui_inputs/chui_datetime/styles.css +3 -3
- package/framework/components/chui_inputs/chui_email/email.js +10 -10
- package/framework/components/chui_inputs/chui_email/styles.css +6 -6
- package/framework/components/chui_inputs/chui_file/file.js +8 -8
- package/framework/components/chui_inputs/chui_file/styles.css +12 -9
- package/framework/components/chui_inputs/chui_hotkey/hotkey.js +39 -39
- package/framework/components/chui_inputs/chui_hotkey/styles.css +6 -6
- package/framework/components/chui_inputs/chui_masked/masked.js +44 -44
- package/framework/components/chui_inputs/chui_masked/styles.css +5 -5
- package/framework/components/chui_inputs/chui_mention/mention.js +13 -13
- package/framework/components/chui_inputs/chui_mention/styles.css +14 -8
- package/framework/components/chui_inputs/chui_multi_combo_box/multi_combo_box.js +147 -137
- package/framework/components/chui_inputs/chui_multi_combo_box/styles.css +14 -8
- package/framework/components/chui_inputs/chui_number/number.js +42 -45
- package/framework/components/chui_inputs/chui_number/styles.css +6 -6
- package/framework/components/chui_inputs/chui_otp/otp.js +32 -32
- package/framework/components/chui_inputs/chui_otp/styles.css +5 -5
- package/framework/components/chui_inputs/chui_password/password.js +30 -36
- package/framework/components/chui_inputs/chui_password/styles.css +7 -7
- package/framework/components/chui_inputs/chui_radio_button/styles.css +2 -2
- package/framework/components/chui_inputs/chui_rating/rating.js +28 -28
- package/framework/components/chui_inputs/chui_rating/styles.css +3 -3
- package/framework/components/chui_inputs/chui_select_box/select_box.js +54 -54
- package/framework/components/chui_inputs/chui_select_box/styles.css +10 -10
- package/framework/components/chui_inputs/chui_slider/slider.js +14 -14
- package/framework/components/chui_inputs/chui_slider/styles.css +5 -4
- package/framework/components/chui_inputs/chui_text/styles.css +7 -7
- package/framework/components/chui_inputs/chui_text/text.js +13 -17
- package/framework/components/chui_inputs/chui_text_area/styles.css +8 -8
- package/framework/components/chui_inputs/chui_text_area/text_area.js +23 -23
- package/framework/components/chui_inputs/chui_time/styles.css +13 -17
- package/framework/components/chui_inputs/chui_time/time.js +35 -24
- package/framework/components/chui_inputs/chui_toggle/styles.css +10 -3
- package/framework/components/chui_inputs/chui_toggle/toggle.js +16 -16
- package/framework/components/chui_json_editor/json_editor.js +87 -87
- package/framework/components/chui_json_editor/styles.css +5 -5
- package/framework/components/chui_json_viewer/json_viewer.js +80 -80
- package/framework/components/chui_json_viewer/styles.css +6 -6
- package/framework/components/chui_kanban/kanban.js +27 -27
- package/framework/components/chui_kanban/styles.css +8 -4
- package/framework/components/chui_kbd/styles.css +1 -1
- package/framework/components/chui_label/label.js +17 -17
- package/framework/components/chui_label/styles.css +1 -1
- package/framework/components/chui_link/link.js +9 -9
- package/framework/components/chui_link/styles.css +11 -4
- package/framework/components/chui_list/list.js +11 -11
- package/framework/components/chui_list/styles.css +2 -2
- package/framework/components/chui_markdown_editor/markdown_editor.js +66 -66
- package/framework/components/chui_markdown_editor/styles.css +5 -5
- package/framework/components/chui_media/audio.js +240 -246
- package/framework/components/chui_media/audio_styles.css +41 -23
- package/framework/components/chui_media/image.js +49 -46
- package/framework/components/chui_media/image_compare.js +35 -35
- package/framework/components/chui_media/image_compare_styles.css +5 -5
- package/framework/components/chui_media/image_styles.css +1 -1
- package/framework/components/chui_media/video.js +148 -148
- package/framework/components/chui_media/video_styles.css +27 -11
- package/framework/components/chui_menu_bar/menu_bar.js +54 -54
- package/framework/components/chui_menu_bar/styles.css +10 -10
- package/framework/components/chui_message_bar/message_bar.js +551 -0
- package/framework/components/chui_message_bar/styles.css +248 -0
- package/framework/components/chui_modal/modal.js +37 -13
- package/framework/components/chui_notification/notification.js +76 -54
- package/framework/components/chui_notification/notification_download.js +26 -81
- package/framework/components/chui_notification/notification_download_card.js +115 -0
- package/framework/components/chui_notification/notification_download_progress.css +2 -2
- package/framework/components/chui_notification/notification_download_progress.js +70 -108
- package/framework/components/chui_notification/notification_update.js +31 -31
- package/framework/components/chui_notification/status_plate.css +3 -3
- package/framework/components/chui_notification/styles.css +6 -1
- package/framework/components/chui_notification/styles_download.css +1 -1
- package/framework/components/chui_notification/styles_update.css +2 -2
- package/framework/components/chui_org_chart/org_chart.js +29 -29
- package/framework/components/chui_org_chart/styles.css +2 -2
- package/framework/components/chui_pagination/pagination.js +3 -3
- package/framework/components/chui_pagination/styles.css +1 -1
- package/framework/components/chui_paragraph/styles.css +2 -2
- package/framework/components/chui_popover/popover.js +29 -23
- package/framework/components/chui_popover/styles.css +1 -1
- package/framework/components/chui_popups/popups.js +124 -124
- package/framework/components/chui_popups/styles.css +5 -5
- package/framework/components/chui_print_button/print_button.js +15 -10
- package/framework/components/chui_progress_bar/progress_bar.js +34 -12
- package/framework/components/chui_progress_bar/styles.css +4 -4
- package/framework/components/chui_progress_ring/progress_ring.js +15 -15
- package/framework/components/chui_progress_ring/styles.css +1 -1
- package/framework/components/chui_qrcode/qrcode.js +12 -12
- package/framework/components/chui_query_builder/query_builder.js +46 -46
- package/framework/components/chui_query_builder/styles.css +4 -4
- package/framework/components/chui_radio_group/styles.css +1 -1
- package/framework/components/chui_result/result.js +15 -15
- package/framework/components/chui_result/styles.css +3 -3
- package/framework/components/chui_scheduler/scheduler.js +74 -74
- package/framework/components/chui_scheduler/styles.css +5 -5
- package/framework/components/chui_screen_spinner/screen_spinner.js +167 -0
- package/framework/components/chui_screen_spinner/styles.css +49 -0
- package/framework/components/chui_segmented_control/segmented_control.js +63 -6
- package/framework/components/chui_segmented_control/styles.css +32 -6
- package/framework/components/chui_settings/settings.js +45 -46
- package/framework/components/chui_settings/styles.css +4 -4
- package/framework/components/chui_shortcut_help/shortcut_help.js +32 -34
- package/framework/components/chui_sidebar_nav/sidebar_nav.js +98 -29
- package/framework/components/chui_sidebar_nav/styles.css +9 -3
- package/framework/components/chui_slideshow/slideshow.js +85 -85
- package/framework/components/chui_slideshow/styles.css +6 -6
- package/framework/components/chui_spinner/spinner.js +10 -10
- package/framework/components/chui_split_button/split_button.js +30 -12
- package/framework/components/chui_split_button/styles.css +21 -5
- package/framework/components/chui_splitter/splitter.js +11 -11
- package/framework/components/chui_splitter/styles.css +2 -2
- package/framework/components/chui_statistic/statistic.js +47 -47
- package/framework/components/chui_status_bar/styles.css +2 -2
- package/framework/components/chui_stepper/stepper.js +202 -31
- package/framework/components/chui_stepper/styles.css +79 -14
- package/framework/components/chui_sticky_bar/sticky_bar.js +44 -13
- package/framework/components/chui_sticky_bar/styles.css +10 -8
- package/framework/components/chui_tabs/chui_tabs.js +74 -26
- package/framework/components/chui_tabs/styles.css +40 -12
- package/framework/components/chui_text_editor/styles.css +7 -7
- package/framework/components/chui_text_editor/text_editor.js +56 -56
- package/framework/components/chui_text_editor/text_editor_panel.js +173 -174
- package/framework/components/chui_theme_toggle/theme_toggle.js +21 -5
- package/framework/components/chui_timeline/styles.css +3 -1
- package/framework/components/chui_toast_queue/styles.css +11 -11
- package/framework/components/chui_toast_queue/toast_queue.js +30 -27
- package/framework/components/chui_toolbar/styles.css +2 -2
- package/framework/components/chui_tooltip/styles.css +2 -2
- package/framework/components/chui_tooltip/tooltip.js +3 -3
- package/framework/components/chui_tour/styles.css +8 -8
- package/framework/components/chui_tour/tour.js +72 -72
- package/framework/components/chui_transfer/styles.css +6 -6
- package/framework/components/chui_transfer/transfer.js +93 -106
- package/framework/components/chui_tree_table/styles.css +4 -4
- package/framework/components/chui_tree_table/tree_table.js +45 -45
- package/framework/components/chui_tree_view/styles.css +10 -8
- package/framework/components/chui_tree_view/tree_view.js +185 -183
- package/framework/components/chui_user_bar/styles.css +145 -0
- package/framework/components/chui_user_bar/user_bar.js +402 -0
- package/framework/components/chui_user_list_bar/styles.css +173 -0
- package/framework/components/chui_user_list_bar/user_list_bar.js +485 -0
- package/framework/components/chui_watermark/watermark.js +17 -17
- package/framework/components/chui_webview/webview.js +9 -9
- package/framework/components/chui_write_bar/styles.css +172 -0
- package/framework/components/chui_write_bar/write_bar.js +320 -0
- package/framework/main_window.js +1234 -0
- package/framework/modules/chui_a11y/chui_a11y.js +78 -79
- package/framework/modules/chui_animations/animations.js +77 -15
- package/framework/modules/chui_animations/motion.js +120 -0
- package/framework/modules/chui_animations/styles.css +36 -3
- package/framework/modules/chui_functions.js +31 -27
- package/framework/modules/chui_highlight/styles.css +13 -10
- package/framework/modules/chui_i18n/chui_i18n.js +3 -3
- package/framework/modules/chui_i18n/locales/feedback.js +62 -0
- package/framework/modules/chui_i18n/locales/navigation.js +4 -0
- package/framework/modules/chui_json/chui_json.js +2 -2
- package/framework/modules/chui_logger/chui_logger.js +23 -8
- package/framework/modules/chui_page/page.js +10 -10
- package/framework/modules/chui_palette/palette.js +61 -0
- package/framework/modules/chui_qr/chui_qr.js +23 -23
- package/framework/modules/chui_scrollbar/chui_scrollbar.js +45 -45
- package/framework/modules/chui_scrollbar/styles.css +3 -3
- package/framework/modules/chui_services/chui_services.js +8 -8
- package/framework/modules/chui_services/desktop.js +77 -71
- package/framework/modules/chui_sortable/chui_sortable.js +17 -17
- package/framework/modules/chui_validate/chui_validate.js +3 -3
- package/framework/tray_bar/chui_menu_items.js +2 -2
- package/index.d.ts +266 -34
- package/index.js +20 -1168
- package/package.json +6 -4
- package/framework/components/telegram_bot/chui_telegram_bot.js +0 -191
|
@@ -13,24 +13,24 @@ const isDayNumber = (cell) => /^\d+$/.test(String(cell).trim());
|
|
|
13
13
|
|
|
14
14
|
class DateInput {
|
|
15
15
|
#id = require("randomstring").generate();
|
|
16
|
-
#
|
|
17
|
-
#
|
|
16
|
+
#chuiDateInput = document.createElement("chui_date_input");
|
|
17
|
+
#dateMainBlock = document.createElement("date_main_block");
|
|
18
18
|
#input = document.createElement("input");
|
|
19
19
|
#label = document.createElement("label");
|
|
20
|
-
#
|
|
21
|
-
#
|
|
20
|
+
#dateDropdownOpen = document.createElement("date_dropdown_open");
|
|
21
|
+
#dateDropdownOpenDisabled = document.createElement("date_dropdown_open");
|
|
22
22
|
#dropdown = document.createElement("date_select_dropdown");
|
|
23
23
|
// Слушатель окна храним полем, чтобы можно было снять в destroy()
|
|
24
|
-
#
|
|
25
|
-
if (!this.#
|
|
24
|
+
#windowClickEvent = (event) => {
|
|
25
|
+
if (!this.#dateMainBlock.contains(event.target)) this.#closeDropdown();
|
|
26
26
|
};
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
27
|
+
#dropdownId = require("randomstring").generate();
|
|
28
|
+
#dateNow = new Date();
|
|
29
|
+
#dateMonthList = document.createElement("date_month_list");
|
|
30
|
+
#dateYearList = document.createElement("date_year_list");
|
|
31
|
+
#dateCalendarTitle = document.createElement("date_calendar_title");
|
|
32
|
+
#calendarYear = this.#dateNow.getFullYear();
|
|
33
|
+
#calendarMonth = this.#dateNow.getMonth();
|
|
34
34
|
// Экран календаря: месяцы (по умолчанию) или выбор года
|
|
35
35
|
#view = "months";
|
|
36
36
|
constructor(options = { name: String(), title: String(), required: Boolean() }) {
|
|
@@ -45,17 +45,17 @@ class DateInput {
|
|
|
45
45
|
Validate.installField(
|
|
46
46
|
this,
|
|
47
47
|
options,
|
|
48
|
-
this.#
|
|
48
|
+
this.#chuiDateInput,
|
|
49
49
|
undefined,
|
|
50
50
|
() => this.#input.value,
|
|
51
|
-
this.#
|
|
51
|
+
this.#dateMainBlock
|
|
52
52
|
);
|
|
53
|
-
this.#
|
|
53
|
+
this.#dateDropdownOpen.innerHTML = new Icon(
|
|
54
54
|
Icons.HARDWARE.KEYBOARD_ARROW_DOWN,
|
|
55
55
|
undefined,
|
|
56
56
|
"var(--blue_prime_background)"
|
|
57
57
|
).getHTML();
|
|
58
|
-
this.#
|
|
58
|
+
this.#dateDropdownOpenDisabled.innerHTML = new Icon(
|
|
59
59
|
Icons.HARDWARE.KEYBOARD_ARROW_DOWN,
|
|
60
60
|
undefined,
|
|
61
61
|
"var(--text_color_disabled)"
|
|
@@ -66,17 +66,17 @@ class DateInput {
|
|
|
66
66
|
this.#label.classList.add("date_input_label");
|
|
67
67
|
this.#label.innerText = options.title;
|
|
68
68
|
this.#label.setAttribute("for", this.#id);
|
|
69
|
-
this.#
|
|
69
|
+
this.#chuiDateInput.appendChild(this.#label);
|
|
70
70
|
}
|
|
71
71
|
// Рамку с кольцом при фокусе рисует общее правило темы (`date_main_block:hover`,
|
|
72
72
|
// `:focus-within`), а не компонент: прежде он ставил то же самое инлайном,
|
|
73
73
|
// а на `blur` снимал весь атрибут `style`
|
|
74
|
-
this.#dropdown.setAttribute("id", this.#
|
|
74
|
+
this.#dropdown.setAttribute("id", this.#dropdownId);
|
|
75
75
|
// Доступность: поле — combobox, календарь — диалог с состоянием раскрытия
|
|
76
76
|
this.#input.setAttribute("role", "combobox");
|
|
77
77
|
this.#input.setAttribute("aria-haspopup", "dialog");
|
|
78
78
|
this.#input.setAttribute("aria-expanded", "false");
|
|
79
|
-
this.#input.setAttribute("aria-controls", this.#
|
|
79
|
+
this.#input.setAttribute("aria-controls", this.#dropdownId);
|
|
80
80
|
this.#dropdown.setAttribute("role", "dialog");
|
|
81
81
|
this.#dropdown.setAttribute("aria-label", I18n.t("date.calendar"));
|
|
82
82
|
// Клавиатура календаря: стрелки по дням, Enter выбирает, Escape закрывает
|
|
@@ -84,7 +84,7 @@ class DateInput {
|
|
|
84
84
|
// Заголовок и список годов — свои кнопки: у них своя обработка Enter/Space
|
|
85
85
|
if (
|
|
86
86
|
event.target instanceof Element &&
|
|
87
|
-
(event.target === this.#
|
|
87
|
+
(event.target === this.#dateCalendarTitle || event.target.closest("date_year") !== null)
|
|
88
88
|
)
|
|
89
89
|
return;
|
|
90
90
|
const days = this.#visibleDays();
|
|
@@ -115,25 +115,25 @@ class DateInput {
|
|
|
115
115
|
if (next >= 0 && next < days.length) days[next].focus();
|
|
116
116
|
});
|
|
117
117
|
this.#dropdown.appendChild(this.#buildCalendarHeader());
|
|
118
|
-
this.#dropdown.appendChild(this.#
|
|
119
|
-
this.#dropdown.appendChild(this.#
|
|
120
|
-
this.#
|
|
121
|
-
this.#buildYear(this.#
|
|
122
|
-
this.#showMonth(this.#
|
|
118
|
+
this.#dropdown.appendChild(this.#dateMonthList);
|
|
119
|
+
this.#dropdown.appendChild(this.#dateYearList);
|
|
120
|
+
this.#dateYearList.hidden = true;
|
|
121
|
+
this.#buildYear(this.#calendarYear);
|
|
122
|
+
this.#showMonth(this.#calendarMonth);
|
|
123
123
|
//LISTENERS
|
|
124
|
-
this.#
|
|
124
|
+
this.#chuiDateInput.addEventListener("click", (event) => {
|
|
125
125
|
if (!this.#input.disabled) {
|
|
126
|
-
if (event.target.parentNode === this.#
|
|
126
|
+
if (event.target.parentNode === this.#dateMainBlock) {
|
|
127
127
|
this.#input.focus();
|
|
128
128
|
this.#openDropdown();
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
});
|
|
132
|
-
window.addEventListener("click", this.#
|
|
133
|
-
this.#
|
|
134
|
-
this.#
|
|
135
|
-
this.#
|
|
136
|
-
this.#
|
|
132
|
+
window.addEventListener("click", this.#windowClickEvent);
|
|
133
|
+
this.#dateMainBlock.appendChild(this.#input);
|
|
134
|
+
this.#dateMainBlock.appendChild(this.#dateDropdownOpen);
|
|
135
|
+
this.#dateMainBlock.appendChild(this.#dropdown);
|
|
136
|
+
this.#chuiDateInput.appendChild(this.#dateMainBlock);
|
|
137
137
|
}
|
|
138
138
|
#buildCalendarHeader() {
|
|
139
139
|
const header = document.createElement("date_calendar_header");
|
|
@@ -158,16 +158,16 @@ class DateInput {
|
|
|
158
158
|
});
|
|
159
159
|
makeKeyboardButton(next);
|
|
160
160
|
// Заголовок — кнопка: по нажатию открывается выбор года (см. #showYears)
|
|
161
|
-
this.#
|
|
162
|
-
this.#
|
|
163
|
-
this.#
|
|
164
|
-
this.#
|
|
161
|
+
this.#dateCalendarTitle.id = this.#id + "_title";
|
|
162
|
+
this.#dateCalendarTitle.setAttribute("title", I18n.t("date.selectYear"));
|
|
163
|
+
this.#dateCalendarTitle.setAttribute("aria-label", I18n.t("date.selectYear"));
|
|
164
|
+
this.#dateCalendarTitle.addEventListener("click", (event) => {
|
|
165
165
|
event.stopPropagation();
|
|
166
166
|
this.#toggleView();
|
|
167
167
|
});
|
|
168
|
-
makeKeyboardButton(this.#
|
|
168
|
+
makeKeyboardButton(this.#dateCalendarTitle);
|
|
169
169
|
header.appendChild(previous);
|
|
170
|
-
header.appendChild(this.#
|
|
170
|
+
header.appendChild(this.#dateCalendarTitle);
|
|
171
171
|
header.appendChild(next);
|
|
172
172
|
return header;
|
|
173
173
|
}
|
|
@@ -182,35 +182,35 @@ class DateInput {
|
|
|
182
182
|
#showYears() {
|
|
183
183
|
this.#view = "years";
|
|
184
184
|
this.#buildYears();
|
|
185
|
-
this.#
|
|
186
|
-
this.#
|
|
187
|
-
const current = this.#yearButton(this.#
|
|
185
|
+
this.#dateMonthList.hidden = true;
|
|
186
|
+
this.#dateYearList.hidden = false;
|
|
187
|
+
const current = this.#yearButton(this.#calendarYear);
|
|
188
188
|
if (current !== null) current.focus();
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
#showMonths() {
|
|
192
192
|
this.#view = "months";
|
|
193
|
-
this.#
|
|
194
|
-
this.#
|
|
195
|
-
this.#showMonth(this.#
|
|
193
|
+
this.#dateYearList.hidden = true;
|
|
194
|
+
this.#dateMonthList.hidden = false;
|
|
195
|
+
this.#showMonth(this.#calendarMonth);
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
#yearPageStart() {
|
|
199
|
-
return Math.floor(this.#
|
|
199
|
+
return Math.floor(this.#calendarYear / YEARS_PER_PAGE) * YEARS_PER_PAGE;
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
#yearButton(year) {
|
|
203
|
-
return [...this.#
|
|
203
|
+
return [...this.#dateYearList.children].find((item) => item.innerText === String(year)) || null;
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
#buildYears() {
|
|
207
207
|
const start = this.#yearPageStart();
|
|
208
|
-
this.#
|
|
208
|
+
this.#dateYearList.innerHTML = "";
|
|
209
209
|
for (let index = 0; index < YEARS_PER_PAGE; index++) {
|
|
210
210
|
const year = start + index;
|
|
211
211
|
const item = document.createElement("date_year");
|
|
212
212
|
item.innerText = String(year);
|
|
213
|
-
if (year === this.#
|
|
213
|
+
if (year === this.#calendarYear) item.classList.add("date_year_current");
|
|
214
214
|
item.addEventListener("click", (event) => {
|
|
215
215
|
event.stopPropagation();
|
|
216
216
|
this.#selectYear(year);
|
|
@@ -218,16 +218,16 @@ class DateInput {
|
|
|
218
218
|
makeKeyboardButton(item);
|
|
219
219
|
// Годы доступны с клавиатуры, но не растягивают общий порядок обхода
|
|
220
220
|
item.setAttribute("tabindex", "-1");
|
|
221
|
-
this.#
|
|
221
|
+
this.#dateYearList.appendChild(item);
|
|
222
222
|
}
|
|
223
|
-
this.#
|
|
223
|
+
this.#dateCalendarTitle.innerText = `${start}—${start + YEARS_PER_PAGE - 1}`;
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
#selectYear(year) {
|
|
227
|
-
this.#
|
|
227
|
+
this.#calendarYear = year;
|
|
228
228
|
this.#buildYear(year);
|
|
229
229
|
this.#showMonths();
|
|
230
|
-
this.#
|
|
230
|
+
this.#dateCalendarTitle.focus();
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
// Стрелки: в месяцах — соседний месяц, в списке годов — соседняя страница
|
|
@@ -242,31 +242,31 @@ class DateInput {
|
|
|
242
242
|
}
|
|
243
243
|
|
|
244
244
|
#goToYearPage(delta) {
|
|
245
|
-
this.#
|
|
245
|
+
this.#calendarYear += delta * YEARS_PER_PAGE;
|
|
246
246
|
// Календарь перестраиваем сразу: выбранный год и список остаются согласованными
|
|
247
|
-
this.#buildYear(this.#
|
|
247
|
+
this.#buildYear(this.#calendarYear);
|
|
248
248
|
this.#buildYears();
|
|
249
249
|
}
|
|
250
250
|
#buildYear(year) {
|
|
251
|
-
this.#
|
|
251
|
+
this.#dateMonthList.innerHTML = "";
|
|
252
252
|
for (let i = 0; i < MONTHS_IN_YEAR; i++) {
|
|
253
253
|
const cal = new Calendar(year, i + 1);
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
for (
|
|
259
|
-
const
|
|
254
|
+
const dateMonthMain = document.createElement("date_month_main");
|
|
255
|
+
dateMonthMain.setAttribute("month-name", cal.getMonthName());
|
|
256
|
+
dateMonthMain.setAttribute("month-index", String(cal.getMonth()));
|
|
257
|
+
dateMonthMain.style.width = "fit-content";
|
|
258
|
+
for (const row of cal.getCalendar()) {
|
|
259
|
+
const dateWeek = document.createElement("date_week");
|
|
260
260
|
let index = 0;
|
|
261
|
-
for (
|
|
262
|
-
const
|
|
261
|
+
for (const cell of row) {
|
|
262
|
+
const dateDay = document.createElement("date_day");
|
|
263
263
|
if (cell !== undefined) {
|
|
264
|
-
|
|
264
|
+
dateDay.innerText = cell;
|
|
265
265
|
if (isDayNumber(cell)) {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
266
|
+
dateDay.classList = "date_day";
|
|
267
|
+
dateDay.setAttribute("tabindex", "-1");
|
|
268
|
+
dateDay.setAttribute("role", "button");
|
|
269
|
+
dateDay.addEventListener("click", () => {
|
|
270
270
|
const selected = new Date(cal.getYear(), cal.getMonth(), Number(cell));
|
|
271
271
|
this.#input.value = formatLocalDate(selected);
|
|
272
272
|
// Выбор в календаре — такое же изменение значения, как правка в поле:
|
|
@@ -279,18 +279,18 @@ class DateInput {
|
|
|
279
279
|
} else {
|
|
280
280
|
index++;
|
|
281
281
|
}
|
|
282
|
-
|
|
282
|
+
dateWeek.appendChild(dateDay);
|
|
283
283
|
}
|
|
284
284
|
if (index !== 7) {
|
|
285
|
-
|
|
285
|
+
dateMonthMain.appendChild(dateWeek);
|
|
286
286
|
}
|
|
287
287
|
}
|
|
288
|
-
this.#
|
|
288
|
+
this.#dateMonthList.appendChild(dateMonthMain);
|
|
289
289
|
}
|
|
290
290
|
}
|
|
291
291
|
// Открытие дропдауна: показ, направление и высота по свободному месту рядом с полем
|
|
292
292
|
#openDropdown() {
|
|
293
|
-
new Animation(this.#dropdown).
|
|
293
|
+
new Animation(this.#dropdown).panelIn();
|
|
294
294
|
this.#placeDropdown();
|
|
295
295
|
this.#input.setAttribute("aria-expanded", "true");
|
|
296
296
|
}
|
|
@@ -300,7 +300,7 @@ class DateInput {
|
|
|
300
300
|
* уходит в прокрутку самого календаря.
|
|
301
301
|
*/
|
|
302
302
|
#placeDropdown() {
|
|
303
|
-
const placement = dropdownPlacement(this.#dropdown, this.#
|
|
303
|
+
const placement = dropdownPlacement(this.#dropdown, this.#dateMainBlock);
|
|
304
304
|
this.#dropdown.style.top = placement.up ? "auto" : "-2px";
|
|
305
305
|
this.#dropdown.style.bottom = placement.up ? "-2px" : "auto";
|
|
306
306
|
if (placement.maxHeight > 0) this.#dropdown.style.maxHeight = `${placement.maxHeight}px`;
|
|
@@ -313,31 +313,29 @@ class DateInput {
|
|
|
313
313
|
}
|
|
314
314
|
/** Полное удаление: снять слушатели окна */
|
|
315
315
|
destroy() {
|
|
316
|
-
window.removeEventListener("click", this.#
|
|
316
|
+
window.removeEventListener("click", this.#windowClickEvent);
|
|
317
317
|
this.#closeDropdown();
|
|
318
318
|
}
|
|
319
319
|
// Дни текущего видимого месяца (по ним ходят стрелки)
|
|
320
320
|
#visibleDays() {
|
|
321
|
-
const month = this.#
|
|
322
|
-
'date_month_main[month-index="' + this.#calendar_month + '"]'
|
|
323
|
-
);
|
|
321
|
+
const month = this.#dateMonthList.querySelector('date_month_main[month-index="' + this.#calendarMonth + '"]');
|
|
324
322
|
if (month === null) return [];
|
|
325
323
|
return [...month.querySelectorAll("date_day")].filter((day) => day.classList.contains("date_day"));
|
|
326
324
|
}
|
|
327
325
|
#showMonth(index) {
|
|
328
|
-
this.#
|
|
329
|
-
const months = this.#
|
|
330
|
-
for (
|
|
326
|
+
this.#calendarMonth = index;
|
|
327
|
+
const months = this.#dateMonthList.querySelectorAll("date_month_main");
|
|
328
|
+
for (const month of months) {
|
|
331
329
|
month.style.display = Number(month.getAttribute("month-index")) === index ? "block" : "none";
|
|
332
330
|
}
|
|
333
|
-
this.#
|
|
334
|
-
new Date(this.#
|
|
331
|
+
this.#dateCalendarTitle.innerText =
|
|
332
|
+
new Date(this.#calendarYear, index).toLocaleString(I18n.getLocale(), { month: "long" }).toUpperCase() +
|
|
335
333
|
" " +
|
|
336
|
-
this.#
|
|
334
|
+
this.#calendarYear;
|
|
337
335
|
}
|
|
338
336
|
#goToMonth(delta) {
|
|
339
|
-
let month = this.#
|
|
340
|
-
let year = this.#
|
|
337
|
+
let month = this.#calendarMonth + delta;
|
|
338
|
+
let year = this.#calendarYear;
|
|
341
339
|
if (month < 0) {
|
|
342
340
|
month = MONTHS_IN_YEAR - 1;
|
|
343
341
|
year--;
|
|
@@ -345,8 +343,8 @@ class DateInput {
|
|
|
345
343
|
month = 0;
|
|
346
344
|
year++;
|
|
347
345
|
}
|
|
348
|
-
if (year !== this.#
|
|
349
|
-
this.#
|
|
346
|
+
if (year !== this.#calendarYear) {
|
|
347
|
+
this.#calendarYear = year;
|
|
350
348
|
this.#buildYear(year);
|
|
351
349
|
}
|
|
352
350
|
this.#showMonth(month);
|
|
@@ -366,21 +364,21 @@ class DateInput {
|
|
|
366
364
|
setDisabled(boolean = Boolean()) {
|
|
367
365
|
this.#input.disabled = boolean;
|
|
368
366
|
if (boolean) {
|
|
369
|
-
this.#
|
|
367
|
+
this.#dateMainBlock.classList.add("date_main_block_disabled");
|
|
370
368
|
this.#input.className = "date_input_disabled";
|
|
371
369
|
this.#label.className = "date_input_label_disabled";
|
|
372
|
-
this.#
|
|
373
|
-
this.#
|
|
370
|
+
this.#dateDropdownOpen.remove();
|
|
371
|
+
this.#dateMainBlock.appendChild(this.#dateDropdownOpenDisabled);
|
|
374
372
|
} else {
|
|
375
|
-
this.#
|
|
373
|
+
this.#dateMainBlock.classList.remove("date_main_block_disabled");
|
|
376
374
|
this.#input.className = "date_input";
|
|
377
375
|
this.#label.className = "date_input_label";
|
|
378
|
-
this.#
|
|
379
|
-
this.#
|
|
376
|
+
this.#dateDropdownOpenDisabled.remove();
|
|
377
|
+
this.#dateMainBlock.appendChild(this.#dateDropdownOpen);
|
|
380
378
|
}
|
|
381
379
|
}
|
|
382
380
|
set() {
|
|
383
|
-
return this.#
|
|
381
|
+
return this.#chuiDateInput;
|
|
384
382
|
}
|
|
385
383
|
}
|
|
386
384
|
|
|
@@ -4,12 +4,12 @@ chui_date_input {
|
|
|
4
4
|
карточку. Токены переопределены у корня поля, поэтому действуют только внутри него
|
|
5
5
|
(тот же приём у полосы меню-бара). */
|
|
6
6
|
--control_padding: var(--control_padding_sm);
|
|
7
|
-
--
|
|
7
|
+
--block_padding: var(--block_padding_sm);
|
|
8
8
|
display: flex;
|
|
9
9
|
flex-direction: column;
|
|
10
10
|
width: max-content;
|
|
11
11
|
height: max-content;
|
|
12
|
-
margin: var(--
|
|
12
|
+
margin: var(--block_margin);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
/* Нативные части поля даты: индикатор календаря не нужен (календарь свой, значок — тоже),
|
|
@@ -33,7 +33,7 @@ date_select_dropdown {
|
|
|
33
33
|
backdrop-filter: var(--global_blur);
|
|
34
34
|
-webkit-backdrop-filter: var(--global_blur);
|
|
35
35
|
border: 1px solid var(--border_color);
|
|
36
|
-
border-radius: var(--
|
|
36
|
+
border-radius: var(--radius_sm);
|
|
37
37
|
position: absolute;
|
|
38
38
|
top: -2px;
|
|
39
39
|
inset-inline-start: -2px;
|
|
@@ -111,7 +111,7 @@ date_year {
|
|
|
111
111
|
cursor: pointer;
|
|
112
112
|
text-align: center;
|
|
113
113
|
padding: 7px 4px;
|
|
114
|
-
border-radius: var(--
|
|
114
|
+
border-radius: var(--radius_sm);
|
|
115
115
|
color: var(--text_color);
|
|
116
116
|
user-select: none;
|
|
117
117
|
}
|
|
@@ -135,7 +135,7 @@ date_day {
|
|
|
135
135
|
cursor: pointer;
|
|
136
136
|
display: block;
|
|
137
137
|
width: 20px;
|
|
138
|
-
border-radius: var(--
|
|
138
|
+
border-radius: var(--radius_sm);
|
|
139
139
|
padding: var(--control_padding);
|
|
140
140
|
text-align: center;
|
|
141
141
|
}
|
|
@@ -170,7 +170,7 @@ date_main_block {
|
|
|
170
170
|
box-sizing: border-box;
|
|
171
171
|
width: max-content;
|
|
172
172
|
height: var(--control_height);
|
|
173
|
-
border-radius: var(--
|
|
173
|
+
border-radius: var(--radius_sm);
|
|
174
174
|
font-size: var(--font_default_size);
|
|
175
175
|
color: var(--text_color);
|
|
176
176
|
position: relative;
|
|
@@ -195,7 +195,7 @@ date_main_block {
|
|
|
195
195
|
.date_input_label {
|
|
196
196
|
height: max-content;
|
|
197
197
|
width: max-content;
|
|
198
|
-
margin: 0 0 var(--
|
|
198
|
+
margin: 0 0 var(--block_margin);
|
|
199
199
|
font-size: var(--font_labels_size);
|
|
200
200
|
font-weight: 500;
|
|
201
201
|
color: var(--text_color);
|
|
@@ -213,7 +213,7 @@ date_main_block {
|
|
|
213
213
|
color: var(--text_color_disabled);
|
|
214
214
|
height: max-content;
|
|
215
215
|
width: max-content;
|
|
216
|
-
margin: 0 0 var(--
|
|
216
|
+
margin: 0 0 var(--block_margin);
|
|
217
217
|
font-size: var(--font_labels_size);
|
|
218
218
|
font-weight: 500;
|
|
219
219
|
}
|
|
@@ -47,12 +47,12 @@ class DateRangeInput {
|
|
|
47
47
|
#end = undefined;
|
|
48
48
|
#id = undefined;
|
|
49
49
|
#name = undefined;
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
#
|
|
50
|
+
#titleText = undefined;
|
|
51
|
+
#labelText = undefined;
|
|
52
|
+
#orderingMessage = undefined;
|
|
53
53
|
#disabled = false;
|
|
54
54
|
#listeners = [];
|
|
55
|
-
#
|
|
55
|
+
#onChange = undefined;
|
|
56
56
|
|
|
57
57
|
constructor(
|
|
58
58
|
options = {
|
|
@@ -73,13 +73,13 @@ class DateRangeInput {
|
|
|
73
73
|
DateRangeInput.#counter += 1;
|
|
74
74
|
this.#id = options.id === undefined ? `chui_date_range_input_${DateRangeInput.#counter}` : options.id;
|
|
75
75
|
this.#name = options.name;
|
|
76
|
-
this.#
|
|
77
|
-
this.#
|
|
76
|
+
this.#labelText = options.label;
|
|
77
|
+
this.#onChange = options.onChange;
|
|
78
78
|
if (options.changeListener !== undefined) this.addChangeListener(options.changeListener);
|
|
79
79
|
if (options.messages !== undefined && options.messages.validate !== undefined)
|
|
80
|
-
this.#
|
|
80
|
+
this.#orderingMessage = String(options.messages.validate);
|
|
81
81
|
// Общий текст берётся из словаря: своё сообщение поля важнее перевода
|
|
82
|
-
if (this.#
|
|
82
|
+
if (this.#orderingMessage === undefined) this.#orderingMessage = I18n.t("dateRange.wrongOrder");
|
|
83
83
|
this.#root.id = this.#id;
|
|
84
84
|
this.#label.className = "date_range_label";
|
|
85
85
|
this.#row.className = "date_range_row";
|
|
@@ -121,13 +121,13 @@ class DateRangeInput {
|
|
|
121
121
|
delete rules.min;
|
|
122
122
|
delete rules.max;
|
|
123
123
|
if (rules.pattern === undefined) rules.pattern = RANGE_PATTERN;
|
|
124
|
-
const
|
|
124
|
+
const ownValidate = options.validate;
|
|
125
125
|
rules.validate = (value) => {
|
|
126
|
-
const custom =
|
|
126
|
+
const custom = ownValidate === undefined ? undefined : ownValidate(value);
|
|
127
127
|
if (custom !== undefined && custom !== null && custom !== true) return custom;
|
|
128
128
|
const [start, end] = String(value).split("..");
|
|
129
129
|
if (start === undefined || end === undefined || start === "" || end === "") return undefined;
|
|
130
|
-
if (end < start) return this.#
|
|
130
|
+
if (end < start) return this.#orderingMessage;
|
|
131
131
|
return undefined;
|
|
132
132
|
};
|
|
133
133
|
Validate.installField(this, rules, this.#root, undefined, () => this.#rawValue(), this.#row);
|
|
@@ -145,12 +145,12 @@ class DateRangeInput {
|
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
getTitle() {
|
|
148
|
-
return this.#
|
|
148
|
+
return this.#titleText;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
/** Доступное имя группы, заданное в `label` */
|
|
152
152
|
getLabel() {
|
|
153
|
-
return this.#
|
|
153
|
+
return this.#labelText;
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
/** Период: строки «ГГГГ-ММ-ДД», пустая строка — дата не выбрана */
|
|
@@ -195,7 +195,7 @@ class DateRangeInput {
|
|
|
195
195
|
|
|
196
196
|
/** Подпись над парой полей; `undefined` её убирает */
|
|
197
197
|
setTitle(text = undefined) {
|
|
198
|
-
this.#
|
|
198
|
+
this.#titleText = text;
|
|
199
199
|
if (text === undefined || text === "") {
|
|
200
200
|
this.#label.hidden = true;
|
|
201
201
|
this.#label.innerText = "";
|
|
@@ -208,7 +208,7 @@ class DateRangeInput {
|
|
|
208
208
|
|
|
209
209
|
/** Доступное имя группы; `undefined` убирает его */
|
|
210
210
|
setLabel(text = undefined) {
|
|
211
|
-
this.#
|
|
211
|
+
this.#labelText = text;
|
|
212
212
|
if (text === undefined) this.#row.removeAttribute("aria-label");
|
|
213
213
|
else this.#row.setAttribute("aria-label", String(text));
|
|
214
214
|
return this;
|
|
@@ -296,13 +296,13 @@ class DateRangeInput {
|
|
|
296
296
|
* так что перевёрнутый период не пройдёт проверку и без нативной границы.
|
|
297
297
|
*/
|
|
298
298
|
#syncLimits() {
|
|
299
|
-
const
|
|
300
|
-
const
|
|
301
|
-
if (
|
|
302
|
-
|
|
299
|
+
const startInput = this.#start.set().querySelector("input.date_input");
|
|
300
|
+
const endInput = this.#end.set().querySelector("input.date_input");
|
|
301
|
+
if (startInput === null || endInput === null) return;
|
|
302
|
+
startInput.removeAttribute("max");
|
|
303
303
|
const value = this.getValue();
|
|
304
|
-
if (value.start === "")
|
|
305
|
-
else
|
|
304
|
+
if (value.start === "") endInput.removeAttribute("min");
|
|
305
|
+
else endInput.min = value.start;
|
|
306
306
|
}
|
|
307
307
|
|
|
308
308
|
#changed() {
|
|
@@ -310,7 +310,7 @@ class DateRangeInput {
|
|
|
310
310
|
this.#status.innerText = this.getValueText();
|
|
311
311
|
const value = this.getValue();
|
|
312
312
|
for (const listener of [...this.#listeners]) listener(value, this);
|
|
313
|
-
if (this.#
|
|
313
|
+
if (this.#onChange !== undefined) this.#onChange(value, this);
|
|
314
314
|
}
|
|
315
315
|
|
|
316
316
|
static #parseDate(value = undefined) {
|
|
@@ -5,18 +5,18 @@ chui_date_range_input {
|
|
|
5
5
|
карточку. Токены переопределены у корня поля, поэтому действуют только внутри него
|
|
6
6
|
(тот же приём у полосы меню-бара). */
|
|
7
7
|
--control_padding: var(--control_padding_sm);
|
|
8
|
-
--
|
|
8
|
+
--block_padding: var(--block_padding_sm);
|
|
9
9
|
display: flex;
|
|
10
10
|
flex-direction: column;
|
|
11
11
|
width: max-content;
|
|
12
12
|
height: max-content;
|
|
13
|
-
margin: var(--
|
|
13
|
+
margin: var(--block_margin);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
.date_range_label {
|
|
17
17
|
display: block;
|
|
18
18
|
width: max-content;
|
|
19
|
-
margin: 0 0 var(--
|
|
19
|
+
margin: 0 0 var(--block_margin);
|
|
20
20
|
color: var(--text_color);
|
|
21
21
|
font-size: var(--font_labels_size);
|
|
22
22
|
font-weight: 500;
|