chuijs 4.0.2 → 4.0.3

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 (221) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +43 -644
  3. package/framework/appLayout/default/chui_app_layout.js +308 -260
  4. package/framework/appLayout/default/global_style.css +85 -48
  5. package/framework/components/chui_accordion/accordion.js +29 -26
  6. package/framework/components/chui_accordion/styles.css +6 -5
  7. package/framework/components/chui_action_sheet/action_sheet.js +59 -33
  8. package/framework/components/chui_action_sheet/styles.css +2 -1
  9. package/framework/components/chui_affix/affix.js +11 -6
  10. package/framework/components/chui_alert/alert.js +23 -14
  11. package/framework/components/chui_avatar/avatar.js +23 -22
  12. package/framework/components/chui_avatar_group/avatar_group.js +21 -19
  13. package/framework/components/chui_backtop/backtop.js +35 -19
  14. package/framework/components/chui_badge/badge.js +15 -13
  15. package/framework/components/chui_breadcrumb/breadcrumb.js +15 -13
  16. package/framework/components/chui_button/button.js +42 -22
  17. package/framework/components/chui_button/styles.css +2 -2
  18. package/framework/components/chui_calendar/calendar.js +12 -10
  19. package/framework/components/chui_card/card.js +43 -23
  20. package/framework/components/chui_chat/chat.js +72 -33
  21. package/framework/components/chui_clipboard_history/clipboard_history.js +30 -21
  22. package/framework/components/chui_clipboard_history/styles.css +4 -2
  23. package/framework/components/chui_code/code.js +2 -2
  24. package/framework/components/chui_code/styles.css +2 -2
  25. package/framework/components/chui_code_editor/code_editor.js +47 -31
  26. package/framework/components/chui_code_editor/styles.css +3 -2
  27. package/framework/components/chui_command_palette/command_palette.js +60 -37
  28. package/framework/components/chui_console/console.js +5 -5
  29. package/framework/components/chui_console/styles.css +1 -1
  30. package/framework/components/chui_content_block/content_block.js +33 -19
  31. package/framework/components/chui_content_block/styles.css +2 -2
  32. package/framework/components/chui_context_menu/context_menu.js +9 -4
  33. package/framework/components/chui_custom_element/custom_element.js +22 -15
  34. package/framework/components/chui_data_grid/data_grid.js +396 -234
  35. package/framework/components/chui_data_grid/styles.css +10 -8
  36. package/framework/components/chui_descriptions/descriptions.js +34 -17
  37. package/framework/components/chui_details/details.js +32 -26
  38. package/framework/components/chui_details/styles.css +5 -4
  39. package/framework/components/chui_diff_viewer/diff_viewer.js +91 -66
  40. package/framework/components/chui_diff_viewer/styles.css +1 -1
  41. package/framework/components/chui_divider/divider.js +13 -11
  42. package/framework/components/chui_drawer/drawer.js +27 -25
  43. package/framework/components/chui_drop_zone/drop_zone.js +31 -21
  44. package/framework/components/chui_empty_state/empty_state.js +20 -15
  45. package/framework/components/chui_fieldset/fieldset.js +37 -20
  46. package/framework/components/chui_fieldset/styles.css +1 -1
  47. package/framework/components/chui_file_explorer/file_explorer.js +157 -86
  48. package/framework/components/chui_file_explorer/styles.css +2 -1
  49. package/framework/components/chui_form/form.js +31 -19
  50. package/framework/components/chui_form/styles.css +1 -1
  51. package/framework/components/chui_gantt/gantt.js +64 -40
  52. package/framework/components/chui_graphs/graphs.js +301 -200
  53. package/framework/components/chui_graphs/styles.css +1 -1
  54. package/framework/components/chui_hero/hero.js +40 -22
  55. package/framework/components/chui_html_block/html_block.js +6 -6
  56. package/framework/components/chui_html_block/styles.css +2 -2
  57. package/framework/components/chui_hx/hx.js +3 -3
  58. package/framework/components/chui_hx/styles.css +11 -4
  59. package/framework/components/chui_icons/icons.js +2109 -2109
  60. package/framework/components/chui_icons/styles.css +2 -2
  61. package/framework/components/chui_inputs/chui_check_box/check_box.js +31 -19
  62. package/framework/components/chui_inputs/chui_check_box/styles.css +18 -18
  63. package/framework/components/chui_inputs/chui_chips/chips.js +50 -40
  64. package/framework/components/chui_inputs/chui_chips/styles.css +4 -2
  65. package/framework/components/chui_inputs/chui_color_picker/color_picker.js +36 -24
  66. package/framework/components/chui_inputs/chui_combo_box/combo_box.js +100 -82
  67. package/framework/components/chui_inputs/chui_combo_box/styles.css +14 -12
  68. package/framework/components/chui_inputs/chui_date/date.js +102 -66
  69. package/framework/components/chui_inputs/chui_date/styles.css +12 -11
  70. package/framework/components/chui_inputs/chui_date_range/date_range.js +40 -29
  71. package/framework/components/chui_inputs/chui_datetime/datetime.js +35 -27
  72. package/framework/components/chui_inputs/chui_email/email.js +43 -31
  73. package/framework/components/chui_inputs/chui_email/styles.css +5 -5
  74. package/framework/components/chui_inputs/chui_file/file.js +68 -41
  75. package/framework/components/chui_inputs/chui_file/styles.css +13 -12
  76. package/framework/components/chui_inputs/chui_hotkey/hotkey.js +61 -36
  77. package/framework/components/chui_inputs/chui_masked/masked.js +39 -28
  78. package/framework/components/chui_inputs/chui_mention/mention.js +77 -30
  79. package/framework/components/chui_inputs/chui_multi_combo_box/multi_combo_box.js +173 -153
  80. package/framework/components/chui_inputs/chui_multi_combo_box/styles.css +9 -7
  81. package/framework/components/chui_inputs/chui_number/number.js +58 -41
  82. package/framework/components/chui_inputs/chui_number/styles.css +7 -7
  83. package/framework/components/chui_inputs/chui_otp/otp.js +38 -29
  84. package/framework/components/chui_inputs/chui_password/password.js +58 -36
  85. package/framework/components/chui_inputs/chui_password/styles.css +8 -8
  86. package/framework/components/chui_inputs/chui_radio_button/radio_button.js +37 -25
  87. package/framework/components/chui_inputs/chui_radio_button/styles.css +20 -20
  88. package/framework/components/chui_inputs/chui_rating/rating.js +26 -22
  89. package/framework/components/chui_inputs/chui_select_box/select_box.js +102 -78
  90. package/framework/components/chui_inputs/chui_select_box/styles.css +11 -11
  91. package/framework/components/chui_inputs/chui_slider/slider.js +29 -26
  92. package/framework/components/chui_inputs/chui_slider/styles.css +2 -1
  93. package/framework/components/chui_inputs/chui_text/styles.css +8 -8
  94. package/framework/components/chui_inputs/chui_text/text.js +65 -44
  95. package/framework/components/chui_inputs/chui_text_area/styles.css +6 -6
  96. package/framework/components/chui_inputs/chui_text_area/text_area.js +51 -28
  97. package/framework/components/chui_inputs/chui_time/styles.css +5 -3
  98. package/framework/components/chui_inputs/chui_time/time.js +38 -27
  99. package/framework/components/chui_inputs/chui_toggle/styles.css +3 -3
  100. package/framework/components/chui_inputs/chui_toggle/toggle.js +16 -16
  101. package/framework/components/chui_json_editor/json_editor.js +53 -43
  102. package/framework/components/chui_json_viewer/json_viewer.js +52 -33
  103. package/framework/components/chui_json_viewer/styles.css +3 -2
  104. package/framework/components/chui_kanban/kanban.js +52 -34
  105. package/framework/components/chui_kbd/kbd.js +12 -10
  106. package/framework/components/chui_label/label.js +14 -12
  107. package/framework/components/chui_label/styles.css +2 -2
  108. package/framework/components/chui_link/link.js +27 -20
  109. package/framework/components/chui_list/list.js +31 -27
  110. package/framework/components/chui_list/styles.css +2 -1
  111. package/framework/components/chui_markdown_editor/markdown_editor.js +60 -44
  112. package/framework/components/chui_media/audio.js +326 -227
  113. package/framework/components/chui_media/audio_styles.css +40 -21
  114. package/framework/components/chui_media/image.js +70 -38
  115. package/framework/components/chui_media/image_compare.js +52 -21
  116. package/framework/components/chui_media/image_styles.css +3 -3
  117. package/framework/components/chui_media/video.js +155 -62
  118. package/framework/components/chui_media/video_styles.css +33 -16
  119. package/framework/components/chui_menu_bar/menu_bar.js +26 -24
  120. package/framework/components/chui_menu_bar/styles.css +4 -2
  121. package/framework/components/chui_modal/modal.js +44 -43
  122. package/framework/components/chui_modal/styles.css +3 -2
  123. package/framework/components/chui_notification/notification.js +50 -34
  124. package/framework/components/chui_notification/notification_download.js +31 -25
  125. package/framework/components/chui_notification/notification_download_progress.css +3 -2
  126. package/framework/components/chui_notification/notification_download_progress.js +47 -41
  127. package/framework/components/chui_notification/notification_update.js +23 -16
  128. package/framework/components/chui_notification/status_plate.js +2 -2
  129. package/framework/components/chui_notification/styles_download.css +1 -1
  130. package/framework/components/chui_notification/styles_update.css +1 -1
  131. package/framework/components/chui_org_chart/org_chart.js +74 -35
  132. package/framework/components/chui_pagination/pagination.js +62 -27
  133. package/framework/components/chui_paragraph/paragraph.js +2 -2
  134. package/framework/components/chui_paragraph/styles.css +1 -1
  135. package/framework/components/chui_popover/popover.js +49 -28
  136. package/framework/components/chui_popups/popups.js +137 -108
  137. package/framework/components/chui_popups/styles.css +2 -2
  138. package/framework/components/chui_print_button/print_button.js +33 -23
  139. package/framework/components/chui_progress_bar/progress_bar.js +23 -15
  140. package/framework/components/chui_progress_bar/styles.css +2 -2
  141. package/framework/components/chui_progress_ring/progress_ring.js +17 -15
  142. package/framework/components/chui_qrcode/qrcode.js +75 -31
  143. package/framework/components/chui_query_builder/query_builder.js +216 -123
  144. package/framework/components/chui_radio_group/radio_group.js +36 -26
  145. package/framework/components/chui_radio_group/styles.css +1 -1
  146. package/framework/components/chui_result/result.js +26 -16
  147. package/framework/components/chui_scheduler/scheduler.js +57 -35
  148. package/framework/components/chui_scheduler/styles.css +6 -2
  149. package/framework/components/chui_segmented_control/segmented_control.js +27 -21
  150. package/framework/components/chui_settings/settings.js +122 -48
  151. package/framework/components/chui_shortcut_help/shortcut_help.js +55 -32
  152. package/framework/components/chui_sidebar_nav/sidebar_nav.js +33 -23
  153. package/framework/components/chui_skeleton/skeleton.js +29 -24
  154. package/framework/components/chui_slideshow/slideshow.js +60 -41
  155. package/framework/components/chui_slideshow/styles.css +18 -12
  156. package/framework/components/chui_spinner/spinner.js +8 -8
  157. package/framework/components/chui_spinner/styles.css +0 -1
  158. package/framework/components/chui_split_button/split_button.js +23 -18
  159. package/framework/components/chui_split_button/styles.css +1 -1
  160. package/framework/components/chui_splitter/splitter.js +35 -28
  161. package/framework/components/chui_statistic/statistic.js +65 -38
  162. package/framework/components/chui_status_bar/status_bar.js +11 -9
  163. package/framework/components/chui_stepper/stepper.js +27 -22
  164. package/framework/components/chui_sticky_bar/sticky_bar.js +9 -4
  165. package/framework/components/chui_sticky_bar/styles.css +3 -1
  166. package/framework/components/chui_tabs/chui_tabs.js +28 -22
  167. package/framework/components/chui_tabs/styles.css +3 -3
  168. package/framework/components/chui_text_editor/styles.css +20 -19
  169. package/framework/components/chui_text_editor/text_editor.js +85 -61
  170. package/framework/components/chui_text_editor/text_editor_panel.js +346 -284
  171. package/framework/components/chui_theme_toggle/theme_toggle.js +27 -22
  172. package/framework/components/chui_timeline/timeline.js +14 -12
  173. package/framework/components/chui_toast_queue/toast_queue.js +52 -46
  174. package/framework/components/chui_toolbar/toolbar.js +20 -13
  175. package/framework/components/chui_tooltip/tooltip.js +37 -24
  176. package/framework/components/chui_tour/styles.css +8 -3
  177. package/framework/components/chui_tour/tour.js +61 -27
  178. package/framework/components/chui_transfer/styles.css +2 -1
  179. package/framework/components/chui_transfer/transfer.js +75 -42
  180. package/framework/components/chui_tree_table/tree_table.js +43 -29
  181. package/framework/components/chui_tree_view/styles.css +4 -2
  182. package/framework/components/chui_tree_view/tree_view.js +142 -99
  183. package/framework/components/chui_watermark/watermark.js +24 -16
  184. package/framework/components/chui_webview/styles.css +2 -2
  185. package/framework/components/chui_webview/webview.js +62 -50
  186. package/framework/components/telegram_bot/chui_telegram_bot.js +71 -64
  187. package/framework/modules/chui_a11y/chui_a11y.js +77 -46
  188. package/framework/modules/chui_animations/animations.js +42 -42
  189. package/framework/modules/chui_animations/styles.css +1 -1
  190. package/framework/modules/chui_bridge/preload.js +36 -25
  191. package/framework/modules/chui_functions.js +52 -50
  192. package/framework/modules/chui_highlight/chui_highlight.js +25 -22
  193. package/framework/modules/chui_i18n/chui_i18n.js +9 -7
  194. package/framework/modules/chui_i18n/locales/a11y.js +5 -5
  195. package/framework/modules/chui_i18n/locales/app_layout.js +5 -5
  196. package/framework/modules/chui_i18n/locales/calendar.js +3 -3
  197. package/framework/modules/chui_i18n/locales/common.js +3 -3
  198. package/framework/modules/chui_i18n/locales/data.js +36 -26
  199. package/framework/modules/chui_i18n/locales/editors.js +40 -13
  200. package/framework/modules/chui_i18n/locales/feedback.js +3 -3
  201. package/framework/modules/chui_i18n/locales/forms.js +8 -8
  202. package/framework/modules/chui_i18n/locales/graphics.js +8 -8
  203. package/framework/modules/chui_i18n/locales/media.js +4 -4
  204. package/framework/modules/chui_i18n/locales/navigation.js +8 -8
  205. package/framework/modules/chui_i18n/locales/validate.js +3 -3
  206. package/framework/modules/chui_json/chui_json.js +9 -9
  207. package/framework/modules/chui_layout/chui_layout.js +12 -10
  208. package/framework/modules/chui_logger/chui_logger.js +29 -25
  209. package/framework/modules/chui_page/page.js +33 -27
  210. package/framework/modules/chui_qr/chui_qr.js +158 -67
  211. package/framework/modules/chui_scrollbar/chui_scrollbar.js +35 -24
  212. package/framework/modules/chui_scrollbar/styles.css +3 -1
  213. package/framework/modules/chui_services/chui_channels.js +27 -13
  214. package/framework/modules/chui_services/chui_services.js +39 -31
  215. package/framework/modules/chui_services/desktop.js +32 -31
  216. package/framework/modules/chui_sortable/chui_sortable.js +17 -12
  217. package/framework/modules/chui_validate/chui_validate.js +7 -4
  218. package/framework/tray_bar/chui_menu_items.js +136 -46
  219. package/index.d.ts +4814 -0
  220. package/index.js +385 -292
  221. package/package.json +79 -68
@@ -1,8 +1,8 @@
1
- const { setStyles, markdownToHtml, optionOr } = require('../../modules/chui_functions');
2
- const { OverlayA11y } = require('../../modules/chui_a11y/chui_a11y');
3
- const { Popover } = require('../chui_popover/popover');
4
- const { Icon, Icons } = require('../chui_icons/icons');
5
- const { I18n } = require('../../modules/chui_i18n/chui_i18n');
1
+ const { setStyles, markdownToHtml, optionOr } = require("../../modules/chui_functions");
2
+ const { OverlayA11y } = require("../../modules/chui_a11y/chui_a11y");
3
+ const { Popover } = require("../chui_popover/popover");
4
+ const { Icon, Icons } = require("../chui_icons/icons");
5
+ const { I18n } = require("../../modules/chui_i18n/chui_i18n");
6
6
 
7
7
  /**
8
8
  * Пошаговое знакомство с интерфейсом: затемнённая подложка с «окном» вокруг цели
@@ -44,7 +44,7 @@ class Tour {
44
44
  TOP: "top",
45
45
  BOTTOM: "bottom",
46
46
  LEFT: "left",
47
- RIGHT: "right"
47
+ RIGHT: "right",
48
48
  };
49
49
  /** Зазор вокруг подсвеченной цели, px */
50
50
  static PADDING = 6;
@@ -55,14 +55,14 @@ class Tour {
55
55
  skip: Icons.AUDIO_VIDEO.SKIP_NEXT,
56
56
  prev: Icons.NAVIGATION.ARROW_BACK,
57
57
  next: Icons.NAVIGATION.ARROW_FORWARD,
58
- finish: Icons.ACTIONS.DONE
58
+ finish: Icons.ACTIONS.DONE,
59
59
  };
60
60
 
61
61
  #id = require("randomstring").generate();
62
62
  #layer = document.createElement("chui_tour");
63
63
  #highlight = document.createElement("tour_highlight");
64
64
  // Объявление для скринридера: узел носит класс общей утилиты скрытия (по нему его узнают стенды)
65
- #status = Object.assign(document.createElement("chui_visually_hidden"), {className: "chui_visually_hidden"});
65
+ #status = Object.assign(document.createElement("chui_visually_hidden"), { className: "chui_visually_hidden" });
66
66
  #popover = undefined;
67
67
  #head = document.createElement("tour_head");
68
68
  #title = document.createElement("tour_title");
@@ -90,11 +90,20 @@ class Tour {
90
90
  #on_change = undefined;
91
91
  #destroyed = false;
92
92
 
93
- constructor(options = {
94
- id: String(), steps: [], mask: Boolean(), closable: Boolean(), keyboard: Boolean(),
95
- scrollIntoView: Boolean(), label: String(),
96
- onFinish: undefined, onClose: undefined, onChange: undefined
97
- }) {
93
+ constructor(
94
+ options = {
95
+ id: String(),
96
+ steps: [],
97
+ mask: Boolean(),
98
+ closable: Boolean(),
99
+ keyboard: Boolean(),
100
+ scrollIntoView: Boolean(),
101
+ label: String(),
102
+ onFinish: undefined,
103
+ onClose: undefined,
104
+ onChange: undefined,
105
+ }
106
+ ) {
98
107
  setStyles(__dirname + "/styles.css", "chUiJS_Tour");
99
108
  this.#steps = Array.isArray(options.steps) ? options.steps : [];
100
109
  // Заготовка опции (`String()`) равносильна отсутствующей: иначе слой без аргументов
@@ -159,7 +168,7 @@ class Tour {
159
168
  this.#a11y = new OverlayA11y(this.#layer, {
160
169
  role: "dialog",
161
170
  describedBy: this.#text,
162
- onEscape: () => this.close()
171
+ onEscape: () => this.close(),
163
172
  });
164
173
  this.#a11y.setLabel(this.#label === undefined ? I18n.t("feedback.tourLabel") : this.#label);
165
174
  this.#close_button.setAttribute("aria-label", I18n.t("a11y.closeDialog"));
@@ -173,7 +182,10 @@ class Tour {
173
182
  /** Начать знакомство с первого шага; шаги без найденной цели в него не попадают */
174
183
  start() {
175
184
  if (this.#destroyed || this.#is_open) return this;
176
- this.#active = this.#steps.filter((step) => step !== undefined && step !== null && (step.target === undefined || this.#targetOf(step) !== undefined));
185
+ this.#active = this.#steps.filter(
186
+ (step) =>
187
+ step !== undefined && step !== null && (step.target === undefined || this.#targetOf(step) !== undefined)
188
+ );
177
189
  if (this.#active.length === 0) return this;
178
190
  this.#index = 0;
179
191
  this.#is_open = true;
@@ -223,15 +235,23 @@ class Tour {
223
235
  return this.#end(false);
224
236
  }
225
237
 
226
- isOpen() { return this.#is_open; }
238
+ isOpen() {
239
+ return this.#is_open;
240
+ }
227
241
  /** Номер текущего шага; вне знакомства — 0 */
228
- getIndex() { return this.#index; }
229
- getSteps() { return [...this.#steps]; }
242
+ getIndex() {
243
+ return this.#index;
244
+ }
245
+ getSteps() {
246
+ return [...this.#steps];
247
+ }
230
248
  setSteps(steps = []) {
231
249
  this.#steps = Array.isArray(steps) ? steps : [];
232
250
  return this;
233
251
  }
234
- getId() { return this.#id; }
252
+ getId() {
253
+ return this.#id;
254
+ }
235
255
 
236
256
  /** Полное удаление: знакомство закрывается без уведомлений, слой и поповер убираются */
237
257
  destroy() {
@@ -254,7 +274,9 @@ class Tour {
254
274
  return this;
255
275
  }
256
276
 
257
- set() { return this.#layer; }
277
+ set() {
278
+ return this.#layer;
279
+ }
258
280
 
259
281
  // === ВНУТРЕННЕЕ ===
260
282
  /**
@@ -304,7 +326,7 @@ class Tour {
304
326
  if (step.markdownText !== undefined) this.#text.innerHTML = markdownToHtml(step.markdownText);
305
327
  else if (step.text !== undefined) this.#text.innerText = String(step.text);
306
328
  // Счётчик, значки и видимость закрывающих кнопок
307
- this.#counter.innerText = I18n.t("feedback.tourStepOf", {index: this.#index + 1, total: this.#active.length});
329
+ this.#counter.innerText = I18n.t("feedback.tourStepOf", { index: this.#index + 1, total: this.#active.length });
308
330
  this.#nameButton(this.#prev_button, "feedback.tourPrev");
309
331
  // Последний шаг: «Далее» становится «Готово» — вместе с именем меняется и значок
310
332
  this.#nameButton(this.#next_button, last ? "feedback.tourFinish" : "feedback.tourNext");
@@ -317,7 +339,9 @@ class Tour {
317
339
  if (this.#layer.contains(previous)) previous.focus();
318
340
  else this.#next_button.focus();
319
341
  }
320
- this.#announce(`${this.#counter.innerText}${this.#title.innerText.trim() === "" ? "" : ". " + this.#title.innerText}`);
342
+ this.#announce(
343
+ `${this.#counter.innerText}${this.#title.innerText.trim() === "" ? "" : ". " + this.#title.innerText}`
344
+ );
321
345
  // Цель: подвести в вид, измерить и поставить «окно» с подсказкой
322
346
  this.#scrollIntoView(step);
323
347
  this.#syncGeometry();
@@ -340,7 +364,12 @@ class Tour {
340
364
  #targetOf(step = {}) {
341
365
  const target = step.target;
342
366
  if (target === undefined || target === null) return undefined;
343
- const node = typeof target === "string" ? document.querySelector(target) : (typeof target.set === "function" ? target.set() : target);
367
+ const node =
368
+ typeof target === "string"
369
+ ? document.querySelector(target)
370
+ : typeof target.set === "function"
371
+ ? target.set()
372
+ : target;
344
373
  return node instanceof Element ? node : undefined;
345
374
  }
346
375
 
@@ -348,7 +377,7 @@ class Tour {
348
377
  if (!this.#scroll_into_view) return;
349
378
  const node = this.#targetOf(step);
350
379
  if (node === undefined) return;
351
- node.scrollIntoView({block: "center", inline: "nearest"});
380
+ node.scrollIntoView({ block: "center", inline: "nearest" });
352
381
  }
353
382
 
354
383
  /** «Окно» вокруг цели: у шага без цели — точка в центре окна (подсказка встаёт у неё) */
@@ -360,10 +389,15 @@ class Tour {
360
389
  let box;
361
390
  if (node === undefined) {
362
391
  const left = Math.max(0, (window.innerWidth - Tour.WIDTH) / 2);
363
- box = {left: left, top: window.innerHeight / 2, width: 0, height: 0};
392
+ box = { left: left, top: window.innerHeight / 2, width: 0, height: 0 };
364
393
  } else {
365
394
  const rect = node.getBoundingClientRect();
366
- box = {left: rect.left - padding, top: rect.top - padding, width: rect.width + padding * 2, height: rect.height + padding * 2};
395
+ box = {
396
+ left: rect.left - padding,
397
+ top: rect.top - padding,
398
+ width: rect.width + padding * 2,
399
+ height: rect.height + padding * 2,
400
+ };
367
401
  }
368
402
  this.#highlight.style.left = `${Math.round(box.left)}px`;
369
403
  this.#highlight.style.top = `${Math.round(box.top)}px`;
@@ -400,4 +434,4 @@ class Tour {
400
434
  };
401
435
  }
402
436
 
403
- exports.Tour = Tour
437
+ exports.Tour = Tour;
@@ -76,7 +76,8 @@ chui_transfer {
76
76
  margin: 0;
77
77
  /* Место под кнопку очистки, чтобы текст не заезжал под неё; слева 11 px — как
78
78
  у текстовых полей (--main_padding_sm) */
79
- padding-block: 0 0; padding-inline: 11px 30px;
79
+ padding-block: 0 0;
80
+ padding-inline: 11px 30px;
80
81
  border: 1px solid var(--border_color);
81
82
  border-radius: var(--border_radius);
82
83
  background: var(--element_background);
@@ -1,8 +1,8 @@
1
- const {setStyles} = require("../../modules/chui_functions");
2
- const {Validate} = require("../../modules/chui_validate/chui_validate");
3
- const {Icon, Icons} = require("../chui_icons/icons");
4
- const {RovingKeyboard} = require("../../modules/chui_a11y/chui_a11y");
5
- const {I18n} = require("../../modules/chui_i18n/chui_i18n");
1
+ const { setStyles } = require("../../modules/chui_functions");
2
+ const { Validate } = require("../../modules/chui_validate/chui_validate");
3
+ const { Icon, Icons } = require("../chui_icons/icons");
4
+ const { RovingKeyboard } = require("../../modules/chui_a11y/chui_a11y");
5
+ const { I18n } = require("../../modules/chui_i18n/chui_i18n");
6
6
 
7
7
  /**
8
8
  * Перенос значений между двумя списками: слева доступное, справа выбранное.
@@ -68,23 +68,25 @@ class Transfer {
68
68
  // Строка, к которой нужно вернуть фокус после перерисовки
69
69
  #focus_value = undefined;
70
70
 
71
- constructor(options = {
72
- id: String(),
73
- name: String(),
74
- title: String(),
75
- label: String(),
76
- hint: String(),
77
- items: Array(),
78
- value: Array(),
79
- sourceTitle: String(),
80
- targetTitle: String(),
81
- searchable: Boolean(),
82
- disabled: Boolean(),
83
- min: Number(),
84
- max: Number(),
85
- changeListener: undefined,
86
- onChange: undefined
87
- }) {
71
+ constructor(
72
+ options = {
73
+ id: String(),
74
+ name: String(),
75
+ title: String(),
76
+ label: String(),
77
+ hint: String(),
78
+ items: Array(),
79
+ value: Array(),
80
+ sourceTitle: String(),
81
+ targetTitle: String(),
82
+ searchable: Boolean(),
83
+ disabled: Boolean(),
84
+ min: Number(),
85
+ max: Number(),
86
+ changeListener: undefined,
87
+ onChange: undefined,
88
+ }
89
+ ) {
88
90
  setStyles(__dirname + "/styles.css", "chUiJS_Transfer");
89
91
  Transfer.#counter += 1;
90
92
  this.#id = options.id === undefined ? `chui_transfer_${Transfer.#counter}` : options.id;
@@ -92,8 +94,10 @@ class Transfer {
92
94
  this.#label_text = options.label;
93
95
  this.#on_change = options.onChange;
94
96
  this.#searchable = options.searchable === true;
95
- this.#source_title = options.sourceTitle === undefined ? I18n.t("transfer.available") : String(options.sourceTitle);
96
- this.#target_title = options.targetTitle === undefined ? I18n.t("transfer.chosen") : String(options.targetTitle);
97
+ this.#source_title =
98
+ options.sourceTitle === undefined ? I18n.t("transfer.available") : String(options.sourceTitle);
99
+ this.#target_title =
100
+ options.targetTitle === undefined ? I18n.t("transfer.chosen") : String(options.targetTitle);
97
101
  this.#min = options.min;
98
102
  this.#max = options.max;
99
103
  this.#root.id = this.#id;
@@ -101,8 +105,20 @@ class Transfer {
101
105
  this.#label.id = `${this.#id}_label`;
102
106
  this.#row.className = "transfer_row";
103
107
  this.#row.setAttribute("role", "group");
104
- this.#list_pane(this.#source_pane, this.#source_head, this.#source_list, this.#source_title, Transfer.SIDE.SOURCE);
105
- this.#list_pane(this.#target_pane, this.#target_head, this.#target_list, this.#target_title, Transfer.SIDE.TARGET);
108
+ this.#list_pane(
109
+ this.#source_pane,
110
+ this.#source_head,
111
+ this.#source_list,
112
+ this.#source_title,
113
+ Transfer.SIDE.SOURCE
114
+ );
115
+ this.#list_pane(
116
+ this.#target_pane,
117
+ this.#target_head,
118
+ this.#target_list,
119
+ this.#target_title,
120
+ Transfer.SIDE.TARGET
121
+ );
106
122
  this.#source_list.addEventListener("click", this.#onClick);
107
123
  this.#target_list.addEventListener("click", this.#onClick);
108
124
  this.#source_list.addEventListener("dblclick", this.#onDoubleClick);
@@ -111,10 +127,18 @@ class Transfer {
111
127
  this.#target_list.addEventListener("keydown", this.#onKeyDown);
112
128
  this.#arrow_target.type = "button";
113
129
  this.#arrow_source.type = "button";
114
- this.#move_button(this.#arrow_target, Transfer.SIDE.TARGET, Icons.NAVIGATION.CHEVRON_RIGHT,
115
- I18n.t("transfer.addMarked", {title: this.#target_title}));
116
- this.#move_button(this.#arrow_source, Transfer.SIDE.SOURCE, Icons.NAVIGATION.CHEVRON_LEFT,
117
- I18n.t("transfer.removeMarked", {title: this.#source_title}));
130
+ this.#move_button(
131
+ this.#arrow_target,
132
+ Transfer.SIDE.TARGET,
133
+ Icons.NAVIGATION.CHEVRON_RIGHT,
134
+ I18n.t("transfer.addMarked", { title: this.#target_title })
135
+ );
136
+ this.#move_button(
137
+ this.#arrow_source,
138
+ Transfer.SIDE.SOURCE,
139
+ Icons.NAVIGATION.CHEVRON_LEFT,
140
+ I18n.t("transfer.removeMarked", { title: this.#source_title })
141
+ );
118
142
  const controls = document.createElement("transfer_controls");
119
143
  controls.className = "transfer_controls";
120
144
  controls.appendChild(this.#arrow_target);
@@ -143,8 +167,8 @@ class Transfer {
143
167
  delete rules_options.max;
144
168
  Validate.installField(this, rules_options, this.#root, this.#error, () => this.getValue(), this.#row);
145
169
  this.#installRules();
146
- this.#source_roving = new RovingKeyboard(this.#source_list, {itemSelector: ".transfer_item"});
147
- this.#target_roving = new RovingKeyboard(this.#target_list, {itemSelector: ".transfer_item"});
170
+ this.#source_roving = new RovingKeyboard(this.#source_list, { itemSelector: ".transfer_item" });
171
+ this.#target_roving = new RovingKeyboard(this.#target_list, { itemSelector: ".transfer_item" });
148
172
  this.setItems(options.items);
149
173
  if (options.value !== undefined) this.setValue(options.value);
150
174
  this.setDisabled(options.disabled === true);
@@ -367,7 +391,8 @@ class Transfer {
367
391
  }
368
392
 
369
393
  static #toItem(item = Object(), index = Number()) {
370
- if (typeof item === "string") return {title: item, subtitle: undefined, value: item, disabled: false, chosen: false};
394
+ if (typeof item === "string")
395
+ return { title: item, subtitle: undefined, value: item, disabled: false, chosen: false };
371
396
  return {
372
397
  title: item.title === undefined ? String(index + 1) : String(item.title),
373
398
  subtitle: item.subtitle === undefined ? undefined : String(item.subtitle),
@@ -408,14 +433,14 @@ class Transfer {
408
433
  search.type = "search";
409
434
  search.className = "transfer_search";
410
435
  search.placeholder = I18n.t("transfer.search");
411
- search.setAttribute("aria-label", I18n.t("transfer.searchIn", {title: title}));
436
+ search.setAttribute("aria-label", I18n.t("transfer.searchIn", { title: title }));
412
437
  // Кнопка очистки — своя: системная кнопка очистки у `input[type=search]` скрыта (см. стили)
413
438
  const box = document.createElement("transfer_search_box");
414
439
  box.className = "transfer_search_box";
415
440
  const clear = document.createElement("button");
416
441
  clear.type = "button";
417
442
  clear.className = "transfer_search_clear";
418
- clear.setAttribute("aria-label", I18n.t("transfer.clearSearchIn", {title: title}));
443
+ clear.setAttribute("aria-label", I18n.t("transfer.clearSearchIn", { title: title }));
419
444
  clear.hidden = true;
420
445
  const glyph = new Icon(Icons.NAVIGATION.CLOSE, "16px").set();
421
446
  glyph.setAttribute("aria-hidden", "true");
@@ -458,12 +483,12 @@ class Transfer {
458
483
  if (!result.valid) return result;
459
484
  const count = this.#markedItems().length;
460
485
  if (this.#min !== undefined && count < this.#min) {
461
- return {valid: false, rule: "min", message: I18n.t("transfer.selectMin", {min: this.#min})};
486
+ return { valid: false, rule: "min", message: I18n.t("transfer.selectMin", { min: this.#min }) };
462
487
  }
463
488
  if (this.#max !== undefined && count > this.#max) {
464
- return {valid: false, rule: "max", message: I18n.t("transfer.selectMax", {max: this.#max})};
489
+ return { valid: false, rule: "max", message: I18n.t("transfer.selectMax", { max: this.#max }) };
465
490
  }
466
- return {valid: true};
491
+ return { valid: true };
467
492
  };
468
493
  return this;
469
494
  }
@@ -535,7 +560,8 @@ class Transfer {
535
560
  const empty = document.createElement("transfer_empty");
536
561
  // Пояснение, а не пункт списка: иначе listbox получил бы фиктивную опцию
537
562
  empty.setAttribute("role", "presentation");
538
- empty.innerText = filter === "" ? I18n.t("transfer.emptyList", {title: title}) : I18n.t("common.nothingFound");
563
+ empty.innerText =
564
+ filter === "" ? I18n.t("transfer.emptyList", { title: title }) : I18n.t("common.nothingFound");
539
565
  list.appendChild(empty);
540
566
  return empty;
541
567
  }
@@ -583,7 +609,7 @@ class Transfer {
583
609
  if (side === Transfer.SIDE.TARGET && this.#max !== undefined) {
584
610
  const room = this.#max - this.#markedItems().length;
585
611
  if (moving.length > room) {
586
- this.#announce(I18n.t("transfer.maxReached", {max: this.#max}));
612
+ this.#announce(I18n.t("transfer.maxReached", { max: this.#max }));
587
613
  return;
588
614
  }
589
615
  }
@@ -597,7 +623,14 @@ class Transfer {
597
623
  this.#focus_value = moving[0];
598
624
  this.#render();
599
625
  const side_title = side === Transfer.SIDE.TARGET ? this.#target_title : this.#source_title;
600
- this.#announce(I18n.t("transfer.moved", {title: side_title, titles: titles.join(", "), count: this.#markedItems().length, total: this.#items.length}));
626
+ this.#announce(
627
+ I18n.t("transfer.moved", {
628
+ title: side_title,
629
+ titles: titles.join(", "),
630
+ count: this.#markedItems().length,
631
+ total: this.#items.length,
632
+ })
633
+ );
601
634
  this.#notify();
602
635
  return this;
603
636
  }
@@ -651,4 +684,4 @@ class Transfer {
651
684
  };
652
685
  }
653
686
 
654
- exports.Transfer = Transfer
687
+ exports.Transfer = Transfer;
@@ -1,6 +1,6 @@
1
- const {setStyles, optionOr} = require("../../modules/chui_functions");
2
- const {Icon, Icons} = require("../chui_icons/icons");
3
- const {I18n} = require("../../modules/chui_i18n/chui_i18n");
1
+ const { setStyles, optionOr } = require("../../modules/chui_functions");
2
+ const { Icon, Icons } = require("../chui_icons/icons");
3
+ const { I18n } = require("../../modules/chui_i18n/chui_i18n");
4
4
 
5
5
  /** Служебные ключи строки: всё остальное — значения колонок */
6
6
  const SERVICE_KEYS = ["id", "children", "expanded", "disabled", "selected"];
@@ -80,21 +80,23 @@ class TreeTable {
80
80
  #focus_id = undefined;
81
81
  #visible_count = 0;
82
82
 
83
- constructor(options = {
84
- id: String(),
85
- title: String(),
86
- label: String(),
87
- columns: Array(),
88
- rows: Array(),
89
- expanded: Array(),
90
- selectable: Boolean(),
91
- indent: Number(),
92
- height: String(),
93
- emptyText: String(),
94
- onSelect: undefined,
95
- onToggle: undefined,
96
- changeEvent: undefined
97
- }) {
83
+ constructor(
84
+ options = {
85
+ id: String(),
86
+ title: String(),
87
+ label: String(),
88
+ columns: Array(),
89
+ rows: Array(),
90
+ expanded: Array(),
91
+ selectable: Boolean(),
92
+ indent: Number(),
93
+ height: String(),
94
+ emptyText: String(),
95
+ onSelect: undefined,
96
+ onToggle: undefined,
97
+ changeEvent: undefined,
98
+ }
99
+ ) {
98
100
  setStyles(__dirname + "/styles.css", "chUiJS_TreeTable");
99
101
  TreeTable.#counter += 1;
100
102
  this.#id = options.id === undefined ? `chui_tree_table_${TreeTable.#counter}` : options.id;
@@ -335,7 +337,8 @@ class TreeTable {
335
337
  setFilter(text = String()) {
336
338
  this.#filter = text === undefined ? "" : String(text);
337
339
  this.#render();
338
- if (this.#filter !== "") this.#announce(I18n.t("treeTable.shownRows", {shown: this.#visible_count, total: this.#index.size}));
340
+ if (this.#filter !== "")
341
+ this.#announce(I18n.t("treeTable.shownRows", { shown: this.#visible_count, total: this.#index.size }));
339
342
  return this;
340
343
  }
341
344
 
@@ -369,7 +372,10 @@ class TreeTable {
369
372
  const target = id === undefined ? undefined : String(id);
370
373
  const list = this.#body.querySelectorAll("tree_table_row");
371
374
  if (list.length === 0) return this;
372
- const row = target === undefined ? list[0] : this.#body.querySelector(`tree_table_row[data-id="${CSS.escape(target)}"]`);
375
+ const row =
376
+ target === undefined
377
+ ? list[0]
378
+ : this.#body.querySelector(`tree_table_row[data-id="${CSS.escape(target)}"]`);
373
379
  if (row === null) return this;
374
380
  this.#focusRow(row.dataset.id);
375
381
  return this;
@@ -396,7 +402,7 @@ class TreeTable {
396
402
  }
397
403
 
398
404
  #describe(node) {
399
- const descriptor = {id: node.id};
405
+ const descriptor = { id: node.id };
400
406
  for (const key of Object.keys(node.values)) descriptor[key] = node.values[key];
401
407
  descriptor.expanded = node.children.length > 0 && this.#expanded.has(node.id);
402
408
  descriptor.disabled = node.disabled;
@@ -463,7 +469,7 @@ class TreeTable {
463
469
  const walk = (nodes, level) => {
464
470
  for (const node of nodes) {
465
471
  if (filter !== "" && !this.#matchesTree(node, filter)) continue;
466
- list.push({node: node, level: level});
472
+ list.push({ node: node, level: level });
467
473
  if (!this.#isOpen(node, filter)) continue;
468
474
  walk(node.children, level + 1);
469
475
  }
@@ -485,7 +491,11 @@ class TreeTable {
485
491
  }
486
492
 
487
493
  #matchesRow(node, filter) {
488
- return this.#columns.some((column) => String(node.values[column.key] === undefined ? "" : node.values[column.key]).toLowerCase().includes(filter));
494
+ return this.#columns.some((column) =>
495
+ String(node.values[column.key] === undefined ? "" : node.values[column.key])
496
+ .toLowerCase()
497
+ .includes(filter)
498
+ );
489
499
  }
490
500
 
491
501
  #render() {
@@ -550,7 +560,10 @@ class TreeTable {
550
560
  toggle.className = "tree_table_toggle";
551
561
  // Стрелка не отдельная остановка обхода: у таблицы одна остановка на строку
552
562
  toggle.setAttribute("tabindex", "-1");
553
- toggle.setAttribute("aria-label", I18n.t(open ? "a11y.collapseNode" : "a11y.expandNode", {name: this.#titleOf(node)}));
563
+ toggle.setAttribute(
564
+ "aria-label",
565
+ I18n.t(open ? "a11y.collapseNode" : "a11y.expandNode", { name: this.#titleOf(node) })
566
+ );
554
567
  toggle.dataset.id = node.id;
555
568
  const glyph = new Icon(Icons.NAVIGATION.CHEVRON_RIGHT, "18px").set();
556
569
  glyph.setAttribute("aria-hidden", "true");
@@ -611,9 +624,11 @@ class TreeTable {
611
624
  else this.#expanded.delete(id);
612
625
  this.#render();
613
626
  if (silent) return this;
614
- this.#announce(value
615
- ? I18n.t("treeTable.expanded", {name: this.#titleOf(node), count: node.children.length})
616
- : I18n.t("treeTable.collapsed", {name: this.#titleOf(node)}));
627
+ this.#announce(
628
+ value
629
+ ? I18n.t("treeTable.expanded", { name: this.#titleOf(node), count: node.children.length })
630
+ : I18n.t("treeTable.collapsed", { name: this.#titleOf(node) })
631
+ );
617
632
  if (this.#on_toggle !== undefined) this.#on_toggle(this.#describe(node), value, this);
618
633
  return this;
619
634
  }
@@ -746,5 +761,4 @@ class TreeTable {
746
761
  };
747
762
  }
748
763
 
749
- exports.TreeTable = TreeTable
750
-
764
+ exports.TreeTable = TreeTable;
@@ -81,7 +81,8 @@ tree_view_button[aria-expanded="true"] tree_view_button_arrow chui_icon {
81
81
  tree_view_panel {
82
82
  display: block;
83
83
  width: -webkit-fill-available;
84
- padding-block: 0 0; padding-inline: 18px 0;
84
+ padding-block: 0 0;
85
+ padding-inline: 18px 0;
85
86
  overflow: hidden;
86
87
  max-height: 0;
87
88
  position: relative;
@@ -115,7 +116,8 @@ tree_view_button:hover {
115
116
  }
116
117
 
117
118
  tree_view_button:active {
118
- background: var(--element_background_prime); color: var(--text_color_hover);
119
+ background: var(--element_background_prime);
120
+ color: var(--text_color_hover);
119
121
  }
120
122
 
121
123
  tree_view_button:focus-visible {