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
@@ -88,32 +88,32 @@ class DataGridBody {
88
88
  static #counter = 0;
89
89
 
90
90
  #root = document.createElement("data_grid_body");
91
- #spacer_top = document.createElement("data_grid_spacer");
92
- #spacer_bottom = document.createElement("data_grid_spacer");
91
+ #spacerTop = document.createElement("data_grid_spacer");
92
+ #spacerBottom = document.createElement("data_grid_spacer");
93
93
  #empty = document.createElement("data_grid_body_empty");
94
94
  #loader = document.createElement("data_grid_body_loader");
95
95
  // Окно в DOM: индекс строки → узел
96
96
  #nodes = new Map();
97
97
  #id = undefined;
98
98
  #items = [];
99
- #item_height = 34;
99
+ #itemHeight = 34;
100
100
  #buffer = DataGridBody.DEFAULT_BUFFER;
101
- #item_tag = "data_grid_row";
102
- #render_item = undefined;
103
- #on_item_click = undefined;
104
- #on_activate = undefined;
105
- #on_render = undefined;
106
- #on_load_more = undefined;
107
- #loading_text = undefined;
108
- #load_threshold = DataGridBody.DEFAULT_LOAD_THRESHOLD;
109
- #has_more = false;
110
- #loading_more = false;
101
+ #itemTag = "data_grid_row";
102
+ #renderItem = undefined;
103
+ #onItemClickCallback = undefined;
104
+ #onActivate = undefined;
105
+ #onRender = undefined;
106
+ #onLoadMore = undefined;
107
+ #loadingText = undefined;
108
+ #loadThreshold = DataGridBody.DEFAULT_LOAD_THRESHOLD;
109
+ #hasMore = false;
110
+ #loadingMore = false;
111
111
  // Длина, для которой запрос уже сделан: не просим ещё раз, пока данных не прибавилось
112
- #requested_at = -1;
113
- #window_state = { from: 0, to: 0 };
112
+ #requestedAt = -1;
113
+ #windowState = { from: 0, to: 0 };
114
114
  #raf = null;
115
- #refresh_raf = null;
116
- #resize_observer = undefined;
115
+ #refreshRaf = null;
116
+ #resizeObserver = undefined;
117
117
  #bound = false;
118
118
 
119
119
  constructor(
@@ -136,23 +136,23 @@ class DataGridBody {
136
136
  ) {
137
137
  DataGridBody.#counter += 1;
138
138
  this.#id = optionOr(options.id, `chui_data_grid_body_${DataGridBody.#counter}`);
139
- this.#item_tag = optionOr(options.itemTag, "data_grid_row");
140
- this.#item_height = options.itemHeight === undefined ? 34 : options.itemHeight;
139
+ this.#itemTag = optionOr(options.itemTag, "data_grid_row");
140
+ this.#itemHeight = options.itemHeight === undefined ? 34 : options.itemHeight;
141
141
  this.#buffer = options.buffer === undefined ? DataGridBody.DEFAULT_BUFFER : options.buffer;
142
- this.#render_item = options.renderItem;
143
- this.#on_item_click = options.onItemClick;
144
- this.#on_activate = options.onActivate;
145
- this.#on_render = options.onRender;
146
- this.#on_load_more = options.onLoadMore;
147
- this.#loading_text = optionOr(options.loadingText, I18n.t("common.loading"));
148
- this.#load_threshold =
142
+ this.#renderItem = options.renderItem;
143
+ this.#onItemClickCallback = options.onItemClick;
144
+ this.#onActivate = options.onActivate;
145
+ this.#onRender = options.onRender;
146
+ this.#onLoadMore = options.onLoadMore;
147
+ this.#loadingText = optionOr(options.loadingText, I18n.t("common.loading"));
148
+ this.#loadThreshold =
149
149
  options.loadMoreThreshold === undefined ? DataGridBody.DEFAULT_LOAD_THRESHOLD : options.loadMoreThreshold;
150
150
  // Без onLoadMore тело считает, что загружено всё
151
- this.#has_more = options.hasMore === undefined ? options.onLoadMore !== undefined : options.hasMore === true;
151
+ this.#hasMore = options.hasMore === undefined ? options.onLoadMore !== undefined : options.hasMore === true;
152
152
  this.#root.id = this.#id;
153
- this.#spacer_top.dataset.pos = "top";
154
- this.#spacer_bottom.dataset.pos = "bottom";
155
- for (const spacer of [this.#spacer_top, this.#spacer_bottom]) {
153
+ this.#spacerTop.dataset.pos = "top";
154
+ this.#spacerBottom.dataset.pos = "bottom";
155
+ for (const spacer of [this.#spacerTop, this.#spacerBottom]) {
156
156
  spacer.setAttribute("aria-hidden", "true");
157
157
  spacer.style.height = "0px";
158
158
  this.#root.appendChild(spacer);
@@ -171,8 +171,8 @@ class DataGridBody {
171
171
  // по нему считается окно, поэтому пересобираем его при изменении размера. Работу
172
172
  // уводим в кадр: правки layout внутри колбэка ResizeObserver дают
173
173
  // «ResizeObserver loop completed with undelivered notifications»
174
- this.#resize_observer = new ResizeObserver(() => this.#scheduleRefresh());
175
- this.#resize_observer.observe(this.#root);
174
+ this.#resizeObserver = new ResizeObserver(() => this.#scheduleRefresh());
175
+ this.#resizeObserver.observe(this.#root);
176
176
  this.#bound = true;
177
177
  }
178
178
 
@@ -181,11 +181,11 @@ class DataGridBody {
181
181
  return this.#id;
182
182
  }
183
183
  getItemHeight() {
184
- return this.#item_height;
184
+ return this.#itemHeight;
185
185
  }
186
186
  /** Окно, которое сейчас в DOM (вместе с запасом `buffer`) */
187
187
  getRenderedRange() {
188
- return { ...this.#window_state };
188
+ return { ...this.#windowState };
189
189
  }
190
190
  /** Только видимые строки — без запаса; это то, что реально видит пользователь */
191
191
  getVisibleRange() {
@@ -213,7 +213,7 @@ class DataGridBody {
213
213
  }
214
214
 
215
215
  setItemHeight(height = Number()) {
216
- this.#item_height = height;
216
+ this.#itemHeight = height;
217
217
  for (const node of this.#nodes.values()) node.style.height = `${height}px`;
218
218
  return this.refresh();
219
219
  }
@@ -227,18 +227,18 @@ class DataGridBody {
227
227
  return this;
228
228
  }
229
229
 
230
- setHasMore(has_more = true) {
231
- this.#has_more = has_more === true;
230
+ setHasMore(hasMore = true) {
231
+ this.#hasMore = hasMore === true;
232
232
  this.#applyLoader();
233
- if (this.#has_more) this.#checkLoadMore(this.#window_state.to);
233
+ if (this.#hasMore) this.#checkLoadMore(this.#windowState.to);
234
234
  return this;
235
235
  }
236
236
 
237
237
  setLoadingMore(loading = true) {
238
- this.#loading_more = loading === true;
238
+ this.#loadingMore = loading === true;
239
239
  this.#applyLoader();
240
240
  // Загрузка завершилась, но окно всё ещё у конца — возможно, нужен следующий запрос
241
- if (!this.#loading_more) this.#checkLoadMore(this.#window_state.to);
241
+ if (!this.#loadingMore) this.#checkLoadMore(this.#windowState.to);
242
242
  return this;
243
243
  }
244
244
 
@@ -252,7 +252,7 @@ class DataGridBody {
252
252
  const count = this.#items.length;
253
253
  if (count === 0) return this;
254
254
  const target = Math.max(0, Math.min(index, count - 1));
255
- const height = this.#item_height;
255
+ const height = this.#itemHeight;
256
256
  const view = this.#root.clientHeight || this.#visibleCount() * height;
257
257
  let top = this.#root.scrollTop;
258
258
  if (align === DataGridBody.ALIGN.START) {
@@ -268,8 +268,8 @@ class DataGridBody {
268
268
  if (target < from) top = target * height;
269
269
  else if (target >= to) top = (target + 1) * height - view;
270
270
  }
271
- const max_top = Math.max(0, count * height - view);
272
- top = Math.max(0, Math.min(top, max_top));
271
+ const maximumTop = Math.max(0, count * height - view);
272
+ top = Math.max(0, Math.min(top, maximumTop));
273
273
  if (top !== this.#root.scrollTop) this.#root.scrollTop = top;
274
274
  // Окно пересобираем сразу: не ждём события scroll, иначе состояние видно «на кадр позже»
275
275
  this.#renderWindow(this.#firstVisible());
@@ -284,14 +284,14 @@ class DataGridBody {
284
284
  cancelAnimationFrame(this.#raf);
285
285
  this.#raf = null;
286
286
  }
287
- if (this.#refresh_raf !== null) {
288
- cancelAnimationFrame(this.#refresh_raf);
289
- this.#refresh_raf = null;
287
+ if (this.#refreshRaf !== null) {
288
+ cancelAnimationFrame(this.#refreshRaf);
289
+ this.#refreshRaf = null;
290
290
  }
291
291
  this.#root.removeEventListener("scroll", this.#onScroll);
292
- if (this.#resize_observer !== undefined) {
293
- this.#resize_observer.disconnect();
294
- this.#resize_observer = undefined;
292
+ if (this.#resizeObserver !== undefined) {
293
+ this.#resizeObserver.disconnect();
294
+ this.#resizeObserver = undefined;
295
295
  }
296
296
  for (const node of this.#nodes.values()) {
297
297
  node.removeEventListener("click", this.#onItemClick);
@@ -302,35 +302,35 @@ class DataGridBody {
302
302
 
303
303
  // === ВНУТРЕННЕЕ ===
304
304
  #scheduleRefresh() {
305
- if (this.#refresh_raf !== null) return;
306
- this.#refresh_raf = requestAnimationFrame(() => {
307
- this.#refresh_raf = null;
305
+ if (this.#refreshRaf !== null) return;
306
+ this.#refreshRaf = requestAnimationFrame(() => {
307
+ this.#refreshRaf = null;
308
308
  if (this.#bound) this.refresh();
309
309
  });
310
310
  }
311
311
 
312
312
  #applyLoader() {
313
- this.#loader.innerText = this.#loading_text;
314
- this.#loader.hidden = !this.#loading_more;
315
- this.#root.dataset.loading = this.#loading_more ? "true" : "false";
313
+ this.#loader.innerText = this.#loadingText;
314
+ this.#loader.hidden = !this.#loadingMore;
315
+ this.#root.dataset.loading = this.#loadingMore ? "true" : "false";
316
316
  this.#syncEmpty();
317
317
  }
318
318
 
319
319
  // «Нет данных» показываем только когда данных нет и новых не ждём: иначе текст пустого
320
320
  // состояния спорил бы с индикатором догрузки на время запроса
321
321
  #syncEmpty() {
322
- this.#empty.hidden = this.#items.length > 0 || this.#has_more || this.#loading_more;
322
+ this.#empty.hidden = this.#items.length > 0 || this.#hasMore || this.#loadingMore;
323
323
  }
324
324
 
325
325
  #firstVisible() {
326
326
  const count = this.#items.length;
327
327
  if (count === 0) return 0;
328
- return Math.min(count - 1, Math.max(0, Math.floor(Math.max(0, this.#root.scrollTop) / this.#item_height)));
328
+ return Math.min(count - 1, Math.max(0, Math.floor(Math.max(0, this.#root.scrollTop) / this.#itemHeight)));
329
329
  }
330
330
 
331
331
  #visibleCount() {
332
- const view = this.#root.clientHeight || this.#item_height * 8;
333
- return Math.max(1, Math.ceil(view / this.#item_height));
332
+ const view = this.#root.clientHeight || this.#itemHeight * 8;
333
+ return Math.max(1, Math.ceil(view / this.#itemHeight));
334
334
  }
335
335
 
336
336
  /** Последний индекс окна: запас `buffer` считается в строках, а не в пикселях */
@@ -349,7 +349,7 @@ class DataGridBody {
349
349
  this.#nodes.delete(index);
350
350
  }
351
351
  }
352
- let previous = this.#spacer_top;
352
+ let previous = this.#spacerTop;
353
353
  for (let index = from; index < to; index++) {
354
354
  let node = this.#nodes.get(index);
355
355
  if (node === undefined) {
@@ -357,49 +357,49 @@ class DataGridBody {
357
357
  this.#nodes.set(index, node);
358
358
  }
359
359
  // Высоту задаём инлайном: иначе фактическая геометрия разошлась бы с распорками
360
- const height = `${this.#item_height}px`;
360
+ const height = `${this.#itemHeight}px`;
361
361
  if (node.style.height !== height) node.style.height = height;
362
362
  // insertBefore(previous.nextSibling) ставит узел сразу за предыдущим и не трогает
363
363
  // остальные, если порядок уже верный
364
364
  if (node.previousSibling !== previous) this.#root.insertBefore(node, previous.nextSibling);
365
365
  previous = node;
366
366
  }
367
- this.#window_state = { from: from, to: to };
367
+ this.#windowState = { from: from, to: to };
368
368
  this.#syncSpacers();
369
- if (this.#on_render !== undefined) this.#on_render({ from: from, to: to });
369
+ if (this.#onRender !== undefined) this.#onRender({ from: from, to: to });
370
370
  this.#checkLoadMore(to);
371
371
  }
372
372
 
373
373
  #syncSpacers() {
374
374
  const count = this.#items.length;
375
- const { from, to } = this.#window_state;
376
- this.#spacer_top.style.height = count === 0 ? "0px" : `${from * this.#item_height}px`;
377
- this.#spacer_bottom.style.height = count === 0 ? "0px" : `${Math.max(0, (count - to) * this.#item_height)}px`;
375
+ const { from, to } = this.#windowState;
376
+ this.#spacerTop.style.height = count === 0 ? "0px" : `${from * this.#itemHeight}px`;
377
+ this.#spacerBottom.style.height = count === 0 ? "0px" : `${Math.max(0, (count - to) * this.#itemHeight)}px`;
378
378
  }
379
379
 
380
380
  #createItem(index = Number()) {
381
- const node = document.createElement(this.#item_tag);
381
+ const node = document.createElement(this.#itemTag);
382
382
  node.id = `${this.#id}_item_${index}`;
383
383
  node.dataset.index = String(index);
384
- if (this.#render_item === undefined) node.innerText = String(this.#items[index]);
385
- else this.#render_item(this.#items[index], index, node);
384
+ if (this.#renderItem === undefined) node.innerText = String(this.#items[index]);
385
+ else this.#renderItem(this.#items[index], index, node);
386
386
  node.addEventListener("click", this.#onItemClick);
387
387
  node.addEventListener("dblclick", this.#onItemDblClick);
388
388
  return node;
389
389
  }
390
390
 
391
391
  #checkLoadMore(to = Number()) {
392
- if (this.#on_load_more === undefined || this.#loading_more || !this.#has_more) return;
392
+ if (this.#onLoadMore === undefined || this.#loadingMore || !this.#hasMore) return;
393
393
  const count = this.#items.length;
394
394
  // Тело пусто или окно дошло до конца загруженного
395
- if (count > 0 && to < count - this.#load_threshold) return;
395
+ if (count > 0 && to < count - this.#loadThreshold) return;
396
396
  // Запрос на такую же длину уже был: ждём данных, а не повторяем в пустоту
397
- if (this.#requested_at === count) return;
398
- this.#requested_at = count;
399
- this.#loading_more = true;
397
+ if (this.#requestedAt === count) return;
398
+ this.#requestedAt = count;
399
+ this.#loadingMore = true;
400
400
  this.#applyLoader();
401
401
  try {
402
- this.#on_load_more(count);
402
+ this.#onLoadMore(count);
403
403
  } catch (error) {
404
404
  // Ошибка обработчика не должна оставлять тело «в загрузке»;
405
405
  // #requested_at не сбрасываем — повтор это `DataGrid.loadMore()`
@@ -423,13 +423,13 @@ class DataGridBody {
423
423
  const { index, node } = this.#itemFromEvent(event);
424
424
  if (index === -1) return;
425
425
  // Событие сетке нужно целиком: по нему она читает модификаторы Ctrl/Shift
426
- if (this.#on_item_click !== undefined) this.#on_item_click(this.#items[index], index, node, event);
426
+ if (this.#onItemClickCallback !== undefined) this.#onItemClickCallback(this.#items[index], index, node, event);
427
427
  };
428
428
 
429
429
  #onItemDblClick = (event) => {
430
430
  const { index, node } = this.#itemFromEvent(event);
431
431
  if (index === -1) return;
432
- if (this.#on_activate !== undefined) this.#on_activate(this.#items[index], index, node);
432
+ if (this.#onActivate !== undefined) this.#onActivate(this.#items[index], index, node);
433
433
  };
434
434
 
435
435
  #onScroll = () => {
@@ -437,7 +437,7 @@ class DataGridBody {
437
437
  this.#raf = requestAnimationFrame(() => {
438
438
  this.#raf = null;
439
439
  const from = this.#firstVisible();
440
- const state = this.#window_state;
440
+ const state = this.#windowState;
441
441
  // Видимая часть уже внутри отрисованного окна — перерисовка не нужна
442
442
  if (from >= state.from && this.#endIndex(from) <= state.to) return;
443
443
  this.#renderWindow(from);
@@ -505,13 +505,13 @@ class DataGrid {
505
505
  #scroll = document.createElement("data_grid_scroll");
506
506
  #bar = document.createElement("data_grid_bar");
507
507
  #head = document.createElement("data_grid_head");
508
- #head_row = document.createElement("data_grid_row");
508
+ #headRow = document.createElement("data_grid_row");
509
509
  #error = document.createElement("data_grid_error");
510
- #error_text = document.createElement("data_grid_error_text");
510
+ #errorText = document.createElement("data_grid_error_text");
511
511
  #status = document.createElement("data_grid_status");
512
512
  #list = undefined;
513
- #chooser_dialog = undefined;
514
- #chooser_block = undefined;
513
+ #chooserDialog = undefined;
514
+ #chooserBlock = undefined;
515
515
 
516
516
  // === СОСТОЯНИЕ ===
517
517
  #id = String();
@@ -520,26 +520,26 @@ class DataGrid {
520
520
  // Видимость по колонкам: ключ скрытой колонки лежит здесь, поэтому DOM собирается по видимым
521
521
  #hidden = new Set();
522
522
  #pinned = [];
523
- #column_reorder = false;
523
+ #columnReorder = false;
524
524
  #data = [];
525
- #row_height = DataGrid.DEFAULT_ROW_HEIGHT;
525
+ #rowHeight = DataGrid.DEFAULT_ROW_HEIGHT;
526
526
  #selection = DataGrid.SELECTION.SINGLE;
527
527
  #selected = new Set();
528
528
  #anchor = undefined;
529
529
  // Индекс строки в исходных данных: `render(row, index)` и ключ по умолчанию
530
- #row_index = new Map();
530
+ #rowIndex = new Map();
531
531
  #filter = "";
532
- #filter_keys = [];
532
+ #filterKeys = [];
533
533
  #sort = { key: undefined, direction: DataGrid.SORT.NONE };
534
- #group_by = undefined;
535
- #group_label = undefined;
534
+ #groupBy = undefined;
535
+ #groupLabel = undefined;
536
536
  #aggregates = {};
537
- #group_collapsed_default = false;
537
+ #groupCollapsedDefault = false;
538
538
  #collapsed = new Map();
539
539
  #editable = undefined;
540
540
  #editing = undefined;
541
541
  #active = { row: 0, col: 0 };
542
- #entry_count = 0;
542
+ #entryCount = 0;
543
543
 
544
544
  // Производные данные (пересобираются одним проходом — см. #recompute)
545
545
  #filtered = [];
@@ -548,27 +548,27 @@ class DataGrid {
548
548
  #entries = [];
549
549
 
550
550
  // Серверный режим
551
- #data_source = undefined;
552
- #page_size = DataGrid.DEFAULT_PAGE_SIZE;
553
- #server_total = undefined;
551
+ #dataSource = undefined;
552
+ #pageSize = DataGrid.DEFAULT_PAGE_SIZE;
553
+ #serverTotal = undefined;
554
554
  #loading = false;
555
555
  #failed = false;
556
- #has_more = false;
556
+ #hasMore = false;
557
557
  #request = 0;
558
558
 
559
559
  // Подписчики
560
- #on_row_activate = undefined;
561
- #on_selection_change = undefined;
562
- #on_cell_edit = undefined;
563
- #on_active_cell_change = undefined;
564
- #on_column_order_change = undefined;
565
- #on_data_load = undefined;
566
- #on_data_error = undefined;
567
- #row_class = undefined;
568
- #custom_key = undefined;
569
- #empty_text = undefined;
570
- #context_menu = undefined;
571
- #resize_observer = undefined;
560
+ #onRowActivate = undefined;
561
+ #onSelectionChange = undefined;
562
+ #onCellEdit = undefined;
563
+ #onActiveCellChange = undefined;
564
+ #onColumnOrderChange = undefined;
565
+ #onDataLoad = undefined;
566
+ #onDataError = undefined;
567
+ #rowClass = undefined;
568
+ #customKey = undefined;
569
+ #emptyText = undefined;
570
+ #contextMenu = undefined;
571
+ #resizeObserver = undefined;
572
572
 
573
573
  // Перестановка колонок
574
574
  #drag = undefined;
@@ -613,39 +613,39 @@ class DataGrid {
613
613
  this.#columns = DataGrid.#normalizeColumns(options.columns);
614
614
  this.#hidden = new Set(DataGrid.#normalizeKeys(options.hiddenColumns, this.#columns));
615
615
  this.#data = Array.isArray(options.data) ? options.data : [];
616
- this.#row_height = options.rowHeight === undefined ? DataGrid.DEFAULT_ROW_HEIGHT : options.rowHeight;
616
+ this.#rowHeight = options.rowHeight === undefined ? DataGrid.DEFAULT_ROW_HEIGHT : options.rowHeight;
617
617
  this.#selection = DataGrid.#normalizeSelection(options.selectable);
618
- this.#custom_key = options.rowKey;
619
- this.#filter_keys = DataGrid.#normalizeKeys(options.filterKeys, this.#columns);
620
- this.#empty_text = options.emptyText;
618
+ this.#customKey = options.rowKey;
619
+ this.#filterKeys = DataGrid.#normalizeKeys(options.filterKeys, this.#columns);
620
+ this.#emptyText = options.emptyText;
621
621
  this.#editable = options.editable;
622
- this.#group_by = options.groupBy;
623
- this.#group_label = options.groupLabel;
622
+ this.#groupBy = options.groupBy;
623
+ this.#groupLabel = options.groupLabel;
624
624
  this.#aggregates = options.aggregates === undefined ? {} : options.aggregates;
625
- this.#group_collapsed_default = options.groupCollapsed === true;
626
- this.#row_class = options.rowClass;
627
- this.#on_row_activate = options.onRowActivate;
628
- this.#on_selection_change = options.onSelectionChange;
629
- this.#on_cell_edit = options.onCellEdit;
630
- this.#on_active_cell_change = options.onActiveCellChange;
631
- this.#on_column_order_change = options.onColumnOrderChange;
632
- this.#on_data_load = options.onDataLoad;
633
- this.#on_data_error = options.onDataError;
634
- this.#data_source = options.dataSource;
635
- this.#page_size = DataGrid.#normalizePageSize(options.pageSize);
636
- this.#column_reorder = options.columnReorder === true;
625
+ this.#groupCollapsedDefault = options.groupCollapsed === true;
626
+ this.#rowClass = options.rowClass;
627
+ this.#onRowActivate = options.onRowActivate;
628
+ this.#onSelectionChange = options.onSelectionChange;
629
+ this.#onCellEdit = options.onCellEdit;
630
+ this.#onActiveCellChange = options.onActiveCellChange;
631
+ this.#onColumnOrderChange = options.onColumnOrderChange;
632
+ this.#onDataLoad = options.onDataLoad;
633
+ this.#onDataError = options.onDataError;
634
+ this.#dataSource = options.dataSource;
635
+ this.#pageSize = DataGrid.#normalizePageSize(options.pageSize);
636
+ this.#columnReorder = options.columnReorder === true;
637
637
  this.setPinned(options.pinned);
638
638
 
639
639
  // === сборка разметки ===
640
640
  this.#root.id = this.#id;
641
641
  this.#root.setAttribute("role", "grid");
642
642
  this.#head.setAttribute("role", "rowgroup");
643
- this.#head_row.setAttribute("role", "row");
644
- this.#head_row.setAttribute("aria-rowindex", "1");
645
- this.#head.appendChild(this.#head_row);
643
+ this.#headRow.setAttribute("role", "row");
644
+ this.#headRow.setAttribute("aria-rowindex", "1");
645
+ this.#head.appendChild(this.#headRow);
646
646
  this.#scroll.appendChild(this.#head);
647
647
  this.#root.appendChild(this.#scroll);
648
- this.#error.appendChild(this.#error_text);
648
+ this.#error.appendChild(this.#errorText);
649
649
  this.#error.appendChild(
650
650
  new Button({ title: I18n.t("dataGrid.retry"), clickEvent: () => this.retryLoad() }).set()
651
651
  );
@@ -661,10 +661,10 @@ class DataGrid {
661
661
  this.#syncColumns();
662
662
  this.#list = new DataGridBody({
663
663
  itemTag: "data_grid_row",
664
- itemHeight: this.#row_height,
664
+ itemHeight: this.#rowHeight,
665
665
  buffer: options.buffer,
666
666
  height: options.height === undefined ? DataGrid.DEFAULT_HEIGHT : options.height,
667
- emptyText: this.#empty_text,
667
+ emptyText: this.#emptyText,
668
668
  hasMore: false,
669
669
  onLoadMore: () => this.loadMore(),
670
670
  renderItem: (entry, index, node) => this.#renderRow(entry, index, node),
@@ -689,26 +689,26 @@ class DataGrid {
689
689
  this.#root.appendChild(this.#status);
690
690
 
691
691
  // Заголовок: делегирование вместо подписки на каждую ячейку
692
- this.#head_row.addEventListener("click", this.#onHeaderClick);
693
- this.#head_row.addEventListener("keydown", this.#onHeaderKeyDown);
694
- this.#head_row.addEventListener("dragstart", this.#onHeaderDragStart);
695
- this.#head_row.addEventListener("dragover", this.#onHeaderDragOver);
696
- this.#head_row.addEventListener("dragleave", this.#onHeaderDragLeave);
697
- this.#head_row.addEventListener("drop", this.#onHeaderDrop);
698
- this.#head_row.addEventListener("dragend", this.#onHeaderDragEnd);
692
+ this.#headRow.addEventListener("click", this.#onHeaderClick);
693
+ this.#headRow.addEventListener("keydown", this.#onHeaderKeyDown);
694
+ this.#headRow.addEventListener("dragstart", this.#onHeaderDragStart);
695
+ this.#headRow.addEventListener("dragover", this.#onHeaderDragOver);
696
+ this.#headRow.addEventListener("dragleave", this.#onHeaderDragLeave);
697
+ this.#headRow.addEventListener("drop", this.#onHeaderDrop);
698
+ this.#headRow.addEventListener("dragend", this.#onHeaderDragEnd);
699
699
  // capture: правку начинает перехват, иначе тело списка успеет сообщить об активации
700
700
  this.#root.addEventListener("dblclick", this.#onDoubleClick, true);
701
701
  this.#root.addEventListener("keydown", this.#onKeyDown);
702
702
  // Ширины закреплённых колонок зависят от размера окна — пересчитываем при изменении
703
- this.#resize_observer = new ResizeObserver(() => this.#syncPinned());
704
- this.#resize_observer.observe(this.#scroll);
703
+ this.#resizeObserver = new ResizeObserver(() => this.#syncPinned());
704
+ this.#resizeObserver.observe(this.#scroll);
705
705
  // Горизонтальная прокрутка: закреплённые колонки удерживаем на месте
706
706
  this.#scroll.addEventListener("scroll", this.#onScrollX, { passive: true });
707
707
 
708
708
  this.#reindex();
709
709
  this.#buildHeader();
710
710
  this.#recompute();
711
- if (this.#data_source !== undefined) this.reload();
711
+ if (this.#dataSource !== undefined) this.reload();
712
712
  }
713
713
 
714
714
  // === НОРМАЛИЗАЦИЯ ВХОДА ===
@@ -843,16 +843,16 @@ class DataGrid {
843
843
  }
844
844
  }
845
845
  }
846
- this.#entry_count = this.#entries.length;
846
+ this.#entryCount = this.#entries.length;
847
847
  // Число строк для скринридера: элементы списка плюс строка заголовка, а в серверном
848
848
  // режиме — то, что сообщил сервер (иначе он знал бы только про загруженное окно)
849
849
  this.#root.setAttribute(
850
850
  "aria-rowcount",
851
- String((this.#server_total === undefined ? this.#entry_count : this.#server_total) + 1)
851
+ String((this.#serverTotal === undefined ? this.#entryCount : this.#serverTotal) + 1)
852
852
  );
853
853
  this.#syncColumns();
854
854
  this.#list.setItems(this.#entries);
855
- this.#list.setHasMore(this.#has_more);
855
+ this.#list.setHasMore(this.#hasMore);
856
856
  this.#syncActiveCells();
857
857
  this.#syncPinned();
858
858
  }
@@ -877,11 +877,11 @@ class DataGrid {
877
877
 
878
878
  #filterRows(rows = []) {
879
879
  // Серверный режим фильтрует сам: локальный фильтр включился бы поверх серверного
880
- if (this.#data_source !== undefined) return rows.slice();
880
+ if (this.#dataSource !== undefined) return rows.slice();
881
881
  const text = this.#filter.trim().toLowerCase();
882
- if (text === "" || this.#filter_keys.length === 0) return rows.slice();
882
+ if (text === "" || this.#filterKeys.length === 0) return rows.slice();
883
883
  return rows.filter((row) =>
884
- this.#filter_keys.some((key) => {
884
+ this.#filterKeys.some((key) => {
885
885
  return DataGrid.#valueText(row[key]).toLowerCase().includes(text);
886
886
  })
887
887
  );
@@ -922,8 +922,8 @@ class DataGrid {
922
922
 
923
923
  /** Группы: порядок — первое появление ключа, поэтому он не зависит от сортировки */
924
924
  #buildGroups(rows = []) {
925
- if (this.#group_by === undefined) return [];
926
- const keyOf = typeof this.#group_by === "function" ? this.#group_by : (row) => row[this.#group_by];
925
+ if (this.#groupBy === undefined) return [];
926
+ const keyOf = typeof this.#groupBy === "function" ? this.#groupBy : (row) => row[this.#groupBy];
927
927
  const map = new Map();
928
928
  for (const row of rows) {
929
929
  const raw = keyOf(row);
@@ -932,12 +932,12 @@ class DataGrid {
932
932
  map.get(key).push(row);
933
933
  }
934
934
  const out = [];
935
- for (const [key, group_rows] of map) {
935
+ for (const [key, groupRows] of map) {
936
936
  out.push({
937
937
  key: key,
938
- rows: group_rows,
939
- aggregates: this.#aggregateValues(group_rows),
940
- collapsed: this.#collapsed.has(key) ? this.#collapsed.get(key) : this.#group_collapsed_default,
938
+ rows: groupRows,
939
+ aggregates: this.#aggregateValues(groupRows),
940
+ collapsed: this.#collapsed.has(key) ? this.#collapsed.get(key) : this.#groupCollapsedDefault,
941
941
  });
942
942
  }
943
943
  return out;
@@ -988,7 +988,7 @@ class DataGrid {
988
988
  #syncColumns() {
989
989
  const visible = this.#visibleColumns();
990
990
  this.#root.style.setProperty("--data_grid_columns", visible.map((entry) => entry.column.width).join(" "));
991
- this.#root.style.setProperty("--data_grid_row_height", `${this.#row_height}px`);
991
+ this.#root.style.setProperty("--data_grid_row_height", `${this.#rowHeight}px`);
992
992
  const explicit = DataGrid.#explicitWidth(visible.map((entry) => entry.column));
993
993
  if (explicit > 0) this.#root.style.setProperty("--data_grid_min_width", `${explicit}px`);
994
994
  else this.#root.style.removeProperty("--data_grid_min_width");
@@ -1022,7 +1022,7 @@ class DataGrid {
1022
1022
  }
1023
1023
  }
1024
1024
  this.#scroll.classList.toggle("data_grid_h_scroll", this.#scroll.scrollWidth > this.#scroll.clientWidth + 1);
1025
- const nodes = [this.#head_row, ...this.#renderedRows()];
1025
+ const nodes = [this.#headRow, ...this.#renderedRows()];
1026
1026
  for (const row of nodes) {
1027
1027
  for (const cell of row.querySelectorAll("data_grid_cell[data-column]")) {
1028
1028
  const index = Number(cell.dataset.column);
@@ -1037,7 +1037,7 @@ class DataGrid {
1037
1037
  }
1038
1038
 
1039
1039
  #cellWidth(index = Number()) {
1040
- const cell = this.#head_row.querySelector(`data_grid_cell[data-column="${index}"]`);
1040
+ const cell = this.#headRow.querySelector(`data_grid_cell[data-column="${index}"]`);
1041
1041
  return cell === null ? 0 : Math.round(cell.getBoundingClientRect().width);
1042
1042
  }
1043
1043
 
@@ -1057,7 +1057,7 @@ class DataGrid {
1057
1057
 
1058
1058
  // === ШАПКА ===
1059
1059
  #buildHeader() {
1060
- this.#head_row.innerHTML = "";
1060
+ this.#headRow.innerHTML = "";
1061
1061
  for (const entry of this.#visibleColumns()) {
1062
1062
  const column = entry.column;
1063
1063
  const cell = document.createElement("data_grid_cell");
@@ -1080,11 +1080,11 @@ class DataGrid {
1080
1080
  // Подпись заголовка объясняет, что Enter и Space сортируют колонку
1081
1081
  cell.setAttribute("aria-label", I18n.t("table.sortBy", { head: column.title }));
1082
1082
  }
1083
- if (this.#column_reorder) {
1083
+ if (this.#columnReorder) {
1084
1084
  cell.setAttribute("draggable", "true");
1085
1085
  if (column.sortable === false) cell.setAttribute("tabindex", "0");
1086
1086
  }
1087
- this.#head_row.appendChild(cell);
1087
+ this.#headRow.appendChild(cell);
1088
1088
  this.#syncSortMark(cell, entry.index);
1089
1089
  }
1090
1090
  }
@@ -1112,7 +1112,7 @@ class DataGrid {
1112
1112
  }
1113
1113
 
1114
1114
  #onHeaderClick = (event) => {
1115
- const cell = DataGrid.#columnFromEvent(event, this.#head_row);
1115
+ const cell = DataGrid.#columnFromEvent(event, this.#headRow);
1116
1116
  if (cell === undefined) return;
1117
1117
  const index = Number(cell.dataset.column);
1118
1118
  const column = this.#columns[index];
@@ -1121,7 +1121,7 @@ class DataGrid {
1121
1121
  };
1122
1122
 
1123
1123
  #onHeaderKeyDown = (event) => {
1124
- const cell = DataGrid.#columnFromEvent(event, this.#head_row);
1124
+ const cell = DataGrid.#columnFromEvent(event, this.#headRow);
1125
1125
  if (cell === undefined) return;
1126
1126
  const index = Number(cell.dataset.column);
1127
1127
  if (event.key === "Enter" || event.key === " ") {
@@ -1130,7 +1130,7 @@ class DataGrid {
1130
1130
  return;
1131
1131
  }
1132
1132
  if (event.altKey && (event.key === "ArrowLeft" || event.key === "ArrowRight")) {
1133
- if (this.#column_reorder === false) return;
1133
+ if (this.#columnReorder === false) return;
1134
1134
  event.preventDefault();
1135
1135
  this.#moveColumn(index, event.key === "ArrowLeft" ? -1 : 1);
1136
1136
  return;
@@ -1142,7 +1142,7 @@ class DataGrid {
1142
1142
  const place = visible.findIndex((entry) => entry.index === index);
1143
1143
  const next = visible[place + (event.key === "ArrowRight" ? 1 : -1)];
1144
1144
  if (next === undefined) return;
1145
- const node = this.#head_row.querySelector(`data_grid_cell[data-column="${next.index}"]`);
1145
+ const node = this.#headRow.querySelector(`data_grid_cell[data-column="${next.index}"]`);
1146
1146
  if (node !== null) node.focus();
1147
1147
  }
1148
1148
  };
@@ -1161,7 +1161,7 @@ class DataGrid {
1161
1161
 
1162
1162
  #applySort() {
1163
1163
  this.#recompute();
1164
- for (const cell of this.#head_row.querySelectorAll("data_grid_cell[data-column]")) {
1164
+ for (const cell of this.#headRow.querySelectorAll("data_grid_cell[data-column]")) {
1165
1165
  this.#syncSortMark(cell, Number(cell.dataset.column));
1166
1166
  }
1167
1167
  this.#announce(this.#sortSummary());
@@ -1202,8 +1202,8 @@ class DataGrid {
1202
1202
  // Свой класс строки ставим ДО класса выделения: запись в `className` затирает уже
1203
1203
  // проставленные классы, и после перерисовки строки (правка ячейки) выделенная
1204
1204
  // строка теряла бы подсветку при включённом `rowClass`
1205
- if (typeof this.#row_class === "function") {
1206
- const classes = this.#row_class(row, entry.rowIndex);
1205
+ if (typeof this.#rowClass === "function") {
1206
+ const classes = this.#rowClass(row, entry.rowIndex);
1207
1207
  if (classes !== undefined && classes !== null && String(classes).trim() !== "")
1208
1208
  node.className = String(classes).trim();
1209
1209
  }
@@ -1279,8 +1279,8 @@ class DataGrid {
1279
1279
  // иначе он повторял бы то же число (прежде там стояла подпись «групп: N», которая
1280
1280
  // называла строки группы группами)
1281
1281
  title.innerText =
1282
- typeof this.#group_label === "function"
1283
- ? String(this.#group_label(entry.group.key, entry.group.rows))
1282
+ typeof this.#groupLabel === "function"
1283
+ ? String(this.#groupLabel(entry.group.key, entry.group.rows))
1284
1284
  : I18n.t("dataGrid.groupTitle", { key: entry.group.key, count: entry.group.rows.length });
1285
1285
  cell.appendChild(title);
1286
1286
  node.appendChild(cell);
@@ -1312,9 +1312,9 @@ class DataGrid {
1312
1312
  #syncRowActive(node = new HTMLElement(), index = Number()) {
1313
1313
  const active = this.#active.row === index;
1314
1314
  for (const cell of node.querySelectorAll("data_grid_cell[data-column]")) {
1315
- const is_active = active && Number(cell.dataset.column) === this.#active.col;
1316
- cell.classList.toggle(A11Y_ACTIVE_CLASS, is_active);
1317
- cell.tabIndex = is_active ? 0 : -1;
1315
+ const isActive = active && Number(cell.dataset.column) === this.#active.col;
1316
+ cell.classList.toggle(A11Y_ACTIVE_CLASS, isActive);
1317
+ cell.tabIndex = isActive ? 0 : -1;
1318
1318
  }
1319
1319
  }
1320
1320
 
@@ -1330,8 +1330,8 @@ class DataGrid {
1330
1330
  // === ВЫБОР СТРОК ВНУТРЕННЕЕ ===
1331
1331
  /** Ключ строки: имя поля, функция или место в исходных данных */
1332
1332
  #keyOf(entry = new DataGridEntry()) {
1333
- if (typeof this.#custom_key === "function") return this.#custom_key(entry.row);
1334
- if (this.#custom_key !== undefined) return entry.row[this.#custom_key];
1333
+ if (typeof this.#customKey === "function") return this.#customKey(entry.row);
1334
+ if (this.#customKey !== undefined) return entry.row[this.#customKey];
1335
1335
  return this.#rowIndexOf(entry.row);
1336
1336
  }
1337
1337
 
@@ -1377,19 +1377,19 @@ class DataGrid {
1377
1377
  node.setAttribute("aria-selected", selected ? "true" : "false");
1378
1378
  }
1379
1379
  this.#syncPinned();
1380
- if (this.#on_selection_change !== undefined) {
1380
+ if (this.#onSelectionChange !== undefined) {
1381
1381
  const rows = this.#viewRows().filter((row) =>
1382
1382
  this.#selected.has(this.#keyOf(DataGrid.#entryOf(row, this.#rowIndexOf(row))))
1383
1383
  );
1384
- this.#on_selection_change(rows, Array.from(this.#selected));
1384
+ this.#onSelectionChange(rows, Array.from(this.#selected));
1385
1385
  }
1386
1386
  this.#announce(I18n.t("dataGrid.rowsSummary", { shown: this.#selected.size }));
1387
1387
  }
1388
1388
 
1389
1389
  // === АКТИВНАЯ ЯЧЕЙКА И КЛАВИАТУРА ===
1390
1390
  #setActive(row = Number(), col = Number(), focus = true) {
1391
- if (this.#entry_count === 0) return;
1392
- const place = Math.min(Math.max(row, 0), this.#entry_count - 1);
1391
+ if (this.#entryCount === 0) return;
1392
+ const place = Math.min(Math.max(row, 0), this.#entryCount - 1);
1393
1393
  const entry = this.#entryAt(place);
1394
1394
  const visible = this.#visibleColumns();
1395
1395
  if (visible.length === 0) return;
@@ -1401,8 +1401,8 @@ class DataGrid {
1401
1401
  this.#syncActiveCells();
1402
1402
  const node = this.#cellNode(place, known);
1403
1403
  if (node !== undefined && focus) node.focus({ preventScroll: true });
1404
- if (this.#on_active_cell_change !== undefined && entry !== undefined && entry.kind === "row") {
1405
- this.#on_active_cell_change(place, known, entry.row);
1404
+ if (this.#onActiveCellChange !== undefined && entry !== undefined && entry.kind === "row") {
1405
+ this.#onActiveCellChange(place, known, entry.row);
1406
1406
  }
1407
1407
  }
1408
1408
 
@@ -1419,19 +1419,19 @@ class DataGrid {
1419
1419
  const place = visible.findIndex((item) => item.index === col);
1420
1420
  if (place === -1) return undefined;
1421
1421
  let next = place + step;
1422
- let next_row = row;
1422
+ let nextRow = row;
1423
1423
  if (next >= visible.length) {
1424
1424
  next = 0;
1425
- next_row = row + 1;
1425
+ nextRow = row + 1;
1426
1426
  }
1427
1427
  if (next < 0) {
1428
1428
  next = visible.length - 1;
1429
- next_row = row - 1;
1429
+ nextRow = row - 1;
1430
1430
  }
1431
- if (next_row < 0 || next_row >= this.#entry_count) return undefined;
1432
- const entry = this.#entryAt(next_row);
1431
+ if (nextRow < 0 || nextRow >= this.#entryCount) return undefined;
1432
+ const entry = this.#entryAt(nextRow);
1433
1433
  if (entry === undefined || entry.kind !== "row") return undefined;
1434
- return { row: next_row, col: visible[next].index };
1434
+ return { row: nextRow, col: visible[next].index };
1435
1435
  }
1436
1436
 
1437
1437
  #onRowClick = (entry = new DataGridEntry(), index = Number(), _node = new HTMLElement(), event = Object()) => {
@@ -1468,13 +1468,13 @@ class DataGrid {
1468
1468
  // Space добавлял бы в выборку несуществующую строку, а перестановка колонки
1469
1469
  // (Alt+←/→) пересобирает шапку и ячейка под уже всплывающим событием осиротеет —
1470
1470
  // `closest` вернул бы null и обработчик падал бы с TypeError
1471
- const row_node = cell.closest("data_grid_row");
1472
- if (row_node === null || row_node.dataset.index === undefined) return;
1473
- const row = Number(row_node.dataset.index);
1471
+ const rowNode = cell.closest("data_grid_row");
1472
+ if (rowNode === null || rowNode.dataset.index === undefined) return;
1473
+ const row = Number(rowNode.dataset.index);
1474
1474
  const col = Number(cell.dataset.column);
1475
1475
  const visible = this.#visibleColumns();
1476
1476
  const place = visible.findIndex((item) => item.index === col);
1477
- const last = this.#entry_count - 1;
1477
+ const last = this.#entryCount - 1;
1478
1478
  const entry = this.#entryAt(row);
1479
1479
  if (entry !== undefined && entry.kind === "group") {
1480
1480
  if (event.key === "Enter" || event.key === " ") {
@@ -1495,9 +1495,9 @@ class DataGrid {
1495
1495
  return;
1496
1496
  }
1497
1497
  }
1498
- const move = (next_row, next_col) => {
1498
+ const move = (nextRow, nextColumn) => {
1499
1499
  event.preventDefault();
1500
- this.#setActive(next_row, next_col === undefined ? col : next_col, true);
1500
+ this.#setActive(nextRow, nextColumn === undefined ? col : nextColumn, true);
1501
1501
  };
1502
1502
  if (event.key === "ArrowDown") return move(Math.min(row + 1, last));
1503
1503
  if (event.key === "ArrowUp") return move(Math.max(row - 1, 0));
@@ -1537,7 +1537,7 @@ class DataGrid {
1537
1537
  #activateRow(index = Number()) {
1538
1538
  const entry = this.#entryAt(index);
1539
1539
  if (entry === undefined || entry.kind !== "row") return;
1540
- if (this.#on_row_activate !== undefined) this.#on_row_activate(entry.row, entry.rowIndex);
1540
+ if (this.#onRowActivate !== undefined) this.#onRowActivate(entry.row, entry.rowIndex);
1541
1541
  }
1542
1542
 
1543
1543
  // === ПРАВКА ЯЧЕЕК ===
@@ -1727,7 +1727,7 @@ class DataGrid {
1727
1727
  editing.component.destroy();
1728
1728
  if (entry !== undefined && entry.kind === "row" && save && value !== editing.old_value) {
1729
1729
  entry.row[editing.key] = value;
1730
- if (this.#on_cell_edit !== undefined) this.#on_cell_edit(entry.row, editing.key, value, editing.old_value);
1730
+ if (this.#onCellEdit !== undefined) this.#onCellEdit(entry.row, editing.key, value, editing.old_value);
1731
1731
  this.#announce(I18n.t("dataGrid.saved", { title: column.title, value: DataGrid.#valueText(value) }));
1732
1732
  } else if (save === false && parsed.ok === false) {
1733
1733
  this.#announce(I18n.t("dataGrid.editCanceledReason", { message: parsed.message }));
@@ -1771,8 +1771,8 @@ class DataGrid {
1771
1771
 
1772
1772
  // === ПЕРЕСТАНОВКА КОЛОНОК ===
1773
1773
  #onHeaderDragStart = (event) => {
1774
- if (this.#column_reorder === false) return;
1775
- const cell = DataGrid.#columnFromEvent(event, this.#head_row);
1774
+ if (this.#columnReorder === false) return;
1775
+ const cell = DataGrid.#columnFromEvent(event, this.#headRow);
1776
1776
  if (cell === undefined) return;
1777
1777
  this.#drag = Number(cell.dataset.column);
1778
1778
  cell.classList.add("data_grid_cell_dragging");
@@ -1803,14 +1803,14 @@ class DataGrid {
1803
1803
 
1804
1804
  #onHeaderDragEnd = () => {
1805
1805
  this.#markDrop(undefined);
1806
- for (const cell of this.#head_row.querySelectorAll("data_grid_cell"))
1806
+ for (const cell of this.#headRow.querySelectorAll("data_grid_cell"))
1807
1807
  cell.classList.remove("data_grid_cell_dragging");
1808
1808
  this.#drag = undefined;
1809
1809
  };
1810
1810
 
1811
1811
  /** Место вставки по координате курсора: середина каждой видимой колонки */
1812
1812
  #dropSlot(clientX = Number()) {
1813
- const cells = Array.from(this.#head_row.querySelectorAll("data_grid_cell[data-column]"));
1813
+ const cells = Array.from(this.#headRow.querySelectorAll("data_grid_cell[data-column]"));
1814
1814
  for (let place = 0; place < cells.length; place++) {
1815
1815
  const rect = cells[place].getBoundingClientRect();
1816
1816
  if (clientX < rect.left + rect.width / 2) return place;
@@ -1819,10 +1819,10 @@ class DataGrid {
1819
1819
  }
1820
1820
 
1821
1821
  #markDrop(slot = undefined) {
1822
- for (const cell of this.#head_row.querySelectorAll("data_grid_cell"))
1822
+ for (const cell of this.#headRow.querySelectorAll("data_grid_cell"))
1823
1823
  cell.classList.remove("data_grid_cell_drop_after");
1824
1824
  if (slot === undefined) return;
1825
- const cells = Array.from(this.#head_row.querySelectorAll("data_grid_cell[data-column]"));
1825
+ const cells = Array.from(this.#headRow.querySelectorAll("data_grid_cell[data-column]"));
1826
1826
  const target = cells[slot === 0 ? 0 : slot - 1];
1827
1827
  if (target !== undefined) target.classList.add("data_grid_cell_drop_after");
1828
1828
  }
@@ -1845,8 +1845,8 @@ class DataGrid {
1845
1845
  this.#onHeaderDragEnd();
1846
1846
  this.#recompute();
1847
1847
  this.#buildHeader();
1848
- if (this.#on_column_order_change !== undefined) {
1849
- this.#on_column_order_change(this.getColumnOrder(), column.key, from, target);
1848
+ if (this.#onColumnOrderChange !== undefined) {
1849
+ this.#onColumnOrderChange(this.getColumnOrder(), column.key, from, target);
1850
1850
  }
1851
1851
  }
1852
1852
 
@@ -1864,13 +1864,13 @@ class DataGrid {
1864
1864
  this.#buildHeader();
1865
1865
  const from = index;
1866
1866
  const to = this.#columns.indexOf(column);
1867
- const node = this.#head_row.querySelector(`data_grid_cell[data-column="${to}"]`);
1867
+ const node = this.#headRow.querySelector(`data_grid_cell[data-column="${to}"]`);
1868
1868
  if (node !== null) node.focus();
1869
1869
  this.#announce(
1870
1870
  I18n.t("dataGrid.columnPlace", { title: column.title, place: to + 1, total: this.#columns.length })
1871
1871
  );
1872
- if (this.#on_column_order_change !== undefined)
1873
- this.#on_column_order_change(this.getColumnOrder(), column.key, from, to);
1872
+ if (this.#onColumnOrderChange !== undefined)
1873
+ this.#onColumnOrderChange(this.getColumnOrder(), column.key, from, to);
1874
1874
  }
1875
1875
 
1876
1876
  // === ПОЛОСА НАД СЕТКОЙ И ДИАЛОГ КОЛОНОК ===
@@ -1887,9 +1887,9 @@ class DataGrid {
1887
1887
  }
1888
1888
 
1889
1889
  #ensureChooser() {
1890
- if (this.#chooser_dialog !== undefined) {
1890
+ if (this.#chooserDialog !== undefined) {
1891
1891
  this.#refreshChooser();
1892
- return this.#chooser_dialog;
1892
+ return this.#chooserDialog;
1893
1893
  }
1894
1894
  const dialog = new Dialog({
1895
1895
  width: "340px",
@@ -1900,16 +1900,16 @@ class DataGrid {
1900
1900
  const block = new ContentBlock({ direction: "column", wrap: "nowrap", width: "-webkit-fill-available" });
1901
1901
  dialog.addToBody(block);
1902
1902
  dialog.addToFooter(new Button({ title: I18n.t("dataGrid.showAll"), clickEvent: () => this.showAllColumns() }));
1903
- this.#chooser_dialog = dialog;
1904
- this.#chooser_block = block;
1903
+ this.#chooserDialog = dialog;
1904
+ this.#chooserBlock = block;
1905
1905
  document.body.appendChild(dialog.set());
1906
1906
  this.#refreshChooser();
1907
1907
  return dialog;
1908
1908
  }
1909
1909
 
1910
1910
  #refreshChooser() {
1911
- if (this.#chooser_block === undefined) return;
1912
- this.#chooser_block.clear();
1911
+ if (this.#chooserBlock === undefined) return;
1912
+ this.#chooserBlock.clear();
1913
1913
  for (const column of this.#columns) {
1914
1914
  const checkbox = new CheckBox({
1915
1915
  name: `${this.#id}_column_${column.key}`,
@@ -1918,7 +1918,7 @@ class DataGrid {
1918
1918
  });
1919
1919
  // У CheckBox нет опции начального значения: ставим его отдельно
1920
1920
  checkbox.setValue(this.isColumnVisible(column.key));
1921
- this.#chooser_block.add(checkbox);
1921
+ this.#chooserBlock.add(checkbox);
1922
1922
  }
1923
1923
  }
1924
1924
 
@@ -1926,28 +1926,28 @@ class DataGrid {
1926
1926
  #requestParams(offset = Number()) {
1927
1927
  return {
1928
1928
  offset: offset,
1929
- limit: this.#page_size,
1929
+ limit: this.#pageSize,
1930
1930
  filter: this.#filter,
1931
- filterKeys: this.#filter_keys,
1931
+ filterKeys: this.#filterKeys,
1932
1932
  sort: { key: this.#sort.key, direction: this.#sort.direction },
1933
1933
  };
1934
1934
  }
1935
1935
 
1936
1936
  async #load(mode = "first") {
1937
- if (this.#data_source === undefined || this.#loading) return;
1937
+ if (this.#dataSource === undefined || this.#loading) return;
1938
1938
  const request = this.#request + 1;
1939
1939
  this.#request = request;
1940
1940
  this.#loading = true;
1941
1941
  this.#setError(undefined);
1942
1942
  this.#list.setLoadingMore(true);
1943
1943
  try {
1944
- const payload = await this.#data_source(this.#requestParams(mode === "first" ? 0 : this.#data.length));
1944
+ const payload = await this.#dataSource(this.#requestParams(mode === "first" ? 0 : this.#data.length));
1945
1945
  if (request !== this.#request) return;
1946
1946
  const rows = DataGrid.#payloadRows(payload);
1947
1947
  const total = DataGrid.#payloadTotal(payload);
1948
1948
  this.#data = mode === "first" ? rows : this.#data.concat(rows);
1949
- this.#server_total = total;
1950
- this.#has_more = total === undefined ? rows.length >= this.#page_size : this.#data.length < total;
1949
+ this.#serverTotal = total;
1950
+ this.#hasMore = total === undefined ? rows.length >= this.#pageSize : this.#data.length < total;
1951
1951
  this.#reindex();
1952
1952
  this.#recompute();
1953
1953
  this.#announce(
@@ -1955,7 +1955,7 @@ class DataGrid {
1955
1955
  ? I18n.t("dataGrid.loadedRows", { shown: this.#data.length })
1956
1956
  : I18n.t("dataGrid.loadedRowsOf", { shown: this.#data.length, total: total })
1957
1957
  );
1958
- if (this.#on_data_load !== undefined) this.#on_data_load(rows, total);
1958
+ if (this.#onDataLoad !== undefined) this.#onDataLoad(rows, total);
1959
1959
  } catch (error) {
1960
1960
  if (request !== this.#request) return;
1961
1961
  this.#failed = true;
@@ -1965,12 +1965,12 @@ class DataGrid {
1965
1965
  : I18n.t("dataGrid.unknownError");
1966
1966
  this.#setError(I18n.t("dataGrid.loadFailed", { message: message }));
1967
1967
  this.#announce(I18n.t("dataGrid.loadFailedAnnounce", { message: message }));
1968
- if (this.#on_data_error !== undefined) this.#on_data_error(error, this.#requestParams(this.#data.length));
1968
+ if (this.#onDataError !== undefined) this.#onDataError(error, this.#requestParams(this.#data.length));
1969
1969
  } finally {
1970
1970
  if (request === this.#request) {
1971
1971
  this.#loading = false;
1972
1972
  this.#list.setLoadingMore(false);
1973
- this.#list.setHasMore(this.#has_more && this.#failed === false);
1973
+ this.#list.setHasMore(this.#hasMore && this.#failed === false);
1974
1974
  }
1975
1975
  }
1976
1976
  }
@@ -1978,10 +1978,10 @@ class DataGrid {
1978
1978
  #setError(message = undefined) {
1979
1979
  const broken = message !== undefined;
1980
1980
  this.#error.hidden = broken === false;
1981
- this.#error_text.innerText = broken ? String(message) : "";
1981
+ this.#errorText.innerText = broken ? String(message) : "";
1982
1982
  // «Нет данных» и «не удалось загрузить» — разное, поэтому подпись пустого списка меняется
1983
1983
  this.#list.setEmptyText(
1984
- broken ? I18n.t("dataGrid.notLoaded") : optionOr(this.#empty_text, I18n.t("dataGrid.empty"))
1984
+ broken ? I18n.t("dataGrid.notLoaded") : optionOr(this.#emptyText, I18n.t("dataGrid.empty"))
1985
1985
  );
1986
1986
  }
1987
1987
 
@@ -2055,13 +2055,13 @@ class DataGrid {
2055
2055
  // === ДАННЫЕ И СОСТОЯНИЕ СЕТКИ ===
2056
2056
  /** Индекс строки в исходных данных: нужен и `render(row, index)`, и ключу по умолчанию */
2057
2057
  #rowIndexOf(row = Object()) {
2058
- const index = this.#row_index.get(row);
2058
+ const index = this.#rowIndex.get(row);
2059
2059
  return index === undefined ? -1 : index;
2060
2060
  }
2061
2061
 
2062
2062
  #reindex() {
2063
- this.#row_index = new Map();
2064
- for (let index = 0; index < this.#data.length; index++) this.#row_index.set(this.#data[index], index);
2063
+ this.#rowIndex = new Map();
2064
+ for (let index = 0; index < this.#data.length; index++) this.#rowIndex.set(this.#data[index], index);
2065
2065
  }
2066
2066
 
2067
2067
  /** Замыкание выравнивания и прокрутки: после смены колонок всё считается заново */
@@ -2100,10 +2100,10 @@ class DataGrid {
2100
2100
  }
2101
2101
  /** Элементов списка: заголовки групп тоже считаются */
2102
2102
  getEntryCount() {
2103
- return this.#entry_count;
2103
+ return this.#entryCount;
2104
2104
  }
2105
2105
  getRowHeight() {
2106
- return this.#row_height;
2106
+ return this.#rowHeight;
2107
2107
  }
2108
2108
  getVisibleRange() {
2109
2109
  return this.#list.getVisibleRange();
@@ -2136,16 +2136,16 @@ class DataGrid {
2136
2136
  return this.#selection;
2137
2137
  }
2138
2138
  isServer() {
2139
- return this.#data_source !== undefined;
2139
+ return this.#dataSource !== undefined;
2140
2140
  }
2141
2141
  isLoading() {
2142
2142
  return this.#loading;
2143
2143
  }
2144
2144
  getServerTotal() {
2145
- return this.#server_total;
2145
+ return this.#serverTotal;
2146
2146
  }
2147
2147
  getPageSize() {
2148
- return this.#page_size;
2148
+ return this.#pageSize;
2149
2149
  }
2150
2150
  isEditing() {
2151
2151
  return this.#editing !== undefined;
@@ -2178,21 +2178,21 @@ class DataGrid {
2178
2178
  return this.#hidden.has(key) === false;
2179
2179
  }
2180
2180
  isColumnReorder() {
2181
- return this.#column_reorder;
2181
+ return this.#columnReorder;
2182
2182
  }
2183
2183
  getColumnOrder() {
2184
2184
  return this.#columns.map((column) => column.key);
2185
2185
  }
2186
2186
  getGroupBy() {
2187
- return this.#group_by;
2187
+ return this.#groupBy;
2188
2188
  }
2189
2189
  /** Группы с агрегатами и состоянием свёрнутости */
2190
2190
  getGroups() {
2191
2191
  return this.#groups.map((group) => ({
2192
2192
  key: group.key,
2193
2193
  title:
2194
- typeof this.#group_label === "function"
2195
- ? String(this.#group_label(group.key, group.rows))
2194
+ typeof this.#groupLabel === "function"
2195
+ ? String(this.#groupLabel(group.key, group.rows))
2196
2196
  : I18n.t("dataGrid.groupTitle", { key: group.key, count: group.rows.length }),
2197
2197
  rows: group.rows.slice(),
2198
2198
  aggregates: group.aggregates,
@@ -2226,9 +2226,9 @@ class DataGrid {
2226
2226
  setData(data = []) {
2227
2227
  this.#data = Array.isArray(data) ? data : [];
2228
2228
  // Ручная замена данных выключает догрузку сервера: иначе она перезаписала бы их
2229
- this.#data_source = undefined;
2230
- this.#has_more = false;
2231
- this.#server_total = undefined;
2229
+ this.#dataSource = undefined;
2230
+ this.#hasMore = false;
2231
+ this.#serverTotal = undefined;
2232
2232
  this.#selected.clear();
2233
2233
  this.#editing = undefined;
2234
2234
  this.#failed = false;
@@ -2248,26 +2248,26 @@ class DataGrid {
2248
2248
  }
2249
2249
 
2250
2250
  setPageSize(size = Number()) {
2251
- this.#page_size = DataGrid.#normalizePageSize(size);
2251
+ this.#pageSize = DataGrid.#normalizePageSize(size);
2252
2252
  return this;
2253
2253
  }
2254
2254
 
2255
2255
  setRowHeight(height = Number()) {
2256
- this.#row_height = Number(height);
2257
- this.#list.setItemHeight(this.#row_height);
2256
+ this.#rowHeight = Number(height);
2257
+ this.#list.setItemHeight(this.#rowHeight);
2258
2258
  this.#syncColumns();
2259
2259
  return this;
2260
2260
  }
2261
2261
 
2262
2262
  /** Перечитать страницы с сервера с текущим фильтром и сортировкой */
2263
2263
  reload() {
2264
- if (this.#data_source === undefined) return this;
2264
+ if (this.#dataSource === undefined) return this;
2265
2265
  this.#request = this.#request + 1;
2266
2266
  this.#loading = false;
2267
2267
  this.#failed = false;
2268
2268
  this.#data = [];
2269
- this.#has_more = true;
2270
- this.#server_total = undefined;
2269
+ this.#hasMore = true;
2270
+ this.#serverTotal = undefined;
2271
2271
  this.#reindex();
2272
2272
  this.#recompute();
2273
2273
  this.#load("first");
@@ -2275,22 +2275,22 @@ class DataGrid {
2275
2275
  }
2276
2276
 
2277
2277
  loadMore() {
2278
- if (this.#data_source === undefined || this.#has_more === false || this.#failed) return this;
2278
+ if (this.#dataSource === undefined || this.#hasMore === false || this.#failed) return this;
2279
2279
  this.#load("more");
2280
2280
  return this;
2281
2281
  }
2282
2282
 
2283
2283
  retryLoad() {
2284
- if (this.#data_source === undefined) return this;
2284
+ if (this.#dataSource === undefined) return this;
2285
2285
  this.#failed = false;
2286
- this.#list.setHasMore(this.#has_more);
2286
+ this.#list.setHasMore(this.#hasMore);
2287
2287
  this.#load("more");
2288
2288
  return this;
2289
2289
  }
2290
2290
 
2291
2291
  setFilter(text = String()) {
2292
2292
  this.#filter = String(text);
2293
- if (this.#data_source !== undefined) return this.reload();
2293
+ if (this.#dataSource !== undefined) return this.reload();
2294
2294
  this.#recompute();
2295
2295
  // Про фильтр сообщаем числом строк: «фильтр «n»: 3 из 12»
2296
2296
  const shown = this.#sorted.length;
@@ -2310,7 +2310,7 @@ class DataGrid {
2310
2310
  setSort(key = undefined, direction = DataGrid.SORT.NONE) {
2311
2311
  const known = this.#columns.some((column) => column.key === key) ? key : undefined;
2312
2312
  this.#sort = { key: known, direction: known === undefined ? DataGrid.SORT.NONE : direction };
2313
- if (this.#data_source !== undefined) return this.reload();
2313
+ if (this.#dataSource !== undefined) return this.reload();
2314
2314
  this.#applySort();
2315
2315
  return this;
2316
2316
  }
@@ -2326,15 +2326,15 @@ class DataGrid {
2326
2326
  }
2327
2327
 
2328
2328
  setOnActiveCellChange(listener = undefined) {
2329
- this.#on_active_cell_change = listener;
2329
+ this.#onActiveCellChange = listener;
2330
2330
  return this;
2331
2331
  }
2332
2332
 
2333
2333
  setContextMenu(ctx = undefined) {
2334
- if (this.#context_menu === ctx) return this;
2335
- if (this.#context_menu !== undefined && typeof this.#context_menu.detach === "function")
2336
- this.#context_menu.detach();
2337
- this.#context_menu = ctx;
2334
+ if (this.#contextMenu === ctx) return this;
2335
+ if (this.#contextMenu !== undefined && typeof this.#contextMenu.detach === "function")
2336
+ this.#contextMenu.detach();
2337
+ this.#contextMenu = ctx;
2338
2338
  if (ctx !== undefined && typeof ctx.attach === "function") ctx.attach(this.#root);
2339
2339
  return this;
2340
2340
  }
@@ -2429,13 +2429,13 @@ class DataGrid {
2429
2429
  }
2430
2430
 
2431
2431
  setColumnReorder(enabled = Boolean()) {
2432
- this.#column_reorder = enabled === true;
2432
+ this.#columnReorder = enabled === true;
2433
2433
  this.#buildHeader();
2434
2434
  return this;
2435
2435
  }
2436
2436
 
2437
2437
  setGroupBy(groupBy = undefined) {
2438
- this.#group_by = groupBy;
2438
+ this.#groupBy = groupBy;
2439
2439
  this.#collapsed.clear();
2440
2440
  this.#recompute();
2441
2441
  return this;
@@ -2483,27 +2483,27 @@ class DataGrid {
2483
2483
 
2484
2484
  /** Снять подписки и отпустить ресурсы; узел остаётся в документе */
2485
2485
  destroy() {
2486
- this.#resize_observer.disconnect();
2487
- this.#head_row.removeEventListener("click", this.#onHeaderClick);
2488
- this.#head_row.removeEventListener("keydown", this.#onHeaderKeyDown);
2489
- this.#head_row.removeEventListener("dragstart", this.#onHeaderDragStart);
2490
- this.#head_row.removeEventListener("dragover", this.#onHeaderDragOver);
2491
- this.#head_row.removeEventListener("dragleave", this.#onHeaderDragLeave);
2492
- this.#head_row.removeEventListener("drop", this.#onHeaderDrop);
2493
- this.#head_row.removeEventListener("dragend", this.#onHeaderDragEnd);
2486
+ this.#resizeObserver.disconnect();
2487
+ this.#headRow.removeEventListener("click", this.#onHeaderClick);
2488
+ this.#headRow.removeEventListener("keydown", this.#onHeaderKeyDown);
2489
+ this.#headRow.removeEventListener("dragstart", this.#onHeaderDragStart);
2490
+ this.#headRow.removeEventListener("dragover", this.#onHeaderDragOver);
2491
+ this.#headRow.removeEventListener("dragleave", this.#onHeaderDragLeave);
2492
+ this.#headRow.removeEventListener("drop", this.#onHeaderDrop);
2493
+ this.#headRow.removeEventListener("dragend", this.#onHeaderDragEnd);
2494
2494
  this.#root.removeEventListener("dblclick", this.#onDoubleClick, true);
2495
2495
  this.#root.removeEventListener("keydown", this.#onKeyDown);
2496
2496
  this.#scroll.removeEventListener("scroll", this.#onScrollX);
2497
2497
  if (this.#editing !== undefined) this.#finishEdit(false, false, false);
2498
- if (this.#context_menu !== undefined && typeof this.#context_menu.detach === "function")
2499
- this.#context_menu.detach();
2498
+ if (this.#contextMenu !== undefined && typeof this.#contextMenu.detach === "function")
2499
+ this.#contextMenu.detach();
2500
2500
  this.#list.destroy();
2501
- if (this.#chooser_dialog !== undefined) {
2501
+ if (this.#chooserDialog !== undefined) {
2502
2502
  // У диалога нет своего «удали себя»: узел снимаем с документа сами
2503
- const node = this.#chooser_dialog.set();
2503
+ const node = this.#chooserDialog.set();
2504
2504
  if (node !== undefined && node.parentNode !== null) node.parentNode.removeChild(node);
2505
- this.#chooser_dialog = undefined;
2506
- this.#chooser_block = undefined;
2505
+ this.#chooserDialog = undefined;
2506
+ this.#chooserBlock = undefined;
2507
2507
  }
2508
2508
  return this;
2509
2509
  }