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
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/* ── ActionsBar — панель действий ───────────────────────────────
|
|
2
|
+
Что можно сделать с тем, о чём сейчас речь: подпись и ряд кнопок со значками.
|
|
3
|
+
Панель не полагает, о чём действия: в переписке она встаёт под шапкой разговора,
|
|
4
|
+
в карточке — над содержимым, и в обоих случаях разделяется волосяной линией снизу. */
|
|
5
|
+
|
|
6
|
+
chui_actions_bar {
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
gap: var(--control_padding_sm);
|
|
10
|
+
box-sizing: border-box;
|
|
11
|
+
width: -webkit-fill-available;
|
|
12
|
+
padding: var(--control_padding) var(--block_padding);
|
|
13
|
+
background: var(--element_background_2);
|
|
14
|
+
border-bottom: 1px solid var(--border_color);
|
|
15
|
+
font-size: var(--font_labels_size);
|
|
16
|
+
color: var(--text_color);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
actions_bar_title {
|
|
20
|
+
display: block;
|
|
21
|
+
font-weight: 500;
|
|
22
|
+
color: var(--text_color_disabled);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
actions_bar_title[hidden] {
|
|
26
|
+
display: none;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* Полоса действий внутри панели своей кромки не рисует: панель и полоса — одна поверхность,
|
|
30
|
+
и вложенная ступень поверхности здесь была бы лишней. Кнопки переносятся по строкам:
|
|
31
|
+
в узкой колонке длинный ряд не ломает раскладку */
|
|
32
|
+
chui_actions_bar chui_toolbar {
|
|
33
|
+
display: flex;
|
|
34
|
+
flex-direction: row;
|
|
35
|
+
flex-wrap: wrap;
|
|
36
|
+
gap: 4px;
|
|
37
|
+
padding: 0;
|
|
38
|
+
background: transparent;
|
|
39
|
+
border: none;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Столбец — вид меню: действия идут друг под другом во всю ширину, как пункты списка */
|
|
43
|
+
chui_actions_bar[data-orientation="vertical"] chui_toolbar {
|
|
44
|
+
flex-direction: column;
|
|
45
|
+
flex-wrap: nowrap;
|
|
46
|
+
gap: 2px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* Кнопка действия: значок и подпись, одна мера с остальными контролами семьи */
|
|
50
|
+
.actions_bar_button {
|
|
51
|
+
display: flex;
|
|
52
|
+
flex-direction: row;
|
|
53
|
+
align-items: center;
|
|
54
|
+
gap: 6px;
|
|
55
|
+
box-sizing: border-box;
|
|
56
|
+
min-height: var(--control_height);
|
|
57
|
+
padding: var(--control_padding_sm) 10px;
|
|
58
|
+
border: none;
|
|
59
|
+
border-radius: var(--radius_sm);
|
|
60
|
+
background: transparent;
|
|
61
|
+
color: var(--text_color);
|
|
62
|
+
font-family: inherit;
|
|
63
|
+
font-size: var(--font_labels_size);
|
|
64
|
+
cursor: pointer;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.actions_bar_button:hover {
|
|
68
|
+
background: var(--element_background_hover);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* Нажатие — заливка контрола, как у кнопок панели ввода */
|
|
72
|
+
.actions_bar_button:active:not(:disabled) {
|
|
73
|
+
background: var(--element_background);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* Включённый переключатель: «закреплено», «без звука» — состояние видно подложкой */
|
|
77
|
+
.actions_bar_button[data-active="true"] {
|
|
78
|
+
background: var(--blue_prime_background_tint);
|
|
79
|
+
color: var(--blue_prime_background);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.actions_bar_button[data-danger="true"] {
|
|
83
|
+
color: var(--red_prime_background);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* Пункт меню: подпись слева, счётчик у правого края */
|
|
87
|
+
chui_actions_bar[data-orientation="vertical"] .actions_bar_button {
|
|
88
|
+
width: -webkit-fill-available;
|
|
89
|
+
justify-content: flex-start;
|
|
90
|
+
text-align: start;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
chui_actions_bar[data-orientation="vertical"] .actions_bar_button_text {
|
|
94
|
+
flex: 1 1 auto;
|
|
95
|
+
overflow: hidden;
|
|
96
|
+
text-overflow: ellipsis;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.actions_bar_button:disabled {
|
|
100
|
+
cursor: not-allowed;
|
|
101
|
+
background: transparent;
|
|
102
|
+
color: var(--text_color_disabled);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.actions_bar_button_icon {
|
|
106
|
+
display: flex;
|
|
107
|
+
align-items: center;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* Значка нет — узел не занимает зазор строки */
|
|
111
|
+
.actions_bar_button_icon:empty {
|
|
112
|
+
display: none;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.actions_bar_button chui_icon {
|
|
116
|
+
color: inherit;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.actions_bar_button_text {
|
|
120
|
+
white-space: nowrap;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* Счётчик действия: число показывает плашка, скринридеру оно попадает в имя */
|
|
124
|
+
actions_bar_badge {
|
|
125
|
+
box-sizing: border-box;
|
|
126
|
+
min-width: 16px;
|
|
127
|
+
padding-inline: 4px;
|
|
128
|
+
border-radius: var(--radius_pill);
|
|
129
|
+
background: var(--red_prime_background);
|
|
130
|
+
color: var(--text_color_hover);
|
|
131
|
+
font-size: 10px;
|
|
132
|
+
font-weight: 600;
|
|
133
|
+
line-height: 16px;
|
|
134
|
+
text-align: center;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
actions_bar_badge[hidden] {
|
|
138
|
+
display: none;
|
|
139
|
+
}
|
|
@@ -42,7 +42,7 @@ class Affix {
|
|
|
42
42
|
#observer = undefined;
|
|
43
43
|
#pending = undefined;
|
|
44
44
|
#destroyed = false;
|
|
45
|
-
#
|
|
45
|
+
#onChange = undefined;
|
|
46
46
|
|
|
47
47
|
constructor(
|
|
48
48
|
options = {
|
|
@@ -63,7 +63,7 @@ class Affix {
|
|
|
63
63
|
this.#root.appendChild(this.#body);
|
|
64
64
|
this.#root.appendChild(this.#content);
|
|
65
65
|
this.#target = options.target;
|
|
66
|
-
this.#
|
|
66
|
+
this.#onChange = options.onChange;
|
|
67
67
|
this.setOffset(options.offset === undefined ? 0 : options.offset);
|
|
68
68
|
this.#observe();
|
|
69
69
|
}
|
|
@@ -123,7 +123,7 @@ class Affix {
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
setOnChange(listener = undefined) {
|
|
126
|
-
this.#
|
|
126
|
+
this.#onChange = listener;
|
|
127
127
|
return this;
|
|
128
128
|
}
|
|
129
129
|
|
|
@@ -228,7 +228,7 @@ class Affix {
|
|
|
228
228
|
this.#fixed = fixed;
|
|
229
229
|
this.#root.dataset.fixed = fixed ? "true" : "false";
|
|
230
230
|
this.#root.classList.toggle("affix_fixed", fixed);
|
|
231
|
-
if (typeof this.#
|
|
231
|
+
if (typeof this.#onChange === "function") this.#onChange(fixed, this);
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
234
|
|
|
@@ -23,6 +23,11 @@ affix_body {
|
|
|
23
23
|
inset-block-start: var(--affix_offset);
|
|
24
24
|
z-index: 5;
|
|
25
25
|
box-sizing: border-box;
|
|
26
|
+
/* Закрепление включает радиус и тень сразу: если тень гаснет плавно, а радиус щёлкает,
|
|
27
|
+
переход читается рваным. Свой список потому и перечисляет оба свойства */
|
|
28
|
+
transition:
|
|
29
|
+
border-radius var(--motion_fast) var(--motion_ease),
|
|
30
|
+
box-shadow var(--motion_fast) var(--motion_ease);
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
affix_content {
|
|
@@ -48,7 +48,7 @@ class Alert {
|
|
|
48
48
|
#id = undefined;
|
|
49
49
|
#style = Alert.STYLE.INFO;
|
|
50
50
|
#dismissed = false;
|
|
51
|
-
#
|
|
51
|
+
#customIcon = false;
|
|
52
52
|
|
|
53
53
|
constructor(
|
|
54
54
|
options = {
|
|
@@ -127,7 +127,7 @@ class Alert {
|
|
|
127
127
|
this.#root.setAttribute("aria-live", assertive ? "assertive" : "polite");
|
|
128
128
|
// Цвет и глиф плашки выбирает общий помощник семьи — по ключу стиля (`alert_error` → `error`).
|
|
129
129
|
// Своя иконка (`setIcon`) важнее статусного глифа и остаётся собой
|
|
130
|
-
if (this.#
|
|
130
|
+
if (this.#customIcon === false)
|
|
131
131
|
setStatusPlate(this.#icon, typeof style === "string" ? style.replace("alert_", "") : undefined);
|
|
132
132
|
return this;
|
|
133
133
|
}
|
|
@@ -135,7 +135,7 @@ class Alert {
|
|
|
135
135
|
/** Своя иконка вместо значка состояния (экземпляр `Icon` или готовый узел); цвет статуса остаётся */
|
|
136
136
|
setIcon(icon = undefined) {
|
|
137
137
|
if (icon === undefined || icon === null) return this;
|
|
138
|
-
this.#
|
|
138
|
+
this.#customIcon = true;
|
|
139
139
|
this.#icon.innerHTML = "";
|
|
140
140
|
this.#icon.appendChild(icon instanceof Element ? icon : icon.set());
|
|
141
141
|
return this;
|
|
@@ -233,11 +233,17 @@ class Alert {
|
|
|
233
233
|
return this;
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
-
/** Убрать сообщение из
|
|
236
|
+
/** Убрать сообщение из документа: уход идёт движением, узел убирается по концу кадра */
|
|
237
237
|
dismiss() {
|
|
238
238
|
if (this.#dismissed) return this;
|
|
239
239
|
this.#dismissed = true;
|
|
240
|
-
this.#root.
|
|
240
|
+
this.#root.classList.add("alert_leaving");
|
|
241
|
+
const remove = (event) => {
|
|
242
|
+
if (event.target !== this.#root) return;
|
|
243
|
+
this.#root.removeEventListener("animationend", remove);
|
|
244
|
+
this.#root.remove();
|
|
245
|
+
};
|
|
246
|
+
this.#root.addEventListener("animationend", remove);
|
|
241
247
|
return this;
|
|
242
248
|
}
|
|
243
249
|
|
|
@@ -18,6 +18,13 @@ chui_alert {
|
|
|
18
18
|
color: var(--text_color);
|
|
19
19
|
font-size: var(--font_default_size);
|
|
20
20
|
text-align: start;
|
|
21
|
+
/* Появление: сообщение встаёт на место — общий кадр из global_style.css */
|
|
22
|
+
animation: chui_appear_up var(--motion_base) var(--motion_ease);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* Уход: сообщение гаснет и сходит вверх, узел убирается по концу кадра */
|
|
26
|
+
.alert_leaving {
|
|
27
|
+
animation: chui_leave_up var(--motion_fast) var(--motion_ease) forwards;
|
|
21
28
|
}
|
|
22
29
|
|
|
23
30
|
alert_content {
|
|
@@ -48,8 +48,8 @@ class Avatar {
|
|
|
48
48
|
|
|
49
49
|
#root = document.createElement("chui_avatar");
|
|
50
50
|
#image = document.createElement("img");
|
|
51
|
-
#
|
|
52
|
-
#
|
|
51
|
+
#initialsNode = document.createElement("avatar_initials");
|
|
52
|
+
#statusNode = document.createElement("avatar_status");
|
|
53
53
|
#id = undefined;
|
|
54
54
|
#name = undefined;
|
|
55
55
|
#initials = undefined;
|
|
@@ -57,7 +57,7 @@ class Avatar {
|
|
|
57
57
|
#status = undefined;
|
|
58
58
|
#shape = Avatar.SHAPE.CIRCLE;
|
|
59
59
|
#decorative = false;
|
|
60
|
-
#
|
|
60
|
+
#clickListeners = [];
|
|
61
61
|
|
|
62
62
|
constructor(
|
|
63
63
|
options = {
|
|
@@ -84,9 +84,9 @@ class Avatar {
|
|
|
84
84
|
this.#image.setAttribute("alt", "");
|
|
85
85
|
this.#image.setAttribute("aria-hidden", "true");
|
|
86
86
|
this.#root.appendChild(this.#image);
|
|
87
|
-
this.#root.appendChild(this.#
|
|
88
|
-
this.#root.appendChild(this.#
|
|
89
|
-
this.#
|
|
87
|
+
this.#root.appendChild(this.#initialsNode);
|
|
88
|
+
this.#root.appendChild(this.#statusNode);
|
|
89
|
+
this.#statusNode.setAttribute("aria-hidden", "true");
|
|
90
90
|
this.setSize(options.size === undefined ? Avatar.SIZE.DEFAULT : options.size);
|
|
91
91
|
this.setShape(options.shape === undefined ? Avatar.SHAPE.CIRCLE : options.shape);
|
|
92
92
|
this.#renderInitials();
|
|
@@ -106,7 +106,7 @@ class Avatar {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
getInitials() {
|
|
109
|
-
return this.#
|
|
109
|
+
return this.#initialsNode.innerText;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
getImageSource() {
|
|
@@ -180,9 +180,9 @@ class Avatar {
|
|
|
180
180
|
/** Значок состояния; `undefined` убирает его и слово из доступного имени */
|
|
181
181
|
setStatus(status = undefined) {
|
|
182
182
|
this.#status = status;
|
|
183
|
-
this.#
|
|
184
|
-
if (status !== undefined) this.#
|
|
185
|
-
else this.#
|
|
183
|
+
this.#statusNode.hidden = status === undefined;
|
|
184
|
+
if (status !== undefined) this.#statusNode.dataset.status = status;
|
|
185
|
+
else this.#statusNode.removeAttribute("data-status");
|
|
186
186
|
this.#syncAria();
|
|
187
187
|
return this;
|
|
188
188
|
}
|
|
@@ -202,7 +202,7 @@ class Avatar {
|
|
|
202
202
|
}
|
|
203
203
|
|
|
204
204
|
addClickListener(listener = () => {}) {
|
|
205
|
-
this.#
|
|
205
|
+
this.#clickListeners.push(listener);
|
|
206
206
|
return this;
|
|
207
207
|
}
|
|
208
208
|
|
|
@@ -244,7 +244,7 @@ class Avatar {
|
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
#renderInitials() {
|
|
247
|
-
this.#
|
|
247
|
+
this.#initialsNode.innerText = this.#deriveInitials();
|
|
248
248
|
this.#syncAria();
|
|
249
249
|
}
|
|
250
250
|
|
|
@@ -264,7 +264,7 @@ class Avatar {
|
|
|
264
264
|
}
|
|
265
265
|
|
|
266
266
|
#onClick = (event) => {
|
|
267
|
-
for (const listener of [...this.#
|
|
267
|
+
for (const listener of [...this.#clickListeners]) listener(event);
|
|
268
268
|
};
|
|
269
269
|
}
|
|
270
270
|
|
|
@@ -45,7 +45,7 @@ class AvatarGroup {
|
|
|
45
45
|
#size = Avatar.SIZE.DEFAULT;
|
|
46
46
|
#shape = undefined;
|
|
47
47
|
#extra = undefined;
|
|
48
|
-
#
|
|
48
|
+
#extraListener = undefined;
|
|
49
49
|
#label = undefined;
|
|
50
50
|
|
|
51
51
|
constructor(
|
|
@@ -64,7 +64,7 @@ class AvatarGroup {
|
|
|
64
64
|
this.#id = optionOr(options.id, `chui_avatar_group_${AvatarGroup.#counter}`);
|
|
65
65
|
this.#root.id = this.#id;
|
|
66
66
|
this.#root.setAttribute("role", "group");
|
|
67
|
-
this.#
|
|
67
|
+
this.#extraListener = options.extraClickListener;
|
|
68
68
|
this.setSize(optionOr(options.size, Avatar.SIZE.DEFAULT));
|
|
69
69
|
if (options.shape !== undefined) this.#shape = options.shape;
|
|
70
70
|
if (options.max !== undefined) this.setMax(options.max);
|
|
@@ -215,7 +215,7 @@ class AvatarGroup {
|
|
|
215
215
|
const extra = document.createElement("avatar_group_extra");
|
|
216
216
|
extra.className = "avatar_group_extra";
|
|
217
217
|
extra.innerText = `+${hidden}`;
|
|
218
|
-
if (this.#
|
|
218
|
+
if (this.#extraListener === undefined) {
|
|
219
219
|
extra.setAttribute("role", "img");
|
|
220
220
|
extra.setAttribute("aria-label", I18n.t("feedback.avatarGroupMore", { count: hidden }));
|
|
221
221
|
} else {
|
|
@@ -223,7 +223,7 @@ class AvatarGroup {
|
|
|
223
223
|
extra.classList.add("avatar_group_extra_button");
|
|
224
224
|
extra.setAttribute("aria-label", I18n.t("feedback.avatarGroupShowAll", { count: hidden }));
|
|
225
225
|
makeKeyboardButton(extra);
|
|
226
|
-
extra.addEventListener("click", (event) => this.#
|
|
226
|
+
extra.addEventListener("click", (event) => this.#extraListener(event, hidden, this));
|
|
227
227
|
}
|
|
228
228
|
this.#extra = extra;
|
|
229
229
|
this.#root.appendChild(extra);
|
|
@@ -198,6 +198,7 @@ class Backtop {
|
|
|
198
198
|
if (this.#destroyed) return this;
|
|
199
199
|
this.#destroyed = true;
|
|
200
200
|
window.removeEventListener("scroll", this.#onScroll, { capture: true });
|
|
201
|
+
this.#root.removeEventListener("transitionend", this.#onHideEnd);
|
|
201
202
|
this.#root.remove();
|
|
202
203
|
return this;
|
|
203
204
|
}
|
|
@@ -238,9 +239,31 @@ class Backtop {
|
|
|
238
239
|
const visible = top > this.#threshold;
|
|
239
240
|
if (visible === this.#visible) return;
|
|
240
241
|
this.#visible = visible;
|
|
241
|
-
this.#
|
|
242
|
-
this.#root.classList.toggle("backtop_visible", visible);
|
|
242
|
+
this.#show(visible);
|
|
243
243
|
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Показ и уход идут движением (переход в styles.css). Узел встаёт в раскладку до класса —
|
|
247
|
+
* иначе перехода не было бы вовсе, — а `hidden` возвращается по концу ухода: в закреплённом
|
|
248
|
+
* положении он держит место в раскладке панели, и снять его до ухода значило бы оборвать его.
|
|
249
|
+
*/
|
|
250
|
+
#show(visible) {
|
|
251
|
+
if (visible) {
|
|
252
|
+
this.#root.hidden = false;
|
|
253
|
+
requestAnimationFrame(() => {
|
|
254
|
+
if (this.#visible === true) this.#root.classList.add("backtop_visible");
|
|
255
|
+
});
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
this.#root.classList.remove("backtop_visible");
|
|
259
|
+
this.#root.addEventListener("transitionend", this.#onHideEnd);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
#onHideEnd = (event) => {
|
|
263
|
+
if (event.target !== this.#root || event.propertyName !== "opacity") return;
|
|
264
|
+
this.#root.removeEventListener("transitionend", this.#onHideEnd);
|
|
265
|
+
if (this.#visible === false) this.#root.hidden = true;
|
|
266
|
+
};
|
|
244
267
|
}
|
|
245
268
|
|
|
246
269
|
exports.Backtop = Backtop;
|
|
@@ -6,6 +6,27 @@ chui_backtop {
|
|
|
6
6
|
--backtop_inline_end: 24px;
|
|
7
7
|
width: max-content;
|
|
8
8
|
height: max-content;
|
|
9
|
+
opacity: 1;
|
|
10
|
+
transform: none;
|
|
11
|
+
/* Появление и уход — движение, а не снятие узла: кнопка поднимается на месте и гаснет.
|
|
12
|
+
`hidden` включает JS по концу ухода: в закреплённом положении он держит место
|
|
13
|
+
в раскладке панели, поэтому снимать его заранее нельзя */
|
|
14
|
+
transition:
|
|
15
|
+
opacity var(--motion_base) var(--motion_ease),
|
|
16
|
+
transform var(--motion_base) var(--motion_ease),
|
|
17
|
+
visibility var(--motion_none) linear;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* Скрытая кнопка не ловит курсор и не попадает в обход Tab: `visibility` переключается
|
|
21
|
+
сразу при показе и только в конце ухода */
|
|
22
|
+
chui_backtop:not(.backtop_visible) {
|
|
23
|
+
opacity: 0;
|
|
24
|
+
transform: translateY(8px);
|
|
25
|
+
visibility: hidden;
|
|
26
|
+
transition:
|
|
27
|
+
opacity var(--motion_fast) var(--motion_ease),
|
|
28
|
+
transform var(--motion_fast) var(--motion_ease),
|
|
29
|
+
visibility var(--motion_none) linear var(--motion_fast);
|
|
9
30
|
}
|
|
10
31
|
|
|
11
32
|
chui_backtop[hidden] {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { setStyles, markdownToHtml, htmlToMarkdown, optionOr } = require("../../modules/chui_functions");
|
|
2
2
|
|
|
3
3
|
class Badge {
|
|
4
|
-
#
|
|
4
|
+
#chuiBadge = document.createElement(`chui_badge`);
|
|
5
5
|
constructor(
|
|
6
6
|
options = {
|
|
7
7
|
id: String(),
|
|
@@ -11,47 +11,47 @@ class Badge {
|
|
|
11
11
|
}
|
|
12
12
|
) {
|
|
13
13
|
setStyles(__dirname + "/styles.css", "chUiJS_Badge");
|
|
14
|
-
if (options.id !== undefined) this.#
|
|
14
|
+
if (options.id !== undefined) this.#chuiBadge.id = options.id;
|
|
15
15
|
const style = optionOr(options.style, undefined);
|
|
16
|
-
if (style !== undefined) this.#
|
|
16
|
+
if (style !== undefined) this.#chuiBadge.classList.add(style);
|
|
17
17
|
// Стили текста баджей: пустая заготовка опции равносильна отсутствующей
|
|
18
18
|
const text = optionOr(options.text, undefined);
|
|
19
|
-
const
|
|
20
|
-
if (text !== undefined &&
|
|
19
|
+
const markdownText = optionOr(options.markdownText, undefined);
|
|
20
|
+
if (text !== undefined && markdownText !== undefined) {
|
|
21
21
|
throw new Error("Должна быть установлена одна опция text или markdownText");
|
|
22
22
|
} else {
|
|
23
|
-
if (text !== undefined) this.#
|
|
24
|
-
if (
|
|
23
|
+
if (text !== undefined) this.#chuiBadge.innerText = text;
|
|
24
|
+
if (markdownText !== undefined) this.#chuiBadge.innerHTML = markdownToHtml(markdownText);
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
// GET
|
|
28
28
|
getId() {
|
|
29
|
-
return this.#
|
|
29
|
+
return this.#chuiBadge.id;
|
|
30
30
|
}
|
|
31
31
|
getText() {
|
|
32
|
-
return this.#
|
|
32
|
+
return this.#chuiBadge.innerText;
|
|
33
33
|
}
|
|
34
34
|
getMarkdownText() {
|
|
35
|
-
return htmlToMarkdown(this.#
|
|
35
|
+
return htmlToMarkdown(this.#chuiBadge.innerHTML);
|
|
36
36
|
}
|
|
37
37
|
// SET
|
|
38
38
|
setText(text = String()) {
|
|
39
|
-
this.#
|
|
39
|
+
this.#chuiBadge.innerText = text;
|
|
40
40
|
}
|
|
41
41
|
setMarkdownText(text = String()) {
|
|
42
|
-
this.#
|
|
42
|
+
this.#chuiBadge.innerHTML = markdownToHtml(text);
|
|
43
43
|
}
|
|
44
44
|
setId(id = String()) {
|
|
45
|
-
this.#
|
|
45
|
+
this.#chuiBadge.id = id;
|
|
46
46
|
}
|
|
47
47
|
setStyle(style = String()) {
|
|
48
48
|
// Пустая строка — «не задана»: `classList.add("")` бросает исключение
|
|
49
49
|
const known = optionOr(style, undefined);
|
|
50
|
-
if (known !== undefined) this.#
|
|
50
|
+
if (known !== undefined) this.#chuiBadge.classList.add(known);
|
|
51
51
|
}
|
|
52
52
|
// RENDER
|
|
53
53
|
set() {
|
|
54
|
-
return this.#
|
|
54
|
+
return this.#chuiBadge;
|
|
55
55
|
}
|
|
56
56
|
static STYLE = {
|
|
57
57
|
ERROR: "badge_error",
|
|
@@ -12,9 +12,9 @@ chui_badge {
|
|
|
12
12
|
height: max-content;
|
|
13
13
|
width: max-content;
|
|
14
14
|
padding: 2px 8px;
|
|
15
|
-
margin: var(--
|
|
15
|
+
margin: var(--block_margin);
|
|
16
16
|
border-radius: var(--radius_pill);
|
|
17
|
-
background: var(--
|
|
17
|
+
background: var(--badge_cancel_background);
|
|
18
18
|
color: var(--badge_cancel_text);
|
|
19
19
|
font-size: var(--font_labels_size);
|
|
20
20
|
font-weight: 500;
|
|
@@ -41,20 +41,20 @@ chui_badge strong {
|
|
|
41
41
|
|
|
42
42
|
/* Код в метке — тем же моношрифтом, что в остальных местах с разметкой */
|
|
43
43
|
chui_badge code {
|
|
44
|
-
font-family: var(--
|
|
44
|
+
font-family: var(--font_mono);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
.badge_error {
|
|
48
|
-
background: var(--
|
|
48
|
+
background: var(--badge_error_background);
|
|
49
49
|
color: var(--badge_error_text);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
.badge_success {
|
|
53
|
-
background: var(--
|
|
53
|
+
background: var(--badge_success_background);
|
|
54
54
|
color: var(--badge_success_text);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
.badge_warning {
|
|
58
|
-
background: var(--
|
|
58
|
+
background: var(--badge_warning_background);
|
|
59
59
|
color: var(--badge_warning_text);
|
|
60
60
|
}
|