chuijs 4.0.1 → 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.
- package/CHANGELOG.md +113 -0
- package/README.md +43 -632
- package/framework/appLayout/default/chui_app_layout.js +314 -273
- package/framework/appLayout/default/global_style.css +93 -53
- package/framework/components/chui_accordion/accordion.js +29 -26
- package/framework/components/chui_accordion/styles.css +6 -5
- package/framework/components/chui_action_sheet/action_sheet.js +59 -33
- package/framework/components/chui_action_sheet/styles.css +2 -1
- package/framework/components/chui_affix/affix.js +11 -6
- package/framework/components/chui_alert/alert.js +23 -14
- package/framework/components/chui_avatar/avatar.js +23 -22
- package/framework/components/chui_avatar_group/avatar_group.js +21 -19
- package/framework/components/chui_backtop/backtop.js +35 -19
- package/framework/components/chui_badge/badge.js +15 -13
- package/framework/components/chui_breadcrumb/breadcrumb.js +15 -13
- package/framework/components/chui_button/button.js +42 -22
- package/framework/components/chui_button/styles.css +2 -2
- package/framework/components/chui_calendar/calendar.js +12 -10
- package/framework/components/chui_card/card.js +43 -23
- package/framework/components/chui_chat/chat.js +72 -33
- package/framework/components/chui_clipboard_history/clipboard_history.js +30 -21
- package/framework/components/chui_clipboard_history/styles.css +4 -2
- package/framework/components/chui_code/code.js +2 -2
- package/framework/components/chui_code/styles.css +2 -2
- package/framework/components/chui_code_editor/code_editor.js +47 -31
- package/framework/components/chui_code_editor/styles.css +3 -2
- package/framework/components/chui_command_palette/command_palette.js +60 -37
- package/framework/components/chui_console/console.js +5 -5
- package/framework/components/chui_console/styles.css +1 -1
- package/framework/components/chui_content_block/content_block.js +33 -19
- package/framework/components/chui_content_block/styles.css +2 -2
- package/framework/components/chui_context_menu/context_menu.js +9 -4
- package/framework/components/chui_custom_element/custom_element.js +22 -15
- package/framework/components/chui_data_grid/data_grid.js +396 -234
- package/framework/components/chui_data_grid/styles.css +10 -8
- package/framework/components/chui_descriptions/descriptions.js +34 -17
- package/framework/components/chui_details/details.js +32 -26
- package/framework/components/chui_details/styles.css +5 -4
- package/framework/components/chui_diff_viewer/diff_viewer.js +91 -66
- package/framework/components/chui_diff_viewer/styles.css +1 -1
- package/framework/components/chui_divider/divider.js +13 -11
- package/framework/components/chui_drawer/drawer.js +27 -25
- package/framework/components/chui_drop_zone/drop_zone.js +31 -21
- package/framework/components/chui_empty_state/empty_state.js +20 -15
- package/framework/components/chui_fieldset/fieldset.js +37 -20
- package/framework/components/chui_fieldset/styles.css +1 -1
- package/framework/components/chui_file_explorer/file_explorer.js +157 -86
- package/framework/components/chui_file_explorer/styles.css +2 -1
- package/framework/components/chui_form/form.js +31 -19
- package/framework/components/chui_form/styles.css +1 -1
- package/framework/components/chui_gantt/gantt.js +64 -40
- package/framework/components/chui_graphs/graphs.js +301 -200
- package/framework/components/chui_graphs/styles.css +1 -1
- package/framework/components/chui_hero/hero.js +40 -22
- package/framework/components/chui_html_block/html_block.js +6 -6
- package/framework/components/chui_html_block/styles.css +2 -2
- package/framework/components/chui_hx/hx.js +3 -3
- package/framework/components/chui_hx/styles.css +11 -4
- package/framework/components/chui_icons/icons.js +2109 -2109
- package/framework/components/chui_icons/styles.css +2 -2
- package/framework/components/chui_inputs/chui_check_box/check_box.js +31 -19
- package/framework/components/chui_inputs/chui_check_box/styles.css +18 -18
- package/framework/components/chui_inputs/chui_chips/chips.js +50 -40
- package/framework/components/chui_inputs/chui_chips/styles.css +4 -2
- package/framework/components/chui_inputs/chui_color_picker/color_picker.js +36 -24
- package/framework/components/chui_inputs/chui_combo_box/combo_box.js +100 -82
- package/framework/components/chui_inputs/chui_combo_box/styles.css +14 -12
- package/framework/components/chui_inputs/chui_date/date.js +102 -66
- package/framework/components/chui_inputs/chui_date/styles.css +12 -11
- package/framework/components/chui_inputs/chui_date_range/date_range.js +40 -29
- package/framework/components/chui_inputs/chui_datetime/datetime.js +35 -27
- package/framework/components/chui_inputs/chui_email/email.js +43 -31
- package/framework/components/chui_inputs/chui_email/styles.css +5 -5
- package/framework/components/chui_inputs/chui_file/file.js +68 -41
- package/framework/components/chui_inputs/chui_file/styles.css +13 -12
- package/framework/components/chui_inputs/chui_hotkey/hotkey.js +61 -36
- package/framework/components/chui_inputs/chui_masked/masked.js +39 -28
- package/framework/components/chui_inputs/chui_mention/mention.js +77 -30
- package/framework/components/chui_inputs/chui_multi_combo_box/multi_combo_box.js +173 -153
- package/framework/components/chui_inputs/chui_multi_combo_box/styles.css +9 -7
- package/framework/components/chui_inputs/chui_number/number.js +58 -41
- package/framework/components/chui_inputs/chui_number/styles.css +7 -7
- package/framework/components/chui_inputs/chui_otp/otp.js +38 -29
- package/framework/components/chui_inputs/chui_password/password.js +58 -36
- package/framework/components/chui_inputs/chui_password/styles.css +8 -8
- package/framework/components/chui_inputs/chui_radio_button/radio_button.js +37 -25
- package/framework/components/chui_inputs/chui_radio_button/styles.css +20 -20
- package/framework/components/chui_inputs/chui_rating/rating.js +26 -22
- package/framework/components/chui_inputs/chui_select_box/select_box.js +102 -78
- package/framework/components/chui_inputs/chui_select_box/styles.css +11 -11
- package/framework/components/chui_inputs/chui_slider/slider.js +29 -26
- package/framework/components/chui_inputs/chui_slider/styles.css +2 -1
- package/framework/components/chui_inputs/chui_text/styles.css +8 -8
- package/framework/components/chui_inputs/chui_text/text.js +65 -44
- package/framework/components/chui_inputs/chui_text_area/styles.css +6 -6
- package/framework/components/chui_inputs/chui_text_area/text_area.js +51 -28
- package/framework/components/chui_inputs/chui_time/styles.css +5 -3
- package/framework/components/chui_inputs/chui_time/time.js +38 -27
- package/framework/components/chui_inputs/chui_toggle/styles.css +3 -3
- package/framework/components/chui_inputs/chui_toggle/toggle.js +16 -16
- package/framework/components/chui_json_editor/json_editor.js +53 -43
- package/framework/components/chui_json_viewer/json_viewer.js +52 -33
- package/framework/components/chui_json_viewer/styles.css +3 -2
- package/framework/components/chui_kanban/kanban.js +52 -34
- package/framework/components/chui_kbd/kbd.js +12 -10
- package/framework/components/chui_label/label.js +14 -12
- package/framework/components/chui_label/styles.css +2 -2
- package/framework/components/chui_link/link.js +27 -20
- package/framework/components/chui_list/list.js +31 -27
- package/framework/components/chui_list/styles.css +2 -1
- package/framework/components/chui_markdown_editor/markdown_editor.js +60 -44
- package/framework/components/chui_media/audio.js +326 -227
- package/framework/components/chui_media/audio_styles.css +40 -21
- package/framework/components/chui_media/image.js +70 -38
- package/framework/components/chui_media/image_compare.js +52 -21
- package/framework/components/chui_media/image_styles.css +3 -3
- package/framework/components/chui_media/video.js +155 -62
- package/framework/components/chui_media/video_styles.css +33 -16
- package/framework/components/chui_menu_bar/menu_bar.js +26 -24
- package/framework/components/chui_menu_bar/styles.css +4 -2
- package/framework/components/chui_modal/modal.js +44 -43
- package/framework/components/chui_modal/styles.css +3 -2
- package/framework/components/chui_notification/notification.js +50 -34
- package/framework/components/chui_notification/notification_download.js +31 -25
- package/framework/components/chui_notification/notification_download_progress.css +3 -2
- package/framework/components/chui_notification/notification_download_progress.js +47 -41
- package/framework/components/chui_notification/notification_update.js +23 -16
- package/framework/components/chui_notification/status_plate.js +2 -2
- package/framework/components/chui_notification/styles_download.css +1 -1
- package/framework/components/chui_notification/styles_update.css +1 -1
- package/framework/components/chui_org_chart/org_chart.js +74 -35
- package/framework/components/chui_pagination/pagination.js +62 -27
- package/framework/components/chui_paragraph/paragraph.js +2 -2
- package/framework/components/chui_paragraph/styles.css +1 -1
- package/framework/components/chui_popover/popover.js +49 -28
- package/framework/components/chui_popups/popups.js +137 -108
- package/framework/components/chui_popups/styles.css +2 -2
- package/framework/components/chui_print_button/print_button.js +33 -23
- package/framework/components/chui_progress_bar/progress_bar.js +23 -15
- package/framework/components/chui_progress_bar/styles.css +2 -2
- package/framework/components/chui_progress_ring/progress_ring.js +17 -15
- package/framework/components/chui_qrcode/qrcode.js +75 -31
- package/framework/components/chui_query_builder/query_builder.js +216 -123
- package/framework/components/chui_radio_group/radio_group.js +36 -26
- package/framework/components/chui_radio_group/styles.css +1 -1
- package/framework/components/chui_result/result.js +26 -16
- package/framework/components/chui_scheduler/scheduler.js +57 -35
- package/framework/components/chui_scheduler/styles.css +6 -2
- package/framework/components/chui_segmented_control/segmented_control.js +27 -21
- package/framework/components/chui_settings/settings.js +122 -48
- package/framework/components/chui_shortcut_help/shortcut_help.js +55 -32
- package/framework/components/chui_sidebar_nav/sidebar_nav.js +33 -23
- package/framework/components/chui_skeleton/skeleton.js +29 -24
- package/framework/components/chui_slideshow/slideshow.js +60 -41
- package/framework/components/chui_slideshow/styles.css +18 -12
- package/framework/components/chui_spinner/spinner.js +8 -8
- package/framework/components/chui_spinner/styles.css +0 -1
- package/framework/components/chui_split_button/split_button.js +23 -18
- package/framework/components/chui_split_button/styles.css +1 -1
- package/framework/components/chui_splitter/splitter.js +35 -28
- package/framework/components/chui_statistic/statistic.js +65 -38
- package/framework/components/chui_status_bar/status_bar.js +11 -9
- package/framework/components/chui_stepper/stepper.js +27 -22
- package/framework/components/chui_sticky_bar/sticky_bar.js +9 -4
- package/framework/components/chui_sticky_bar/styles.css +3 -1
- package/framework/components/chui_tabs/chui_tabs.js +28 -22
- package/framework/components/chui_tabs/styles.css +3 -3
- package/framework/components/chui_text_editor/styles.css +20 -19
- package/framework/components/chui_text_editor/text_editor.js +85 -61
- package/framework/components/chui_text_editor/text_editor_panel.js +346 -284
- package/framework/components/chui_theme_toggle/theme_toggle.js +27 -22
- package/framework/components/chui_timeline/timeline.js +14 -12
- package/framework/components/chui_toast_queue/toast_queue.js +52 -46
- package/framework/components/chui_toolbar/toolbar.js +20 -13
- package/framework/components/chui_tooltip/tooltip.js +37 -24
- package/framework/components/chui_tour/styles.css +8 -3
- package/framework/components/chui_tour/tour.js +61 -27
- package/framework/components/chui_transfer/styles.css +2 -1
- package/framework/components/chui_transfer/transfer.js +75 -42
- package/framework/components/chui_tree_table/tree_table.js +43 -29
- package/framework/components/chui_tree_view/styles.css +4 -2
- package/framework/components/chui_tree_view/tree_view.js +142 -99
- package/framework/components/chui_watermark/watermark.js +24 -16
- package/framework/components/chui_webview/styles.css +2 -2
- package/framework/components/chui_webview/webview.js +62 -50
- package/framework/components/telegram_bot/chui_telegram_bot.js +71 -64
- package/framework/modules/chui_a11y/chui_a11y.js +77 -46
- package/framework/modules/chui_animations/animations.js +42 -42
- package/framework/modules/chui_animations/styles.css +1 -1
- package/framework/modules/chui_bridge/preload.js +56 -26
- package/framework/modules/chui_functions.js +52 -50
- package/framework/modules/chui_highlight/chui_highlight.js +25 -22
- package/framework/modules/chui_i18n/chui_i18n.js +9 -7
- package/framework/modules/chui_i18n/locales/a11y.js +5 -5
- package/framework/modules/chui_i18n/locales/app_layout.js +5 -5
- package/framework/modules/chui_i18n/locales/calendar.js +3 -3
- package/framework/modules/chui_i18n/locales/common.js +3 -3
- package/framework/modules/chui_i18n/locales/data.js +36 -26
- package/framework/modules/chui_i18n/locales/editors.js +40 -13
- package/framework/modules/chui_i18n/locales/feedback.js +3 -3
- package/framework/modules/chui_i18n/locales/forms.js +8 -8
- package/framework/modules/chui_i18n/locales/graphics.js +8 -8
- package/framework/modules/chui_i18n/locales/media.js +4 -4
- package/framework/modules/chui_i18n/locales/navigation.js +8 -8
- package/framework/modules/chui_i18n/locales/validate.js +3 -3
- package/framework/modules/chui_json/chui_json.js +9 -9
- package/framework/modules/chui_layout/chui_layout.js +12 -10
- package/framework/modules/chui_logger/chui_logger.js +29 -25
- package/framework/modules/chui_page/page.js +33 -27
- package/framework/modules/chui_page/styles.css +3 -26
- package/framework/modules/chui_qr/chui_qr.js +158 -67
- package/framework/modules/chui_scrollbar/chui_scrollbar.js +35 -24
- package/framework/modules/chui_scrollbar/styles.css +3 -1
- package/framework/modules/chui_services/chui_channels.js +76 -11
- package/framework/modules/chui_services/chui_services.js +39 -31
- package/framework/modules/chui_services/desktop.js +149 -30
- package/framework/modules/chui_sortable/chui_sortable.js +17 -12
- package/framework/modules/chui_validate/chui_validate.js +7 -4
- package/framework/tray_bar/chui_menu_items.js +136 -46
- package/index.d.ts +4814 -0
- package/index.js +449 -334
- package/package.json +79 -68
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const { setStyles, markdownToHtml, optionOr } = require(
|
|
2
|
-
const { OverlayA11y } = require(
|
|
3
|
-
const { Popover } = require(
|
|
4
|
-
const { Icon, Icons } = require(
|
|
5
|
-
const { I18n } = require(
|
|
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(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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(
|
|
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() {
|
|
238
|
+
isOpen() {
|
|
239
|
+
return this.#is_open;
|
|
240
|
+
}
|
|
227
241
|
/** Номер текущего шага; вне знакомства — 0 */
|
|
228
|
-
getIndex() {
|
|
229
|
-
|
|
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() {
|
|
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() {
|
|
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(
|
|
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 =
|
|
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 = {
|
|
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;
|
|
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(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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 =
|
|
96
|
-
|
|
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(
|
|
105
|
-
|
|
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(
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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")
|
|
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 =
|
|
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(
|
|
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(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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 !== "")
|
|
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 =
|
|
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) =>
|
|
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(
|
|
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(
|
|
615
|
-
|
|
616
|
-
|
|
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;
|
|
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);
|
|
119
|
+
background: var(--element_background_prime);
|
|
120
|
+
color: var(--text_color_hover);
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
tree_view_button:focus-visible {
|