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
@@ -5,18 +5,18 @@ chui_time_input {
5
5
  карточку. Токены переопределены у корня поля, поэтому действуют только внутри него
6
6
  (тот же приём у полосы меню-бара). */
7
7
  --control_padding: var(--control_padding_sm);
8
- --main_padding: var(--main_padding_sm);
8
+ --block_padding: var(--block_padding_sm);
9
9
  display: flex;
10
10
  flex-direction: column;
11
11
  width: max-content;
12
12
  height: max-content;
13
- margin: var(--margin);
13
+ margin: var(--block_margin);
14
14
  }
15
15
 
16
16
  time_input_label {
17
17
  display: block;
18
18
  width: max-content;
19
- margin: 0 0 var(--margin);
19
+ margin: 0 0 var(--block_margin);
20
20
  color: var(--text_color);
21
21
  font-size: var(--font_labels_size);
22
22
  font-weight: 500;
@@ -39,13 +39,13 @@ time_main_block {
39
39
  width: max-content;
40
40
  height: var(--control_height);
41
41
  border: 1px solid var(--border_color);
42
- border-radius: var(--border_radius);
42
+ border-radius: var(--radius_sm);
43
43
  background: var(--element_background);
44
44
  color: var(--text_color);
45
45
  }
46
46
 
47
47
  /* Индикатор часов — системный: время выбирают в своей панели, поэтому он скрыт (свой значок есть) */
48
- chui_time_input input[type=time]::-webkit-calendar-picker-indicator {
48
+ chui_time_input input[type="time"]::-webkit-calendar-picker-indicator {
49
49
  display: none;
50
50
  }
51
51
 
@@ -59,7 +59,8 @@ input.time_input {
59
59
  width: 96px;
60
60
  height: 100%;
61
61
  margin: 0;
62
- padding-block: 0 0; padding-inline: 10px 4px;
62
+ padding-block: 0 0;
63
+ padding-inline: 10px 4px;
63
64
  border: none;
64
65
  background: transparent;
65
66
  color: var(--text_color);
@@ -85,7 +86,8 @@ input.time_input:disabled {
85
86
  box-sizing: border-box;
86
87
  height: 100%;
87
88
  margin: 0;
88
- padding-block: 0 0; padding-inline: 2px 8px;
89
+ padding-block: 0 0;
90
+ padding-inline: 2px 8px;
89
91
  border: none;
90
92
  border-radius: var(--radius_sm);
91
93
  background: transparent;
@@ -132,7 +134,7 @@ input.time_input:disabled {
132
134
  в прокрутку панели — иначе колонки часов и минут обрезались бы краем окна */
133
135
  overflow: hidden auto;
134
136
  border: 1px solid var(--border_color);
135
- border-radius: var(--border_radius);
137
+ border-radius: var(--radius_sm);
136
138
  background: var(--header_background);
137
139
  backdrop-filter: var(--global_blur);
138
140
  -webkit-backdrop-filter: var(--global_blur);
@@ -142,18 +144,14 @@ input.time_input:disabled {
142
144
 
143
145
  .time_dropdown_shown {
144
146
  display: flex;
145
- animation: time_dropdown_in var(--transition_time) ease-out;
146
- }
147
-
148
- @keyframes time_dropdown_in {
149
- from {
150
- opacity: 0;
151
- transform: translateY(-4px);
152
- }
153
- to {
154
- opacity: 1;
155
- transform: none;
156
- }
147
+ /* Панель открывается общим кадром: свой у неё был тот же по смыслу (прозрачность и подъём),
148
+ но без роста, а кривая шла торможением вместо отклика */
149
+ animation: chui_panel_in var(--motion_base) var(--motion_spring);
150
+ }
151
+
152
+ /* Уход панели: она гаснет и сходит вверх, а класс показа снимается по концу кадра */
153
+ .time_dropdown_leaving {
154
+ animation: chui_leave_up var(--motion_fast) var(--motion_ease) forwards;
157
155
  }
158
156
 
159
157
  .time_list {
@@ -1,7 +1,7 @@
1
- const {setStyles, optionOr, dropdownPlacement} = require('../../../modules/chui_functions');
2
- const {Icon, Icons} = require('../../chui_icons/icons');
3
- const {Validate} = require('../../../modules/chui_validate/chui_validate');
4
- const {I18n} = require('../../../modules/chui_i18n/chui_i18n');
1
+ const { setStyles, optionOr, dropdownPlacement } = require("../../../modules/chui_functions");
2
+ const { Icon, Icons } = require("../../chui_icons/icons");
3
+ const { Validate } = require("../../../modules/chui_validate/chui_validate");
4
+ const { I18n } = require("../../../modules/chui_i18n/chui_i18n");
5
5
 
6
6
  // Формат значения поля: 24-часовое «ЧЧ:ММ» — так же, как отдаёт нативный input[type=time]
7
7
  const TIME_PATTERN = "^([01][0-9]|2[0-3]):[0-5][0-9]$";
@@ -47,38 +47,40 @@ class TimeInput {
47
47
  #minutes = document.createElement("time_list");
48
48
  #id = undefined;
49
49
  #name = undefined;
50
- #title_text = undefined;
51
- #label_text = undefined;
50
+ #titleText = undefined;
51
+ #labelText = undefined;
52
52
  #step = 5;
53
53
  #min = undefined;
54
54
  #max = undefined;
55
55
  #disabled = false;
56
- #is_open = false;
56
+ #isOpen = false;
57
57
  #listeners = [];
58
- #on_change = undefined;
59
- #window_click_event = (event) => {
58
+ #onChange = undefined;
59
+ #windowClickEvent = (event) => {
60
60
  if (!this.#block.contains(event.target)) this.#closeDropdown();
61
61
  };
62
62
 
63
- constructor(options = {
64
- id: String(),
65
- name: String(),
66
- title: String(),
67
- label: String(),
68
- value: String(),
69
- step: Number(),
70
- min: String(),
71
- max: String(),
72
- disabled: Boolean(),
73
- changeListener: undefined,
74
- onChange: undefined
75
- }) {
63
+ constructor(
64
+ options = {
65
+ id: String(),
66
+ name: String(),
67
+ title: String(),
68
+ label: String(),
69
+ value: String(),
70
+ step: Number(),
71
+ min: String(),
72
+ max: String(),
73
+ disabled: Boolean(),
74
+ changeListener: undefined,
75
+ onChange: undefined,
76
+ }
77
+ ) {
76
78
  setStyles(__dirname + "/styles.css", "chUiJS_TimeInput");
77
79
  TimeInput.#counter += 1;
78
80
  this.#id = options.id === undefined ? `chui_time_input_${TimeInput.#counter}` : options.id;
79
81
  this.#name = options.name;
80
- this.#label_text = options.label;
81
- this.#on_change = options.onChange;
82
+ this.#labelText = options.label;
83
+ this.#onChange = options.onChange;
82
84
  if (options.changeListener !== undefined) this.addChangeListener(options.changeListener);
83
85
  this.#root.id = this.#id;
84
86
  this.#input.type = "time";
@@ -114,7 +116,7 @@ class TimeInput {
114
116
  this.#open.appendChild(glyph);
115
117
  this.#open.addEventListener("click", () => {
116
118
  if (this.#input.disabled) return;
117
- if (this.#is_open) this.#closeDropdown();
119
+ if (this.#isOpen) this.#closeDropdown();
118
120
  else this.#openDropdown();
119
121
  });
120
122
  this.#label.className = "time_input_label";
@@ -138,22 +140,29 @@ class TimeInput {
138
140
  delete rules.min;
139
141
  delete rules.max;
140
142
  if (rules.pattern === undefined) rules.pattern = TIME_PATTERN;
141
- const own_validate = options.validate;
143
+ const ownValidate = options.validate;
142
144
  if (this.#min !== undefined || this.#max !== undefined) {
143
145
  rules.validate = (value) => {
144
- const custom = own_validate === undefined ? undefined : own_validate(value);
146
+ const custom = ownValidate === undefined ? undefined : ownValidate(value);
145
147
  if (custom !== undefined && custom !== null && custom !== true) return custom;
146
148
  const parsed = TimeInput.parse(value);
147
149
  if (parsed === undefined) return undefined;
148
- if (this.#min !== undefined && parsed < this.#min) return I18n.t("time.min", {min: this.#min});
149
- if (this.#max !== undefined && parsed > this.#max) return I18n.t("time.max", {max: this.#max});
150
+ if (this.#min !== undefined && parsed < this.#min) return I18n.t("time.min", { min: this.#min });
151
+ if (this.#max !== undefined && parsed > this.#max) return I18n.t("time.max", { max: this.#max });
150
152
  return undefined;
151
153
  };
152
154
  }
153
- Validate.installField(this, rules, this.#root, undefined, () => (this.#input.value === undefined ? "" : this.#input.value), this.#block);
155
+ Validate.installField(
156
+ this,
157
+ rules,
158
+ this.#root,
159
+ undefined,
160
+ () => (this.#input.value === undefined ? "" : this.#input.value),
161
+ this.#block
162
+ );
154
163
  if (options.value !== undefined) this.setValue(options.value);
155
164
  this.setDisabled(options.disabled === true);
156
- window.addEventListener('click', this.#window_click_event);
165
+ window.addEventListener("click", this.#windowClickEvent);
157
166
  }
158
167
 
159
168
  // GET
@@ -166,7 +175,7 @@ class TimeInput {
166
175
  }
167
176
 
168
177
  getTitle() {
169
- return this.#title_text;
178
+ return this.#titleText;
170
179
  }
171
180
 
172
181
  /** Значение в виде «ЧЧ:ММ»; пустая строка — время не задано */
@@ -192,7 +201,7 @@ class TimeInput {
192
201
  }
193
202
 
194
203
  isOpen() {
195
- return this.#is_open;
204
+ return this.#isOpen;
196
205
  }
197
206
 
198
207
  /**
@@ -236,7 +245,7 @@ class TimeInput {
236
245
 
237
246
  /** Подпись над полем; `undefined` её убирает */
238
247
  setTitle(text = undefined) {
239
- this.#title_text = text;
248
+ this.#titleText = text;
240
249
  if (text === undefined || text === "") {
241
250
  this.#label.hidden = true;
242
251
  this.#label.innerText = "";
@@ -255,8 +264,8 @@ class TimeInput {
255
264
 
256
265
  /** Доступное имя поля, когда подписи в разметке нет */
257
266
  setLabel(text = undefined) {
258
- this.#label_text = text;
259
- if (this.#title_text === undefined || this.#title_text === "") {
267
+ this.#labelText = text;
268
+ if (this.#titleText === undefined || this.#titleText === "") {
260
269
  if (text === undefined) this.#input.removeAttribute("aria-label");
261
270
  else this.#input.setAttribute("aria-label", String(text));
262
271
  }
@@ -342,8 +351,8 @@ class TimeInput {
342
351
 
343
352
  // === ПАНЕЛЬ ===
344
353
  #accessibleName() {
345
- if (this.#title_text !== undefined && this.#title_text !== "") return this.#title_text;
346
- if (this.#label_text !== undefined && this.#label_text !== "") return this.#label_text;
354
+ if (this.#titleText !== undefined && this.#titleText !== "") return this.#titleText;
355
+ if (this.#labelText !== undefined && this.#labelText !== "") return this.#labelText;
347
356
  return I18n.t("time.label");
348
357
  }
349
358
 
@@ -378,8 +387,10 @@ class TimeInput {
378
387
  const selected = TimeInput.parse(this.getValue());
379
388
  const hours = selected === undefined ? undefined : selected.slice(0, 2);
380
389
  const minutes = selected === undefined ? undefined : selected.slice(3, 5);
381
- for (const option of this.#visibleOptions(this.#hours)) this.#markSelected(option, option.dataset.value === hours);
382
- for (const option of this.#visibleOptions(this.#minutes)) this.#markSelected(option, option.dataset.value === minutes);
390
+ for (const option of this.#visibleOptions(this.#hours))
391
+ this.#markSelected(option, option.dataset.value === hours);
392
+ for (const option of this.#visibleOptions(this.#minutes))
393
+ this.#markSelected(option, option.dataset.value === minutes);
383
394
  }
384
395
 
385
396
  #markSelected(option = new HTMLElement(), selected = Boolean()) {
@@ -390,8 +401,8 @@ class TimeInput {
390
401
 
391
402
  #pick(unit = String(), text = String()) {
392
403
  const current = TimeInput.parse(this.getValue());
393
- const hours = unit === "hours" ? text : (current === undefined ? "00" : current.slice(0, 2));
394
- const minutes = unit === "minutes" ? text : (current === undefined ? "00" : current.slice(3, 5));
404
+ const hours = unit === "hours" ? text : current === undefined ? "00" : current.slice(0, 2);
405
+ const minutes = unit === "minutes" ? text : current === undefined ? "00" : current.slice(3, 5);
395
406
  this.#input.value = `${hours}:${minutes}`;
396
407
  this.#changed();
397
408
  }
@@ -414,11 +425,12 @@ class TimeInput {
414
425
 
415
426
  #openDropdown() {
416
427
  this.#renderOptions();
417
- this.#is_open = true;
428
+ this.#isOpen = true;
418
429
  this.#input.setAttribute("aria-expanded", "true");
419
430
  // Показ — классом, а не общей `Animation`: её `animationend` снимает `display`,
420
431
  // и панель, открытая поверх незавершённого закрытия, гасла бы сама.
421
432
  // Класс назван иначе, чем у каретки: одно имя давало бы панели стили кнопки
433
+ this.#dropdown.classList.remove("time_dropdown_leaving");
422
434
  this.#dropdown.classList.add("time_dropdown_shown");
423
435
  this.#placeDropdown();
424
436
  this.#focusSelected("hours");
@@ -437,10 +449,20 @@ class TimeInput {
437
449
  }
438
450
 
439
451
  #closeDropdown() {
440
- if (!this.#is_open) return;
441
- this.#is_open = false;
452
+ if (!this.#isOpen) return;
453
+ this.#isOpen = false;
442
454
  this.#input.setAttribute("aria-expanded", "false");
443
- this.#dropdown.classList.remove("time_dropdown_shown");
455
+ // Уход идёт движением: класс показа снимается по концу кадра, а незавершённый уход
456
+ // отменяется при открытии — иначе панель погасла бы уже открытой
457
+ this.#dropdown.classList.add("time_dropdown_leaving");
458
+ const done = (event) => {
459
+ if (event.target !== this.#dropdown) return;
460
+ this.#dropdown.removeEventListener("animationend", done);
461
+ if (this.#dropdown.classList.contains("time_dropdown_leaving") === false) return;
462
+ this.#dropdown.classList.remove("time_dropdown_leaving");
463
+ this.#dropdown.classList.remove("time_dropdown_shown");
464
+ };
465
+ this.#dropdown.addEventListener("animationend", done);
444
466
  }
445
467
 
446
468
  #changed() {
@@ -448,7 +470,7 @@ class TimeInput {
448
470
  this.#markOptions();
449
471
  const value = this.getValue();
450
472
  for (const listener of [...this.#listeners]) listener(value, this);
451
- if (this.#on_change !== undefined) this.#on_change(value, this);
473
+ if (this.#onChange !== undefined) this.#onChange(value, this);
452
474
  }
453
475
 
454
476
  #moveOption(delta = Number()) {
@@ -539,9 +561,9 @@ class TimeInput {
539
561
 
540
562
  /** Полное удаление: панель и слушатель окна */
541
563
  destroy() {
542
- window.removeEventListener('click', this.#window_click_event);
564
+ window.removeEventListener("click", this.#windowClickEvent);
543
565
  this.#closeDropdown();
544
566
  }
545
567
  }
546
568
 
547
- exports.TimeInput = TimeInput
569
+ exports.TimeInput = TimeInput;
@@ -3,7 +3,7 @@
3
3
  width: 50px;
4
4
  height: 25px;
5
5
  border-radius: var(--radius_pill);
6
- margin: var(--margin);
6
+ margin: var(--block_margin);
7
7
  background: var(--element_background);
8
8
  border: none;
9
9
  box-shadow: 0 0 1px 0 var(--border_color);
@@ -44,20 +44,27 @@
44
44
  белой: один и тот же тумблер менял цвет детали */
45
45
  .slider:before {
46
46
  position: absolute;
47
- content: '';
47
+ content: "";
48
48
  height: 15px;
49
49
  width: 15px;
50
50
  inset-inline-start: 5px;
51
51
  bottom: 5px;
52
52
  border-radius: var(--radius_circle);
53
53
  background-color: var(--text_color_hover);
54
- /* Тень как у бегунка ползунка: поднятая белая деталь на дорожке */
55
- box-shadow: 0 1px 3px rgb(0 0 0 / 16%);
54
+ /* Тень как у бегунка ползунка: поднятая белая деталь на дорожке — общий ключ
55
+ контролов */
56
+ box-shadow: var(--box_shadow_control);
57
+ /* Ручка едет пружиной: лёгкий перелёт читается как щелчок переключателя.
58
+ Свой список перехода заменяет общий, поэтому цвет и тень перечислены рядом */
59
+ transition:
60
+ transform var(--motion_base) var(--motion_spring),
61
+ background-color var(--motion_fast) var(--motion_ease),
62
+ box-shadow var(--motion_fast) var(--motion_ease);
56
63
  }
57
64
 
58
65
  input:checked + .slider:before {
59
66
  position: absolute;
60
- content: '';
67
+ content: "";
61
68
  height: 15px;
62
69
  width: 15px;
63
70
  inset-inline-start: 5px;
@@ -110,4 +117,4 @@ input:checked + .slider:before {
110
117
  /* Включённый, но выключенный — цвет выделения тоже приглушается */
111
118
  .switch.switch_disabled input:checked + .slider {
112
119
  background: var(--element_background_disabled);
113
- }
120
+ }
@@ -1,36 +1,36 @@
1
- const {Validate} = require('../../../modules/chui_validate/chui_validate');
1
+ const { Validate } = require("../../../modules/chui_validate/chui_validate");
2
2
 
3
3
  class Toggle {
4
- #Toggle = document.createElement('label');
5
- #toggle_span = document.createElement('span');
6
- #toggle_input = document.createElement('input');
4
+ #Toggle = document.createElement("label");
5
+ #toggleSpan = document.createElement("span");
6
+ #toggleInput = document.createElement("input");
7
7
  #label = undefined;
8
- constructor(options = {label: String(), name: String(), value: Boolean(), disabled: Boolean()}) {
8
+ constructor(options = { label: String(), name: String(), value: Boolean(), disabled: Boolean() }) {
9
9
  // Валидация: required для переключателя — «должен быть включён»
10
- Validate.installField(this, options, this.#Toggle, undefined, () => this.#toggle_input.checked);
11
- require('../../../modules/chui_functions').setStyles(__dirname + "/styles.css", "chUiJS_Toggle")
12
- this.#Toggle.className = 'switch';
13
- this.#toggle_input.type = 'checkbox';
14
- this.#toggle_span.className = 'slider round';
15
- if (options.name !== undefined) this.#toggle_input.name = options.name;
10
+ Validate.installField(this, options, this.#Toggle, undefined, () => this.#toggleInput.checked);
11
+ require("../../../modules/chui_functions").setStyles(__dirname + "/styles.css", "chUiJS_Toggle");
12
+ this.#Toggle.className = "switch";
13
+ this.#toggleInput.type = "checkbox";
14
+ this.#toggleSpan.className = "slider round";
15
+ if (options.name !== undefined) this.#toggleInput.name = options.name;
16
16
  // В разметке переключателя нет текста, поэтому подпись уходит в aria-label
17
17
  this.setLabel(options.label);
18
- this.#Toggle.appendChild(this.#toggle_input);
19
- this.#Toggle.appendChild(this.#toggle_span);
18
+ this.#Toggle.appendChild(this.#toggleInput);
19
+ this.#Toggle.appendChild(this.#toggleSpan);
20
20
  if (options.value !== undefined) this.setValue(options.value === true);
21
21
  if (options.disabled !== undefined) this.setDisabled(options.disabled === true);
22
22
  }
23
23
  setMargin(pos = { top: undefined, bottom: undefined, left: undefined, right: undefined }) {
24
- if (pos.top !== undefined) this.#Toggle.style.marginTop = pos.top
25
- if (pos.bottom !== undefined) this.#Toggle.style.marginBottom = pos.bottom
26
- if (pos.left !== undefined) this.#Toggle.style.marginLeft = pos.left
27
- if (pos.right !== undefined) this.#Toggle.style.marginRight = pos.right
24
+ if (pos.top !== undefined) this.#Toggle.style.marginTop = pos.top;
25
+ if (pos.bottom !== undefined) this.#Toggle.style.marginBottom = pos.bottom;
26
+ if (pos.left !== undefined) this.#Toggle.style.marginLeft = pos.left;
27
+ if (pos.right !== undefined) this.#Toggle.style.marginRight = pos.right;
28
28
  }
29
29
  setId(id) {
30
30
  this.#Toggle.id = id;
31
31
  }
32
32
  getName() {
33
- return this.#toggle_input.name;
33
+ return this.#toggleInput.name;
34
34
  }
35
35
  /** Подпись для скринридера: в самой разметке переключателя текста нет */
36
36
  getLabel() {
@@ -38,30 +38,30 @@ class Toggle {
38
38
  }
39
39
  setLabel(label = String()) {
40
40
  this.#label = label === undefined || label === "" ? undefined : label;
41
- if (this.#label === undefined) this.#toggle_input.removeAttribute("aria-label");
42
- else this.#toggle_input.setAttribute("aria-label", this.#label);
41
+ if (this.#label === undefined) this.#toggleInput.removeAttribute("aria-label");
42
+ else this.#toggleInput.setAttribute("aria-label", this.#label);
43
43
  return this;
44
44
  }
45
45
  getDisabled() {
46
- return this.#toggle_input.disabled;
46
+ return this.#toggleInput.disabled;
47
47
  }
48
48
  setDisabled(boolean = Boolean()) {
49
- this.#toggle_input.disabled = boolean;
49
+ this.#toggleInput.disabled = boolean;
50
50
  this.#Toggle.classList.toggle("switch_disabled", boolean);
51
51
  return this;
52
52
  }
53
- addChangeListener (listener) {
54
- this.#toggle_input.addEventListener('change', listener);
53
+ addChangeListener(listener) {
54
+ this.#toggleInput.addEventListener("change", listener);
55
55
  }
56
56
  getValue() {
57
- return this.#toggle_input.checked;
57
+ return this.#toggleInput.checked;
58
58
  }
59
59
  setValue(boolean) {
60
- this.#toggle_input.checked = boolean;
60
+ this.#toggleInput.checked = boolean;
61
61
  }
62
62
  set() {
63
63
  return this.#Toggle;
64
64
  }
65
65
  }
66
66
 
67
- exports.Toggle = Toggle
67
+ exports.Toggle = Toggle;