chuijs 4.0.2 → 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.
Files changed (292) hide show
  1. package/CHANGELOG.md +597 -0
  2. package/README.md +43 -644
  3. package/framework/appLayout/default/chui_app_layout.js +602 -496
  4. package/framework/appLayout/default/global_style.css +288 -97
  5. package/framework/appLayout/default/main_theme_style.css +188 -101
  6. package/framework/components/chui_accordion/accordion.js +38 -35
  7. package/framework/components/chui_accordion/styles.css +13 -12
  8. package/framework/components/chui_action_sheet/action_sheet.js +93 -64
  9. package/framework/components/chui_action_sheet/styles.css +12 -5
  10. package/framework/components/chui_actions_bar/actions_bar.js +338 -0
  11. package/framework/components/chui_actions_bar/styles.css +139 -0
  12. package/framework/components/chui_affix/affix.js +16 -11
  13. package/framework/components/chui_affix/styles.css +5 -0
  14. package/framework/components/chui_alert/alert.js +34 -19
  15. package/framework/components/chui_alert/styles.css +7 -0
  16. package/framework/components/chui_avatar/avatar.js +36 -35
  17. package/framework/components/chui_avatar/styles.css +1 -1
  18. package/framework/components/chui_avatar_group/avatar_group.js +25 -23
  19. package/framework/components/chui_avatar_group/styles.css +1 -1
  20. package/framework/components/chui_backtop/backtop.js +60 -21
  21. package/framework/components/chui_backtop/styles.css +21 -0
  22. package/framework/components/chui_badge/badge.js +30 -28
  23. package/framework/components/chui_badge/styles.css +6 -6
  24. package/framework/components/chui_banner/banner.js +222 -0
  25. package/framework/components/chui_banner/styles.css +170 -0
  26. package/framework/components/chui_breadcrumb/breadcrumb.js +15 -13
  27. package/framework/components/chui_breadcrumb/styles.css +1 -1
  28. package/framework/components/chui_button/button.js +52 -36
  29. package/framework/components/chui_button/styles.css +7 -7
  30. package/framework/components/chui_calendar/calendar.js +18 -16
  31. package/framework/components/chui_card/card.js +52 -32
  32. package/framework/components/chui_card_scroll/card_scroll.js +169 -0
  33. package/framework/components/chui_card_scroll/styles.css +86 -0
  34. package/framework/components/chui_chat/chat.js +140 -79
  35. package/framework/components/chui_chat/styles.css +18 -7
  36. package/framework/components/chui_clipboard_history/clipboard_history.js +53 -39
  37. package/framework/components/chui_clipboard_history/styles.css +13 -9
  38. package/framework/components/chui_code/code.js +10 -10
  39. package/framework/components/chui_code/styles.css +4 -4
  40. package/framework/components/chui_code_editor/code_editor.js +73 -57
  41. package/framework/components/chui_code_editor/styles.css +6 -5
  42. package/framework/components/chui_command_palette/command_palette.js +87 -64
  43. package/framework/components/chui_command_palette/styles.css +5 -5
  44. package/framework/components/chui_console/console.js +13 -13
  45. package/framework/components/chui_console/styles.css +6 -3
  46. package/framework/components/chui_content_block/content_block.js +35 -21
  47. package/framework/components/chui_content_block/styles.css +2 -2
  48. package/framework/components/chui_context_menu/context_menu.js +171 -58
  49. package/framework/components/chui_context_menu/styles.css +82 -8
  50. package/framework/components/chui_custom_element/custom_element.js +25 -18
  51. package/framework/components/chui_data_grid/data_grid.js +633 -471
  52. package/framework/components/chui_data_grid/styles.css +24 -22
  53. package/framework/components/chui_descriptions/descriptions.js +34 -17
  54. package/framework/components/chui_descriptions/styles.css +1 -1
  55. package/framework/components/chui_details/details.js +42 -36
  56. package/framework/components/chui_details/styles.css +12 -11
  57. package/framework/components/chui_diff_viewer/diff_viewer.js +172 -147
  58. package/framework/components/chui_diff_viewer/styles.css +10 -10
  59. package/framework/components/chui_divider/divider.js +19 -17
  60. package/framework/components/chui_divider/styles.css +2 -2
  61. package/framework/components/chui_drawer/drawer.js +63 -38
  62. package/framework/components/chui_drawer/styles.css +18 -4
  63. package/framework/components/chui_drop_zone/drop_zone.js +37 -27
  64. package/framework/components/chui_drop_zone/styles.css +10 -6
  65. package/framework/components/chui_empty_state/empty_state.js +20 -15
  66. package/framework/components/chui_fieldset/fieldset.js +40 -23
  67. package/framework/components/chui_fieldset/styles.css +6 -6
  68. package/framework/components/chui_file_explorer/file_explorer.js +260 -189
  69. package/framework/components/chui_file_explorer/styles.css +8 -7
  70. package/framework/components/chui_form/form.js +40 -28
  71. package/framework/components/chui_form/styles.css +1 -1
  72. package/framework/components/chui_gantt/gantt.js +102 -78
  73. package/framework/components/chui_gantt/styles.css +5 -5
  74. package/framework/components/chui_graphs/graphs.js +376 -239
  75. package/framework/components/chui_graphs/styles.css +27 -6
  76. package/framework/components/chui_hero/hero.js +98 -37
  77. package/framework/components/chui_hero/styles.css +176 -7
  78. package/framework/components/chui_html_block/html_block.js +8 -8
  79. package/framework/components/chui_html_block/styles.css +3 -3
  80. package/framework/components/chui_hx/hx.js +3 -3
  81. package/framework/components/chui_hx/styles.css +13 -6
  82. package/framework/components/chui_icons/icons.js +2115 -2115
  83. package/framework/components/chui_icons/styles.css +4 -3
  84. package/framework/components/chui_inputs/chui_check_box/check_box.js +31 -19
  85. package/framework/components/chui_inputs/chui_check_box/styles.css +30 -21
  86. package/framework/components/chui_inputs/chui_chips/chips.js +141 -70
  87. package/framework/components/chui_inputs/chui_chips/styles.css +32 -7
  88. package/framework/components/chui_inputs/chui_color_picker/color_picker.js +55 -38
  89. package/framework/components/chui_inputs/chui_color_picker/styles.css +7 -7
  90. package/framework/components/chui_inputs/chui_combo_box/combo_box.js +127 -109
  91. package/framework/components/chui_inputs/chui_combo_box/styles.css +23 -21
  92. package/framework/components/chui_inputs/chui_date/date.js +161 -127
  93. package/framework/components/chui_inputs/chui_date/styles.css +20 -19
  94. package/framework/components/chui_inputs/chui_date_range/date_range.js +61 -50
  95. package/framework/components/chui_inputs/chui_date_range/styles.css +3 -3
  96. package/framework/components/chui_inputs/chui_datetime/datetime.js +47 -39
  97. package/framework/components/chui_inputs/chui_datetime/styles.css +3 -3
  98. package/framework/components/chui_inputs/chui_email/email.js +48 -36
  99. package/framework/components/chui_inputs/chui_email/styles.css +11 -11
  100. package/framework/components/chui_inputs/chui_file/file.js +71 -44
  101. package/framework/components/chui_inputs/chui_file/styles.css +23 -19
  102. package/framework/components/chui_inputs/chui_hotkey/hotkey.js +101 -76
  103. package/framework/components/chui_inputs/chui_hotkey/styles.css +6 -6
  104. package/framework/components/chui_inputs/chui_masked/masked.js +83 -72
  105. package/framework/components/chui_inputs/chui_masked/styles.css +5 -5
  106. package/framework/components/chui_inputs/chui_mention/mention.js +87 -40
  107. package/framework/components/chui_inputs/chui_mention/styles.css +14 -8
  108. package/framework/components/chui_inputs/chui_multi_combo_box/multi_combo_box.js +242 -212
  109. package/framework/components/chui_inputs/chui_multi_combo_box/styles.css +23 -15
  110. package/framework/components/chui_inputs/chui_number/number.js +84 -70
  111. package/framework/components/chui_inputs/chui_number/styles.css +13 -13
  112. package/framework/components/chui_inputs/chui_otp/otp.js +71 -62
  113. package/framework/components/chui_inputs/chui_otp/styles.css +5 -5
  114. package/framework/components/chui_inputs/chui_password/password.js +72 -56
  115. package/framework/components/chui_inputs/chui_password/styles.css +15 -15
  116. package/framework/components/chui_inputs/chui_radio_button/radio_button.js +37 -25
  117. package/framework/components/chui_inputs/chui_radio_button/styles.css +22 -22
  118. package/framework/components/chui_inputs/chui_rating/rating.js +54 -50
  119. package/framework/components/chui_inputs/chui_rating/styles.css +3 -3
  120. package/framework/components/chui_inputs/chui_select_box/select_box.js +132 -108
  121. package/framework/components/chui_inputs/chui_select_box/styles.css +21 -21
  122. package/framework/components/chui_inputs/chui_slider/slider.js +41 -38
  123. package/framework/components/chui_inputs/chui_slider/styles.css +7 -5
  124. package/framework/components/chui_inputs/chui_text/styles.css +14 -14
  125. package/framework/components/chui_inputs/chui_text/text.js +69 -52
  126. package/framework/components/chui_inputs/chui_text_area/styles.css +14 -14
  127. package/framework/components/chui_inputs/chui_text_area/text_area.js +59 -36
  128. package/framework/components/chui_inputs/chui_time/styles.css +18 -20
  129. package/framework/components/chui_inputs/chui_time/time.js +71 -49
  130. package/framework/components/chui_inputs/chui_toggle/styles.css +13 -6
  131. package/framework/components/chui_inputs/chui_toggle/toggle.js +27 -27
  132. package/framework/components/chui_json_editor/json_editor.js +137 -127
  133. package/framework/components/chui_json_editor/styles.css +5 -5
  134. package/framework/components/chui_json_viewer/json_viewer.js +133 -114
  135. package/framework/components/chui_json_viewer/styles.css +9 -8
  136. package/framework/components/chui_kanban/kanban.js +78 -60
  137. package/framework/components/chui_kanban/styles.css +8 -4
  138. package/framework/components/chui_kbd/kbd.js +12 -10
  139. package/framework/components/chui_kbd/styles.css +1 -1
  140. package/framework/components/chui_label/label.js +31 -29
  141. package/framework/components/chui_label/styles.css +3 -3
  142. package/framework/components/chui_link/link.js +36 -29
  143. package/framework/components/chui_link/styles.css +11 -4
  144. package/framework/components/chui_list/list.js +42 -38
  145. package/framework/components/chui_list/styles.css +4 -3
  146. package/framework/components/chui_markdown_editor/markdown_editor.js +125 -109
  147. package/framework/components/chui_markdown_editor/styles.css +5 -5
  148. package/framework/components/chui_media/audio.js +457 -364
  149. package/framework/components/chui_media/audio_styles.css +74 -37
  150. package/framework/components/chui_media/image.js +99 -64
  151. package/framework/components/chui_media/image_compare.js +86 -55
  152. package/framework/components/chui_media/image_compare_styles.css +5 -5
  153. package/framework/components/chui_media/image_styles.css +4 -4
  154. package/framework/components/chui_media/video.js +264 -171
  155. package/framework/components/chui_media/video_styles.css +57 -24
  156. package/framework/components/chui_menu_bar/menu_bar.js +67 -65
  157. package/framework/components/chui_menu_bar/styles.css +14 -12
  158. package/framework/components/chui_message_bar/message_bar.js +551 -0
  159. package/framework/components/chui_message_bar/styles.css +248 -0
  160. package/framework/components/chui_modal/modal.js +81 -56
  161. package/framework/components/chui_modal/styles.css +3 -2
  162. package/framework/components/chui_notification/notification.js +107 -69
  163. package/framework/components/chui_notification/notification_download.js +28 -77
  164. package/framework/components/chui_notification/notification_download_card.js +115 -0
  165. package/framework/components/chui_notification/notification_download_progress.css +5 -4
  166. package/framework/components/chui_notification/notification_download_progress.js +73 -105
  167. package/framework/components/chui_notification/notification_update.js +44 -37
  168. package/framework/components/chui_notification/status_plate.css +3 -3
  169. package/framework/components/chui_notification/status_plate.js +2 -2
  170. package/framework/components/chui_notification/styles.css +6 -1
  171. package/framework/components/chui_notification/styles_download.css +2 -2
  172. package/framework/components/chui_notification/styles_update.css +3 -3
  173. package/framework/components/chui_org_chart/org_chart.js +101 -62
  174. package/framework/components/chui_org_chart/styles.css +2 -2
  175. package/framework/components/chui_pagination/pagination.js +65 -30
  176. package/framework/components/chui_pagination/styles.css +1 -1
  177. package/framework/components/chui_paragraph/paragraph.js +2 -2
  178. package/framework/components/chui_paragraph/styles.css +3 -3
  179. package/framework/components/chui_popover/popover.js +77 -50
  180. package/framework/components/chui_popover/styles.css +1 -1
  181. package/framework/components/chui_popups/popups.js +210 -181
  182. package/framework/components/chui_popups/styles.css +7 -7
  183. package/framework/components/chui_print_button/print_button.js +48 -33
  184. package/framework/components/chui_progress_bar/progress_bar.js +49 -19
  185. package/framework/components/chui_progress_bar/styles.css +6 -6
  186. package/framework/components/chui_progress_ring/progress_ring.js +32 -30
  187. package/framework/components/chui_progress_ring/styles.css +1 -1
  188. package/framework/components/chui_qrcode/qrcode.js +85 -41
  189. package/framework/components/chui_query_builder/query_builder.js +263 -170
  190. package/framework/components/chui_query_builder/styles.css +4 -4
  191. package/framework/components/chui_radio_group/radio_group.js +36 -26
  192. package/framework/components/chui_radio_group/styles.css +2 -2
  193. package/framework/components/chui_result/result.js +41 -31
  194. package/framework/components/chui_result/styles.css +3 -3
  195. package/framework/components/chui_scheduler/scheduler.js +126 -104
  196. package/framework/components/chui_scheduler/styles.css +11 -7
  197. package/framework/components/chui_screen_spinner/screen_spinner.js +167 -0
  198. package/framework/components/chui_screen_spinner/styles.css +49 -0
  199. package/framework/components/chui_segmented_control/segmented_control.js +90 -27
  200. package/framework/components/chui_segmented_control/styles.css +32 -6
  201. package/framework/components/chui_settings/settings.js +160 -87
  202. package/framework/components/chui_settings/styles.css +4 -4
  203. package/framework/components/chui_shortcut_help/shortcut_help.js +82 -61
  204. package/framework/components/chui_sidebar_nav/sidebar_nav.js +132 -53
  205. package/framework/components/chui_sidebar_nav/styles.css +9 -3
  206. package/framework/components/chui_skeleton/skeleton.js +29 -24
  207. package/framework/components/chui_slideshow/slideshow.js +122 -103
  208. package/framework/components/chui_slideshow/styles.css +22 -16
  209. package/framework/components/chui_spinner/spinner.js +17 -17
  210. package/framework/components/chui_spinner/styles.css +0 -1
  211. package/framework/components/chui_split_button/split_button.js +53 -30
  212. package/framework/components/chui_split_button/styles.css +22 -6
  213. package/framework/components/chui_splitter/splitter.js +46 -39
  214. package/framework/components/chui_splitter/styles.css +2 -2
  215. package/framework/components/chui_statistic/statistic.js +111 -84
  216. package/framework/components/chui_status_bar/status_bar.js +11 -9
  217. package/framework/components/chui_status_bar/styles.css +2 -2
  218. package/framework/components/chui_stepper/stepper.js +230 -54
  219. package/framework/components/chui_stepper/styles.css +79 -14
  220. package/framework/components/chui_sticky_bar/sticky_bar.js +53 -17
  221. package/framework/components/chui_sticky_bar/styles.css +11 -7
  222. package/framework/components/chui_tabs/chui_tabs.js +100 -46
  223. package/framework/components/chui_tabs/styles.css +43 -15
  224. package/framework/components/chui_text_editor/styles.css +24 -23
  225. package/framework/components/chui_text_editor/text_editor.js +103 -79
  226. package/framework/components/chui_text_editor/text_editor_panel.js +428 -367
  227. package/framework/components/chui_theme_toggle/theme_toggle.js +46 -25
  228. package/framework/components/chui_timeline/styles.css +3 -1
  229. package/framework/components/chui_timeline/timeline.js +14 -12
  230. package/framework/components/chui_toast_queue/styles.css +11 -11
  231. package/framework/components/chui_toast_queue/toast_queue.js +82 -73
  232. package/framework/components/chui_toolbar/styles.css +2 -2
  233. package/framework/components/chui_toolbar/toolbar.js +20 -13
  234. package/framework/components/chui_tooltip/styles.css +2 -2
  235. package/framework/components/chui_tooltip/tooltip.js +40 -27
  236. package/framework/components/chui_tour/styles.css +12 -7
  237. package/framework/components/chui_tour/tour.js +132 -98
  238. package/framework/components/chui_transfer/styles.css +8 -7
  239. package/framework/components/chui_transfer/transfer.js +143 -123
  240. package/framework/components/chui_tree_table/styles.css +4 -4
  241. package/framework/components/chui_tree_table/tree_table.js +88 -74
  242. package/framework/components/chui_tree_view/styles.css +14 -10
  243. package/framework/components/chui_tree_view/tree_view.js +298 -253
  244. package/framework/components/chui_user_bar/styles.css +145 -0
  245. package/framework/components/chui_user_bar/user_bar.js +402 -0
  246. package/framework/components/chui_user_list_bar/styles.css +173 -0
  247. package/framework/components/chui_user_list_bar/user_list_bar.js +485 -0
  248. package/framework/components/chui_watermark/watermark.js +41 -33
  249. package/framework/components/chui_webview/styles.css +2 -2
  250. package/framework/components/chui_webview/webview.js +64 -52
  251. package/framework/components/chui_write_bar/styles.css +172 -0
  252. package/framework/components/chui_write_bar/write_bar.js +320 -0
  253. package/framework/main_window.js +1234 -0
  254. package/framework/modules/chui_a11y/chui_a11y.js +153 -123
  255. package/framework/modules/chui_animations/animations.js +105 -43
  256. package/framework/modules/chui_animations/motion.js +120 -0
  257. package/framework/modules/chui_animations/styles.css +37 -4
  258. package/framework/modules/chui_bridge/preload.js +36 -25
  259. package/framework/modules/chui_functions.js +69 -63
  260. package/framework/modules/chui_highlight/chui_highlight.js +25 -22
  261. package/framework/modules/chui_highlight/styles.css +13 -10
  262. package/framework/modules/chui_i18n/chui_i18n.js +12 -10
  263. package/framework/modules/chui_i18n/locales/a11y.js +5 -5
  264. package/framework/modules/chui_i18n/locales/app_layout.js +5 -5
  265. package/framework/modules/chui_i18n/locales/calendar.js +3 -3
  266. package/framework/modules/chui_i18n/locales/common.js +3 -3
  267. package/framework/modules/chui_i18n/locales/data.js +36 -26
  268. package/framework/modules/chui_i18n/locales/editors.js +40 -13
  269. package/framework/modules/chui_i18n/locales/feedback.js +65 -3
  270. package/framework/modules/chui_i18n/locales/forms.js +8 -8
  271. package/framework/modules/chui_i18n/locales/graphics.js +8 -8
  272. package/framework/modules/chui_i18n/locales/media.js +4 -4
  273. package/framework/modules/chui_i18n/locales/navigation.js +12 -8
  274. package/framework/modules/chui_i18n/locales/validate.js +3 -3
  275. package/framework/modules/chui_json/chui_json.js +11 -11
  276. package/framework/modules/chui_layout/chui_layout.js +12 -10
  277. package/framework/modules/chui_logger/chui_logger.js +47 -28
  278. package/framework/modules/chui_page/page.js +39 -33
  279. package/framework/modules/chui_palette/palette.js +61 -0
  280. package/framework/modules/chui_qr/chui_qr.js +179 -88
  281. package/framework/modules/chui_scrollbar/chui_scrollbar.js +79 -68
  282. package/framework/modules/chui_scrollbar/styles.css +4 -2
  283. package/framework/modules/chui_services/chui_channels.js +27 -13
  284. package/framework/modules/chui_services/chui_services.js +47 -39
  285. package/framework/modules/chui_services/desktop.js +108 -101
  286. package/framework/modules/chui_sortable/chui_sortable.js +33 -28
  287. package/framework/modules/chui_validate/chui_validate.js +10 -7
  288. package/framework/tray_bar/chui_menu_items.js +136 -46
  289. package/index.d.ts +5046 -0
  290. package/index.js +199 -1254
  291. package/package.json +81 -68
  292. package/framework/components/telegram_bot/chui_telegram_bot.js +0 -184
@@ -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
+ }
@@ -1,4 +1,4 @@
1
- const {setStyles, optionOr, scrollParent} = require('../../modules/chui_functions');
1
+ const { setStyles, optionOr, scrollParent } = require("../../modules/chui_functions");
2
2
 
3
3
  /**
4
4
  * Раздел с закреплённой панелью: панель остаётся на виду, пока её раздел на экране.
@@ -42,11 +42,16 @@ class Affix {
42
42
  #observer = undefined;
43
43
  #pending = undefined;
44
44
  #destroyed = false;
45
- #on_change = undefined;
46
-
47
- constructor(options = {
48
- id: String(), offset: Number(), target: undefined, onChange: undefined
49
- }) {
45
+ #onChange = undefined;
46
+
47
+ constructor(
48
+ options = {
49
+ id: String(),
50
+ offset: Number(),
51
+ target: undefined,
52
+ onChange: undefined,
53
+ }
54
+ ) {
50
55
  setStyles(__dirname + "/styles.css", "chUiJS_Affix");
51
56
  Affix.#counter += 1;
52
57
  this.#id = optionOr(options.id, `chui_affix_${Affix.#counter}`);
@@ -58,7 +63,7 @@ class Affix {
58
63
  this.#root.appendChild(this.#body);
59
64
  this.#root.appendChild(this.#content);
60
65
  this.#target = options.target;
61
- this.#on_change = options.onChange;
66
+ this.#onChange = options.onChange;
62
67
  this.setOffset(options.offset === undefined ? 0 : options.offset);
63
68
  this.#observe();
64
69
  }
@@ -118,7 +123,7 @@ class Affix {
118
123
  }
119
124
 
120
125
  setOnChange(listener = undefined) {
121
- this.#on_change = listener;
126
+ this.#onChange = listener;
122
127
  return this;
123
128
  }
124
129
 
@@ -204,7 +209,7 @@ class Affix {
204
209
  root: root,
205
210
  // Сторож уходит из области прокрутки ровно тогда, когда панель дошла до отступа
206
211
  rootMargin: `-${this.#offset}px 0px 0px 0px`,
207
- threshold: 0
212
+ threshold: 0,
208
213
  });
209
214
  this.#observer.observe(this.#sentinel);
210
215
  // Наблюдатель отвечает асинхронно: до первого ответа закрепления нет,
@@ -223,8 +228,8 @@ class Affix {
223
228
  this.#fixed = fixed;
224
229
  this.#root.dataset.fixed = fixed ? "true" : "false";
225
230
  this.#root.classList.toggle("affix_fixed", fixed);
226
- if (typeof this.#on_change === "function") this.#on_change(fixed, this);
231
+ if (typeof this.#onChange === "function") this.#onChange(fixed, this);
227
232
  }
228
233
  }
229
234
 
230
- exports.Affix = Affix
235
+ exports.Affix = Affix;
@@ -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 {
@@ -1,8 +1,8 @@
1
- const {setStyles, markdownToHtml, optionOr} = require("../../modules/chui_functions");
2
- const {Icon, Icons} = require("../chui_icons/icons");
3
- const {I18n} = require("../../modules/chui_i18n/chui_i18n");
1
+ const { setStyles, markdownToHtml, optionOr } = require("../../modules/chui_functions");
2
+ const { Icon, Icons } = require("../chui_icons/icons");
3
+ const { I18n } = require("../../modules/chui_i18n/chui_i18n");
4
4
  // Плашка значка — общая с уведомлениями: одна фигура и одни цвета состояния
5
- const {setStatusPlate} = require("../chui_notification/status_plate");
5
+ const { setStatusPlate } = require("../chui_notification/status_plate");
6
6
 
7
7
  /**
8
8
  * Сообщение в потоке страницы: подсказка, предупреждение или ошибка прямо в разметке, а не
@@ -34,7 +34,7 @@ class Alert {
34
34
  INFO: "alert_info",
35
35
  SUCCESS: "alert_success",
36
36
  WARNING: "alert_warning",
37
- ERROR: "alert_error"
37
+ ERROR: "alert_error",
38
38
  };
39
39
  static #counter = 0;
40
40
 
@@ -48,14 +48,22 @@ class Alert {
48
48
  #id = undefined;
49
49
  #style = Alert.STYLE.INFO;
50
50
  #dismissed = false;
51
- #custom_icon = false;
52
-
53
- constructor(options = {
54
- id: String(), title: String(), markdownTitle: String(),
55
- text: String(), markdownText: String(),
56
- style: String(), icon: undefined, dismissible: Boolean(),
57
- actions: [], margin: Object()
58
- }) {
51
+ #customIcon = false;
52
+
53
+ constructor(
54
+ options = {
55
+ id: String(),
56
+ title: String(),
57
+ markdownTitle: String(),
58
+ text: String(),
59
+ markdownText: String(),
60
+ style: String(),
61
+ icon: undefined,
62
+ dismissible: Boolean(),
63
+ actions: [],
64
+ margin: Object(),
65
+ }
66
+ ) {
59
67
  setStyles(__dirname + "/styles.css", "chUiJS_Alert");
60
68
  Alert.#counter += 1;
61
69
  this.#id = options.id === undefined ? `chui_alert_${Alert.#counter}` : options.id;
@@ -119,14 +127,15 @@ class Alert {
119
127
  this.#root.setAttribute("aria-live", assertive ? "assertive" : "polite");
120
128
  // Цвет и глиф плашки выбирает общий помощник семьи — по ключу стиля (`alert_error` → `error`).
121
129
  // Своя иконка (`setIcon`) важнее статусного глифа и остаётся собой
122
- if (this.#custom_icon === false) setStatusPlate(this.#icon, typeof style === "string" ? style.replace("alert_", "") : undefined);
130
+ if (this.#customIcon === false)
131
+ setStatusPlate(this.#icon, typeof style === "string" ? style.replace("alert_", "") : undefined);
123
132
  return this;
124
133
  }
125
134
 
126
135
  /** Своя иконка вместо значка состояния (экземпляр `Icon` или готовый узел); цвет статуса остаётся */
127
136
  setIcon(icon = undefined) {
128
137
  if (icon === undefined || icon === null) return this;
129
- this.#custom_icon = true;
138
+ this.#customIcon = true;
130
139
  this.#icon.innerHTML = "";
131
140
  this.#icon.appendChild(icon instanceof Element ? icon : icon.set());
132
141
  return this;
@@ -216,7 +225,7 @@ class Alert {
216
225
  }
217
226
 
218
227
  /** Отступы сообщения: {top, bottom, left, right} — как у `Divider.setMargin()` */
219
- setMargin(margin = {top: undefined, bottom: undefined, left: undefined, right: undefined}) {
228
+ setMargin(margin = { top: undefined, bottom: undefined, left: undefined, right: undefined }) {
220
229
  if (margin.top !== undefined) this.#root.style.marginTop = margin.top;
221
230
  if (margin.bottom !== undefined) this.#root.style.marginBottom = margin.bottom;
222
231
  if (margin.left !== undefined) this.#root.style.marginLeft = margin.left;
@@ -224,11 +233,17 @@ class Alert {
224
233
  return this;
225
234
  }
226
235
 
227
- /** Убрать сообщение из документа */
236
+ /** Убрать сообщение из документа: уход идёт движением, узел убирается по концу кадра */
228
237
  dismiss() {
229
238
  if (this.#dismissed) return this;
230
239
  this.#dismissed = true;
231
- this.#root.remove();
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);
232
247
  return this;
233
248
  }
234
249
 
@@ -238,4 +253,4 @@ class Alert {
238
253
  }
239
254
  }
240
255
 
241
- exports.Alert = Alert
256
+ exports.Alert = Alert;
@@ -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 {
@@ -1,5 +1,5 @@
1
- const {setStyles} = require('../../modules/chui_functions');
2
- const {I18n} = require('../../modules/chui_i18n/chui_i18n');
1
+ const { setStyles } = require("../../modules/chui_functions");
2
+ const { I18n } = require("../../modules/chui_i18n/chui_i18n");
3
3
 
4
4
  /**
5
5
  * Аватар: изображение пользователя или его инициалы, при необходимости со значком состояния.
@@ -22,34 +22,34 @@ const {I18n} = require('../../modules/chui_i18n/chui_i18n');
22
22
  class Avatar {
23
23
  static SHAPE = {
24
24
  CIRCLE: "circle",
25
- SQUARE: "square"
25
+ SQUARE: "square",
26
26
  };
27
27
  static SIZE = {
28
28
  SMALL: "28px",
29
29
  DEFAULT: "40px",
30
30
  LARGE: "56px",
31
- BIG: "72px"
31
+ BIG: "72px",
32
32
  };
33
33
  static STATUS = {
34
34
  ONLINE: "online",
35
35
  OFFLINE: "offline",
36
36
  BUSY: "busy",
37
- AWAY: "away"
37
+ AWAY: "away",
38
38
  };
39
39
  static get STATUS_LABEL() {
40
40
  return {
41
41
  online: I18n.t("feedback.statusOnline"),
42
42
  offline: I18n.t("feedback.statusOffline"),
43
43
  busy: I18n.t("feedback.statusBusy"),
44
- away: I18n.t("feedback.statusAway")
44
+ away: I18n.t("feedback.statusAway"),
45
45
  };
46
46
  }
47
47
  static #counter = 0;
48
48
 
49
49
  #root = document.createElement("chui_avatar");
50
50
  #image = document.createElement("img");
51
- #initials_node = document.createElement("avatar_initials");
52
- #status_node = document.createElement("avatar_status");
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,20 +57,22 @@ class Avatar {
57
57
  #status = undefined;
58
58
  #shape = Avatar.SHAPE.CIRCLE;
59
59
  #decorative = false;
60
- #click_listeners = [];
60
+ #clickListeners = [];
61
61
 
62
- constructor(options = {
63
- id: String(),
64
- name: String(),
65
- initials: String(),
66
- image: Object(),
67
- size: String(),
68
- shape: String(),
69
- status: String(),
70
- label: String(),
71
- decorative: Boolean(),
72
- clickListener: undefined
73
- }) {
62
+ constructor(
63
+ options = {
64
+ id: String(),
65
+ name: String(),
66
+ initials: String(),
67
+ image: Object(),
68
+ size: String(),
69
+ shape: String(),
70
+ status: String(),
71
+ label: String(),
72
+ decorative: Boolean(),
73
+ clickListener: undefined,
74
+ }
75
+ ) {
74
76
  setStyles(__dirname + "/styles.css", "chUiJS_Avatar");
75
77
  Avatar.#counter += 1;
76
78
  this.#id = options.id === undefined ? `chui_avatar_${Avatar.#counter}` : options.id;
@@ -82,9 +84,9 @@ class Avatar {
82
84
  this.#image.setAttribute("alt", "");
83
85
  this.#image.setAttribute("aria-hidden", "true");
84
86
  this.#root.appendChild(this.#image);
85
- this.#root.appendChild(this.#initials_node);
86
- this.#root.appendChild(this.#status_node);
87
- this.#status_node.setAttribute("aria-hidden", "true");
87
+ this.#root.appendChild(this.#initialsNode);
88
+ this.#root.appendChild(this.#statusNode);
89
+ this.#statusNode.setAttribute("aria-hidden", "true");
88
90
  this.setSize(options.size === undefined ? Avatar.SIZE.DEFAULT : options.size);
89
91
  this.setShape(options.shape === undefined ? Avatar.SHAPE.CIRCLE : options.shape);
90
92
  this.#renderInitials();
@@ -104,7 +106,7 @@ class Avatar {
104
106
  }
105
107
 
106
108
  getInitials() {
107
- return this.#initials_node.innerText;
109
+ return this.#initialsNode.innerText;
108
110
  }
109
111
 
110
112
  getImageSource() {
@@ -178,9 +180,9 @@ class Avatar {
178
180
  /** Значок состояния; `undefined` убирает его и слово из доступного имени */
179
181
  setStatus(status = undefined) {
180
182
  this.#status = status;
181
- this.#status_node.hidden = status === undefined;
182
- if (status !== undefined) this.#status_node.dataset.status = status;
183
- else this.#status_node.removeAttribute("data-status");
183
+ this.#statusNode.hidden = status === undefined;
184
+ if (status !== undefined) this.#statusNode.dataset.status = status;
185
+ else this.#statusNode.removeAttribute("data-status");
184
186
  this.#syncAria();
185
187
  return this;
186
188
  }
@@ -200,7 +202,7 @@ class Avatar {
200
202
  }
201
203
 
202
204
  addClickListener(listener = () => {}) {
203
- this.#click_listeners.push(listener);
205
+ this.#clickListeners.push(listener);
204
206
  return this;
205
207
  }
206
208
 
@@ -242,7 +244,7 @@ class Avatar {
242
244
  }
243
245
 
244
246
  #renderInitials() {
245
- this.#initials_node.innerText = this.#deriveInitials();
247
+ this.#initialsNode.innerText = this.#deriveInitials();
246
248
  this.#syncAria();
247
249
  }
248
250
 
@@ -255,16 +257,15 @@ class Avatar {
255
257
  }
256
258
  this.#root.removeAttribute("aria-hidden");
257
259
  this.#root.setAttribute("role", "img");
258
- const base = this.#label === undefined
259
- ? (this.#name === undefined ? this.#deriveInitials() : this.#name)
260
- : this.#label;
260
+ const base =
261
+ this.#label === undefined ? (this.#name === undefined ? this.#deriveInitials() : this.#name) : this.#label;
261
262
  const status = this.#status === undefined ? undefined : Avatar.STATUS_LABEL[this.#status];
262
263
  this.#root.setAttribute("aria-label", status === undefined ? base : `${base}, ${status}`);
263
264
  }
264
265
 
265
266
  #onClick = (event) => {
266
- for (const listener of [...this.#click_listeners]) listener(event);
267
+ for (const listener of [...this.#clickListeners]) listener(event);
267
268
  };
268
269
  }
269
270
 
270
- exports.Avatar = Avatar
271
+ exports.Avatar = Avatar;
@@ -20,7 +20,7 @@ chui_avatar[data-shape="circle"] {
20
20
  }
21
21
 
22
22
  chui_avatar[data-shape="square"] {
23
- border-radius: var(--border_radius);
23
+ border-radius: var(--radius_sm);
24
24
  }
25
25
 
26
26
  chui_avatar img {
@@ -1,7 +1,7 @@
1
- const {setStyles, optionOr} = require('../../modules/chui_functions');
2
- const {Avatar} = require('../chui_avatar/avatar');
3
- const {I18n} = require('../../modules/chui_i18n/chui_i18n');
4
- const {makeKeyboardButton} = require('../../modules/chui_a11y/chui_a11y');
1
+ const { setStyles, optionOr } = require("../../modules/chui_functions");
2
+ const { Avatar } = require("../chui_avatar/avatar");
3
+ const { I18n } = require("../../modules/chui_i18n/chui_i18n");
4
+ const { makeKeyboardButton } = require("../../modules/chui_a11y/chui_a11y");
5
5
 
6
6
  /**
7
7
  * Группа аватаров: несколько участников в ряд с нахлёстом и счётчиком скрытых.
@@ -45,24 +45,26 @@ class AvatarGroup {
45
45
  #size = Avatar.SIZE.DEFAULT;
46
46
  #shape = undefined;
47
47
  #extra = undefined;
48
- #extra_listener = undefined;
48
+ #extraListener = undefined;
49
49
  #label = undefined;
50
50
 
51
- constructor(options = {
52
- id: String(),
53
- avatars: [],
54
- max: Number(),
55
- size: String(),
56
- shape: String(),
57
- label: String(),
58
- extraClickListener: undefined
59
- }) {
51
+ constructor(
52
+ options = {
53
+ id: String(),
54
+ avatars: [],
55
+ max: Number(),
56
+ size: String(),
57
+ shape: String(),
58
+ label: String(),
59
+ extraClickListener: undefined,
60
+ }
61
+ ) {
60
62
  setStyles(__dirname + "/styles.css", "chUiJS_AvatarGroup");
61
63
  AvatarGroup.#counter += 1;
62
64
  this.#id = optionOr(options.id, `chui_avatar_group_${AvatarGroup.#counter}`);
63
65
  this.#root.id = this.#id;
64
66
  this.#root.setAttribute("role", "group");
65
- this.#extra_listener = options.extraClickListener;
67
+ this.#extraListener = options.extraClickListener;
66
68
  this.setSize(optionOr(options.size, Avatar.SIZE.DEFAULT));
67
69
  if (options.shape !== undefined) this.#shape = options.shape;
68
70
  if (options.max !== undefined) this.setMax(options.max);
@@ -187,13 +189,13 @@ class AvatarGroup {
187
189
  #push(item = undefined) {
188
190
  if (item === undefined || item === null) return;
189
191
  if (item instanceof Element) {
190
- this.#entries.push({node: item, avatar: undefined});
192
+ this.#entries.push({ node: item, avatar: undefined });
191
193
  return;
192
194
  }
193
195
  const avatar = item instanceof Avatar ? item : new Avatar(item);
194
196
  if (this.#size !== undefined) avatar.setSize(this.#size);
195
197
  if (this.#shape !== undefined) avatar.setShape(this.#shape);
196
- this.#entries.push({node: avatar.set(), avatar: avatar});
198
+ this.#entries.push({ node: avatar.set(), avatar: avatar });
197
199
  }
198
200
 
199
201
  #sync() {
@@ -213,24 +215,24 @@ class AvatarGroup {
213
215
  const extra = document.createElement("avatar_group_extra");
214
216
  extra.className = "avatar_group_extra";
215
217
  extra.innerText = `+${hidden}`;
216
- if (this.#extra_listener === undefined) {
218
+ if (this.#extraListener === undefined) {
217
219
  extra.setAttribute("role", "img");
218
- extra.setAttribute("aria-label", I18n.t("feedback.avatarGroupMore", {count: hidden}));
220
+ extra.setAttribute("aria-label", I18n.t("feedback.avatarGroupMore", { count: hidden }));
219
221
  } else {
220
222
  // Кнопка: Enter/Space посылает click, поэтому обработчик один
221
223
  extra.classList.add("avatar_group_extra_button");
222
- extra.setAttribute("aria-label", I18n.t("feedback.avatarGroupShowAll", {count: hidden}));
224
+ extra.setAttribute("aria-label", I18n.t("feedback.avatarGroupShowAll", { count: hidden }));
223
225
  makeKeyboardButton(extra);
224
- extra.addEventListener("click", (event) => this.#extra_listener(event, hidden, this));
226
+ extra.addEventListener("click", (event) => this.#extraListener(event, hidden, this));
225
227
  }
226
228
  this.#extra = extra;
227
229
  this.#root.appendChild(extra);
228
230
  }
229
231
 
230
232
  #syncAria() {
231
- const name = optionOr(this.#label, I18n.t("feedback.avatarGroupCount", {count: this.#entries.length}));
233
+ const name = optionOr(this.#label, I18n.t("feedback.avatarGroupCount", { count: this.#entries.length }));
232
234
  this.#root.setAttribute("aria-label", name);
233
235
  }
234
236
  }
235
237
 
236
- exports.AvatarGroup = AvatarGroup
238
+ exports.AvatarGroup = AvatarGroup;
@@ -7,7 +7,7 @@ chui_avatar_group {
7
7
  flex-wrap: nowrap;
8
8
  width: max-content;
9
9
  height: max-content;
10
- margin: var(--margin);
10
+ margin: var(--block_margin);
11
11
  --avatar_size: 40px;
12
12
  --avatar_group_ring: var(--element_background_2);
13
13
  }