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.
- package/CHANGELOG.md +536 -0
- package/framework/appLayout/default/chui_app_layout.js +361 -303
- package/framework/appLayout/default/global_style.css +243 -89
- package/framework/appLayout/default/main_theme_style.css +188 -101
- package/framework/components/chui_accordion/accordion.js +17 -17
- package/framework/components/chui_accordion/styles.css +7 -7
- package/framework/components/chui_action_sheet/action_sheet.js +35 -32
- package/framework/components/chui_action_sheet/styles.css +10 -4
- package/framework/components/chui_actions_bar/actions_bar.js +338 -0
- package/framework/components/chui_actions_bar/styles.css +139 -0
- package/framework/components/chui_affix/affix.js +4 -4
- package/framework/components/chui_affix/styles.css +5 -0
- package/framework/components/chui_alert/alert.js +11 -5
- package/framework/components/chui_alert/styles.css +7 -0
- package/framework/components/chui_avatar/avatar.js +13 -13
- package/framework/components/chui_avatar/styles.css +1 -1
- package/framework/components/chui_avatar_group/avatar_group.js +4 -4
- package/framework/components/chui_avatar_group/styles.css +1 -1
- package/framework/components/chui_backtop/backtop.js +25 -2
- package/framework/components/chui_backtop/styles.css +21 -0
- package/framework/components/chui_badge/badge.js +15 -15
- package/framework/components/chui_badge/styles.css +6 -6
- package/framework/components/chui_banner/banner.js +222 -0
- package/framework/components/chui_banner/styles.css +170 -0
- package/framework/components/chui_breadcrumb/styles.css +1 -1
- package/framework/components/chui_button/button.js +24 -28
- package/framework/components/chui_button/styles.css +5 -5
- package/framework/components/chui_calendar/calendar.js +6 -6
- package/framework/components/chui_card/card.js +14 -14
- package/framework/components/chui_card_scroll/card_scroll.js +169 -0
- package/framework/components/chui_card_scroll/styles.css +86 -0
- package/framework/components/chui_chat/chat.js +73 -51
- package/framework/components/chui_chat/styles.css +18 -7
- package/framework/components/chui_clipboard_history/clipboard_history.js +25 -20
- package/framework/components/chui_clipboard_history/styles.css +10 -8
- package/framework/components/chui_code/code.js +8 -8
- package/framework/components/chui_code/styles.css +2 -2
- package/framework/components/chui_code_editor/code_editor.js +26 -26
- package/framework/components/chui_code_editor/styles.css +3 -3
- package/framework/components/chui_command_palette/command_palette.js +29 -29
- package/framework/components/chui_command_palette/styles.css +5 -5
- package/framework/components/chui_console/console.js +9 -9
- package/framework/components/chui_console/styles.css +5 -2
- package/framework/components/chui_content_block/content_block.js +2 -2
- package/framework/components/chui_context_menu/context_menu.js +162 -54
- package/framework/components/chui_context_menu/styles.css +82 -8
- package/framework/components/chui_custom_element/custom_element.js +11 -11
- package/framework/components/chui_data_grid/data_grid.js +268 -268
- package/framework/components/chui_data_grid/styles.css +14 -14
- package/framework/components/chui_descriptions/styles.css +1 -1
- package/framework/components/chui_details/details.js +12 -12
- package/framework/components/chui_details/styles.css +7 -7
- package/framework/components/chui_diff_viewer/diff_viewer.js +88 -88
- package/framework/components/chui_diff_viewer/styles.css +9 -9
- package/framework/components/chui_divider/divider.js +6 -6
- package/framework/components/chui_divider/styles.css +2 -2
- package/framework/components/chui_drawer/drawer.js +37 -14
- package/framework/components/chui_drawer/styles.css +18 -4
- package/framework/components/chui_drop_zone/drop_zone.js +6 -6
- package/framework/components/chui_drop_zone/styles.css +10 -6
- package/framework/components/chui_fieldset/fieldset.js +6 -6
- package/framework/components/chui_fieldset/styles.css +5 -5
- package/framework/components/chui_file_explorer/file_explorer.js +115 -115
- package/framework/components/chui_file_explorer/styles.css +6 -6
- package/framework/components/chui_form/form.js +11 -11
- package/framework/components/chui_gantt/gantt.js +41 -41
- package/framework/components/chui_gantt/styles.css +5 -5
- package/framework/components/chui_graphs/graphs.js +82 -46
- package/framework/components/chui_graphs/styles.css +26 -5
- package/framework/components/chui_hero/hero.js +63 -20
- package/framework/components/chui_hero/styles.css +176 -7
- package/framework/components/chui_html_block/html_block.js +5 -5
- package/framework/components/chui_html_block/styles.css +1 -1
- package/framework/components/chui_hx/styles.css +2 -2
- package/framework/components/chui_icons/icons.js +7 -7
- package/framework/components/chui_icons/styles.css +2 -1
- package/framework/components/chui_inputs/chui_check_box/styles.css +12 -3
- package/framework/components/chui_inputs/chui_chips/chips.js +92 -31
- package/framework/components/chui_inputs/chui_chips/styles.css +28 -5
- package/framework/components/chui_inputs/chui_color_picker/color_picker.js +20 -15
- package/framework/components/chui_inputs/chui_color_picker/styles.css +7 -7
- package/framework/components/chui_inputs/chui_combo_box/combo_box.js +58 -58
- package/framework/components/chui_inputs/chui_combo_box/styles.css +9 -9
- package/framework/components/chui_inputs/chui_date/date.js +93 -95
- package/framework/components/chui_inputs/chui_date/styles.css +8 -8
- package/framework/components/chui_inputs/chui_date_range/date_range.js +22 -22
- package/framework/components/chui_inputs/chui_date_range/styles.css +3 -3
- package/framework/components/chui_inputs/chui_datetime/datetime.js +12 -12
- package/framework/components/chui_inputs/chui_datetime/styles.css +3 -3
- package/framework/components/chui_inputs/chui_email/email.js +10 -10
- package/framework/components/chui_inputs/chui_email/styles.css +6 -6
- package/framework/components/chui_inputs/chui_file/file.js +8 -8
- package/framework/components/chui_inputs/chui_file/styles.css +12 -9
- package/framework/components/chui_inputs/chui_hotkey/hotkey.js +39 -39
- package/framework/components/chui_inputs/chui_hotkey/styles.css +6 -6
- package/framework/components/chui_inputs/chui_masked/masked.js +44 -44
- package/framework/components/chui_inputs/chui_masked/styles.css +5 -5
- package/framework/components/chui_inputs/chui_mention/mention.js +13 -13
- package/framework/components/chui_inputs/chui_mention/styles.css +14 -8
- package/framework/components/chui_inputs/chui_multi_combo_box/multi_combo_box.js +147 -137
- package/framework/components/chui_inputs/chui_multi_combo_box/styles.css +14 -8
- package/framework/components/chui_inputs/chui_number/number.js +42 -45
- package/framework/components/chui_inputs/chui_number/styles.css +6 -6
- package/framework/components/chui_inputs/chui_otp/otp.js +32 -32
- package/framework/components/chui_inputs/chui_otp/styles.css +5 -5
- package/framework/components/chui_inputs/chui_password/password.js +30 -36
- package/framework/components/chui_inputs/chui_password/styles.css +7 -7
- package/framework/components/chui_inputs/chui_radio_button/styles.css +2 -2
- package/framework/components/chui_inputs/chui_rating/rating.js +28 -28
- package/framework/components/chui_inputs/chui_rating/styles.css +3 -3
- package/framework/components/chui_inputs/chui_select_box/select_box.js +54 -54
- package/framework/components/chui_inputs/chui_select_box/styles.css +10 -10
- package/framework/components/chui_inputs/chui_slider/slider.js +14 -14
- package/framework/components/chui_inputs/chui_slider/styles.css +5 -4
- package/framework/components/chui_inputs/chui_text/styles.css +7 -7
- package/framework/components/chui_inputs/chui_text/text.js +13 -17
- package/framework/components/chui_inputs/chui_text_area/styles.css +8 -8
- package/framework/components/chui_inputs/chui_text_area/text_area.js +23 -23
- package/framework/components/chui_inputs/chui_time/styles.css +13 -17
- package/framework/components/chui_inputs/chui_time/time.js +35 -24
- package/framework/components/chui_inputs/chui_toggle/styles.css +10 -3
- package/framework/components/chui_inputs/chui_toggle/toggle.js +16 -16
- package/framework/components/chui_json_editor/json_editor.js +87 -87
- package/framework/components/chui_json_editor/styles.css +5 -5
- package/framework/components/chui_json_viewer/json_viewer.js +80 -80
- package/framework/components/chui_json_viewer/styles.css +6 -6
- package/framework/components/chui_kanban/kanban.js +27 -27
- package/framework/components/chui_kanban/styles.css +8 -4
- package/framework/components/chui_kbd/styles.css +1 -1
- package/framework/components/chui_label/label.js +17 -17
- package/framework/components/chui_label/styles.css +1 -1
- package/framework/components/chui_link/link.js +9 -9
- package/framework/components/chui_link/styles.css +11 -4
- package/framework/components/chui_list/list.js +11 -11
- package/framework/components/chui_list/styles.css +2 -2
- package/framework/components/chui_markdown_editor/markdown_editor.js +66 -66
- package/framework/components/chui_markdown_editor/styles.css +5 -5
- package/framework/components/chui_media/audio.js +240 -246
- package/framework/components/chui_media/audio_styles.css +41 -23
- package/framework/components/chui_media/image.js +49 -46
- package/framework/components/chui_media/image_compare.js +35 -35
- package/framework/components/chui_media/image_compare_styles.css +5 -5
- package/framework/components/chui_media/image_styles.css +1 -1
- package/framework/components/chui_media/video.js +148 -148
- package/framework/components/chui_media/video_styles.css +27 -11
- package/framework/components/chui_menu_bar/menu_bar.js +54 -54
- package/framework/components/chui_menu_bar/styles.css +10 -10
- package/framework/components/chui_message_bar/message_bar.js +551 -0
- package/framework/components/chui_message_bar/styles.css +248 -0
- package/framework/components/chui_modal/modal.js +37 -13
- package/framework/components/chui_notification/notification.js +76 -54
- package/framework/components/chui_notification/notification_download.js +26 -81
- package/framework/components/chui_notification/notification_download_card.js +115 -0
- package/framework/components/chui_notification/notification_download_progress.css +2 -2
- package/framework/components/chui_notification/notification_download_progress.js +70 -108
- package/framework/components/chui_notification/notification_update.js +31 -31
- package/framework/components/chui_notification/status_plate.css +3 -3
- package/framework/components/chui_notification/styles.css +6 -1
- package/framework/components/chui_notification/styles_download.css +1 -1
- package/framework/components/chui_notification/styles_update.css +2 -2
- package/framework/components/chui_org_chart/org_chart.js +29 -29
- package/framework/components/chui_org_chart/styles.css +2 -2
- package/framework/components/chui_pagination/pagination.js +3 -3
- package/framework/components/chui_pagination/styles.css +1 -1
- package/framework/components/chui_paragraph/styles.css +2 -2
- package/framework/components/chui_popover/popover.js +29 -23
- package/framework/components/chui_popover/styles.css +1 -1
- package/framework/components/chui_popups/popups.js +124 -124
- package/framework/components/chui_popups/styles.css +5 -5
- package/framework/components/chui_print_button/print_button.js +15 -10
- package/framework/components/chui_progress_bar/progress_bar.js +34 -12
- package/framework/components/chui_progress_bar/styles.css +4 -4
- package/framework/components/chui_progress_ring/progress_ring.js +15 -15
- package/framework/components/chui_progress_ring/styles.css +1 -1
- package/framework/components/chui_qrcode/qrcode.js +12 -12
- package/framework/components/chui_query_builder/query_builder.js +46 -46
- package/framework/components/chui_query_builder/styles.css +4 -4
- package/framework/components/chui_radio_group/styles.css +1 -1
- package/framework/components/chui_result/result.js +15 -15
- package/framework/components/chui_result/styles.css +3 -3
- package/framework/components/chui_scheduler/scheduler.js +74 -74
- package/framework/components/chui_scheduler/styles.css +5 -5
- package/framework/components/chui_screen_spinner/screen_spinner.js +167 -0
- package/framework/components/chui_screen_spinner/styles.css +49 -0
- package/framework/components/chui_segmented_control/segmented_control.js +63 -6
- package/framework/components/chui_segmented_control/styles.css +32 -6
- package/framework/components/chui_settings/settings.js +45 -46
- package/framework/components/chui_settings/styles.css +4 -4
- package/framework/components/chui_shortcut_help/shortcut_help.js +32 -34
- package/framework/components/chui_sidebar_nav/sidebar_nav.js +98 -29
- package/framework/components/chui_sidebar_nav/styles.css +9 -3
- package/framework/components/chui_slideshow/slideshow.js +85 -85
- package/framework/components/chui_slideshow/styles.css +6 -6
- package/framework/components/chui_spinner/spinner.js +10 -10
- package/framework/components/chui_split_button/split_button.js +30 -12
- package/framework/components/chui_split_button/styles.css +21 -5
- package/framework/components/chui_splitter/splitter.js +11 -11
- package/framework/components/chui_splitter/styles.css +2 -2
- package/framework/components/chui_statistic/statistic.js +47 -47
- package/framework/components/chui_status_bar/styles.css +2 -2
- package/framework/components/chui_stepper/stepper.js +202 -31
- package/framework/components/chui_stepper/styles.css +79 -14
- package/framework/components/chui_sticky_bar/sticky_bar.js +44 -13
- package/framework/components/chui_sticky_bar/styles.css +10 -8
- package/framework/components/chui_tabs/chui_tabs.js +74 -26
- package/framework/components/chui_tabs/styles.css +40 -12
- package/framework/components/chui_text_editor/styles.css +7 -7
- package/framework/components/chui_text_editor/text_editor.js +56 -56
- package/framework/components/chui_text_editor/text_editor_panel.js +173 -174
- package/framework/components/chui_theme_toggle/theme_toggle.js +21 -5
- package/framework/components/chui_timeline/styles.css +3 -1
- package/framework/components/chui_toast_queue/styles.css +11 -11
- package/framework/components/chui_toast_queue/toast_queue.js +30 -27
- package/framework/components/chui_toolbar/styles.css +2 -2
- package/framework/components/chui_tooltip/styles.css +2 -2
- package/framework/components/chui_tooltip/tooltip.js +3 -3
- package/framework/components/chui_tour/styles.css +8 -8
- package/framework/components/chui_tour/tour.js +72 -72
- package/framework/components/chui_transfer/styles.css +6 -6
- package/framework/components/chui_transfer/transfer.js +93 -106
- package/framework/components/chui_tree_table/styles.css +4 -4
- package/framework/components/chui_tree_table/tree_table.js +45 -45
- package/framework/components/chui_tree_view/styles.css +10 -8
- package/framework/components/chui_tree_view/tree_view.js +185 -183
- package/framework/components/chui_user_bar/styles.css +145 -0
- package/framework/components/chui_user_bar/user_bar.js +402 -0
- package/framework/components/chui_user_list_bar/styles.css +173 -0
- package/framework/components/chui_user_list_bar/user_list_bar.js +485 -0
- package/framework/components/chui_watermark/watermark.js +17 -17
- package/framework/components/chui_webview/webview.js +9 -9
- package/framework/components/chui_write_bar/styles.css +172 -0
- package/framework/components/chui_write_bar/write_bar.js +320 -0
- package/framework/main_window.js +1234 -0
- package/framework/modules/chui_a11y/chui_a11y.js +78 -79
- package/framework/modules/chui_animations/animations.js +77 -15
- package/framework/modules/chui_animations/motion.js +120 -0
- package/framework/modules/chui_animations/styles.css +36 -3
- package/framework/modules/chui_functions.js +31 -27
- package/framework/modules/chui_highlight/styles.css +13 -10
- package/framework/modules/chui_i18n/chui_i18n.js +3 -3
- package/framework/modules/chui_i18n/locales/feedback.js +62 -0
- package/framework/modules/chui_i18n/locales/navigation.js +4 -0
- package/framework/modules/chui_json/chui_json.js +2 -2
- package/framework/modules/chui_logger/chui_logger.js +23 -8
- package/framework/modules/chui_page/page.js +10 -10
- package/framework/modules/chui_palette/palette.js +61 -0
- package/framework/modules/chui_qr/chui_qr.js +23 -23
- package/framework/modules/chui_scrollbar/chui_scrollbar.js +45 -45
- package/framework/modules/chui_scrollbar/styles.css +3 -3
- package/framework/modules/chui_services/chui_services.js +8 -8
- package/framework/modules/chui_services/desktop.js +77 -71
- package/framework/modules/chui_sortable/chui_sortable.js +17 -17
- package/framework/modules/chui_validate/chui_validate.js +3 -3
- package/framework/tray_bar/chui_menu_items.js +2 -2
- package/index.d.ts +266 -34
- package/index.js +20 -1168
- package/package.json +6 -4
- package/framework/components/telegram_bot/chui_telegram_bot.js +0 -191
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
width: 50px;
|
|
4
4
|
height: 25px;
|
|
5
5
|
border-radius: var(--radius_pill);
|
|
6
|
-
margin: var(--
|
|
6
|
+
margin: var(--block_margin);
|
|
7
7
|
background: var(--element_background);
|
|
8
8
|
border: none;
|
|
9
9
|
box-shadow: 0 0 1px 0 var(--border_color);
|
|
@@ -51,8 +51,15 @@
|
|
|
51
51
|
bottom: 5px;
|
|
52
52
|
border-radius: var(--radius_circle);
|
|
53
53
|
background-color: var(--text_color_hover);
|
|
54
|
-
/* Тень как у бегунка ползунка: поднятая белая деталь на дорожке
|
|
55
|
-
|
|
54
|
+
/* Тень как у бегунка ползунка: поднятая белая деталь на дорожке — общий ключ
|
|
55
|
+
контролов */
|
|
56
|
+
box-shadow: var(--box_shadow_control);
|
|
57
|
+
/* Ручка едет пружиной: лёгкий перелёт читается как щелчок переключателя.
|
|
58
|
+
Свой список перехода заменяет общий, поэтому цвет и тень перечислены рядом */
|
|
59
|
+
transition:
|
|
60
|
+
transform var(--motion_base) var(--motion_spring),
|
|
61
|
+
background-color var(--motion_fast) var(--motion_ease),
|
|
62
|
+
box-shadow var(--motion_fast) var(--motion_ease);
|
|
56
63
|
}
|
|
57
64
|
|
|
58
65
|
input:checked + .slider:before {
|
|
@@ -2,21 +2,21 @@ const { Validate } = require("../../../modules/chui_validate/chui_validate");
|
|
|
2
2
|
|
|
3
3
|
class Toggle {
|
|
4
4
|
#Toggle = document.createElement("label");
|
|
5
|
-
#
|
|
6
|
-
#
|
|
5
|
+
#toggleSpan = document.createElement("span");
|
|
6
|
+
#toggleInput = document.createElement("input");
|
|
7
7
|
#label = undefined;
|
|
8
8
|
constructor(options = { label: String(), name: String(), value: Boolean(), disabled: Boolean() }) {
|
|
9
9
|
// Валидация: required для переключателя — «должен быть включён»
|
|
10
|
-
Validate.installField(this, options, this.#Toggle, undefined, () => this.#
|
|
10
|
+
Validate.installField(this, options, this.#Toggle, undefined, () => this.#toggleInput.checked);
|
|
11
11
|
require("../../../modules/chui_functions").setStyles(__dirname + "/styles.css", "chUiJS_Toggle");
|
|
12
12
|
this.#Toggle.className = "switch";
|
|
13
|
-
this.#
|
|
14
|
-
this.#
|
|
15
|
-
if (options.name !== undefined) this.#
|
|
13
|
+
this.#toggleInput.type = "checkbox";
|
|
14
|
+
this.#toggleSpan.className = "slider round";
|
|
15
|
+
if (options.name !== undefined) this.#toggleInput.name = options.name;
|
|
16
16
|
// В разметке переключателя нет текста, поэтому подпись уходит в aria-label
|
|
17
17
|
this.setLabel(options.label);
|
|
18
|
-
this.#Toggle.appendChild(this.#
|
|
19
|
-
this.#Toggle.appendChild(this.#
|
|
18
|
+
this.#Toggle.appendChild(this.#toggleInput);
|
|
19
|
+
this.#Toggle.appendChild(this.#toggleSpan);
|
|
20
20
|
if (options.value !== undefined) this.setValue(options.value === true);
|
|
21
21
|
if (options.disabled !== undefined) this.setDisabled(options.disabled === true);
|
|
22
22
|
}
|
|
@@ -30,7 +30,7 @@ class Toggle {
|
|
|
30
30
|
this.#Toggle.id = id;
|
|
31
31
|
}
|
|
32
32
|
getName() {
|
|
33
|
-
return this.#
|
|
33
|
+
return this.#toggleInput.name;
|
|
34
34
|
}
|
|
35
35
|
/** Подпись для скринридера: в самой разметке переключателя текста нет */
|
|
36
36
|
getLabel() {
|
|
@@ -38,26 +38,26 @@ class Toggle {
|
|
|
38
38
|
}
|
|
39
39
|
setLabel(label = String()) {
|
|
40
40
|
this.#label = label === undefined || label === "" ? undefined : label;
|
|
41
|
-
if (this.#label === undefined) this.#
|
|
42
|
-
else this.#
|
|
41
|
+
if (this.#label === undefined) this.#toggleInput.removeAttribute("aria-label");
|
|
42
|
+
else this.#toggleInput.setAttribute("aria-label", this.#label);
|
|
43
43
|
return this;
|
|
44
44
|
}
|
|
45
45
|
getDisabled() {
|
|
46
|
-
return this.#
|
|
46
|
+
return this.#toggleInput.disabled;
|
|
47
47
|
}
|
|
48
48
|
setDisabled(boolean = Boolean()) {
|
|
49
|
-
this.#
|
|
49
|
+
this.#toggleInput.disabled = boolean;
|
|
50
50
|
this.#Toggle.classList.toggle("switch_disabled", boolean);
|
|
51
51
|
return this;
|
|
52
52
|
}
|
|
53
53
|
addChangeListener(listener) {
|
|
54
|
-
this.#
|
|
54
|
+
this.#toggleInput.addEventListener("change", listener);
|
|
55
55
|
}
|
|
56
56
|
getValue() {
|
|
57
|
-
return this.#
|
|
57
|
+
return this.#toggleInput.checked;
|
|
58
58
|
}
|
|
59
59
|
setValue(boolean) {
|
|
60
|
-
this.#
|
|
60
|
+
this.#toggleInput.checked = boolean;
|
|
61
61
|
}
|
|
62
62
|
set() {
|
|
63
63
|
return this.#Toggle;
|
|
@@ -54,32 +54,32 @@ class JsonEditor {
|
|
|
54
54
|
#panes = document.createElement("json_editor_panes");
|
|
55
55
|
#editor = undefined;
|
|
56
56
|
#viewer = undefined;
|
|
57
|
-
#
|
|
57
|
+
#treeButton = undefined;
|
|
58
58
|
#actions = new Map();
|
|
59
59
|
#state = document.createElement("json_editor_state");
|
|
60
|
-
#
|
|
60
|
+
#parseLine = document.createElement("json_editor_parse");
|
|
61
61
|
#count = document.createElement("json_editor_count");
|
|
62
62
|
#hint = document.createElement("json_editor_hint");
|
|
63
63
|
#status = document.createElement("json_editor_status");
|
|
64
64
|
#error = document.createElement("chui_error_message");
|
|
65
65
|
#id = undefined;
|
|
66
66
|
#name = undefined;
|
|
67
|
-
#
|
|
68
|
-
#
|
|
67
|
+
#titleText = undefined;
|
|
68
|
+
#labelText = undefined;
|
|
69
69
|
#indent = 4;
|
|
70
|
-
#
|
|
71
|
-
#
|
|
72
|
-
#
|
|
70
|
+
#previewEnabled = false;
|
|
71
|
+
#previewOn = false;
|
|
72
|
+
#maxLength = undefined;
|
|
73
73
|
#width = undefined;
|
|
74
74
|
#height = "260px";
|
|
75
75
|
#disabled = false;
|
|
76
|
-
#
|
|
77
|
-
#
|
|
76
|
+
#readOnly = false;
|
|
77
|
+
#toolbarShown = true;
|
|
78
78
|
#parsed = undefined;
|
|
79
|
-
#
|
|
79
|
+
#errorObject = undefined;
|
|
80
80
|
#listeners = [];
|
|
81
|
-
#
|
|
82
|
-
#
|
|
81
|
+
#onChange = undefined;
|
|
82
|
+
#notifyPaused = false;
|
|
83
83
|
|
|
84
84
|
constructor(
|
|
85
85
|
options = {
|
|
@@ -108,12 +108,12 @@ class JsonEditor {
|
|
|
108
108
|
JsonEditor.#counter += 1;
|
|
109
109
|
this.#id = options.id === undefined ? `chui_json_editor_${JsonEditor.#counter}` : options.id;
|
|
110
110
|
this.#name = options.name;
|
|
111
|
-
this.#
|
|
112
|
-
this.#
|
|
111
|
+
this.#labelText = options.label;
|
|
112
|
+
this.#onChange = options.onChange;
|
|
113
113
|
this.#indent = options.indent === undefined ? 4 : Number(options.indent);
|
|
114
|
-
this.#
|
|
115
|
-
this.#
|
|
116
|
-
this.#
|
|
114
|
+
this.#previewEnabled = options.preview === true;
|
|
115
|
+
this.#toolbarShown = options.toolbar !== false;
|
|
116
|
+
this.#maxLength = options.maxLength === undefined ? undefined : Number(options.maxLength);
|
|
117
117
|
this.#root.id = this.#id;
|
|
118
118
|
this.#label.className = "json_editor_label";
|
|
119
119
|
this.#label.hidden = true;
|
|
@@ -122,7 +122,7 @@ class JsonEditor {
|
|
|
122
122
|
this.#toolbar.setAttribute("aria-label", I18n.t("jsonEditor.actions"));
|
|
123
123
|
this.#panes.className = "json_editor_panes";
|
|
124
124
|
this.#state.className = "json_editor_state";
|
|
125
|
-
this.#
|
|
125
|
+
this.#parseLine.className = "json_editor_parse";
|
|
126
126
|
this.#count.className = "json_editor_count";
|
|
127
127
|
this.#count.setAttribute("aria-hidden", "true");
|
|
128
128
|
this.#hint.className = "json_editor_hint";
|
|
@@ -138,26 +138,26 @@ class JsonEditor {
|
|
|
138
138
|
this.#root.appendChild(this.#toolbar);
|
|
139
139
|
this.#root.appendChild(this.#panes);
|
|
140
140
|
// Состояние разбора и счётчик знаков — одна строка под полем
|
|
141
|
-
this.#state.appendChild(this.#
|
|
141
|
+
this.#state.appendChild(this.#parseLine);
|
|
142
142
|
this.#state.appendChild(this.#count);
|
|
143
143
|
this.#root.appendChild(this.#state);
|
|
144
144
|
this.#root.appendChild(this.#hint);
|
|
145
145
|
this.#root.appendChild(this.#status);
|
|
146
146
|
if (options.title !== undefined) this.setTitle(options.title);
|
|
147
|
-
this.setLabel(this.#
|
|
147
|
+
this.setLabel(this.#labelText === undefined ? I18n.t("jsonEditor.text") : this.#labelText);
|
|
148
148
|
if (options.hint !== undefined) this.setHint(options.hint);
|
|
149
149
|
if (options.width !== undefined) this.setWidth(options.width);
|
|
150
150
|
this.setHeight(options.height === undefined ? this.#height : options.height);
|
|
151
151
|
if (options.data !== undefined) this.setData(options.data);
|
|
152
152
|
else this.setValue(options.value === undefined ? "" : options.value);
|
|
153
153
|
Validate.installField(this, options, this.#root, this.#error, () => this.getValue(), this.#panes);
|
|
154
|
-
const
|
|
154
|
+
const baseValidate = this.validate;
|
|
155
155
|
// Разбор JSON — обязательное правило поля: неразобранный текст не проходит проверку,
|
|
156
156
|
// даже если своих правил у поля нет. Правило называется `json`, чтобы по имени было
|
|
157
157
|
// видно причину, а правила формы и своё правило из опций при этом сохраняются
|
|
158
158
|
// (своё правило из опций тоже приходит сюда как `validate` — и тоже зовётся `json`)
|
|
159
159
|
this.validate = () => {
|
|
160
|
-
const result =
|
|
160
|
+
const result = baseValidate();
|
|
161
161
|
if (result.valid === false) {
|
|
162
162
|
if (result.rule === "validate") return { valid: false, rule: "json", message: result.message };
|
|
163
163
|
return result;
|
|
@@ -171,7 +171,7 @@ class JsonEditor {
|
|
|
171
171
|
};
|
|
172
172
|
this.setReadOnly(options.readOnly === true);
|
|
173
173
|
this.setDisabled(options.disabled === true);
|
|
174
|
-
this.setToolbar(this.#
|
|
174
|
+
this.setToolbar(this.#toolbarShown);
|
|
175
175
|
if (options.changeListener !== undefined) this.addChangeListener(options.changeListener);
|
|
176
176
|
}
|
|
177
177
|
|
|
@@ -185,11 +185,11 @@ class JsonEditor {
|
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
getTitle() {
|
|
188
|
-
return this.#
|
|
188
|
+
return this.#titleText;
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
getLabel() {
|
|
192
|
-
return this.#
|
|
192
|
+
return this.#labelText;
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
/** Текст JSON как есть */
|
|
@@ -205,13 +205,13 @@ class JsonEditor {
|
|
|
205
205
|
|
|
206
206
|
/** Место ошибки разбора: `{line, column, offset}` или `undefined` (у ошибки может не быть места) */
|
|
207
207
|
getErrorPlace() {
|
|
208
|
-
if (this.#
|
|
209
|
-
return { line: this.#
|
|
208
|
+
if (this.#errorObject === undefined || this.#errorObject.offset === undefined) return undefined;
|
|
209
|
+
return { line: this.#errorObject.line, column: this.#errorObject.column, offset: this.#errorObject.offset };
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
/** Текст ошибки разбора словами (пустая строка, если разбор прошёл) */
|
|
213
213
|
getErrorText() {
|
|
214
|
-
return Json.errorText(this.#
|
|
214
|
+
return Json.errorText(this.#errorObject);
|
|
215
215
|
}
|
|
216
216
|
|
|
217
217
|
isValid() {
|
|
@@ -219,15 +219,15 @@ class JsonEditor {
|
|
|
219
219
|
}
|
|
220
220
|
|
|
221
221
|
isPreview() {
|
|
222
|
-
return this.#
|
|
222
|
+
return this.#previewOn;
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
isPreviewEnabled() {
|
|
226
|
-
return this.#
|
|
226
|
+
return this.#previewEnabled;
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
getMaxLength() {
|
|
230
|
-
return this.#
|
|
230
|
+
return this.#maxLength;
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
getHeight() {
|
|
@@ -243,7 +243,7 @@ class JsonEditor {
|
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
isReadOnly() {
|
|
246
|
-
return this.#
|
|
246
|
+
return this.#readOnly;
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
getDisabled() {
|
|
@@ -279,7 +279,7 @@ class JsonEditor {
|
|
|
279
279
|
}
|
|
280
280
|
|
|
281
281
|
setTitle(text = undefined) {
|
|
282
|
-
this.#
|
|
282
|
+
this.#titleText = text;
|
|
283
283
|
if (text === undefined || text === "") {
|
|
284
284
|
this.#label.innerText = "";
|
|
285
285
|
this.#label.hidden = true;
|
|
@@ -294,7 +294,7 @@ class JsonEditor {
|
|
|
294
294
|
|
|
295
295
|
/** Имя поля, когда подписи в разметке нет */
|
|
296
296
|
setLabel(text = undefined) {
|
|
297
|
-
this.#
|
|
297
|
+
this.#labelText = text;
|
|
298
298
|
this.#syncLabel();
|
|
299
299
|
return this;
|
|
300
300
|
}
|
|
@@ -316,10 +316,10 @@ class JsonEditor {
|
|
|
316
316
|
setValue(value = String(), silent = false) {
|
|
317
317
|
const text = value === undefined || value === null ? "" : String(value);
|
|
318
318
|
// В тихом режиме (так зовёт Form.setValues) слишком длинный текст не подставляем
|
|
319
|
-
if (silent === true && this.#
|
|
320
|
-
this.#
|
|
319
|
+
if (silent === true && this.#maxLength !== undefined && text.length > this.#maxLength) return this;
|
|
320
|
+
this.#notifyPaused = true;
|
|
321
321
|
this.#editor.setValue(text);
|
|
322
|
-
this.#
|
|
322
|
+
this.#notifyPaused = false;
|
|
323
323
|
this.#refresh();
|
|
324
324
|
return this;
|
|
325
325
|
}
|
|
@@ -331,9 +331,9 @@ class JsonEditor {
|
|
|
331
331
|
|
|
332
332
|
/** Очистка для форм */
|
|
333
333
|
clear() {
|
|
334
|
-
this.#
|
|
334
|
+
this.#notifyPaused = true;
|
|
335
335
|
this.#editor.setValue("");
|
|
336
|
-
this.#
|
|
336
|
+
this.#notifyPaused = false;
|
|
337
337
|
this.#refresh();
|
|
338
338
|
return this;
|
|
339
339
|
}
|
|
@@ -365,18 +365,18 @@ class JsonEditor {
|
|
|
365
365
|
|
|
366
366
|
/** Предпросмотр деревом (`JsonViewer`) вместо поля */
|
|
367
367
|
setPreview(on = Boolean()) {
|
|
368
|
-
if (!this.#
|
|
369
|
-
this.#
|
|
370
|
-
if (this.#
|
|
371
|
-
this.#editor.set().hidden = this.#
|
|
372
|
-
if (this.#viewer !== undefined) this.#viewer.set().hidden = !this.#
|
|
373
|
-
if (this.#
|
|
374
|
-
this.#
|
|
375
|
-
this.#
|
|
368
|
+
if (!this.#previewEnabled) return this;
|
|
369
|
+
this.#previewOn = on === true;
|
|
370
|
+
if (this.#previewOn) this.#buildViewer();
|
|
371
|
+
this.#editor.set().hidden = this.#previewOn;
|
|
372
|
+
if (this.#viewer !== undefined) this.#viewer.set().hidden = !this.#previewOn;
|
|
373
|
+
if (this.#treeButton !== undefined) {
|
|
374
|
+
this.#treeButton.setAttribute("aria-pressed", this.#previewOn ? "true" : "false");
|
|
375
|
+
this.#treeButton.setAttribute(
|
|
376
376
|
"aria-label",
|
|
377
|
-
this.#
|
|
377
|
+
this.#previewOn ? I18n.t("jsonEditor.showText") : I18n.t("jsonEditor.showTree")
|
|
378
378
|
);
|
|
379
|
-
this.#
|
|
379
|
+
this.#treeButton.innerText = this.#previewOn
|
|
380
380
|
? I18n.t("jsonEditor.textShort")
|
|
381
381
|
: I18n.t("jsonEditor.treeShort");
|
|
382
382
|
}
|
|
@@ -384,13 +384,13 @@ class JsonEditor {
|
|
|
384
384
|
}
|
|
385
385
|
|
|
386
386
|
togglePreview() {
|
|
387
|
-
return this.setPreview(!this.#
|
|
387
|
+
return this.setPreview(!this.#previewOn);
|
|
388
388
|
}
|
|
389
389
|
|
|
390
390
|
/** Панель действий: `false` её убирает, поле остаётся полем */
|
|
391
391
|
setToolbar(shown = Boolean()) {
|
|
392
|
-
this.#
|
|
393
|
-
this.#toolbar.hidden = !this.#
|
|
392
|
+
this.#toolbarShown = shown !== false;
|
|
393
|
+
this.#toolbar.hidden = !this.#toolbarShown;
|
|
394
394
|
return this;
|
|
395
395
|
}
|
|
396
396
|
|
|
@@ -413,10 +413,10 @@ class JsonEditor {
|
|
|
413
413
|
return this;
|
|
414
414
|
}
|
|
415
415
|
|
|
416
|
-
setReadOnly(
|
|
417
|
-
this.#
|
|
418
|
-
this.#root.classList.toggle("json_editor_readonly", this.#
|
|
419
|
-
this.#editor.setReadOnly(this.#
|
|
416
|
+
setReadOnly(readOnly = Boolean()) {
|
|
417
|
+
this.#readOnly = readOnly === true;
|
|
418
|
+
this.#root.classList.toggle("json_editor_readonly", this.#readOnly);
|
|
419
|
+
this.#editor.setReadOnly(this.#readOnly);
|
|
420
420
|
this.#actionState();
|
|
421
421
|
return this;
|
|
422
422
|
}
|
|
@@ -439,7 +439,7 @@ class JsonEditor {
|
|
|
439
439
|
/** Фокус в поле (из предпросмотра поле возвращается) */
|
|
440
440
|
focus() {
|
|
441
441
|
if (this.#disabled) return this;
|
|
442
|
-
if (this.#
|
|
442
|
+
if (this.#previewOn) this.setPreview(false);
|
|
443
443
|
this.#editor.focus();
|
|
444
444
|
return this;
|
|
445
445
|
}
|
|
@@ -480,17 +480,17 @@ class JsonEditor {
|
|
|
480
480
|
this.#actions.set(action.id, button);
|
|
481
481
|
this.#toolbar.appendChild(button);
|
|
482
482
|
}
|
|
483
|
-
if (this.#
|
|
484
|
-
this.#
|
|
485
|
-
this.#
|
|
486
|
-
this.#
|
|
487
|
-
this.#
|
|
488
|
-
this.#
|
|
483
|
+
if (this.#previewEnabled) {
|
|
484
|
+
this.#treeButton = document.createElement("button");
|
|
485
|
+
this.#treeButton.type = "button";
|
|
486
|
+
this.#treeButton.className = "json_editor_action json_editor_tree";
|
|
487
|
+
this.#treeButton.setAttribute("aria-pressed", "false");
|
|
488
|
+
this.#treeButton.setAttribute("aria-label", I18n.t("jsonEditor.showTree"));
|
|
489
489
|
// `aria-controls` появится в `#buildViewer()`: до первого показа дерева узла
|
|
490
490
|
// нет, а ссылка на несуществующий id — висячая
|
|
491
|
-
this.#
|
|
492
|
-
this.#
|
|
493
|
-
this.#toolbar.appendChild(this.#
|
|
491
|
+
this.#treeButton.innerText = I18n.t("jsonEditor.treeShort");
|
|
492
|
+
this.#treeButton.addEventListener("click", () => this.togglePreview());
|
|
493
|
+
this.#toolbar.appendChild(this.#treeButton);
|
|
494
494
|
}
|
|
495
495
|
// Панель — одна остановка обхода: по кнопкам ходят стрелки/Home/End
|
|
496
496
|
new RovingKeyboard(this.#toolbar, { itemSelector: "button" });
|
|
@@ -511,12 +511,12 @@ class JsonEditor {
|
|
|
511
511
|
});
|
|
512
512
|
this.#viewer.set().hidden = true;
|
|
513
513
|
this.#panes.appendChild(this.#viewer.set());
|
|
514
|
-
this.#
|
|
514
|
+
this.#treeButton.setAttribute("aria-controls", this.#viewer.getId());
|
|
515
515
|
return this;
|
|
516
516
|
}
|
|
517
517
|
|
|
518
518
|
#runAction(id = String()) {
|
|
519
|
-
if (this.#disabled || this.#
|
|
519
|
+
if (this.#disabled || this.#readOnly) return this;
|
|
520
520
|
if (id === "format") this.format();
|
|
521
521
|
else if (id === "minify") this.minify();
|
|
522
522
|
else if (id === "check") this.check();
|
|
@@ -548,17 +548,17 @@ class JsonEditor {
|
|
|
548
548
|
}
|
|
549
549
|
|
|
550
550
|
#refuseAction(error = Object()) {
|
|
551
|
-
this.#
|
|
552
|
-
this.#
|
|
553
|
-
this.#
|
|
551
|
+
this.#errorObject = error;
|
|
552
|
+
this.#parseLine.classList.add("json_editor_parse_error");
|
|
553
|
+
this.#parseLine.innerText = Json.errorText(error);
|
|
554
554
|
this.#announce(Json.errorText(error));
|
|
555
555
|
return this;
|
|
556
556
|
}
|
|
557
557
|
|
|
558
558
|
#actionState() {
|
|
559
|
-
const off = this.#disabled || this.#
|
|
559
|
+
const off = this.#disabled || this.#readOnly;
|
|
560
560
|
for (const button of this.#actions.values()) button.disabled = off;
|
|
561
|
-
if (this.#
|
|
561
|
+
if (this.#treeButton !== undefined) this.#treeButton.disabled = this.#disabled;
|
|
562
562
|
return this;
|
|
563
563
|
}
|
|
564
564
|
|
|
@@ -583,7 +583,7 @@ class JsonEditor {
|
|
|
583
583
|
area.id = `${this.#id}_input`;
|
|
584
584
|
// Подпись — настоящий <label>: связь с полем держим всегда, а видимость — по подписи
|
|
585
585
|
this.#label.setAttribute("for", area.id);
|
|
586
|
-
if (this.#
|
|
586
|
+
if (this.#titleText !== undefined && this.#titleText !== "") area.removeAttribute("aria-label");
|
|
587
587
|
else area.setAttribute("aria-label", this.#accessibleName());
|
|
588
588
|
this.#syncDescribedBy();
|
|
589
589
|
if (this.#viewer !== undefined)
|
|
@@ -592,17 +592,17 @@ class JsonEditor {
|
|
|
592
592
|
}
|
|
593
593
|
|
|
594
594
|
#accessibleName() {
|
|
595
|
-
if (this.#
|
|
596
|
-
if (this.#
|
|
595
|
+
if (this.#titleText !== undefined && this.#titleText !== "") return this.#titleText;
|
|
596
|
+
if (this.#labelText !== undefined && this.#labelText !== "") return this.#labelText;
|
|
597
597
|
return I18n.t("jsonEditor.text");
|
|
598
598
|
}
|
|
599
599
|
|
|
600
600
|
#syncCount() {
|
|
601
|
-
const
|
|
602
|
-
this.#count.hidden = !
|
|
603
|
-
if (!
|
|
604
|
-
this.#count.innerText = `${this.getValue().length} / ${this.#
|
|
605
|
-
this.#count.classList.toggle("json_editor_count_over", this.getValue().length > this.#
|
|
601
|
+
const hasLimit = this.#maxLength !== undefined;
|
|
602
|
+
this.#count.hidden = !hasLimit;
|
|
603
|
+
if (!hasLimit) return this;
|
|
604
|
+
this.#count.innerText = `${this.getValue().length} / ${this.#maxLength}`;
|
|
605
|
+
this.#count.classList.toggle("json_editor_count_over", this.getValue().length > this.#maxLength);
|
|
606
606
|
return this;
|
|
607
607
|
}
|
|
608
608
|
|
|
@@ -617,11 +617,11 @@ class JsonEditor {
|
|
|
617
617
|
const state = Json.parse(text);
|
|
618
618
|
// Пустое поле — не ошибка разбора (так же считает и `validate` ниже): `JSON.parse("")`
|
|
619
619
|
// бросает исключение, но показывать его как ошибку нельзя — поле просто пустое
|
|
620
|
-
this.#
|
|
620
|
+
this.#errorObject = state.ok || blank ? undefined : state.error;
|
|
621
621
|
this.#parsed = state.ok ? state.value : undefined;
|
|
622
|
-
this.#
|
|
623
|
-
this.#
|
|
624
|
-
this.#
|
|
622
|
+
this.#parseLine.classList.toggle("json_editor_parse_error", !state.ok && blank === false);
|
|
623
|
+
this.#parseLine.classList.toggle("json_editor_parse_ok", state.ok && blank === false);
|
|
624
|
+
this.#parseLine.innerText = blank
|
|
625
625
|
? I18n.t("jsonEditor.empty")
|
|
626
626
|
: state.ok
|
|
627
627
|
? I18n.t("jsonEditor.correct")
|
|
@@ -639,13 +639,13 @@ class JsonEditor {
|
|
|
639
639
|
#notify() {
|
|
640
640
|
const value = this.getValue();
|
|
641
641
|
for (const listener of [...this.#listeners]) listener(value, this);
|
|
642
|
-
if (this.#
|
|
642
|
+
if (this.#onChange !== undefined) this.#onChange(value, this);
|
|
643
643
|
return this;
|
|
644
644
|
}
|
|
645
645
|
|
|
646
646
|
#onInput = () => {
|
|
647
647
|
this.#refresh();
|
|
648
|
-
if (this.#
|
|
648
|
+
if (this.#notifyPaused) return;
|
|
649
649
|
this.#notify();
|
|
650
650
|
};
|
|
651
651
|
}
|
|
@@ -8,14 +8,14 @@ chui_json_editor {
|
|
|
8
8
|
width: -webkit-fill-available;
|
|
9
9
|
max-width: 100%;
|
|
10
10
|
height: max-content;
|
|
11
|
-
margin: var(--
|
|
11
|
+
margin: var(--block_margin);
|
|
12
12
|
color: var(--text_color);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
.json_editor_label {
|
|
16
16
|
display: block;
|
|
17
17
|
width: max-content;
|
|
18
|
-
margin: var(--
|
|
18
|
+
margin: var(--block_margin);
|
|
19
19
|
color: var(--text_color);
|
|
20
20
|
font-size: var(--font_labels_size);
|
|
21
21
|
font-weight: 500;
|
|
@@ -34,7 +34,7 @@ chui_json_editor {
|
|
|
34
34
|
padding: 4px;
|
|
35
35
|
border: 1px solid var(--border_color);
|
|
36
36
|
border-bottom: none;
|
|
37
|
-
border-radius: var(--
|
|
37
|
+
border-radius: var(--radius_sm) var(--radius_sm) 0 0;
|
|
38
38
|
background: var(--element_background_2);
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -44,7 +44,7 @@ chui_json_editor {
|
|
|
44
44
|
|
|
45
45
|
/* Скрытая панель не оставляет углов: поле занимает всю рамку само */
|
|
46
46
|
.json_editor_toolbar[hidden] + .json_editor_panes {
|
|
47
|
-
border-radius: var(--
|
|
47
|
+
border-radius: var(--radius_sm);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
.json_editor_action {
|
|
@@ -91,7 +91,7 @@ chui_json_editor {
|
|
|
91
91
|
box-sizing: border-box;
|
|
92
92
|
overflow: hidden;
|
|
93
93
|
border: 1px solid var(--border_color);
|
|
94
|
-
border-radius: 0 0 var(--
|
|
94
|
+
border-radius: 0 0 var(--radius_sm) var(--radius_sm);
|
|
95
95
|
background: var(--element_background);
|
|
96
96
|
}
|
|
97
97
|
|