chuijs 4.0.2 → 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 +597 -0
- package/README.md +43 -644
- package/framework/appLayout/default/chui_app_layout.js +602 -496
- package/framework/appLayout/default/global_style.css +288 -97
- package/framework/appLayout/default/main_theme_style.css +188 -101
- package/framework/components/chui_accordion/accordion.js +38 -35
- package/framework/components/chui_accordion/styles.css +13 -12
- package/framework/components/chui_action_sheet/action_sheet.js +93 -64
- package/framework/components/chui_action_sheet/styles.css +12 -5
- 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 +16 -11
- package/framework/components/chui_affix/styles.css +5 -0
- package/framework/components/chui_alert/alert.js +34 -19
- package/framework/components/chui_alert/styles.css +7 -0
- package/framework/components/chui_avatar/avatar.js +36 -35
- package/framework/components/chui_avatar/styles.css +1 -1
- package/framework/components/chui_avatar_group/avatar_group.js +25 -23
- package/framework/components/chui_avatar_group/styles.css +1 -1
- package/framework/components/chui_backtop/backtop.js +60 -21
- package/framework/components/chui_backtop/styles.css +21 -0
- package/framework/components/chui_badge/badge.js +30 -28
- 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/breadcrumb.js +15 -13
- package/framework/components/chui_breadcrumb/styles.css +1 -1
- package/framework/components/chui_button/button.js +52 -36
- package/framework/components/chui_button/styles.css +7 -7
- package/framework/components/chui_calendar/calendar.js +18 -16
- package/framework/components/chui_card/card.js +52 -32
- 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 +140 -79
- package/framework/components/chui_chat/styles.css +18 -7
- package/framework/components/chui_clipboard_history/clipboard_history.js +53 -39
- package/framework/components/chui_clipboard_history/styles.css +13 -9
- package/framework/components/chui_code/code.js +10 -10
- package/framework/components/chui_code/styles.css +4 -4
- package/framework/components/chui_code_editor/code_editor.js +73 -57
- package/framework/components/chui_code_editor/styles.css +6 -5
- package/framework/components/chui_command_palette/command_palette.js +87 -64
- package/framework/components/chui_command_palette/styles.css +5 -5
- package/framework/components/chui_console/console.js +13 -13
- package/framework/components/chui_console/styles.css +6 -3
- package/framework/components/chui_content_block/content_block.js +35 -21
- package/framework/components/chui_content_block/styles.css +2 -2
- package/framework/components/chui_context_menu/context_menu.js +171 -58
- package/framework/components/chui_context_menu/styles.css +82 -8
- package/framework/components/chui_custom_element/custom_element.js +25 -18
- package/framework/components/chui_data_grid/data_grid.js +633 -471
- package/framework/components/chui_data_grid/styles.css +24 -22
- package/framework/components/chui_descriptions/descriptions.js +34 -17
- package/framework/components/chui_descriptions/styles.css +1 -1
- package/framework/components/chui_details/details.js +42 -36
- package/framework/components/chui_details/styles.css +12 -11
- package/framework/components/chui_diff_viewer/diff_viewer.js +172 -147
- package/framework/components/chui_diff_viewer/styles.css +10 -10
- package/framework/components/chui_divider/divider.js +19 -17
- package/framework/components/chui_divider/styles.css +2 -2
- package/framework/components/chui_drawer/drawer.js +63 -38
- package/framework/components/chui_drawer/styles.css +18 -4
- package/framework/components/chui_drop_zone/drop_zone.js +37 -27
- package/framework/components/chui_drop_zone/styles.css +10 -6
- package/framework/components/chui_empty_state/empty_state.js +20 -15
- package/framework/components/chui_fieldset/fieldset.js +40 -23
- package/framework/components/chui_fieldset/styles.css +6 -6
- package/framework/components/chui_file_explorer/file_explorer.js +260 -189
- package/framework/components/chui_file_explorer/styles.css +8 -7
- package/framework/components/chui_form/form.js +40 -28
- package/framework/components/chui_form/styles.css +1 -1
- package/framework/components/chui_gantt/gantt.js +102 -78
- package/framework/components/chui_gantt/styles.css +5 -5
- package/framework/components/chui_graphs/graphs.js +376 -239
- package/framework/components/chui_graphs/styles.css +27 -6
- package/framework/components/chui_hero/hero.js +98 -37
- package/framework/components/chui_hero/styles.css +176 -7
- package/framework/components/chui_html_block/html_block.js +8 -8
- package/framework/components/chui_html_block/styles.css +3 -3
- package/framework/components/chui_hx/hx.js +3 -3
- package/framework/components/chui_hx/styles.css +13 -6
- package/framework/components/chui_icons/icons.js +2115 -2115
- package/framework/components/chui_icons/styles.css +4 -3
- package/framework/components/chui_inputs/chui_check_box/check_box.js +31 -19
- package/framework/components/chui_inputs/chui_check_box/styles.css +30 -21
- package/framework/components/chui_inputs/chui_chips/chips.js +141 -70
- package/framework/components/chui_inputs/chui_chips/styles.css +32 -7
- package/framework/components/chui_inputs/chui_color_picker/color_picker.js +55 -38
- package/framework/components/chui_inputs/chui_color_picker/styles.css +7 -7
- package/framework/components/chui_inputs/chui_combo_box/combo_box.js +127 -109
- package/framework/components/chui_inputs/chui_combo_box/styles.css +23 -21
- package/framework/components/chui_inputs/chui_date/date.js +161 -127
- package/framework/components/chui_inputs/chui_date/styles.css +20 -19
- package/framework/components/chui_inputs/chui_date_range/date_range.js +61 -50
- package/framework/components/chui_inputs/chui_date_range/styles.css +3 -3
- package/framework/components/chui_inputs/chui_datetime/datetime.js +47 -39
- package/framework/components/chui_inputs/chui_datetime/styles.css +3 -3
- package/framework/components/chui_inputs/chui_email/email.js +48 -36
- package/framework/components/chui_inputs/chui_email/styles.css +11 -11
- package/framework/components/chui_inputs/chui_file/file.js +71 -44
- package/framework/components/chui_inputs/chui_file/styles.css +23 -19
- package/framework/components/chui_inputs/chui_hotkey/hotkey.js +101 -76
- package/framework/components/chui_inputs/chui_hotkey/styles.css +6 -6
- package/framework/components/chui_inputs/chui_masked/masked.js +83 -72
- package/framework/components/chui_inputs/chui_masked/styles.css +5 -5
- package/framework/components/chui_inputs/chui_mention/mention.js +87 -40
- package/framework/components/chui_inputs/chui_mention/styles.css +14 -8
- package/framework/components/chui_inputs/chui_multi_combo_box/multi_combo_box.js +242 -212
- package/framework/components/chui_inputs/chui_multi_combo_box/styles.css +23 -15
- package/framework/components/chui_inputs/chui_number/number.js +84 -70
- package/framework/components/chui_inputs/chui_number/styles.css +13 -13
- package/framework/components/chui_inputs/chui_otp/otp.js +71 -62
- package/framework/components/chui_inputs/chui_otp/styles.css +5 -5
- package/framework/components/chui_inputs/chui_password/password.js +72 -56
- package/framework/components/chui_inputs/chui_password/styles.css +15 -15
- package/framework/components/chui_inputs/chui_radio_button/radio_button.js +37 -25
- package/framework/components/chui_inputs/chui_radio_button/styles.css +22 -22
- package/framework/components/chui_inputs/chui_rating/rating.js +54 -50
- package/framework/components/chui_inputs/chui_rating/styles.css +3 -3
- package/framework/components/chui_inputs/chui_select_box/select_box.js +132 -108
- package/framework/components/chui_inputs/chui_select_box/styles.css +21 -21
- package/framework/components/chui_inputs/chui_slider/slider.js +41 -38
- package/framework/components/chui_inputs/chui_slider/styles.css +7 -5
- package/framework/components/chui_inputs/chui_text/styles.css +14 -14
- package/framework/components/chui_inputs/chui_text/text.js +69 -52
- package/framework/components/chui_inputs/chui_text_area/styles.css +14 -14
- package/framework/components/chui_inputs/chui_text_area/text_area.js +59 -36
- package/framework/components/chui_inputs/chui_time/styles.css +18 -20
- package/framework/components/chui_inputs/chui_time/time.js +71 -49
- package/framework/components/chui_inputs/chui_toggle/styles.css +13 -6
- package/framework/components/chui_inputs/chui_toggle/toggle.js +27 -27
- package/framework/components/chui_json_editor/json_editor.js +137 -127
- package/framework/components/chui_json_editor/styles.css +5 -5
- package/framework/components/chui_json_viewer/json_viewer.js +133 -114
- package/framework/components/chui_json_viewer/styles.css +9 -8
- package/framework/components/chui_kanban/kanban.js +78 -60
- package/framework/components/chui_kanban/styles.css +8 -4
- package/framework/components/chui_kbd/kbd.js +12 -10
- package/framework/components/chui_kbd/styles.css +1 -1
- package/framework/components/chui_label/label.js +31 -29
- package/framework/components/chui_label/styles.css +3 -3
- package/framework/components/chui_link/link.js +36 -29
- package/framework/components/chui_link/styles.css +11 -4
- package/framework/components/chui_list/list.js +42 -38
- package/framework/components/chui_list/styles.css +4 -3
- package/framework/components/chui_markdown_editor/markdown_editor.js +125 -109
- package/framework/components/chui_markdown_editor/styles.css +5 -5
- package/framework/components/chui_media/audio.js +457 -364
- package/framework/components/chui_media/audio_styles.css +74 -37
- package/framework/components/chui_media/image.js +99 -64
- package/framework/components/chui_media/image_compare.js +86 -55
- package/framework/components/chui_media/image_compare_styles.css +5 -5
- package/framework/components/chui_media/image_styles.css +4 -4
- package/framework/components/chui_media/video.js +264 -171
- package/framework/components/chui_media/video_styles.css +57 -24
- package/framework/components/chui_menu_bar/menu_bar.js +67 -65
- package/framework/components/chui_menu_bar/styles.css +14 -12
- 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 +81 -56
- package/framework/components/chui_modal/styles.css +3 -2
- package/framework/components/chui_notification/notification.js +107 -69
- package/framework/components/chui_notification/notification_download.js +28 -77
- package/framework/components/chui_notification/notification_download_card.js +115 -0
- package/framework/components/chui_notification/notification_download_progress.css +5 -4
- package/framework/components/chui_notification/notification_download_progress.js +73 -105
- package/framework/components/chui_notification/notification_update.js +44 -37
- package/framework/components/chui_notification/status_plate.css +3 -3
- package/framework/components/chui_notification/status_plate.js +2 -2
- package/framework/components/chui_notification/styles.css +6 -1
- package/framework/components/chui_notification/styles_download.css +2 -2
- package/framework/components/chui_notification/styles_update.css +3 -3
- package/framework/components/chui_org_chart/org_chart.js +101 -62
- package/framework/components/chui_org_chart/styles.css +2 -2
- package/framework/components/chui_pagination/pagination.js +65 -30
- package/framework/components/chui_pagination/styles.css +1 -1
- package/framework/components/chui_paragraph/paragraph.js +2 -2
- package/framework/components/chui_paragraph/styles.css +3 -3
- package/framework/components/chui_popover/popover.js +77 -50
- package/framework/components/chui_popover/styles.css +1 -1
- package/framework/components/chui_popups/popups.js +210 -181
- package/framework/components/chui_popups/styles.css +7 -7
- package/framework/components/chui_print_button/print_button.js +48 -33
- package/framework/components/chui_progress_bar/progress_bar.js +49 -19
- package/framework/components/chui_progress_bar/styles.css +6 -6
- package/framework/components/chui_progress_ring/progress_ring.js +32 -30
- package/framework/components/chui_progress_ring/styles.css +1 -1
- package/framework/components/chui_qrcode/qrcode.js +85 -41
- package/framework/components/chui_query_builder/query_builder.js +263 -170
- package/framework/components/chui_query_builder/styles.css +4 -4
- package/framework/components/chui_radio_group/radio_group.js +36 -26
- package/framework/components/chui_radio_group/styles.css +2 -2
- package/framework/components/chui_result/result.js +41 -31
- package/framework/components/chui_result/styles.css +3 -3
- package/framework/components/chui_scheduler/scheduler.js +126 -104
- package/framework/components/chui_scheduler/styles.css +11 -7
- 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 +90 -27
- package/framework/components/chui_segmented_control/styles.css +32 -6
- package/framework/components/chui_settings/settings.js +160 -87
- package/framework/components/chui_settings/styles.css +4 -4
- package/framework/components/chui_shortcut_help/shortcut_help.js +82 -61
- package/framework/components/chui_sidebar_nav/sidebar_nav.js +132 -53
- package/framework/components/chui_sidebar_nav/styles.css +9 -3
- package/framework/components/chui_skeleton/skeleton.js +29 -24
- package/framework/components/chui_slideshow/slideshow.js +122 -103
- package/framework/components/chui_slideshow/styles.css +22 -16
- package/framework/components/chui_spinner/spinner.js +17 -17
- package/framework/components/chui_spinner/styles.css +0 -1
- package/framework/components/chui_split_button/split_button.js +53 -30
- package/framework/components/chui_split_button/styles.css +22 -6
- package/framework/components/chui_splitter/splitter.js +46 -39
- package/framework/components/chui_splitter/styles.css +2 -2
- package/framework/components/chui_statistic/statistic.js +111 -84
- package/framework/components/chui_status_bar/status_bar.js +11 -9
- package/framework/components/chui_status_bar/styles.css +2 -2
- package/framework/components/chui_stepper/stepper.js +230 -54
- package/framework/components/chui_stepper/styles.css +79 -14
- package/framework/components/chui_sticky_bar/sticky_bar.js +53 -17
- package/framework/components/chui_sticky_bar/styles.css +11 -7
- package/framework/components/chui_tabs/chui_tabs.js +100 -46
- package/framework/components/chui_tabs/styles.css +43 -15
- package/framework/components/chui_text_editor/styles.css +24 -23
- package/framework/components/chui_text_editor/text_editor.js +103 -79
- package/framework/components/chui_text_editor/text_editor_panel.js +428 -367
- package/framework/components/chui_theme_toggle/theme_toggle.js +46 -25
- package/framework/components/chui_timeline/styles.css +3 -1
- package/framework/components/chui_timeline/timeline.js +14 -12
- package/framework/components/chui_toast_queue/styles.css +11 -11
- package/framework/components/chui_toast_queue/toast_queue.js +82 -73
- package/framework/components/chui_toolbar/styles.css +2 -2
- package/framework/components/chui_toolbar/toolbar.js +20 -13
- package/framework/components/chui_tooltip/styles.css +2 -2
- package/framework/components/chui_tooltip/tooltip.js +40 -27
- package/framework/components/chui_tour/styles.css +12 -7
- package/framework/components/chui_tour/tour.js +132 -98
- package/framework/components/chui_transfer/styles.css +8 -7
- package/framework/components/chui_transfer/transfer.js +143 -123
- package/framework/components/chui_tree_table/styles.css +4 -4
- package/framework/components/chui_tree_table/tree_table.js +88 -74
- package/framework/components/chui_tree_view/styles.css +14 -10
- package/framework/components/chui_tree_view/tree_view.js +298 -253
- 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 +41 -33
- package/framework/components/chui_webview/styles.css +2 -2
- package/framework/components/chui_webview/webview.js +64 -52
- 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 +153 -123
- package/framework/modules/chui_animations/animations.js +105 -43
- package/framework/modules/chui_animations/motion.js +120 -0
- package/framework/modules/chui_animations/styles.css +37 -4
- package/framework/modules/chui_bridge/preload.js +36 -25
- package/framework/modules/chui_functions.js +69 -63
- package/framework/modules/chui_highlight/chui_highlight.js +25 -22
- package/framework/modules/chui_highlight/styles.css +13 -10
- package/framework/modules/chui_i18n/chui_i18n.js +12 -10
- 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 +65 -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 +12 -8
- package/framework/modules/chui_i18n/locales/validate.js +3 -3
- package/framework/modules/chui_json/chui_json.js +11 -11
- package/framework/modules/chui_layout/chui_layout.js +12 -10
- package/framework/modules/chui_logger/chui_logger.js +47 -28
- package/framework/modules/chui_page/page.js +39 -33
- package/framework/modules/chui_palette/palette.js +61 -0
- package/framework/modules/chui_qr/chui_qr.js +179 -88
- package/framework/modules/chui_scrollbar/chui_scrollbar.js +79 -68
- package/framework/modules/chui_scrollbar/styles.css +4 -2
- package/framework/modules/chui_services/chui_channels.js +27 -13
- package/framework/modules/chui_services/chui_services.js +47 -39
- package/framework/modules/chui_services/desktop.js +108 -101
- package/framework/modules/chui_sortable/chui_sortable.js +33 -28
- package/framework/modules/chui_validate/chui_validate.js +10 -7
- package/framework/tray_bar/chui_menu_items.js +136 -46
- package/index.d.ts +5046 -0
- package/index.js +199 -1254
- package/package.json +81 -68
- package/framework/components/telegram_bot/chui_telegram_bot.js +0 -184
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
chui_icon {
|
|
2
|
-
font-family:
|
|
2
|
+
font-family: "chui_mir";
|
|
3
3
|
font-weight: normal;
|
|
4
4
|
font-style: normal;
|
|
5
5
|
font-size: var(--header_icon_size);
|
|
@@ -10,5 +10,6 @@ chui_icon {
|
|
|
10
10
|
direction: ltr;
|
|
11
11
|
color: var(--text_color);
|
|
12
12
|
pointer-events: none;
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
/* Глиф меняет только цвет: `all` тянул бы за собой и вёрстку, если она когда-нибудь изменится */
|
|
14
|
+
transition: color var(--motion_fast) var(--motion_ease);
|
|
15
|
+
}
|
|
@@ -1,32 +1,44 @@
|
|
|
1
|
-
const {Validate} = require(
|
|
1
|
+
const { Validate } = require("../../../modules/chui_validate/chui_validate");
|
|
2
2
|
|
|
3
3
|
class CheckBox {
|
|
4
4
|
#id = require("randomstring").generate();
|
|
5
|
-
#checkBox = document.createElement(
|
|
6
|
-
#input = document.createElement(
|
|
7
|
-
#label = document.createElement(
|
|
5
|
+
#checkBox = document.createElement("checkbox");
|
|
6
|
+
#input = document.createElement("input");
|
|
7
|
+
#label = document.createElement("label");
|
|
8
8
|
constructor(options = { name: String(), title: String(), required: Boolean(), changeListener: () => {} }) {
|
|
9
|
-
require(
|
|
10
|
-
this.#input.classList.add(
|
|
11
|
-
this.#input.type =
|
|
12
|
-
this.#input.classList.add(
|
|
9
|
+
require("../../../modules/chui_functions").setStyles(__dirname + "/styles.css", "chUiJS_Checkbox");
|
|
10
|
+
this.#input.classList.add("checkbox");
|
|
11
|
+
this.#input.type = "checkbox";
|
|
12
|
+
this.#input.classList.add("checkbox_input");
|
|
13
13
|
this.#input.id = this.#id;
|
|
14
|
-
this.#label.setAttribute(
|
|
15
|
-
this.#label.classList.add(
|
|
14
|
+
this.#label.setAttribute("for", this.#id);
|
|
15
|
+
this.#label.classList.add("labelz");
|
|
16
16
|
// Установка опций
|
|
17
17
|
if (options.name !== undefined) this.#input.name = options.name;
|
|
18
18
|
if (options.title !== undefined) this.#label.innerText = options.title;
|
|
19
19
|
if (options.required !== undefined) this.#input.required = options.required;
|
|
20
20
|
// Валидация: required для флажка — «должен быть отмечен»
|
|
21
21
|
Validate.installField(this, options, this.#checkBox, undefined, () => this.#input.checked);
|
|
22
|
-
if (options.changeListener !== undefined) this.#input.addEventListener(
|
|
23
|
-
}
|
|
24
|
-
getName() {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
if (options.changeListener !== undefined) this.#input.addEventListener("change", options.changeListener);
|
|
23
|
+
}
|
|
24
|
+
getName() {
|
|
25
|
+
return this.#input.name;
|
|
26
|
+
}
|
|
27
|
+
getValue() {
|
|
28
|
+
return this.#input.checked;
|
|
29
|
+
}
|
|
30
|
+
getTitle() {
|
|
31
|
+
return this.#label.innerText;
|
|
32
|
+
}
|
|
33
|
+
setValue(value = Boolean()) {
|
|
34
|
+
this.#input.checked = value;
|
|
35
|
+
}
|
|
36
|
+
addChangeListener(listener = () => {}) {
|
|
37
|
+
this.#input.addEventListener("change", listener);
|
|
38
|
+
}
|
|
39
|
+
setDisabled(boolean = Boolean()) {
|
|
40
|
+
this.#input.disabled = boolean;
|
|
41
|
+
}
|
|
30
42
|
set() {
|
|
31
43
|
this.#checkBox.appendChild(this.#input);
|
|
32
44
|
this.#checkBox.appendChild(this.#label);
|
|
@@ -34,4 +46,4 @@ class CheckBox {
|
|
|
34
46
|
}
|
|
35
47
|
}
|
|
36
48
|
|
|
37
|
-
exports.CheckBox = CheckBox
|
|
49
|
+
exports.CheckBox = CheckBox;
|
|
@@ -4,30 +4,30 @@ checkbox {
|
|
|
4
4
|
карточку. Токены переопределены у корня поля, поэтому действуют только внутри него
|
|
5
5
|
(тот же приём у полосы меню-бара). */
|
|
6
6
|
--control_padding: var(--control_padding_sm);
|
|
7
|
-
--
|
|
7
|
+
--block_padding: var(--block_padding_sm);
|
|
8
8
|
display: flex;
|
|
9
9
|
align-items: center;
|
|
10
10
|
justify-content: center;
|
|
11
11
|
font-size: var(--font_default_size);
|
|
12
|
-
margin: var(--
|
|
13
|
-
width: max-content
|
|
12
|
+
margin: var(--block_margin);
|
|
13
|
+
width: max-content;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
.checkbox {
|
|
17
17
|
position: absolute;
|
|
18
18
|
z-index: -1;
|
|
19
|
-
opacity: 0
|
|
19
|
+
opacity: 0;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
.checkbox+label {
|
|
22
|
+
.checkbox + label {
|
|
23
23
|
display: inline-flex;
|
|
24
24
|
align-items: center;
|
|
25
|
-
color:var(--text_color)
|
|
25
|
+
color: var(--text_color);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
.checkbox+label::before {
|
|
28
|
+
.checkbox + label::before {
|
|
29
29
|
font-size: var(--font_default_size);
|
|
30
|
-
content:
|
|
30
|
+
content: "";
|
|
31
31
|
display: flex;
|
|
32
32
|
width: 1.2em;
|
|
33
33
|
height: 1.2em;
|
|
@@ -38,20 +38,28 @@ checkbox {
|
|
|
38
38
|
align-items: center;
|
|
39
39
|
justify-content: center;
|
|
40
40
|
color: var(--element_background_2);
|
|
41
|
-
font-family:
|
|
41
|
+
font-family: "chui_I";
|
|
42
42
|
background: var(--element_background);
|
|
43
43
|
border: none;
|
|
44
44
|
box-shadow: 0 0 1px 0 var(--border_color);
|
|
45
45
|
background-repeat: no-repeat;
|
|
46
46
|
background-position: center center;
|
|
47
|
-
|
|
47
|
+
/* Галка прорастает из нуля: смена картинки мгновенная, а размер её растёт —
|
|
48
|
+
так отметка «попадает» в коробку, а не появляется готовой */
|
|
49
|
+
background-size: 0% 0%;
|
|
50
|
+
/* Свой список перехода заменяет общий, поэтому цвет и тень перечислены рядом */
|
|
51
|
+
transition:
|
|
52
|
+
background-color var(--motion_fast) var(--motion_ease),
|
|
53
|
+
color var(--motion_fast) var(--motion_ease),
|
|
54
|
+
box-shadow var(--motion_fast) var(--motion_ease),
|
|
55
|
+
background-size var(--motion_base) var(--motion_spring);
|
|
48
56
|
}
|
|
49
57
|
|
|
50
|
-
.checkbox:not(:disabled):not(:checked)+label:hover::before {
|
|
58
|
+
.checkbox:not(:disabled):not(:checked) + label:hover::before {
|
|
51
59
|
background: var(--element_background_hover);
|
|
52
60
|
}
|
|
53
61
|
|
|
54
|
-
.checkbox:disabled:not(:checked)+label::before {
|
|
62
|
+
.checkbox:disabled:not(:checked) + label::before {
|
|
55
63
|
cursor: not-allowed;
|
|
56
64
|
background: var(--element_background_disabled);
|
|
57
65
|
border: none;
|
|
@@ -59,7 +67,7 @@ checkbox {
|
|
|
59
67
|
color: var(--text_color_disabled);
|
|
60
68
|
}
|
|
61
69
|
|
|
62
|
-
.checkbox:disabled:checked+label::before {
|
|
70
|
+
.checkbox:disabled:checked + label::before {
|
|
63
71
|
cursor: not-allowed;
|
|
64
72
|
color: var(--text_color_disabled);
|
|
65
73
|
background: var(--element_background_disabled);
|
|
@@ -67,32 +75,33 @@ checkbox {
|
|
|
67
75
|
box-shadow: 0 0 1px 0 var(--border_color);
|
|
68
76
|
}
|
|
69
77
|
|
|
70
|
-
.checkbox:not(:disabled):active+label::before {
|
|
78
|
+
.checkbox:not(:disabled):active + label::before {
|
|
71
79
|
background-color: var(--blue_prime_background);
|
|
72
|
-
color:var(--text_color_disabled);
|
|
80
|
+
color: var(--text_color_disabled);
|
|
73
81
|
border: none;
|
|
74
82
|
box-shadow: 0 0 1px 0 var(--border_color);
|
|
75
83
|
}
|
|
76
84
|
|
|
77
|
-
.checkbox:focus-visible+label::before {
|
|
85
|
+
.checkbox:focus-visible + label::before {
|
|
78
86
|
outline: var(--focus_outline);
|
|
79
87
|
outline-offset: var(--focus_outline_offset);
|
|
80
88
|
}
|
|
81
89
|
|
|
82
|
-
.checkbox:checked+label::before {
|
|
90
|
+
.checkbox:checked + label::before {
|
|
83
91
|
background-color: var(--blue_prime_background);
|
|
84
|
-
color:var(--text_color_hover);
|
|
92
|
+
color: var(--text_color_hover);
|
|
85
93
|
border: none;
|
|
86
94
|
box-shadow: 0 0 1px 0 var(--blue_prime_background);
|
|
95
|
+
background-size: 50% 50%;
|
|
87
96
|
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e");
|
|
88
97
|
}
|
|
89
98
|
|
|
90
99
|
.labelz {
|
|
91
100
|
cursor: pointer;
|
|
92
|
-
font-size: var(--font_default_size)
|
|
101
|
+
font-size: var(--font_default_size);
|
|
93
102
|
}
|
|
94
103
|
|
|
95
|
-
.checkbox:disabled+label {
|
|
104
|
+
.checkbox:disabled + label {
|
|
96
105
|
cursor: not-allowed;
|
|
97
106
|
color: var(--text_color_disabled);
|
|
98
|
-
}
|
|
107
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const {setStyles, dropdownPlacement, optionOr} = require(
|
|
2
|
-
const {Validate} = require(
|
|
3
|
-
const {ComboboxKeyboard} = require(
|
|
4
|
-
const {Icon, Icons} = require(
|
|
5
|
-
const {I18n} = require(
|
|
1
|
+
const { setStyles, dropdownPlacement, optionOr } = require("../../../modules/chui_functions");
|
|
2
|
+
const { Validate } = require("../../../modules/chui_validate/chui_validate");
|
|
3
|
+
const { ComboboxKeyboard } = require("../../../modules/chui_a11y/chui_a11y");
|
|
4
|
+
const { Icon, Icons } = require("../../chui_icons/icons");
|
|
5
|
+
const { I18n } = require("../../../modules/chui_i18n/chui_i18n");
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Поле с метками (chips): ввод тегов, почтовых адресов, ключевых слов.
|
|
@@ -29,9 +29,11 @@ const {I18n} = require('../../../modules/chui_i18n/chui_i18n');
|
|
|
29
29
|
* Валидация: `Validate.installField` — для этого поля осмысленны `required` и границы
|
|
30
30
|
* **числа меток** (`min`, `max`), потому что проверяется количество, а не текст.
|
|
31
31
|
*
|
|
32
|
-
* Слушателей на `window`/`document` и таймеров нет,
|
|
33
|
-
*
|
|
34
|
-
*
|
|
32
|
+
* Слушателей на `window`/`document` и таймеров нет, но `destroy()` нужен: за шириной строки
|
|
33
|
+
* меток следит `ResizeObserver`, а пересчёт счётчика «+N» отложен в кадр
|
|
34
|
+
* (`requestAnimationFrame`). Прежний комментарий утверждал, что достаточно убрать узел из
|
|
35
|
+
* документа, — это неверно: наблюдатель держит цель живой, а отложенный кадр продолжал бы
|
|
36
|
+
* считать метки уже удалённого поля.
|
|
35
37
|
*
|
|
36
38
|
* ```javascript
|
|
37
39
|
* const tags = new Chips({name: 'tags', title: 'Теги', placeholder: 'Добавить тег',
|
|
@@ -50,8 +52,8 @@ class Chips {
|
|
|
50
52
|
#input = document.createElement("input");
|
|
51
53
|
#more = document.createElement("chips_more");
|
|
52
54
|
#dropdown = document.createElement("chips_dropdown");
|
|
53
|
-
#
|
|
54
|
-
#
|
|
55
|
+
#overflowFrame = undefined;
|
|
56
|
+
#overflowObserver = undefined;
|
|
55
57
|
#a11y = undefined;
|
|
56
58
|
#hint = document.createElement("chips_hint");
|
|
57
59
|
#status = document.createElement("chips_status");
|
|
@@ -61,33 +63,35 @@ class Chips {
|
|
|
61
63
|
#placeholder = I18n.t("forms.chipsPlaceholder");
|
|
62
64
|
#disabled = false;
|
|
63
65
|
#unique = true;
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
#
|
|
66
|
+
#allowCustom = true;
|
|
67
|
+
#commitOnBlur = false;
|
|
68
|
+
#maxChips = undefined;
|
|
67
69
|
#suggestions = [];
|
|
68
|
-
#
|
|
69
|
-
|
|
70
|
-
constructor(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
70
|
+
#changeListeners = [];
|
|
71
|
+
|
|
72
|
+
constructor(
|
|
73
|
+
options = {
|
|
74
|
+
id: String(),
|
|
75
|
+
name: String(),
|
|
76
|
+
title: String(),
|
|
77
|
+
placeholder: String(),
|
|
78
|
+
width: String(),
|
|
79
|
+
chips: [],
|
|
80
|
+
suggestions: [],
|
|
81
|
+
allowCustom: Boolean(),
|
|
82
|
+
commitOnBlur: Boolean(),
|
|
83
|
+
maxChips: Number(),
|
|
84
|
+
unique: Boolean(),
|
|
85
|
+
disabled: Boolean(),
|
|
86
|
+
hint: String(),
|
|
87
|
+
required: Boolean(),
|
|
88
|
+
min: Number(),
|
|
89
|
+
max: Number(),
|
|
90
|
+
messages: Object(),
|
|
91
|
+
validate: undefined,
|
|
92
|
+
changeListener: undefined,
|
|
93
|
+
}
|
|
94
|
+
) {
|
|
91
95
|
setStyles(__dirname + "/styles.css", "chUiJS_Chips");
|
|
92
96
|
Chips.#counter += 1;
|
|
93
97
|
this.#id = options.id === undefined ? `chui_chips_${Chips.#counter}` : options.id;
|
|
@@ -95,9 +99,9 @@ class Chips {
|
|
|
95
99
|
this.#root.id = this.#id;
|
|
96
100
|
if (options.placeholder !== undefined) this.#placeholder = options.placeholder;
|
|
97
101
|
if (options.unique === false) this.#unique = false;
|
|
98
|
-
if (options.allowCustom === false) this.#
|
|
99
|
-
if (options.commitOnBlur === true) this.#
|
|
100
|
-
if (options.maxChips !== undefined) this.#
|
|
102
|
+
if (options.allowCustom === false) this.#allowCustom = false;
|
|
103
|
+
if (options.commitOnBlur === true) this.#commitOnBlur = true;
|
|
104
|
+
if (options.maxChips !== undefined) this.#maxChips = options.maxChips;
|
|
101
105
|
if (options.suggestions !== undefined) this.#suggestions = [...options.suggestions];
|
|
102
106
|
if (options.title !== undefined) this.setTitle(options.title);
|
|
103
107
|
else this.#title.hidden = true;
|
|
@@ -117,7 +121,7 @@ class Chips {
|
|
|
117
121
|
dropdown: this.#dropdown,
|
|
118
122
|
optionSelector: ".chips_option",
|
|
119
123
|
onEscape: () => this.#setDropdown(false),
|
|
120
|
-
onOpen: () => this.#setDropdown(true)
|
|
124
|
+
onOpen: () => this.#setDropdown(true),
|
|
121
125
|
});
|
|
122
126
|
this.#input.addEventListener("keydown", this.#onInputKeyDown);
|
|
123
127
|
this.#input.addEventListener("blur", this.#onInputBlur);
|
|
@@ -142,8 +146,8 @@ class Chips {
|
|
|
142
146
|
// Ширину строки задаёт вёрстка вокруг, поэтому о смене размера сообщает наблюдатель
|
|
143
147
|
// за самой строкой: поле может получить ширину уже после создания (ленивые разделы витрины)
|
|
144
148
|
if (typeof ResizeObserver === "function") {
|
|
145
|
-
this.#
|
|
146
|
-
this.#
|
|
149
|
+
this.#overflowObserver = new ResizeObserver(() => this.#scheduleOverflow());
|
|
150
|
+
this.#overflowObserver.observe(this.#row);
|
|
147
151
|
}
|
|
148
152
|
this.#syncFieldAria();
|
|
149
153
|
|
|
@@ -151,9 +155,7 @@ class Chips {
|
|
|
151
155
|
this.#status.setAttribute("role", "status");
|
|
152
156
|
this.#status.setAttribute("aria-live", "polite");
|
|
153
157
|
this.#hint.classList.add("chui_visually_hidden");
|
|
154
|
-
this.#hint.innerText = options.hint === undefined
|
|
155
|
-
? I18n.t("forms.chipsHint")
|
|
156
|
-
: options.hint;
|
|
158
|
+
this.#hint.innerText = options.hint === undefined ? I18n.t("forms.chipsHint") : options.hint;
|
|
157
159
|
this.#root.appendChild(this.#title);
|
|
158
160
|
this.#root.appendChild(this.#field);
|
|
159
161
|
this.#root.appendChild(this.#hint);
|
|
@@ -161,7 +163,14 @@ class Chips {
|
|
|
161
163
|
|
|
162
164
|
// Правила считают число меток: пустой список — «пустое» значение для required.
|
|
163
165
|
// Рамка ошибки — только у самого поля: корень оборачивает ещё подпись и подсказку
|
|
164
|
-
Validate.installField(
|
|
166
|
+
Validate.installField(
|
|
167
|
+
this,
|
|
168
|
+
options,
|
|
169
|
+
this.#root,
|
|
170
|
+
undefined,
|
|
171
|
+
() => (this.#chips.length === 0 ? "" : String(this.#chips.length)),
|
|
172
|
+
this.#field
|
|
173
|
+
);
|
|
165
174
|
if (options.chips !== undefined) this.setValue(options.chips);
|
|
166
175
|
if (options.disabled === true) this.setDisabled(true);
|
|
167
176
|
if (options.changeListener !== undefined) this.addChangeListener(options.changeListener);
|
|
@@ -190,7 +199,7 @@ class Chips {
|
|
|
190
199
|
}
|
|
191
200
|
|
|
192
201
|
getMaxChips() {
|
|
193
|
-
return this.#
|
|
202
|
+
return this.#maxChips;
|
|
194
203
|
}
|
|
195
204
|
|
|
196
205
|
getSuggestions() {
|
|
@@ -229,7 +238,7 @@ class Chips {
|
|
|
229
238
|
}
|
|
230
239
|
|
|
231
240
|
setMaxChips(max = Number()) {
|
|
232
|
-
this.#
|
|
241
|
+
this.#maxChips = max;
|
|
233
242
|
this.#syncDisabledState();
|
|
234
243
|
return this;
|
|
235
244
|
}
|
|
@@ -273,13 +282,15 @@ class Chips {
|
|
|
273
282
|
if (index === -1) return this;
|
|
274
283
|
this.#chips.splice(index, 1);
|
|
275
284
|
const node = this.#list.children[index];
|
|
276
|
-
|
|
285
|
+
// Метка уходит движением: из строки она убирается по концу кадра, а счётчик «+N»
|
|
286
|
+
// пересчитывается заново — иначе он считал бы уходящую метку живой
|
|
287
|
+
if (node !== undefined) this.#leaveChip(node);
|
|
277
288
|
// Место в строке освободилось: прежде скрытые метки могут вернуться
|
|
278
289
|
this.#scheduleOverflow();
|
|
279
290
|
this.#renderSuggestions();
|
|
280
291
|
this.#syncDisabledState();
|
|
281
292
|
if (this.clearError !== undefined) this.clearError();
|
|
282
|
-
this.#announce(I18n.t("forms.chipsRemoved", {value: value, count: this.#chips.length}));
|
|
293
|
+
this.#announce(I18n.t("forms.chipsRemoved", { value: value, count: this.#chips.length }));
|
|
283
294
|
this.#emit();
|
|
284
295
|
return this;
|
|
285
296
|
}
|
|
@@ -298,7 +309,7 @@ class Chips {
|
|
|
298
309
|
return this;
|
|
299
310
|
}
|
|
300
311
|
addChangeListener(listener = () => {}) {
|
|
301
|
-
this.#
|
|
312
|
+
this.#changeListeners.push(listener);
|
|
302
313
|
return this;
|
|
303
314
|
}
|
|
304
315
|
|
|
@@ -317,24 +328,49 @@ class Chips {
|
|
|
317
328
|
set() {
|
|
318
329
|
return this.#root;
|
|
319
330
|
}
|
|
331
|
+
|
|
332
|
+
/** Полное удаление: снять наблюдатель за строкой, отложенный кадр и клавиатурный слой */
|
|
333
|
+
destroy() {
|
|
334
|
+
if (this.#overflowObserver !== undefined) {
|
|
335
|
+
this.#overflowObserver.disconnect();
|
|
336
|
+
this.#overflowObserver = undefined;
|
|
337
|
+
}
|
|
338
|
+
if (this.#overflowFrame !== undefined) {
|
|
339
|
+
cancelAnimationFrame(this.#overflowFrame);
|
|
340
|
+
this.#overflowFrame = undefined;
|
|
341
|
+
}
|
|
342
|
+
if (this.#a11y !== undefined) this.#a11y.destroy();
|
|
343
|
+
}
|
|
320
344
|
// === ВНУТРЕННЕЕ ===
|
|
321
345
|
// Общая точка добавления: возвращает признак «метка действительно добавлена»
|
|
322
346
|
#tryAdd(text = String()) {
|
|
323
347
|
const value = String(text).trim();
|
|
324
348
|
if (value === "") return false;
|
|
325
349
|
if (this.#unique && this.#chips.includes(value)) return false;
|
|
326
|
-
if (this.#
|
|
327
|
-
if (!this.#
|
|
350
|
+
if (this.#maxChips !== undefined && this.#chips.length >= this.#maxChips) return false;
|
|
351
|
+
if (!this.#allowCustom && !this.#suggestions.includes(value)) return false;
|
|
328
352
|
this.#chips.push(value);
|
|
329
353
|
this.#appendChip(value);
|
|
330
354
|
this.#renderSuggestions();
|
|
331
355
|
this.#syncDisabledState();
|
|
332
356
|
// Метка добавлена — прежняя ошибка (например, «нужен хотя бы один тег») больше не верна
|
|
333
357
|
if (this.clearError !== undefined) this.clearError();
|
|
334
|
-
this.#announce(I18n.t("forms.chipsAdded", {value: value, count: this.#chips.length}));
|
|
358
|
+
this.#announce(I18n.t("forms.chipsAdded", { value: value, count: this.#chips.length }));
|
|
335
359
|
return true;
|
|
336
360
|
}
|
|
337
361
|
|
|
362
|
+
/** Уход метки: она гаснет и сжимается, а из строки убирается по концу кадра */
|
|
363
|
+
#leaveChip(node) {
|
|
364
|
+
node.classList.add("chips_item_leaving");
|
|
365
|
+
const done = (event) => {
|
|
366
|
+
if (event.target !== node) return;
|
|
367
|
+
node.removeEventListener("animationend", done);
|
|
368
|
+
node.remove();
|
|
369
|
+
this.#scheduleOverflow();
|
|
370
|
+
};
|
|
371
|
+
node.addEventListener("animationend", done);
|
|
372
|
+
}
|
|
373
|
+
|
|
338
374
|
#appendChip(text = String()) {
|
|
339
375
|
const item = document.createElement("chips_item");
|
|
340
376
|
const label = document.createElement("chips_text");
|
|
@@ -345,12 +381,21 @@ class Chips {
|
|
|
345
381
|
remove.className = "chips_remove";
|
|
346
382
|
remove.dataset.chip = text;
|
|
347
383
|
// Настоящая кнопка: удаление доступно и мышью, и с клавиатуры, и скринридеру
|
|
348
|
-
remove.setAttribute("aria-label", I18n.t("forms.chipsRemove", {value: text}));
|
|
384
|
+
remove.setAttribute("aria-label", I18n.t("forms.chipsRemove", { value: text }));
|
|
349
385
|
remove.setAttribute("title", I18n.t("common.delete"));
|
|
350
386
|
remove.appendChild(new Icon(Icons.NAVIGATION.CLOSE, "12px").set());
|
|
351
387
|
if (this.#disabled) remove.disabled = true;
|
|
352
388
|
item.appendChild(remove);
|
|
353
389
|
this.#list.appendChild(item);
|
|
390
|
+
// Новая метка встаёт на место общим кадром появления, а не возникает рывком.
|
|
391
|
+
// Класс снимается по концу кадра: при пересборке списка метки его не переигрывают
|
|
392
|
+
item.classList.add("chips_item_appearing");
|
|
393
|
+
const appeared = (event) => {
|
|
394
|
+
if (event.target !== item) return;
|
|
395
|
+
item.removeEventListener("animationend", appeared);
|
|
396
|
+
item.classList.remove("chips_item_appearing");
|
|
397
|
+
};
|
|
398
|
+
item.addEventListener("animationend", appeared);
|
|
354
399
|
// Метка могла не поместиться в строку — пересчёт счётчика «+N»
|
|
355
400
|
this.#scheduleOverflow();
|
|
356
401
|
}
|
|
@@ -376,7 +421,7 @@ class Chips {
|
|
|
376
421
|
// Не помещается: ищем, сколько меток показать числом, чтобы строка сошлась
|
|
377
422
|
for (let hidden = 1; hidden <= items.length; hidden += 1) {
|
|
378
423
|
this.#more.innerText = `+${hidden}`;
|
|
379
|
-
this.#more.setAttribute("aria-label", I18n.t("forms.chipsMore", {count: hidden}));
|
|
424
|
+
this.#more.setAttribute("aria-label", I18n.t("forms.chipsMore", { count: hidden }));
|
|
380
425
|
this.#more.hidden = false;
|
|
381
426
|
const counter = this.#more.getBoundingClientRect().width + gap;
|
|
382
427
|
if (total(items.length - hidden) + counter + reserve <= available) {
|
|
@@ -390,13 +435,31 @@ class Chips {
|
|
|
390
435
|
|
|
391
436
|
/** Пересчёт счётчика после текущего кадра: к этому моменту разметка меток уже уложена */
|
|
392
437
|
#scheduleOverflow() {
|
|
393
|
-
if (this.#
|
|
394
|
-
this.#
|
|
395
|
-
this.#
|
|
438
|
+
if (this.#overflowFrame !== undefined) return;
|
|
439
|
+
this.#overflowFrame = requestAnimationFrame(() => {
|
|
440
|
+
this.#overflowFrame = undefined;
|
|
396
441
|
this.#syncOverflow();
|
|
397
442
|
});
|
|
398
443
|
}
|
|
399
444
|
|
|
445
|
+
/**
|
|
446
|
+
* Уход списка идёт движением: `hidden` возвращается по концу кадра, поэтому список
|
|
447
|
+
* не пропадает рывком. Открытие за время ухода отменяет снятие — иначе список
|
|
448
|
+
* погас бы уже открытым.
|
|
449
|
+
*/
|
|
450
|
+
#hideDropdown() {
|
|
451
|
+
if (this.#dropdown.hidden === true) return;
|
|
452
|
+
this.#dropdown.classList.add("chips_dropdown_leaving");
|
|
453
|
+
const done = (event) => {
|
|
454
|
+
if (event.target !== this.#dropdown) return;
|
|
455
|
+
this.#dropdown.removeEventListener("animationend", done);
|
|
456
|
+
if (this.#dropdown.classList.contains("chips_dropdown_leaving") === false) return;
|
|
457
|
+
this.#dropdown.classList.remove("chips_dropdown_leaving");
|
|
458
|
+
this.#dropdown.hidden = true;
|
|
459
|
+
};
|
|
460
|
+
this.#dropdown.addEventListener("animationend", done);
|
|
461
|
+
}
|
|
462
|
+
|
|
400
463
|
// Список подсказок: свой выпадающий список в материале остальных дропдаунов
|
|
401
464
|
#renderSuggestions() {
|
|
402
465
|
// Уже добавленные метки в подсказках не нужны, набранный текст сужает список
|
|
@@ -428,8 +491,13 @@ class Chips {
|
|
|
428
491
|
this.#scheduleOverflow();
|
|
429
492
|
}
|
|
430
493
|
const visible = open === true && this.#disabled === false && this.#dropdown.childElementCount > 0;
|
|
431
|
-
|
|
432
|
-
|
|
494
|
+
if (visible === true) {
|
|
495
|
+
this.#dropdown.classList.remove("chips_dropdown_leaving");
|
|
496
|
+
this.#dropdown.hidden = false;
|
|
497
|
+
this.#placeDropdown();
|
|
498
|
+
} else {
|
|
499
|
+
this.#hideDropdown();
|
|
500
|
+
}
|
|
433
501
|
if (this.#a11y !== undefined) this.#a11y.setExpanded(visible);
|
|
434
502
|
return visible;
|
|
435
503
|
}
|
|
@@ -463,11 +531,13 @@ class Chips {
|
|
|
463
531
|
}
|
|
464
532
|
|
|
465
533
|
#syncDisabledState() {
|
|
466
|
-
const full = this.#
|
|
534
|
+
const full = this.#maxChips !== undefined && this.#chips.length >= this.#maxChips;
|
|
467
535
|
// Поле ввода остаётся доступным и при достигнутом пределе: иначе нельзя было бы
|
|
468
536
|
// убрать метку с клавиатуры, а причина отказа объясняется в статусе
|
|
469
537
|
this.#input.disabled = this.#disabled;
|
|
470
|
-
this.#input.placeholder = full
|
|
538
|
+
this.#input.placeholder = full
|
|
539
|
+
? I18n.t("forms.chipsLimitPlaceholder", { count: this.#maxChips })
|
|
540
|
+
: this.#placeholder;
|
|
471
541
|
for (const button of this.#list.querySelectorAll(".chips_remove")) button.disabled = this.#disabled;
|
|
472
542
|
}
|
|
473
543
|
|
|
@@ -477,7 +547,7 @@ class Chips {
|
|
|
477
547
|
|
|
478
548
|
#emit() {
|
|
479
549
|
const chips = this.getValue();
|
|
480
|
-
for (const listener of [...this.#
|
|
550
|
+
for (const listener of [...this.#changeListeners]) listener(chips);
|
|
481
551
|
}
|
|
482
552
|
|
|
483
553
|
#commitInput() {
|
|
@@ -490,12 +560,13 @@ class Chips {
|
|
|
490
560
|
return;
|
|
491
561
|
}
|
|
492
562
|
// Текст не теряем: либо он уже есть, либо метка не из подсказок, либо предел
|
|
493
|
-
if (this.#
|
|
494
|
-
this.#announce(I18n.t("forms.chipsLimitReached", {count: this.#
|
|
563
|
+
if (this.#maxChips !== undefined && this.#chips.length >= this.#maxChips) {
|
|
564
|
+
this.#announce(I18n.t("forms.chipsLimitReached", { count: this.#maxChips }));
|
|
495
565
|
return;
|
|
496
566
|
}
|
|
497
|
-
if (this.#unique && this.#chips.includes(value.trim()))
|
|
498
|
-
|
|
567
|
+
if (this.#unique && this.#chips.includes(value.trim()))
|
|
568
|
+
this.#announce(I18n.t("forms.chipsDuplicate", { value: value.trim() }));
|
|
569
|
+
else this.#announce(I18n.t("forms.chipsNotSuggested", { value: value.trim() }));
|
|
499
570
|
}
|
|
500
571
|
|
|
501
572
|
#onInputInput = () => {
|
|
@@ -556,7 +627,7 @@ class Chips {
|
|
|
556
627
|
};
|
|
557
628
|
|
|
558
629
|
#onInputBlur = () => {
|
|
559
|
-
if (this.#
|
|
630
|
+
if (this.#commitOnBlur) this.#commitInput();
|
|
560
631
|
};
|
|
561
632
|
|
|
562
633
|
#onFieldClick = (event) => {
|
|
@@ -572,4 +643,4 @@ class Chips {
|
|
|
572
643
|
};
|
|
573
644
|
}
|
|
574
645
|
|
|
575
|
-
exports.Chips = Chips
|
|
646
|
+
exports.Chips = Chips;
|