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.
Files changed (258) hide show
  1. package/CHANGELOG.md +536 -0
  2. package/framework/appLayout/default/chui_app_layout.js +361 -303
  3. package/framework/appLayout/default/global_style.css +243 -89
  4. package/framework/appLayout/default/main_theme_style.css +188 -101
  5. package/framework/components/chui_accordion/accordion.js +17 -17
  6. package/framework/components/chui_accordion/styles.css +7 -7
  7. package/framework/components/chui_action_sheet/action_sheet.js +35 -32
  8. package/framework/components/chui_action_sheet/styles.css +10 -4
  9. package/framework/components/chui_actions_bar/actions_bar.js +338 -0
  10. package/framework/components/chui_actions_bar/styles.css +139 -0
  11. package/framework/components/chui_affix/affix.js +4 -4
  12. package/framework/components/chui_affix/styles.css +5 -0
  13. package/framework/components/chui_alert/alert.js +11 -5
  14. package/framework/components/chui_alert/styles.css +7 -0
  15. package/framework/components/chui_avatar/avatar.js +13 -13
  16. package/framework/components/chui_avatar/styles.css +1 -1
  17. package/framework/components/chui_avatar_group/avatar_group.js +4 -4
  18. package/framework/components/chui_avatar_group/styles.css +1 -1
  19. package/framework/components/chui_backtop/backtop.js +25 -2
  20. package/framework/components/chui_backtop/styles.css +21 -0
  21. package/framework/components/chui_badge/badge.js +15 -15
  22. package/framework/components/chui_badge/styles.css +6 -6
  23. package/framework/components/chui_banner/banner.js +222 -0
  24. package/framework/components/chui_banner/styles.css +170 -0
  25. package/framework/components/chui_breadcrumb/styles.css +1 -1
  26. package/framework/components/chui_button/button.js +24 -28
  27. package/framework/components/chui_button/styles.css +5 -5
  28. package/framework/components/chui_calendar/calendar.js +6 -6
  29. package/framework/components/chui_card/card.js +14 -14
  30. package/framework/components/chui_card_scroll/card_scroll.js +169 -0
  31. package/framework/components/chui_card_scroll/styles.css +86 -0
  32. package/framework/components/chui_chat/chat.js +73 -51
  33. package/framework/components/chui_chat/styles.css +18 -7
  34. package/framework/components/chui_clipboard_history/clipboard_history.js +25 -20
  35. package/framework/components/chui_clipboard_history/styles.css +10 -8
  36. package/framework/components/chui_code/code.js +8 -8
  37. package/framework/components/chui_code/styles.css +2 -2
  38. package/framework/components/chui_code_editor/code_editor.js +26 -26
  39. package/framework/components/chui_code_editor/styles.css +3 -3
  40. package/framework/components/chui_command_palette/command_palette.js +29 -29
  41. package/framework/components/chui_command_palette/styles.css +5 -5
  42. package/framework/components/chui_console/console.js +9 -9
  43. package/framework/components/chui_console/styles.css +5 -2
  44. package/framework/components/chui_content_block/content_block.js +2 -2
  45. package/framework/components/chui_context_menu/context_menu.js +162 -54
  46. package/framework/components/chui_context_menu/styles.css +82 -8
  47. package/framework/components/chui_custom_element/custom_element.js +11 -11
  48. package/framework/components/chui_data_grid/data_grid.js +268 -268
  49. package/framework/components/chui_data_grid/styles.css +14 -14
  50. package/framework/components/chui_descriptions/styles.css +1 -1
  51. package/framework/components/chui_details/details.js +12 -12
  52. package/framework/components/chui_details/styles.css +7 -7
  53. package/framework/components/chui_diff_viewer/diff_viewer.js +88 -88
  54. package/framework/components/chui_diff_viewer/styles.css +9 -9
  55. package/framework/components/chui_divider/divider.js +6 -6
  56. package/framework/components/chui_divider/styles.css +2 -2
  57. package/framework/components/chui_drawer/drawer.js +37 -14
  58. package/framework/components/chui_drawer/styles.css +18 -4
  59. package/framework/components/chui_drop_zone/drop_zone.js +6 -6
  60. package/framework/components/chui_drop_zone/styles.css +10 -6
  61. package/framework/components/chui_fieldset/fieldset.js +6 -6
  62. package/framework/components/chui_fieldset/styles.css +5 -5
  63. package/framework/components/chui_file_explorer/file_explorer.js +115 -115
  64. package/framework/components/chui_file_explorer/styles.css +6 -6
  65. package/framework/components/chui_form/form.js +11 -11
  66. package/framework/components/chui_gantt/gantt.js +41 -41
  67. package/framework/components/chui_gantt/styles.css +5 -5
  68. package/framework/components/chui_graphs/graphs.js +82 -46
  69. package/framework/components/chui_graphs/styles.css +26 -5
  70. package/framework/components/chui_hero/hero.js +63 -20
  71. package/framework/components/chui_hero/styles.css +176 -7
  72. package/framework/components/chui_html_block/html_block.js +5 -5
  73. package/framework/components/chui_html_block/styles.css +1 -1
  74. package/framework/components/chui_hx/styles.css +2 -2
  75. package/framework/components/chui_icons/icons.js +7 -7
  76. package/framework/components/chui_icons/styles.css +2 -1
  77. package/framework/components/chui_inputs/chui_check_box/styles.css +12 -3
  78. package/framework/components/chui_inputs/chui_chips/chips.js +92 -31
  79. package/framework/components/chui_inputs/chui_chips/styles.css +28 -5
  80. package/framework/components/chui_inputs/chui_color_picker/color_picker.js +20 -15
  81. package/framework/components/chui_inputs/chui_color_picker/styles.css +7 -7
  82. package/framework/components/chui_inputs/chui_combo_box/combo_box.js +58 -58
  83. package/framework/components/chui_inputs/chui_combo_box/styles.css +9 -9
  84. package/framework/components/chui_inputs/chui_date/date.js +93 -95
  85. package/framework/components/chui_inputs/chui_date/styles.css +8 -8
  86. package/framework/components/chui_inputs/chui_date_range/date_range.js +22 -22
  87. package/framework/components/chui_inputs/chui_date_range/styles.css +3 -3
  88. package/framework/components/chui_inputs/chui_datetime/datetime.js +12 -12
  89. package/framework/components/chui_inputs/chui_datetime/styles.css +3 -3
  90. package/framework/components/chui_inputs/chui_email/email.js +10 -10
  91. package/framework/components/chui_inputs/chui_email/styles.css +6 -6
  92. package/framework/components/chui_inputs/chui_file/file.js +8 -8
  93. package/framework/components/chui_inputs/chui_file/styles.css +12 -9
  94. package/framework/components/chui_inputs/chui_hotkey/hotkey.js +39 -39
  95. package/framework/components/chui_inputs/chui_hotkey/styles.css +6 -6
  96. package/framework/components/chui_inputs/chui_masked/masked.js +44 -44
  97. package/framework/components/chui_inputs/chui_masked/styles.css +5 -5
  98. package/framework/components/chui_inputs/chui_mention/mention.js +13 -13
  99. package/framework/components/chui_inputs/chui_mention/styles.css +14 -8
  100. package/framework/components/chui_inputs/chui_multi_combo_box/multi_combo_box.js +147 -137
  101. package/framework/components/chui_inputs/chui_multi_combo_box/styles.css +14 -8
  102. package/framework/components/chui_inputs/chui_number/number.js +42 -45
  103. package/framework/components/chui_inputs/chui_number/styles.css +6 -6
  104. package/framework/components/chui_inputs/chui_otp/otp.js +32 -32
  105. package/framework/components/chui_inputs/chui_otp/styles.css +5 -5
  106. package/framework/components/chui_inputs/chui_password/password.js +30 -36
  107. package/framework/components/chui_inputs/chui_password/styles.css +7 -7
  108. package/framework/components/chui_inputs/chui_radio_button/styles.css +2 -2
  109. package/framework/components/chui_inputs/chui_rating/rating.js +28 -28
  110. package/framework/components/chui_inputs/chui_rating/styles.css +3 -3
  111. package/framework/components/chui_inputs/chui_select_box/select_box.js +54 -54
  112. package/framework/components/chui_inputs/chui_select_box/styles.css +10 -10
  113. package/framework/components/chui_inputs/chui_slider/slider.js +14 -14
  114. package/framework/components/chui_inputs/chui_slider/styles.css +5 -4
  115. package/framework/components/chui_inputs/chui_text/styles.css +7 -7
  116. package/framework/components/chui_inputs/chui_text/text.js +13 -17
  117. package/framework/components/chui_inputs/chui_text_area/styles.css +8 -8
  118. package/framework/components/chui_inputs/chui_text_area/text_area.js +23 -23
  119. package/framework/components/chui_inputs/chui_time/styles.css +13 -17
  120. package/framework/components/chui_inputs/chui_time/time.js +35 -24
  121. package/framework/components/chui_inputs/chui_toggle/styles.css +10 -3
  122. package/framework/components/chui_inputs/chui_toggle/toggle.js +16 -16
  123. package/framework/components/chui_json_editor/json_editor.js +87 -87
  124. package/framework/components/chui_json_editor/styles.css +5 -5
  125. package/framework/components/chui_json_viewer/json_viewer.js +80 -80
  126. package/framework/components/chui_json_viewer/styles.css +6 -6
  127. package/framework/components/chui_kanban/kanban.js +27 -27
  128. package/framework/components/chui_kanban/styles.css +8 -4
  129. package/framework/components/chui_kbd/styles.css +1 -1
  130. package/framework/components/chui_label/label.js +17 -17
  131. package/framework/components/chui_label/styles.css +1 -1
  132. package/framework/components/chui_link/link.js +9 -9
  133. package/framework/components/chui_link/styles.css +11 -4
  134. package/framework/components/chui_list/list.js +11 -11
  135. package/framework/components/chui_list/styles.css +2 -2
  136. package/framework/components/chui_markdown_editor/markdown_editor.js +66 -66
  137. package/framework/components/chui_markdown_editor/styles.css +5 -5
  138. package/framework/components/chui_media/audio.js +240 -246
  139. package/framework/components/chui_media/audio_styles.css +41 -23
  140. package/framework/components/chui_media/image.js +49 -46
  141. package/framework/components/chui_media/image_compare.js +35 -35
  142. package/framework/components/chui_media/image_compare_styles.css +5 -5
  143. package/framework/components/chui_media/image_styles.css +1 -1
  144. package/framework/components/chui_media/video.js +148 -148
  145. package/framework/components/chui_media/video_styles.css +27 -11
  146. package/framework/components/chui_menu_bar/menu_bar.js +54 -54
  147. package/framework/components/chui_menu_bar/styles.css +10 -10
  148. package/framework/components/chui_message_bar/message_bar.js +551 -0
  149. package/framework/components/chui_message_bar/styles.css +248 -0
  150. package/framework/components/chui_modal/modal.js +37 -13
  151. package/framework/components/chui_notification/notification.js +76 -54
  152. package/framework/components/chui_notification/notification_download.js +26 -81
  153. package/framework/components/chui_notification/notification_download_card.js +115 -0
  154. package/framework/components/chui_notification/notification_download_progress.css +2 -2
  155. package/framework/components/chui_notification/notification_download_progress.js +70 -108
  156. package/framework/components/chui_notification/notification_update.js +31 -31
  157. package/framework/components/chui_notification/status_plate.css +3 -3
  158. package/framework/components/chui_notification/styles.css +6 -1
  159. package/framework/components/chui_notification/styles_download.css +1 -1
  160. package/framework/components/chui_notification/styles_update.css +2 -2
  161. package/framework/components/chui_org_chart/org_chart.js +29 -29
  162. package/framework/components/chui_org_chart/styles.css +2 -2
  163. package/framework/components/chui_pagination/pagination.js +3 -3
  164. package/framework/components/chui_pagination/styles.css +1 -1
  165. package/framework/components/chui_paragraph/styles.css +2 -2
  166. package/framework/components/chui_popover/popover.js +29 -23
  167. package/framework/components/chui_popover/styles.css +1 -1
  168. package/framework/components/chui_popups/popups.js +124 -124
  169. package/framework/components/chui_popups/styles.css +5 -5
  170. package/framework/components/chui_print_button/print_button.js +15 -10
  171. package/framework/components/chui_progress_bar/progress_bar.js +34 -12
  172. package/framework/components/chui_progress_bar/styles.css +4 -4
  173. package/framework/components/chui_progress_ring/progress_ring.js +15 -15
  174. package/framework/components/chui_progress_ring/styles.css +1 -1
  175. package/framework/components/chui_qrcode/qrcode.js +12 -12
  176. package/framework/components/chui_query_builder/query_builder.js +46 -46
  177. package/framework/components/chui_query_builder/styles.css +4 -4
  178. package/framework/components/chui_radio_group/styles.css +1 -1
  179. package/framework/components/chui_result/result.js +15 -15
  180. package/framework/components/chui_result/styles.css +3 -3
  181. package/framework/components/chui_scheduler/scheduler.js +74 -74
  182. package/framework/components/chui_scheduler/styles.css +5 -5
  183. package/framework/components/chui_screen_spinner/screen_spinner.js +167 -0
  184. package/framework/components/chui_screen_spinner/styles.css +49 -0
  185. package/framework/components/chui_segmented_control/segmented_control.js +63 -6
  186. package/framework/components/chui_segmented_control/styles.css +32 -6
  187. package/framework/components/chui_settings/settings.js +45 -46
  188. package/framework/components/chui_settings/styles.css +4 -4
  189. package/framework/components/chui_shortcut_help/shortcut_help.js +32 -34
  190. package/framework/components/chui_sidebar_nav/sidebar_nav.js +98 -29
  191. package/framework/components/chui_sidebar_nav/styles.css +9 -3
  192. package/framework/components/chui_slideshow/slideshow.js +85 -85
  193. package/framework/components/chui_slideshow/styles.css +6 -6
  194. package/framework/components/chui_spinner/spinner.js +10 -10
  195. package/framework/components/chui_split_button/split_button.js +30 -12
  196. package/framework/components/chui_split_button/styles.css +21 -5
  197. package/framework/components/chui_splitter/splitter.js +11 -11
  198. package/framework/components/chui_splitter/styles.css +2 -2
  199. package/framework/components/chui_statistic/statistic.js +47 -47
  200. package/framework/components/chui_status_bar/styles.css +2 -2
  201. package/framework/components/chui_stepper/stepper.js +202 -31
  202. package/framework/components/chui_stepper/styles.css +79 -14
  203. package/framework/components/chui_sticky_bar/sticky_bar.js +44 -13
  204. package/framework/components/chui_sticky_bar/styles.css +10 -8
  205. package/framework/components/chui_tabs/chui_tabs.js +74 -26
  206. package/framework/components/chui_tabs/styles.css +40 -12
  207. package/framework/components/chui_text_editor/styles.css +7 -7
  208. package/framework/components/chui_text_editor/text_editor.js +56 -56
  209. package/framework/components/chui_text_editor/text_editor_panel.js +173 -174
  210. package/framework/components/chui_theme_toggle/theme_toggle.js +21 -5
  211. package/framework/components/chui_timeline/styles.css +3 -1
  212. package/framework/components/chui_toast_queue/styles.css +11 -11
  213. package/framework/components/chui_toast_queue/toast_queue.js +30 -27
  214. package/framework/components/chui_toolbar/styles.css +2 -2
  215. package/framework/components/chui_tooltip/styles.css +2 -2
  216. package/framework/components/chui_tooltip/tooltip.js +3 -3
  217. package/framework/components/chui_tour/styles.css +8 -8
  218. package/framework/components/chui_tour/tour.js +72 -72
  219. package/framework/components/chui_transfer/styles.css +6 -6
  220. package/framework/components/chui_transfer/transfer.js +93 -106
  221. package/framework/components/chui_tree_table/styles.css +4 -4
  222. package/framework/components/chui_tree_table/tree_table.js +45 -45
  223. package/framework/components/chui_tree_view/styles.css +10 -8
  224. package/framework/components/chui_tree_view/tree_view.js +185 -183
  225. package/framework/components/chui_user_bar/styles.css +145 -0
  226. package/framework/components/chui_user_bar/user_bar.js +402 -0
  227. package/framework/components/chui_user_list_bar/styles.css +173 -0
  228. package/framework/components/chui_user_list_bar/user_list_bar.js +485 -0
  229. package/framework/components/chui_watermark/watermark.js +17 -17
  230. package/framework/components/chui_webview/webview.js +9 -9
  231. package/framework/components/chui_write_bar/styles.css +172 -0
  232. package/framework/components/chui_write_bar/write_bar.js +320 -0
  233. package/framework/main_window.js +1234 -0
  234. package/framework/modules/chui_a11y/chui_a11y.js +78 -79
  235. package/framework/modules/chui_animations/animations.js +77 -15
  236. package/framework/modules/chui_animations/motion.js +120 -0
  237. package/framework/modules/chui_animations/styles.css +36 -3
  238. package/framework/modules/chui_functions.js +31 -27
  239. package/framework/modules/chui_highlight/styles.css +13 -10
  240. package/framework/modules/chui_i18n/chui_i18n.js +3 -3
  241. package/framework/modules/chui_i18n/locales/feedback.js +62 -0
  242. package/framework/modules/chui_i18n/locales/navigation.js +4 -0
  243. package/framework/modules/chui_json/chui_json.js +2 -2
  244. package/framework/modules/chui_logger/chui_logger.js +23 -8
  245. package/framework/modules/chui_page/page.js +10 -10
  246. package/framework/modules/chui_palette/palette.js +61 -0
  247. package/framework/modules/chui_qr/chui_qr.js +23 -23
  248. package/framework/modules/chui_scrollbar/chui_scrollbar.js +45 -45
  249. package/framework/modules/chui_scrollbar/styles.css +3 -3
  250. package/framework/modules/chui_services/chui_services.js +8 -8
  251. package/framework/modules/chui_services/desktop.js +77 -71
  252. package/framework/modules/chui_sortable/chui_sortable.js +17 -17
  253. package/framework/modules/chui_validate/chui_validate.js +3 -3
  254. package/framework/tray_bar/chui_menu_items.js +2 -2
  255. package/index.d.ts +266 -34
  256. package/index.js +20 -1168
  257. package/package.json +6 -4
  258. package/framework/components/telegram_bot/chui_telegram_bot.js +0 -191
@@ -28,14 +28,14 @@ class Slider {
28
28
  #root = document.createElement("chui_slider");
29
29
  #header = document.createElement("slider_header");
30
30
  #title = document.createElement("slider_title");
31
- #value_text = document.createElement("slider_value");
31
+ #valueLabel = document.createElement("slider_value");
32
32
  #field = document.createElement("slider_field");
33
33
  #track = document.createElement("slider_track");
34
34
  #fill = document.createElement("slider_fill");
35
35
  #thumbs = [];
36
36
  #id = undefined;
37
37
  #name = undefined;
38
- #title_text = undefined;
38
+ #titleText = undefined;
39
39
  #label = undefined;
40
40
  #min = 0;
41
41
  #max = 100;
@@ -44,8 +44,8 @@ class Slider {
44
44
  #values = [0];
45
45
  #disabled = false;
46
46
  #format = undefined;
47
- #change_listeners = [];
48
- #input_listeners = [];
47
+ #changeListeners = [];
48
+ #inputListeners = [];
49
49
  #dragging = undefined;
50
50
 
51
51
  constructor(
@@ -88,13 +88,13 @@ class Slider {
88
88
  }
89
89
  this.#track.addEventListener("pointerdown", this.#onTrackPointerDown);
90
90
  this.#header.appendChild(this.#title);
91
- this.#header.appendChild(this.#value_text);
91
+ this.#header.appendChild(this.#valueLabel);
92
92
  this.#root.appendChild(this.#header);
93
93
  this.#root.appendChild(this.#field);
94
94
 
95
95
  if (options.title !== undefined) this.setTitle(options.title);
96
96
  else this.#header.hidden = true;
97
- if (options.showValue === false) this.#value_text.hidden = true;
97
+ if (options.showValue === false) this.#valueLabel.hidden = true;
98
98
  this.setValue(options.value === undefined ? (this.#range ? [this.#min, this.#max] : this.#min) : options.value);
99
99
  if (options.disabled === true) this.setDisabled(true);
100
100
  if (options.width !== undefined) this.setWidth(options.width);
@@ -153,7 +153,7 @@ class Slider {
153
153
  }
154
154
 
155
155
  setTitle(text = String()) {
156
- this.#title_text = text;
156
+ this.#titleText = text;
157
157
  this.#title.innerText = text;
158
158
  this.#header.hidden = false;
159
159
  this.#render();
@@ -189,7 +189,7 @@ class Slider {
189
189
 
190
190
  /** Показывать ли читаемое значение рядом с заголовком */
191
191
  setShowValue(show = Boolean()) {
192
- this.#value_text.hidden = show === false;
192
+ this.#valueLabel.hidden = show === false;
193
193
  return this;
194
194
  }
195
195
 
@@ -223,13 +223,13 @@ class Slider {
223
223
  // ПОДПИСКИ
224
224
  /** Вызов на отпускание бегунка, клик по дорожке и ход с клавиатуры */
225
225
  addChangeListener(listener = () => {}) {
226
- this.#change_listeners.push(listener);
226
+ this.#changeListeners.push(listener);
227
227
  return this;
228
228
  }
229
229
 
230
230
  /** Вызов на каждое изменение во время перетаскивания */
231
231
  addInputListener(listener = () => {}) {
232
- this.#input_listeners.push(listener);
232
+ this.#inputListeners.push(listener);
233
233
  return this;
234
234
  }
235
235
 
@@ -281,9 +281,9 @@ class Slider {
281
281
  #thumbLabel(index = Number()) {
282
282
  const base =
283
283
  this.#label === undefined
284
- ? this.#title_text === undefined
284
+ ? this.#titleText === undefined
285
285
  ? I18n.t("forms.sliderValue")
286
- : this.#title_text
286
+ : this.#titleText
287
287
  : this.#label;
288
288
  if (!this.#range) return base;
289
289
  return `${base}: ${index === 0 ? I18n.t("forms.sliderMin") : I18n.t("forms.sliderMax")}`;
@@ -309,7 +309,7 @@ class Slider {
309
309
  if (this.#disabled) thumb.setAttribute("aria-disabled", "true");
310
310
  else thumb.removeAttribute("aria-disabled");
311
311
  });
312
- this.#value_text.innerText = this.#range
312
+ this.#valueLabel.innerText = this.#range
313
313
  ? `${this.#valueText(low)} – ${this.#valueText(high)}`
314
314
  : this.#valueText(low);
315
315
  }
@@ -327,7 +327,7 @@ class Slider {
327
327
  }
328
328
 
329
329
  #emit(type = String()) {
330
- const listeners = type === "input" ? this.#input_listeners : this.#change_listeners;
330
+ const listeners = type === "input" ? this.#inputListeners : this.#changeListeners;
331
331
  const value = this.getValue();
332
332
  for (const listener of [...listeners]) listener(value);
333
333
  }
@@ -4,12 +4,12 @@ chui_slider {
4
4
  карточку. Токены переопределены у корня поля, поэтому действуют только внутри него
5
5
  (тот же приём у полосы меню-бара). */
6
6
  --control_padding: var(--control_padding_sm);
7
- --main_padding: var(--main_padding_sm);
7
+ --block_padding: var(--block_padding_sm);
8
8
  display: block;
9
9
  /* fill-available учитывает собственный margin, 100% — нет: слайдер уезжал
10
10
  вправо и вылезал за родителя на 6px */
11
11
  width: -webkit-fill-available;
12
- margin: var(--margin);
12
+ margin: var(--block_margin);
13
13
  font-size: var(--font_default_size);
14
14
  color: var(--text_color);
15
15
  }
@@ -81,11 +81,12 @@ slider_thumb {
81
81
  border-radius: var(--radius_circle);
82
82
  background: var(--blue_prime_background);
83
83
  border: 2px solid var(--main_background);
84
- box-shadow: 0 1px 3px rgb(0 0 0 / 16%);
84
+ box-shadow: var(--box_shadow_control);
85
85
  cursor: pointer;
86
86
  outline: none;
87
87
  touch-action: none;
88
- transition: transform var(--transition_time);
88
+ /* Ползунок растёт на наведении и захвате: отклик с лёгким перелётом, а не линейный рост */
89
+ transition: transform var(--motion_base) var(--motion_spring);
89
90
  }
90
91
 
91
92
  slider_thumb:hover,
@@ -4,12 +4,12 @@ chui_text_input {
4
4
  карточку. Токены переопределены у корня поля, поэтому действуют только внутри него
5
5
  (тот же приём у полосы меню-бара). */
6
6
  --control_padding: var(--control_padding_sm);
7
- --main_padding: var(--main_padding_sm);
7
+ --block_padding: var(--block_padding_sm);
8
8
  display: flex;
9
9
  flex-direction: column;
10
10
  width: var(--control_width);
11
11
  height: max-content;
12
- margin: var(--margin);
12
+ margin: var(--block_margin);
13
13
  }
14
14
 
15
15
  chui_text_main {
@@ -17,12 +17,12 @@ chui_text_main {
17
17
  width: -webkit-fill-available;
18
18
  height: max-content;
19
19
  margin: 0;
20
- border-radius: var(--border_radius);
20
+ border-radius: var(--radius_sm);
21
21
  background: var(--element_background);
22
22
  color: var(--text_color);
23
23
  align-items: center;
24
24
  position: relative;
25
- padding: var(--main_padding);
25
+ padding: var(--block_padding);
26
26
  border: 1px solid var(--border_color);
27
27
  }
28
28
 
@@ -40,7 +40,7 @@ chui_text_main {
40
40
  .input_label {
41
41
  height: max-content;
42
42
  width: max-content;
43
- margin: 0 0 var(--margin);
43
+ margin: 0 0 var(--block_margin);
44
44
  font-size: var(--font_labels_size);
45
45
  font-weight: 500;
46
46
  color: var(--text_color);
@@ -50,7 +50,7 @@ error_message_text {
50
50
  display: none;
51
51
  height: max-content;
52
52
  width: max-content;
53
- margin: var(--margin) var(--margin) 0 var(--margin);
53
+ margin: var(--block_margin) var(--block_margin) 0 var(--block_margin);
54
54
  font-size: var(--font_labels_size);
55
55
  font-weight: 500;
56
56
  color: var(--red_prime_background);
@@ -83,7 +83,7 @@ error_message_text {
83
83
  cursor: not-allowed;
84
84
  height: max-content;
85
85
  width: max-content;
86
- margin: 0 0 var(--margin);
86
+ margin: 0 0 var(--block_margin);
87
87
  font-size: var(--font_labels_size);
88
88
  font-weight: 500;
89
89
  color: var(--text_color_disabled);
@@ -4,13 +4,13 @@ const { Animation } = require("../../../modules/chui_animations/animations");
4
4
  const { Validate } = require("../../../modules/chui_validate/chui_validate");
5
5
 
6
6
  class TextInput {
7
- #chui_text_main = document.createElement("chui_text_main");
8
- #chui_text_input = document.createElement("chui_text_input");
7
+ #chuiTextMain = document.createElement("chui_text_main");
8
+ #chuiTextInput = document.createElement("chui_text_input");
9
9
  #id = require("randomstring").generate();
10
10
  #title = String();
11
11
  #input = document.createElement("input");
12
12
  #label = document.createElement("label");
13
- #error_message_text = document.createElement("error_message_text");
13
+ #errorMessageText = document.createElement("error_message_text");
14
14
  constructor(
15
15
  options = {
16
16
  name: String(),
@@ -38,33 +38,29 @@ class TextInput {
38
38
  if (options.value !== undefined) this.#input.value = options.value;
39
39
  if (options.required !== undefined) this.#input.required = options.required;
40
40
  // Валидация и показ ошибки: правила из options (required/min/max/pattern/…)
41
- Validate.installField(this, options, this.#chui_text_main, this.#error_message_text, () => this.#input.value);
42
- if (options.disableFocus !== undefined)
43
- this.#input.addEventListener("mousedown", () => {
44
- return false;
45
- });
41
+ Validate.installField(this, options, this.#chuiTextMain, this.#errorMessageText, () => this.#input.value);
46
42
  if (options.title !== undefined) {
47
43
  this.#title = options.title;
48
44
  this.#label.innerText = options.title;
49
45
  this.#label.className = "input_label";
50
46
  this.#label.setAttribute("for", this.#id);
51
- this.#chui_text_input.appendChild(this.#label);
47
+ this.#chuiTextInput.appendChild(this.#label);
52
48
  }
53
- if (options.width !== undefined) this.#chui_text_input.style.width = options.width;
49
+ if (options.width !== undefined) this.#chuiTextInput.style.width = options.width;
54
50
  if (options.placeholder !== undefined) this.#input.placeholder = options.placeholder;
55
51
  // Опция `disableFocus`: поле не подсвечивается фокусом. Класс читает тема
56
52
  // (`field_no_focus` рядом с общим правилом полей), а не сам компонент
57
- if (options.disableFocus) this.#chui_text_main.classList.add("field_no_focus");
53
+ if (options.disableFocus) this.#chuiTextMain.classList.add("field_no_focus");
58
54
  // Рамку с кольцом при фокусе и подсказку при наведении рисует общее правило темы
59
55
  // (`chui_text_main:hover`, `:focus-within` в global_style.css), а не компонент:
60
56
  // прежде он ставил то же самое инлайном, а на `blur` снимал весь атрибут `style`
61
- this.#chui_text_main.appendChild(this.#input);
62
- this.#chui_text_input.appendChild(this.#chui_text_main);
57
+ this.#chuiTextMain.appendChild(this.#input);
58
+ this.#chuiTextInput.appendChild(this.#chuiTextMain);
63
59
 
64
60
  //
65
61
  this.#input.addEventListener("input", () => {
66
62
  this.clearError();
67
- new Animation(this.#error_message_text).fadeOut();
63
+ new Animation(this.#errorMessageText).fadeOut();
68
64
  });
69
65
  }
70
66
  addInputListener(listener = () => {}) {
@@ -91,11 +87,11 @@ class TextInput {
91
87
  setDisabled(boolean = Boolean()) {
92
88
  this.#input.disabled = boolean;
93
89
  if (boolean) {
94
- this.#chui_text_main.classList.add("chui_text_main_disabled");
90
+ this.#chuiTextMain.classList.add("chui_text_main_disabled");
95
91
  this.#input.className = "text_input_disabled";
96
92
  this.#label.className = "input_label_disabled";
97
93
  } else {
98
- this.#chui_text_main.classList.remove("chui_text_main_disabled");
94
+ this.#chuiTextMain.classList.remove("chui_text_main_disabled");
99
95
  this.#input.className = "text_input";
100
96
  this.#label.className = "input_label";
101
97
  }
@@ -104,7 +100,7 @@ class TextInput {
104
100
  this.setError(message);
105
101
  }
106
102
  set() {
107
- return this.#chui_text_input;
103
+ return this.#chuiTextInput;
108
104
  }
109
105
  }
110
106
 
@@ -4,12 +4,12 @@ chui_area_input {
4
4
  карточку. Токены переопределены у корня поля, поэтому действуют только внутри него
5
5
  (тот же приём у полосы меню-бара). */
6
6
  --control_padding: var(--control_padding_sm);
7
- --main_padding: var(--main_padding_sm);
7
+ --block_padding: var(--block_padding_sm);
8
8
  display: flex;
9
9
  flex-direction: column;
10
10
  width: var(--control_width);
11
11
  height: max-content;
12
- margin: var(--margin);
12
+ margin: var(--block_margin);
13
13
  }
14
14
 
15
15
  .resize_off {
@@ -19,8 +19,8 @@ chui_area_input {
19
19
  .area_input {
20
20
  height: inherit;
21
21
  width: -webkit-fill-available;
22
- border-radius: var(--border_radius);
23
- padding: var(--main_padding);
22
+ border-radius: var(--radius_sm);
23
+ padding: var(--block_padding);
24
24
  font-size: var(--font_default_size);
25
25
  color: var(--text_color);
26
26
  background: var(--element_background);
@@ -30,7 +30,7 @@ chui_area_input {
30
30
  .textarea_label {
31
31
  height: max-content;
32
32
  width: max-content;
33
- margin: 0 0 var(--margin);
33
+ margin: 0 0 var(--block_margin);
34
34
  font-size: var(--font_labels_size);
35
35
  font-weight: 500;
36
36
  color: var(--text_color);
@@ -41,8 +41,8 @@ chui_area_input {
41
41
  cursor: not-allowed;
42
42
  height: inherit;
43
43
  width: -webkit-fill-available;
44
- border-radius: var(--border_radius);
45
- padding: var(--main_padding);
44
+ border-radius: var(--radius_sm);
45
+ padding: var(--block_padding);
46
46
  font-size: var(--font_default_size);
47
47
  color: var(--text_color_disabled);
48
48
  background: var(--element_background_disabled);
@@ -53,7 +53,7 @@ chui_area_input {
53
53
  cursor: not-allowed;
54
54
  height: max-content;
55
55
  width: max-content;
56
- margin: 0 0 var(--margin);
56
+ margin: 0 0 var(--block_margin);
57
57
  font-size: var(--font_labels_size);
58
58
  font-weight: 500;
59
59
  color: var(--text_color_disabled);
@@ -2,8 +2,8 @@ const { Validate } = require("../../../modules/chui_validate/chui_validate");
2
2
 
3
3
  class TextArea {
4
4
  #id = require("randomstring").generate();
5
- #chui_text_input = document.createElement("chui_area_input");
6
- #text_area = document.createElement("textarea");
5
+ #chuiTextInput = document.createElement("chui_area_input");
6
+ #textArea = document.createElement("textarea");
7
7
  #label = document.createElement("label");
8
8
  #title = undefined;
9
9
  constructor(
@@ -17,64 +17,64 @@ class TextArea {
17
17
  }
18
18
  ) {
19
19
  require("../../../modules/chui_functions").setStyles(__dirname + "/styles.css", "chUiJS_TextArea");
20
- this.#text_area.classList.add("area_input", "resize_off");
21
- this.#text_area.id = this.#id;
22
- if (options.name !== undefined) this.#text_area.name = options.name;
23
- if (options.required !== undefined) this.#text_area.required = options.required;
20
+ this.#textArea.classList.add("area_input", "resize_off");
21
+ this.#textArea.id = this.#id;
22
+ if (options.name !== undefined) this.#textArea.name = options.name;
23
+ if (options.required !== undefined) this.#textArea.required = options.required;
24
24
  // Валидация и показ ошибки: правила из options. Текст ошибки — в корень поля
25
25
  // (под областью ввода), а рамку получает само поле: иначе узел с текстом попал бы
26
26
  // внутрь `<textarea>` и читался бы как его содержимое
27
27
  Validate.installField(
28
28
  this,
29
29
  options,
30
- this.#chui_text_input,
30
+ this.#chuiTextInput,
31
31
  undefined,
32
- () => this.#text_area.value,
33
- this.#text_area
32
+ () => this.#textArea.value,
33
+ this.#textArea
34
34
  );
35
35
  if (options.title !== undefined) {
36
36
  this.#title = options.title;
37
37
  this.#label.innerText = options.title;
38
38
  this.#label.classList.add("textarea_label");
39
39
  this.#label.setAttribute("for", this.#id);
40
- this.#chui_text_input.appendChild(this.#label);
40
+ this.#chuiTextInput.appendChild(this.#label);
41
41
  }
42
- if (options.placeholder !== undefined) this.#text_area.placeholder = options.placeholder;
43
- if (options.width !== undefined) this.#chui_text_input.style.width = options.width;
44
- if (options.height !== undefined) this.#chui_text_input.style.height = options.height;
42
+ if (options.placeholder !== undefined) this.#textArea.placeholder = options.placeholder;
43
+ if (options.width !== undefined) this.#chuiTextInput.style.width = options.width;
44
+ if (options.height !== undefined) this.#chuiTextInput.style.height = options.height;
45
45
  // Рамку с кольцом при фокусе рисует общее правило темы (`.area_input:hover`,
46
46
  // `:focus-within`), а не компонент: прежде он ставил то же самое инлайном,
47
47
  // а на `blur` снимал весь атрибут `style`
48
- this.#chui_text_input.appendChild(this.#text_area);
48
+ this.#chuiTextInput.appendChild(this.#textArea);
49
49
  }
50
50
  getName() {
51
- return this.#text_area.name;
51
+ return this.#textArea.name;
52
52
  }
53
53
  getTitle() {
54
54
  return this.#title;
55
55
  }
56
56
  getValue() {
57
- return this.#text_area.value;
57
+ return this.#textArea.value;
58
58
  }
59
59
  setValue(text = String()) {
60
- this.#text_area.value = text;
60
+ this.#textArea.value = text;
61
61
  }
62
62
  setDisabled(boolean = Boolean()) {
63
- this.#text_area.disabled = boolean;
63
+ this.#textArea.disabled = boolean;
64
64
  if (boolean) {
65
- this.#text_area.classList.remove("area_input");
66
- this.#text_area.classList.add("area_input_disabled");
65
+ this.#textArea.classList.remove("area_input");
66
+ this.#textArea.classList.add("area_input_disabled");
67
67
  this.#label.classList.remove("textarea_label");
68
68
  this.#label.classList.add("textarea_label_disabled");
69
69
  } else {
70
- this.#text_area.classList.add("area_input");
71
- this.#text_area.classList.remove("area_input_disabled");
70
+ this.#textArea.classList.add("area_input");
71
+ this.#textArea.classList.remove("area_input_disabled");
72
72
  this.#label.classList.add("textarea_label");
73
73
  this.#label.classList.remove("textarea_label_disabled");
74
74
  }
75
75
  }
76
76
  set() {
77
- return this.#chui_text_input;
77
+ return this.#chuiTextInput;
78
78
  }
79
79
  }
80
80
 
@@ -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,7 +39,7 @@ 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
  }
@@ -134,7 +134,7 @@ input.time_input:disabled {
134
134
  в прокрутку панели — иначе колонки часов и минут обрезались бы краем окна */
135
135
  overflow: hidden auto;
136
136
  border: 1px solid var(--border_color);
137
- border-radius: var(--border_radius);
137
+ border-radius: var(--radius_sm);
138
138
  background: var(--header_background);
139
139
  backdrop-filter: var(--global_blur);
140
140
  -webkit-backdrop-filter: var(--global_blur);
@@ -144,18 +144,14 @@ input.time_input:disabled {
144
144
 
145
145
  .time_dropdown_shown {
146
146
  display: flex;
147
- animation: time_dropdown_in var(--transition_time) ease-out;
148
- }
149
-
150
- @keyframes time_dropdown_in {
151
- from {
152
- opacity: 0;
153
- transform: translateY(-4px);
154
- }
155
- to {
156
- opacity: 1;
157
- transform: none;
158
- }
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;
159
155
  }
160
156
 
161
157
  .time_list {
@@ -47,16 +47,16 @@ 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
 
@@ -79,8 +79,8 @@ class TimeInput {
79
79
  TimeInput.#counter += 1;
80
80
  this.#id = options.id === undefined ? `chui_time_input_${TimeInput.#counter}` : options.id;
81
81
  this.#name = options.name;
82
- this.#label_text = options.label;
83
- this.#on_change = options.onChange;
82
+ this.#labelText = options.label;
83
+ this.#onChange = options.onChange;
84
84
  if (options.changeListener !== undefined) this.addChangeListener(options.changeListener);
85
85
  this.#root.id = this.#id;
86
86
  this.#input.type = "time";
@@ -116,7 +116,7 @@ class TimeInput {
116
116
  this.#open.appendChild(glyph);
117
117
  this.#open.addEventListener("click", () => {
118
118
  if (this.#input.disabled) return;
119
- if (this.#is_open) this.#closeDropdown();
119
+ if (this.#isOpen) this.#closeDropdown();
120
120
  else this.#openDropdown();
121
121
  });
122
122
  this.#label.className = "time_input_label";
@@ -140,10 +140,10 @@ class TimeInput {
140
140
  delete rules.min;
141
141
  delete rules.max;
142
142
  if (rules.pattern === undefined) rules.pattern = TIME_PATTERN;
143
- const own_validate = options.validate;
143
+ const ownValidate = options.validate;
144
144
  if (this.#min !== undefined || this.#max !== undefined) {
145
145
  rules.validate = (value) => {
146
- const custom = own_validate === undefined ? undefined : own_validate(value);
146
+ const custom = ownValidate === undefined ? undefined : ownValidate(value);
147
147
  if (custom !== undefined && custom !== null && custom !== true) return custom;
148
148
  const parsed = TimeInput.parse(value);
149
149
  if (parsed === undefined) return undefined;
@@ -162,7 +162,7 @@ class TimeInput {
162
162
  );
163
163
  if (options.value !== undefined) this.setValue(options.value);
164
164
  this.setDisabled(options.disabled === true);
165
- window.addEventListener("click", this.#window_click_event);
165
+ window.addEventListener("click", this.#windowClickEvent);
166
166
  }
167
167
 
168
168
  // GET
@@ -175,7 +175,7 @@ class TimeInput {
175
175
  }
176
176
 
177
177
  getTitle() {
178
- return this.#title_text;
178
+ return this.#titleText;
179
179
  }
180
180
 
181
181
  /** Значение в виде «ЧЧ:ММ»; пустая строка — время не задано */
@@ -201,7 +201,7 @@ class TimeInput {
201
201
  }
202
202
 
203
203
  isOpen() {
204
- return this.#is_open;
204
+ return this.#isOpen;
205
205
  }
206
206
 
207
207
  /**
@@ -245,7 +245,7 @@ class TimeInput {
245
245
 
246
246
  /** Подпись над полем; `undefined` её убирает */
247
247
  setTitle(text = undefined) {
248
- this.#title_text = text;
248
+ this.#titleText = text;
249
249
  if (text === undefined || text === "") {
250
250
  this.#label.hidden = true;
251
251
  this.#label.innerText = "";
@@ -264,8 +264,8 @@ class TimeInput {
264
264
 
265
265
  /** Доступное имя поля, когда подписи в разметке нет */
266
266
  setLabel(text = undefined) {
267
- this.#label_text = text;
268
- if (this.#title_text === undefined || this.#title_text === "") {
267
+ this.#labelText = text;
268
+ if (this.#titleText === undefined || this.#titleText === "") {
269
269
  if (text === undefined) this.#input.removeAttribute("aria-label");
270
270
  else this.#input.setAttribute("aria-label", String(text));
271
271
  }
@@ -351,8 +351,8 @@ class TimeInput {
351
351
 
352
352
  // === ПАНЕЛЬ ===
353
353
  #accessibleName() {
354
- if (this.#title_text !== undefined && this.#title_text !== "") return this.#title_text;
355
- 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;
356
356
  return I18n.t("time.label");
357
357
  }
358
358
 
@@ -425,11 +425,12 @@ class TimeInput {
425
425
 
426
426
  #openDropdown() {
427
427
  this.#renderOptions();
428
- this.#is_open = true;
428
+ this.#isOpen = true;
429
429
  this.#input.setAttribute("aria-expanded", "true");
430
430
  // Показ — классом, а не общей `Animation`: её `animationend` снимает `display`,
431
431
  // и панель, открытая поверх незавершённого закрытия, гасла бы сама.
432
432
  // Класс назван иначе, чем у каретки: одно имя давало бы панели стили кнопки
433
+ this.#dropdown.classList.remove("time_dropdown_leaving");
433
434
  this.#dropdown.classList.add("time_dropdown_shown");
434
435
  this.#placeDropdown();
435
436
  this.#focusSelected("hours");
@@ -448,10 +449,20 @@ class TimeInput {
448
449
  }
449
450
 
450
451
  #closeDropdown() {
451
- if (!this.#is_open) return;
452
- this.#is_open = false;
452
+ if (!this.#isOpen) return;
453
+ this.#isOpen = false;
453
454
  this.#input.setAttribute("aria-expanded", "false");
454
- 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);
455
466
  }
456
467
 
457
468
  #changed() {
@@ -459,7 +470,7 @@ class TimeInput {
459
470
  this.#markOptions();
460
471
  const value = this.getValue();
461
472
  for (const listener of [...this.#listeners]) listener(value, this);
462
- if (this.#on_change !== undefined) this.#on_change(value, this);
473
+ if (this.#onChange !== undefined) this.#onChange(value, this);
463
474
  }
464
475
 
465
476
  #moveOption(delta = Number()) {
@@ -550,7 +561,7 @@ class TimeInput {
550
561
 
551
562
  /** Полное удаление: панель и слушатель окна */
552
563
  destroy() {
553
- window.removeEventListener("click", this.#window_click_event);
564
+ window.removeEventListener("click", this.#windowClickEvent);
554
565
  this.#closeDropdown();
555
566
  }
556
567
  }