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
|
@@ -45,11 +45,11 @@ class Scheduler {
|
|
|
45
45
|
|
|
46
46
|
#root = document.createElement("chui_scheduler");
|
|
47
47
|
#title = document.createElement("scheduler_title");
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
#
|
|
48
|
+
#prevButton = document.createElement("button");
|
|
49
|
+
#nextButton = document.createElement("button");
|
|
50
|
+
#todayButton = document.createElement("button");
|
|
51
|
+
#viewButtons = new Map();
|
|
52
|
+
#daysHead = document.createElement("scheduler_days_head");
|
|
53
53
|
#scroll = document.createElement("scheduler_scroll");
|
|
54
54
|
#times = document.createElement("scheduler_times");
|
|
55
55
|
#days = document.createElement("scheduler_days");
|
|
@@ -57,15 +57,15 @@ class Scheduler {
|
|
|
57
57
|
#date = new Date();
|
|
58
58
|
#view = Scheduler.VIEW.WEEK;
|
|
59
59
|
#events = [];
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
#
|
|
63
|
-
#
|
|
64
|
-
#
|
|
60
|
+
#startHour = 8;
|
|
61
|
+
#endHour = 20;
|
|
62
|
+
#slotMinutes = Scheduler.DEFAULT_SLOT_MINUTES;
|
|
63
|
+
#hourHeight = Scheduler.DEFAULT_HOUR_HEIGHT;
|
|
64
|
+
#firstDay = Scheduler.DEFAULT_FIRST_DAY;
|
|
65
65
|
#label = undefined;
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
#
|
|
66
|
+
#onEventClick = undefined;
|
|
67
|
+
#onSlotClick = undefined;
|
|
68
|
+
#onPeriodChangeCallback = undefined;
|
|
69
69
|
|
|
70
70
|
constructor(
|
|
71
71
|
options = {
|
|
@@ -95,18 +95,18 @@ class Scheduler {
|
|
|
95
95
|
// вид, которого сетка не рисует
|
|
96
96
|
this.#view = options.view === Scheduler.VIEW.DAY ? Scheduler.VIEW.DAY : Scheduler.VIEW.WEEK;
|
|
97
97
|
this.#events = Array.isArray(options.events) ? [...options.events] : [];
|
|
98
|
-
this.#
|
|
99
|
-
this.#
|
|
100
|
-
this.#
|
|
101
|
-
this.#
|
|
102
|
-
this.#
|
|
103
|
-
this.#
|
|
104
|
-
this.#
|
|
105
|
-
this.#
|
|
98
|
+
this.#startHour = options.startHour === undefined ? this.#startHour : options.startHour;
|
|
99
|
+
this.#endHour = options.endHour === undefined ? this.#endHour : options.endHour;
|
|
100
|
+
this.#slotMinutes = options.slotMinutes === undefined ? this.#slotMinutes : options.slotMinutes;
|
|
101
|
+
this.#hourHeight = options.hourHeight === undefined ? this.#hourHeight : options.hourHeight;
|
|
102
|
+
this.#firstDay = options.firstDay === undefined ? this.#firstDay : options.firstDay;
|
|
103
|
+
this.#onEventClick = options.onEventClick;
|
|
104
|
+
this.#onSlotClick = options.onSlotClick;
|
|
105
|
+
this.#onPeriodChangeCallback = options.onPeriodChange;
|
|
106
106
|
this.setLabel(optionOr(options.label, I18n.t("scheduler.title")));
|
|
107
107
|
if (options.height !== undefined) this.setHeight(options.height);
|
|
108
108
|
this.#buildHead();
|
|
109
|
-
this.#root.appendChild(this.#
|
|
109
|
+
this.#root.appendChild(this.#daysHead);
|
|
110
110
|
this.#scroll.appendChild(this.#times);
|
|
111
111
|
this.#scroll.appendChild(this.#days);
|
|
112
112
|
this.#root.appendChild(this.#scroll);
|
|
@@ -139,15 +139,15 @@ class Scheduler {
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
getStartHour() {
|
|
142
|
-
return this.#
|
|
142
|
+
return this.#startHour;
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
getEndHour() {
|
|
146
|
-
return this.#
|
|
146
|
+
return this.#endHour;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
getSlotMinutes() {
|
|
150
|
-
return this.#
|
|
150
|
+
return this.#slotMinutes;
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
/** События, попавшие на день (с учётом пересечения полуночи) */
|
|
@@ -266,7 +266,7 @@ class Scheduler {
|
|
|
266
266
|
#startOfPeriod() {
|
|
267
267
|
const day = Scheduler.#startOfDay(this.#date);
|
|
268
268
|
if (this.#view === Scheduler.VIEW.DAY) return day;
|
|
269
|
-
const offset = (day.getDay() - this.#
|
|
269
|
+
const offset = (day.getDay() - this.#firstDay + 7) % 7;
|
|
270
270
|
day.setDate(day.getDate() - offset);
|
|
271
271
|
return day;
|
|
272
272
|
}
|
|
@@ -305,13 +305,13 @@ class Scheduler {
|
|
|
305
305
|
*/
|
|
306
306
|
#layout(date = new Date()) {
|
|
307
307
|
const dayStart = this.#startOfDayMinutes();
|
|
308
|
-
const dayEnd = this.#
|
|
308
|
+
const dayEnd = this.#endHour * 60;
|
|
309
309
|
const items = [];
|
|
310
310
|
for (const event of this.#events) {
|
|
311
311
|
if (!this.#overlapsDay(event, date)) continue;
|
|
312
312
|
const start = Scheduler.#eventDate(event, "start");
|
|
313
313
|
const end = Scheduler.#eventDate(event, "end");
|
|
314
|
-
const finished = Number.isNaN(end.getTime()) ? new Date(start.getTime() + this.#
|
|
314
|
+
const finished = Number.isNaN(end.getTime()) ? new Date(start.getTime() + this.#slotMinutes * 60000) : end;
|
|
315
315
|
const sameStartDay = Scheduler.#sameDay(Scheduler.#startOfDay(start), date);
|
|
316
316
|
const sameEndDay = Scheduler.#sameDay(Scheduler.#startOfDay(finished), date);
|
|
317
317
|
let from = sameStartDay ? Scheduler.#minutesOf(start) : 0;
|
|
@@ -320,7 +320,7 @@ class Scheduler {
|
|
|
320
320
|
from = 0;
|
|
321
321
|
to = 24 * 60;
|
|
322
322
|
}
|
|
323
|
-
if (to <= from) to = from + this.#
|
|
323
|
+
if (to <= from) to = from + this.#slotMinutes;
|
|
324
324
|
from = Math.max(from, dayStart);
|
|
325
325
|
to = Math.min(to, dayEnd);
|
|
326
326
|
if (to <= from) continue;
|
|
@@ -329,7 +329,7 @@ class Scheduler {
|
|
|
329
329
|
items.sort((left, right) => left.start - right.start || left.end - right.end);
|
|
330
330
|
// Кластеры пересекающихся событий и дорожки внутри них
|
|
331
331
|
let cluster = [];
|
|
332
|
-
let
|
|
332
|
+
let clusterEnd = -1;
|
|
333
333
|
const flush = () => {
|
|
334
334
|
if (cluster.length === 0) return;
|
|
335
335
|
const lanes = [];
|
|
@@ -345,38 +345,38 @@ class Scheduler {
|
|
|
345
345
|
}
|
|
346
346
|
for (const item of cluster) item.lanes = lanes.length;
|
|
347
347
|
cluster = [];
|
|
348
|
-
|
|
348
|
+
clusterEnd = -1;
|
|
349
349
|
};
|
|
350
350
|
for (const item of items) {
|
|
351
|
-
if (cluster.length > 0 && item.start >=
|
|
351
|
+
if (cluster.length > 0 && item.start >= clusterEnd) flush();
|
|
352
352
|
cluster.push(item);
|
|
353
|
-
|
|
353
|
+
clusterEnd = Math.max(clusterEnd, item.end);
|
|
354
354
|
}
|
|
355
355
|
flush();
|
|
356
356
|
return items;
|
|
357
357
|
}
|
|
358
358
|
|
|
359
359
|
#startOfDayMinutes() {
|
|
360
|
-
return this.#
|
|
360
|
+
return this.#startHour * 60;
|
|
361
361
|
}
|
|
362
362
|
|
|
363
363
|
// === РЕНДЕР ===
|
|
364
364
|
#buildHead() {
|
|
365
365
|
const head = document.createElement("scheduler_head");
|
|
366
|
-
this.#
|
|
367
|
-
this.#
|
|
368
|
-
this.#
|
|
369
|
-
this.#
|
|
370
|
-
this.#
|
|
371
|
-
this.#
|
|
372
|
-
this.#
|
|
373
|
-
this.#
|
|
374
|
-
this.#
|
|
375
|
-
this.#
|
|
376
|
-
this.#
|
|
377
|
-
this.#
|
|
378
|
-
this.#
|
|
379
|
-
this.#
|
|
366
|
+
this.#prevButton.type = "button";
|
|
367
|
+
this.#nextButton.type = "button";
|
|
368
|
+
this.#todayButton.type = "button";
|
|
369
|
+
this.#prevButton.className = "scheduler_nav";
|
|
370
|
+
this.#nextButton.className = "scheduler_nav";
|
|
371
|
+
this.#todayButton.className = "scheduler_today";
|
|
372
|
+
this.#prevButton.dataset.action = "prev";
|
|
373
|
+
this.#nextButton.dataset.action = "next";
|
|
374
|
+
this.#todayButton.dataset.action = "today";
|
|
375
|
+
this.#prevButton.innerText = "‹";
|
|
376
|
+
this.#nextButton.innerText = "›";
|
|
377
|
+
this.#todayButton.innerText = I18n.t("scheduler.today");
|
|
378
|
+
this.#prevButton.setAttribute("aria-label", I18n.t("scheduler.previousPeriod"));
|
|
379
|
+
this.#nextButton.setAttribute("aria-label", I18n.t("scheduler.nextPeriod"));
|
|
380
380
|
this.#title.setAttribute("aria-live", "polite");
|
|
381
381
|
const views = document.createElement("scheduler_views");
|
|
382
382
|
views.setAttribute("role", "group");
|
|
@@ -391,11 +391,11 @@ class Scheduler {
|
|
|
391
391
|
button.dataset.view = view;
|
|
392
392
|
button.innerText = label;
|
|
393
393
|
views.appendChild(button);
|
|
394
|
-
this.#
|
|
394
|
+
this.#viewButtons.set(view, button);
|
|
395
395
|
}
|
|
396
|
-
head.appendChild(this.#
|
|
397
|
-
head.appendChild(this.#
|
|
398
|
-
head.appendChild(this.#
|
|
396
|
+
head.appendChild(this.#prevButton);
|
|
397
|
+
head.appendChild(this.#nextButton);
|
|
398
|
+
head.appendChild(this.#todayButton);
|
|
399
399
|
head.appendChild(this.#title);
|
|
400
400
|
head.appendChild(views);
|
|
401
401
|
this.#root.appendChild(head);
|
|
@@ -405,25 +405,25 @@ class Scheduler {
|
|
|
405
405
|
const days = this.#dayDates();
|
|
406
406
|
const today = new Date();
|
|
407
407
|
this.#title.innerText = this.#periodTitle(days);
|
|
408
|
-
for (const [view, button] of this.#
|
|
408
|
+
for (const [view, button] of this.#viewButtons)
|
|
409
409
|
button.setAttribute("aria-pressed", view === this.#view ? "true" : "false");
|
|
410
|
-
this.#
|
|
410
|
+
this.#prevButton.setAttribute(
|
|
411
411
|
"aria-label",
|
|
412
412
|
this.#view === Scheduler.VIEW.DAY ? I18n.t("scheduler.previousDay") : I18n.t("scheduler.previousWeek")
|
|
413
413
|
);
|
|
414
|
-
this.#
|
|
414
|
+
this.#nextButton.setAttribute(
|
|
415
415
|
"aria-label",
|
|
416
416
|
this.#view === Scheduler.VIEW.DAY ? I18n.t("scheduler.nextDay") : I18n.t("scheduler.nextWeek")
|
|
417
417
|
);
|
|
418
418
|
// Заголовки дней лежат вне области прокрутки и повторяют колонки сетки; ширина
|
|
419
419
|
// вертикальной полосы прокрутки компенсируется, иначе заголовки уехали бы вправо
|
|
420
420
|
const scrollbar = Math.max(0, this.#scroll.offsetWidth - this.#scroll.clientWidth);
|
|
421
|
-
this.#
|
|
422
|
-
this.#
|
|
423
|
-
this.#
|
|
421
|
+
this.#daysHead.style.paddingRight = `${scrollbar}px`;
|
|
422
|
+
this.#daysHead.innerHTML = "";
|
|
423
|
+
this.#daysHead.style.gridTemplateColumns = `56px repeat(${days.length}, minmax(0, 1fr))`;
|
|
424
424
|
const corner = document.createElement("scheduler_corner");
|
|
425
425
|
corner.setAttribute("aria-hidden", "true");
|
|
426
|
-
this.#
|
|
426
|
+
this.#daysHead.appendChild(corner);
|
|
427
427
|
for (const day of days) {
|
|
428
428
|
const head = document.createElement("scheduler_day_head");
|
|
429
429
|
if (Scheduler.#sameDay(day, today)) head.classList.add("scheduler_today_head");
|
|
@@ -433,7 +433,7 @@ class Scheduler {
|
|
|
433
433
|
number.innerText = String(day.getDate());
|
|
434
434
|
head.appendChild(name);
|
|
435
435
|
head.appendChild(number);
|
|
436
|
-
this.#
|
|
436
|
+
this.#daysHead.appendChild(head);
|
|
437
437
|
}
|
|
438
438
|
this.#renderTimes();
|
|
439
439
|
this.#renderDays(days, today);
|
|
@@ -441,9 +441,9 @@ class Scheduler {
|
|
|
441
441
|
|
|
442
442
|
#renderTimes() {
|
|
443
443
|
this.#times.innerHTML = "";
|
|
444
|
-
for (let hour = this.#
|
|
444
|
+
for (let hour = this.#startHour; hour < this.#endHour; hour++) {
|
|
445
445
|
const cell = document.createElement("scheduler_hour");
|
|
446
|
-
cell.style.height = `${this.#
|
|
446
|
+
cell.style.height = `${this.#hourHeight}px`;
|
|
447
447
|
cell.innerText = `${String(hour).padStart(2, "0")}:00`;
|
|
448
448
|
this.#times.appendChild(cell);
|
|
449
449
|
}
|
|
@@ -455,10 +455,10 @@ class Scheduler {
|
|
|
455
455
|
for (const day of days) {
|
|
456
456
|
const column = document.createElement("scheduler_day");
|
|
457
457
|
column.dataset.day = Scheduler.#key(day);
|
|
458
|
-
column.style.height = `${(this.#
|
|
458
|
+
column.style.height = `${(this.#endHour - this.#startHour) * this.#hourHeight}px`;
|
|
459
459
|
if (Scheduler.#sameDay(day, today)) column.classList.add("scheduler_today");
|
|
460
460
|
// Часовые линии рисует фон: узлы на каждый час не нужны
|
|
461
|
-
column.style.backgroundSize = `100% ${this.#
|
|
461
|
+
column.style.backgroundSize = `100% ${this.#hourHeight}px`;
|
|
462
462
|
for (const item of this.#layout(day)) column.appendChild(this.#createEvent(item, day));
|
|
463
463
|
this.#days.appendChild(column);
|
|
464
464
|
}
|
|
@@ -470,8 +470,8 @@ class Scheduler {
|
|
|
470
470
|
|
|
471
471
|
#createEvent(item = Object(), day = new Date()) {
|
|
472
472
|
const event = item.event;
|
|
473
|
-
const top = ((item.start - this.#startOfDayMinutes()) / 60) * this.#
|
|
474
|
-
const height = Math.max(18, ((item.end - item.start) / 60) * this.#
|
|
473
|
+
const top = ((item.start - this.#startOfDayMinutes()) / 60) * this.#hourHeight;
|
|
474
|
+
const height = Math.max(18, ((item.end - item.start) / 60) * this.#hourHeight);
|
|
475
475
|
const lanes = Math.max(1, item.lanes);
|
|
476
476
|
const width = 100 / lanes;
|
|
477
477
|
const node = document.createElement("button");
|
|
@@ -544,19 +544,19 @@ class Scheduler {
|
|
|
544
544
|
const eventNode = target.closest(".scheduler_event");
|
|
545
545
|
if (eventNode !== null) {
|
|
546
546
|
const found = this.#events[Number(eventNode.dataset.index)];
|
|
547
|
-
if (this.#
|
|
548
|
-
this.#
|
|
547
|
+
if (this.#onEventClick !== undefined)
|
|
548
|
+
this.#onEventClick(found === undefined ? undefined : found, eventNode);
|
|
549
549
|
return;
|
|
550
550
|
}
|
|
551
551
|
const dayNode = target.closest("scheduler_day");
|
|
552
552
|
if (dayNode !== null) {
|
|
553
553
|
const column = dayNode.getBoundingClientRect();
|
|
554
554
|
const offset = Math.max(0, Math.min(event.clientY - column.top, column.height));
|
|
555
|
-
const raw = this.#startOfDayMinutes() + (offset / this.#
|
|
556
|
-
const minutes = Math.round(raw / this.#
|
|
555
|
+
const raw = this.#startOfDayMinutes() + (offset / this.#hourHeight) * 60;
|
|
556
|
+
const minutes = Math.round(raw / this.#slotMinutes) * this.#slotMinutes;
|
|
557
557
|
const date = this.#dayDates().find((day) => Scheduler.#key(day) === dayNode.dataset.day);
|
|
558
|
-
if (date !== undefined && this.#
|
|
559
|
-
this.#
|
|
558
|
+
if (date !== undefined && this.#onSlotClick !== undefined) {
|
|
559
|
+
this.#onSlotClick({ date: date, minutes: minutes, time: Scheduler.#timeText(minutes) });
|
|
560
560
|
}
|
|
561
561
|
}
|
|
562
562
|
};
|
|
@@ -579,9 +579,9 @@ class Scheduler {
|
|
|
579
579
|
};
|
|
580
580
|
|
|
581
581
|
#onPeriodChange() {
|
|
582
|
-
if (this.#
|
|
582
|
+
if (this.#onPeriodChangeCallback === undefined) return;
|
|
583
583
|
const range = this.getRange();
|
|
584
|
-
this.#
|
|
584
|
+
this.#onPeriodChangeCallback(range.from, range.to);
|
|
585
585
|
}
|
|
586
586
|
}
|
|
587
587
|
|
|
@@ -4,12 +4,12 @@ chui_scheduler {
|
|
|
4
4
|
flex-direction: column;
|
|
5
5
|
width: -webkit-fill-available;
|
|
6
6
|
box-sizing: border-box;
|
|
7
|
-
margin: var(--
|
|
7
|
+
margin: var(--block_margin);
|
|
8
8
|
color: var(--text_color);
|
|
9
9
|
font-size: var(--font_default_size);
|
|
10
10
|
background: var(--element_background_2);
|
|
11
11
|
border: 1px solid var(--border_color);
|
|
12
|
-
border-radius: var(--
|
|
12
|
+
border-radius: var(--radius_sm);
|
|
13
13
|
overflow: hidden;
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -17,7 +17,7 @@ scheduler_head {
|
|
|
17
17
|
display: flex;
|
|
18
18
|
align-items: center;
|
|
19
19
|
gap: 6px;
|
|
20
|
-
padding: var(--
|
|
20
|
+
padding: var(--block_padding);
|
|
21
21
|
border-bottom: 1px solid var(--border_color);
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -25,7 +25,7 @@ button.scheduler_nav,
|
|
|
25
25
|
button.scheduler_today,
|
|
26
26
|
button.scheduler_view {
|
|
27
27
|
border: none;
|
|
28
|
-
border-radius: var(--
|
|
28
|
+
border-radius: var(--radius_sm);
|
|
29
29
|
background: var(--element_background);
|
|
30
30
|
color: var(--text_color);
|
|
31
31
|
font-family: inherit;
|
|
@@ -157,7 +157,7 @@ button.scheduler_event {
|
|
|
157
157
|
overflow: hidden;
|
|
158
158
|
text-align: start;
|
|
159
159
|
border: none;
|
|
160
|
-
border-radius: var(--
|
|
160
|
+
border-radius: var(--radius_sm);
|
|
161
161
|
background: var(--blue_prime_background);
|
|
162
162
|
color: var(--text_color_hover);
|
|
163
163
|
font-family: inherit;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
const { Spinner } = require("../chui_spinner/spinner");
|
|
2
|
+
const { I18n } = require("../../modules/chui_i18n/chui_i18n");
|
|
3
|
+
const { setStyles, optionOr } = require("../../modules/chui_functions");
|
|
4
|
+
const { Animation } = require("../../modules/chui_animations/animations");
|
|
5
|
+
const { OverlayA11y } = require("../../modules/chui_a11y/chui_a11y");
|
|
6
|
+
const { tokenTime } = require("../../modules/chui_animations/motion");
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Экран занят: слой поверх всего окна с индикатором загрузки. Пока он открыт, до содержимого
|
|
10
|
+
* под ним не добраться — ни мышью, ни клавиатурой, ни скринридером.
|
|
11
|
+
*
|
|
12
|
+
* От `Spinner` отличается тем, что тот просто рисует индикатор в потоке, а этот занимает экран:
|
|
13
|
+
* слой встаёт в `body` (в карточке с `backdrop-filter` Chromium собирает такой узел отдельной
|
|
14
|
+
* поверхностью и рисует её под слоями из `body` — так уже теряли диалог), фокус удерживается
|
|
15
|
+
* внутри, а фон становится инертным. Роль слоя — `dialog` с именем загрузки, внутри объявляется
|
|
16
|
+
* `progressbar`; Escape слой не закрывает: это не сообщение, а признак занятости.
|
|
17
|
+
*
|
|
18
|
+
* Опции: `id`, `label` (подпись и имя для скринридера, по умолчанию «{loading}» из словаря),
|
|
19
|
+
* `delay` (мс до появления — против мигания на коротких операциях).
|
|
20
|
+
*
|
|
21
|
+
* Методы: `show()`, `hide()`, `isShown()`, `setLabel(text)`, `destroy()`, `set()`.
|
|
22
|
+
* Статические: `ScreenSpinner.show(options)` (создать и показать), `ScreenSpinner.hide()`,
|
|
23
|
+
* `ScreenSpinner.current`.
|
|
24
|
+
*
|
|
25
|
+
* ```javascript
|
|
26
|
+
* const busy = new ScreenSpinner({ delay: 200 });
|
|
27
|
+
* busy.show();
|
|
28
|
+
* await load();
|
|
29
|
+
* busy.hide();
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
class ScreenSpinner {
|
|
33
|
+
// На экране один такой слой: два спиннера наложились бы друг на друга
|
|
34
|
+
static #current = undefined;
|
|
35
|
+
|
|
36
|
+
#root = document.createElement("chui_screen_spinner");
|
|
37
|
+
#card = document.createElement("screen_spinner_card");
|
|
38
|
+
#labelNode = document.createElement("screen_spinner_label");
|
|
39
|
+
#spinner = undefined;
|
|
40
|
+
#a11y = undefined;
|
|
41
|
+
#delay = 0;
|
|
42
|
+
#timer = undefined;
|
|
43
|
+
#shown = false;
|
|
44
|
+
#removed = false;
|
|
45
|
+
|
|
46
|
+
constructor(options = {}) {
|
|
47
|
+
setStyles(__dirname + "/styles.css", "chUiJS_ScreenSpinner");
|
|
48
|
+
if (options.id !== undefined) this.#root.id = options.id;
|
|
49
|
+
const delay = Number(options.delay);
|
|
50
|
+
this.#delay = Number.isFinite(delay) && delay > 0 ? delay : 0;
|
|
51
|
+
this.#spinner = new Spinner();
|
|
52
|
+
this.#card.append(this.#spinner.set(), this.#labelNode);
|
|
53
|
+
this.#root.appendChild(this.#card);
|
|
54
|
+
this.#root.setAttribute("aria-busy", "true");
|
|
55
|
+
this.setLabel(optionOr(options.label, I18n.t("feedback.loading")));
|
|
56
|
+
this.#a11y = new OverlayA11y(this.#root, {
|
|
57
|
+
role: "dialog",
|
|
58
|
+
label: this.#labelNode.innerText,
|
|
59
|
+
// Escape здесь ничего не закрывает: занятость — не сообщение, которое можно отклонить
|
|
60
|
+
onEscape: () => {},
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
isShown() {
|
|
65
|
+
return this.#shown;
|
|
66
|
+
}
|
|
67
|
+
getLabel() {
|
|
68
|
+
return this.#labelNode.innerText;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
setLabel(text = String()) {
|
|
72
|
+
const value = String(text);
|
|
73
|
+
this.#labelNode.innerText = value;
|
|
74
|
+
// Подпись пуста — под ней и места не надо: индикатор говорит сам
|
|
75
|
+
this.#labelNode.hidden = value.trim() === "";
|
|
76
|
+
if (this.#a11y !== undefined) this.#a11y.setLabel(value.trim() === "" ? I18n.t("feedback.loading") : value);
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Показ: слой встаёт в `body` и объявляет себя слоем. Задержка нужна против мигания —
|
|
82
|
+
* короткая операция успевает закончиться раньше, чем слой появится, и экран не дрожит.
|
|
83
|
+
*/
|
|
84
|
+
show() {
|
|
85
|
+
if (this.#shown === true) return this;
|
|
86
|
+
this.#shown = true;
|
|
87
|
+
// Слой показывают заново: след уборки прошлого показа снимаем, иначе новый слой
|
|
88
|
+
// не уберётся по концу кадра (`finish` посчитал бы работу сделанной)
|
|
89
|
+
this.#removed = false;
|
|
90
|
+
if (ScreenSpinner.#current !== undefined && ScreenSpinner.#current !== this) ScreenSpinner.#current.hide();
|
|
91
|
+
ScreenSpinner.#current = this;
|
|
92
|
+
const reveal = () => {
|
|
93
|
+
this.#timer = undefined;
|
|
94
|
+
if (this.#shown === false) return;
|
|
95
|
+
if (document.body.contains(this.#root) === false) document.body.appendChild(this.#root);
|
|
96
|
+
new Animation(this.#root).fadeIn();
|
|
97
|
+
new Animation(this.#card).panelIn();
|
|
98
|
+
this.#a11y.open();
|
|
99
|
+
this.#focusIn();
|
|
100
|
+
};
|
|
101
|
+
if (this.#delay > 0) this.#timer = setTimeout(reveal, this.#delay);
|
|
102
|
+
else reveal();
|
|
103
|
+
return this;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Уход: слой гаснет, узел убирается по концу кадра. Слушатель одноразовый (проверка цели) —
|
|
108
|
+
* иначе он поймал бы любой конец кадра на слое, а срок из токена страхует случай, когда
|
|
109
|
+
* кадр не проиграется вовсе (слой скрыт вместе с родителем).
|
|
110
|
+
*/
|
|
111
|
+
hide() {
|
|
112
|
+
if (this.#shown === false) return this;
|
|
113
|
+
this.#shown = false;
|
|
114
|
+
if (this.#timer !== undefined) {
|
|
115
|
+
clearTimeout(this.#timer);
|
|
116
|
+
this.#timer = undefined;
|
|
117
|
+
}
|
|
118
|
+
if (ScreenSpinner.#current === this) ScreenSpinner.#current = undefined;
|
|
119
|
+
// Слой ещё не успел появиться (сработала задержка) — убирать нечего
|
|
120
|
+
if (this.#root.parentElement === null) return this;
|
|
121
|
+
this.#a11y.close();
|
|
122
|
+
new Animation(this.#root).fadeOut();
|
|
123
|
+
new Animation(this.#card).fadeOut();
|
|
124
|
+
const finish = () => {
|
|
125
|
+
if (this.#removed === true) return;
|
|
126
|
+
this.#removed = true;
|
|
127
|
+
this.#root.removeEventListener("animationend", finish);
|
|
128
|
+
this.#root.remove();
|
|
129
|
+
};
|
|
130
|
+
this.#root.addEventListener("animationend", finish);
|
|
131
|
+
setTimeout(finish, tokenTime("--motion_fast"));
|
|
132
|
+
return this;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
set() {
|
|
136
|
+
return this.#root;
|
|
137
|
+
}
|
|
138
|
+
/** Полное удаление: снять слой (вместе с инертным фоном и слушателями) и убрать узел */
|
|
139
|
+
destroy() {
|
|
140
|
+
this.hide();
|
|
141
|
+
this.#removed = true;
|
|
142
|
+
this.#root.remove();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// === СТАТИЧЕСКОЕ ===
|
|
146
|
+
/** Показать спиннер, не заводя переменную: `ScreenSpinner.show({ label: "Сохраняем" })` */
|
|
147
|
+
static show(options = {}) {
|
|
148
|
+
const spinner = new ScreenSpinner(options);
|
|
149
|
+
spinner.show();
|
|
150
|
+
return spinner;
|
|
151
|
+
}
|
|
152
|
+
static hide() {
|
|
153
|
+
if (ScreenSpinner.#current !== undefined) ScreenSpinner.#current.hide();
|
|
154
|
+
}
|
|
155
|
+
static get current() {
|
|
156
|
+
return ScreenSpinner.#current;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// === ВНУТРЕННЕЕ ===
|
|
160
|
+
/** Фокус — в слой: иначе он остался бы на кнопке под ним, и Tab уходил бы в фон */
|
|
161
|
+
#focusIn() {
|
|
162
|
+
this.#root.setAttribute("tabindex", "-1");
|
|
163
|
+
this.#root.focus({ preventScroll: true });
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
exports.ScreenSpinner = ScreenSpinner;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/* Экран занят: слой поверх окна с индикатором загрузки.
|
|
2
|
+
Занавес держит сам слой (он и есть затемнение), а материал карточки — размытие: у слоя
|
|
3
|
+
`backdrop-filter` нет, иначе карточка внутри не увидела бы страницу (элемент с фильтром
|
|
4
|
+
становится собственным «backdrop root»). */
|
|
5
|
+
|
|
6
|
+
chui_screen_spinner {
|
|
7
|
+
position: fixed;
|
|
8
|
+
inset: 0;
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
justify-content: center;
|
|
12
|
+
box-sizing: border-box;
|
|
13
|
+
/* Выше модальных слоёв (у диалога 1000, у занавеса 999): занятость перекрывает всё */
|
|
14
|
+
z-index: 1100;
|
|
15
|
+
background: var(--modal_scrim);
|
|
16
|
+
/* Слой принимает на себя мышь и клавиатуру: под ним ничего не нажать */
|
|
17
|
+
cursor: progress;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
chui_screen_spinner:focus-visible {
|
|
21
|
+
outline: none;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
screen_spinner_card {
|
|
25
|
+
display: flex;
|
|
26
|
+
flex-direction: column;
|
|
27
|
+
align-items: center;
|
|
28
|
+
gap: 10px;
|
|
29
|
+
box-sizing: border-box;
|
|
30
|
+
padding: 18px 22px;
|
|
31
|
+
border: 1px solid var(--border_color);
|
|
32
|
+
border-radius: var(--radius_md);
|
|
33
|
+
background: var(--modal_background);
|
|
34
|
+
backdrop-filter: var(--global_blur);
|
|
35
|
+
-webkit-backdrop-filter: var(--global_blur);
|
|
36
|
+
box-shadow: var(--box_shadow_modal);
|
|
37
|
+
color: var(--text_color);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
screen_spinner_label {
|
|
41
|
+
font-size: var(--font_labels_size);
|
|
42
|
+
color: var(--text_color_disabled);
|
|
43
|
+
text-align: center;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Подписи нет — под неё не остаётся и зазора */
|
|
47
|
+
screen_spinner_label[hidden] {
|
|
48
|
+
display: none;
|
|
49
|
+
}
|