@rt-tools/ui-kit-v2 0.23.3 → 0.24.0
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/fesm2022/rt-tools-ui-kit-v2-accordion.mjs +142 -71
- package/fesm2022/rt-tools-ui-kit-v2-accordion.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs +467 -231
- package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs +260 -91
- package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-aside-section.mjs +80 -46
- package/fesm2022/rt-tools-ui-kit-v2-aside-section.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-aside.mjs +984 -697
- package/fesm2022/rt-tools-ui-kit-v2-aside.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs +452 -210
- package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-bar-list.mjs +143 -52
- package/fesm2022/rt-tools-ui-kit-v2-bar-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-bottom-sheet.mjs +158 -83
- package/fesm2022/rt-tools-ui-kit-v2-bottom-sheet.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-breadcrumbs.mjs +335 -0
- package/fesm2022/rt-tools-ui-kit-v2-breadcrumbs.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-button.mjs +437 -363
- package/fesm2022/rt-tools-ui-kit-v2-button.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs +430 -149
- package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-card.mjs +155 -71
- package/fesm2022/rt-tools-ui-kit-v2-card.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-carousel.mjs +155 -0
- package/fesm2022/rt-tools-ui-kit-v2-carousel.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs +215 -110
- package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-collapsible-text.mjs +158 -75
- package/fesm2022/rt-tools-ui-kit-v2-collapsible-text.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-color-palette.mjs +769 -0
- package/fesm2022/rt-tools-ui-kit-v2-color-palette.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-confirm-popover.mjs +462 -253
- package/fesm2022/rt-tools-ui-kit-v2-confirm-popover.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-container.mjs +1276 -1316
- package/fesm2022/rt-tools-ui-kit-v2-container.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs +185 -80
- package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs +2321 -2619
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-counter-row.mjs +100 -44
- package/fesm2022/rt-tools-ui-kit-v2-counter-row.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-counter.mjs +290 -155
- package/fesm2022/rt-tools-ui-kit-v2-counter.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs +2097 -858
- package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs +2247 -1176
- package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs +1043 -705
- package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs +810 -525
- package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-delta-view.mjs +158 -138
- package/fesm2022/rt-tools-ui-kit-v2-delta-view.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-detail-list.mjs +177 -67
- package/fesm2022/rt-tools-ui-kit-v2-detail-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-dialog.mjs +550 -477
- package/fesm2022/rt-tools-ui-kit-v2-dialog.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-dot-field.mjs +185 -168
- package/fesm2022/rt-tools-ui-kit-v2-dot-field.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-download-link.mjs +116 -43
- package/fesm2022/rt-tools-ui-kit-v2-download-link.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs +585 -0
- package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs +755 -259
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +3266 -1115
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-empty-state.mjs +190 -55
- package/fesm2022/rt-tools-ui-kit-v2-empty-state.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs +283 -103
- package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-field.mjs +393 -177
- package/fesm2022/rt-tools-ui-kit-v2-field.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs +399 -207
- package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-file-drop.mjs +288 -212
- package/fesm2022/rt-tools-ui-kit-v2-file-drop.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-file-input.mjs +262 -116
- package/fesm2022/rt-tools-ui-kit-v2-file-input.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-file-list.mjs +57 -31
- package/fesm2022/rt-tools-ui-kit-v2-file-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs +258 -90
- package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs +249 -215
- package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-header.mjs +199 -71
- package/fesm2022/rt-tools-ui-kit-v2-header.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree-selector.mjs +231 -0
- package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree-selector.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs +336 -0
- package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs +451 -162
- package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-icon.mjs +931 -686
- package/fesm2022/rt-tools-ui-kit-v2-icon.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-image-cropper.mjs +664 -491
- package/fesm2022/rt-tools-ui-kit-v2-image-cropper.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs +574 -222
- package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-info-item.mjs +150 -36
- package/fesm2022/rt-tools-ui-kit-v2-info-item.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-inline-edit.mjs +606 -0
- package/fesm2022/rt-tools-ui-kit-v2-inline-edit.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs +461 -355
- package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-input.mjs +338 -143
- package/fesm2022/rt-tools-ui-kit-v2-input.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-live-badge.mjs +135 -48
- package/fesm2022/rt-tools-ui-kit-v2-live-badge.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-logo.mjs +166 -92
- package/fesm2022/rt-tools-ui-kit-v2-logo.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-markdown-text.mjs +118 -56
- package/fesm2022/rt-tools-ui-kit-v2-markdown-text.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-menu.mjs +1054 -527
- package/fesm2022/rt-tools-ui-kit-v2-menu.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-message.mjs +230 -104
- package/fesm2022/rt-tools-ui-kit-v2-message.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-money-list.mjs +210 -70
- package/fesm2022/rt-tools-ui-kit-v2-money-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs +532 -311
- package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-night-grid.mjs +125 -50
- package/fesm2022/rt-tools-ui-kit-v2-night-grid.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-note.mjs +73 -43
- package/fesm2022/rt-tools-ui-kit-v2-note.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-notifications-bell.mjs +161 -53
- package/fesm2022/rt-tools-ui-kit-v2-notifications-bell.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +491 -310
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs +374 -174
- package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-photo-viewer.mjs +202 -159
- package/fesm2022/rt-tools-ui-kit-v2-photo-viewer.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-popover.mjs +438 -309
- package/fesm2022/rt-tools-ui-kit-v2-popover.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-profile-menu.mjs +295 -0
- package/fesm2022/rt-tools-ui-kit-v2-profile-menu.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-prompt-suggestion.mjs +135 -45
- package/fesm2022/rt-tools-ui-kit-v2-prompt-suggestion.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs +293 -171
- package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-radius.mjs +62 -55
- package/fesm2022/rt-tools-ui-kit-v2-radius.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +3379 -1466
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-ripple.mjs +114 -116
- package/fesm2022/rt-tools-ui-kit-v2-ripple.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs +406 -299
- package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs +137 -36
- package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-select.mjs +687 -468
- package/fesm2022/rt-tools-ui-kit-v2-select.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +2195 -1569
- package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-skeleton-wrapper.mjs +187 -48
- package/fesm2022/rt-tools-ui-kit-v2-skeleton-wrapper.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-skeleton.mjs +242 -122
- package/fesm2022/rt-tools-ui-kit-v2-skeleton.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs +439 -0
- package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-spinner.mjs +218 -69
- package/fesm2022/rt-tools-ui-kit-v2-spinner.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs +292 -91
- package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs +225 -138
- package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs +150 -116
- package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-table.mjs +2462 -1583
- package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs +647 -346
- package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tag.mjs +335 -121
- package/fesm2022/rt-tools-ui-kit-v2-tag.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs +217 -84
- package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs +151 -72
- package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +697 -226
- package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-timeline.mjs +92 -38
- package/fesm2022/rt-tools-ui-kit-v2-timeline.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-toast.mjs +752 -338
- package/fesm2022/rt-tools-ui-kit-v2-toast.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs +310 -129
- package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs +286 -158
- package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs +270 -134
- package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs +322 -202
- package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs +908 -0
- package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-tree.mjs +785 -0
- package/fesm2022/rt-tools-ui-kit-v2-tree.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-welcome-dialog.mjs +118 -63
- package/fesm2022/rt-tools-ui-kit-v2-welcome-dialog.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs +783 -262
- package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs +633 -294
- package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2.mjs +100 -103
- package/package.json +45 -1
- package/src/assets/icons/collapse-all.svg +9 -0
- package/src/assets/icons/expand-all.svg +9 -0
- package/src/assets/icons-material/collapse-all.fill.svg +5 -0
- package/src/assets/icons-material/collapse-all.svg +5 -0
- package/src/assets/icons-material/expand-all.fill.svg +5 -0
- package/src/assets/icons-material/expand-all.svg +5 -0
- package/src/assets/icons-material/undo.fill.svg +5 -0
- package/src/assets/icons-material/undo.svg +5 -0
- package/src/lib/components/bottom-sheet/CONTEXT.md +20 -2
- package/src/lib/components/bottom-sheet/rt-bottom-sheet.component.scss +36 -1
- package/src/lib/components/breadcrumbs/CONTEXT.md +37 -0
- package/src/lib/components/breadcrumbs/rt-breadcrumbs.component.scss +205 -0
- package/src/lib/components/carousel/CONTEXT.md +42 -0
- package/src/lib/components/carousel/rt-carousel.component.scss +117 -0
- package/src/lib/components/checkbox/CONTEXT.md +3 -0
- package/src/lib/components/checkbox/rt-checkbox.component.scss +9 -3
- package/src/lib/components/color-palette/CONTEXT.md +49 -0
- package/src/lib/components/color-palette/picker/rt-color-picker.component.scss +161 -0
- package/src/lib/components/color-palette/rt-color-palette.component.scss +132 -0
- package/src/lib/components/draggable-tree/CONTEXT.md +54 -0
- package/src/lib/components/draggable-tree/rt-draggable-tree.component.scss +219 -0
- package/src/lib/components/hybrid-tree/CONTEXT.md +31 -0
- package/src/lib/components/hybrid-tree-selector/CONTEXT.md +25 -0
- package/src/lib/components/icon-button/CONTEXT.md +3 -0
- package/src/lib/components/inline-edit/CONTEXT.md +41 -0
- package/src/lib/components/inline-edit/rt-inline-edit.component.scss +274 -0
- package/src/lib/components/popover/CONTEXT.md +3 -0
- package/src/lib/components/profile-menu/CONTEXT.md +32 -0
- package/src/lib/components/profile-menu/rt-profile-menu.component.scss +104 -0
- package/src/lib/components/speed-menu/CONTEXT.md +34 -0
- package/src/lib/components/speed-menu/rt-speed-menu.component.scss +118 -0
- package/src/lib/components/tag/rt-tag.component.scss +12 -0
- package/src/lib/components/thread-list/CONTEXT.md +1 -0
- package/src/lib/components/thread-list/rt-thread-list.component.scss +2 -1
- package/src/lib/components/toolbar/CONTEXT.md +9 -4
- package/src/lib/components/toolbar/rt-toolbar.component.scss +10 -2
- package/src/lib/components/tooltip/CONTEXT.md +8 -1
- package/src/lib/components/tree/CONTEXT.md +66 -0
- package/src/lib/components/tree/rt-tree.component.scss +313 -0
- package/src/lib/components/tree-selector/CONTEXT.md +47 -0
- package/src/lib/components/tree-selector/rt-tree-selector.component.scss +121 -0
- package/src/styles/_primitives.scss +4 -0
- package/src/styles/_semantic.scss +5 -0
- package/styles/tokens.css +43 -0
- package/types/rt-tools-ui-kit-v2-accordion.d.ts +31 -24
- package/types/rt-tools-ui-kit-v2-action-bar.d.ts +112 -91
- package/types/rt-tools-ui-kit-v2-ai-run-status.d.ts +64 -40
- package/types/rt-tools-ui-kit-v2-aside-section.d.ts +13 -10
- package/types/rt-tools-ui-kit-v2-aside.d.ts +268 -206
- package/types/rt-tools-ui-kit-v2-autocomplete.d.ts +102 -61
- package/types/rt-tools-ui-kit-v2-bar-list.d.ts +39 -27
- package/types/rt-tools-ui-kit-v2-bottom-sheet.d.ts +31 -20
- package/types/rt-tools-ui-kit-v2-breadcrumbs.d.ts +89 -0
- package/types/rt-tools-ui-kit-v2-button.d.ts +119 -59
- package/types/rt-tools-ui-kit-v2-calendar.d.ts +151 -86
- package/types/rt-tools-ui-kit-v2-card.d.ts +42 -21
- package/types/rt-tools-ui-kit-v2-carousel.d.ts +76 -0
- package/types/rt-tools-ui-kit-v2-checkbox.d.ts +48 -24
- package/types/rt-tools-ui-kit-v2-collapsible-text.d.ts +28 -20
- package/types/rt-tools-ui-kit-v2-color-palette.d.ts +208 -0
- package/types/rt-tools-ui-kit-v2-confirm-popover.d.ts +104 -47
- package/types/rt-tools-ui-kit-v2-container.d.ts +278 -221
- package/types/rt-tools-ui-kit-v2-copy-value.d.ts +39 -24
- package/types/rt-tools-ui-kit-v2-core.d.ts +862 -865
- package/types/rt-tools-ui-kit-v2-counter-row.d.ts +20 -12
- package/types/rt-tools-ui-kit-v2-counter.d.ts +70 -38
- package/types/rt-tools-ui-kit-v2-data-list.d.ts +429 -264
- package/types/rt-tools-ui-kit-v2-data-table.d.ts +500 -351
- package/types/rt-tools-ui-kit-v2-date-picker.d.ts +164 -138
- package/types/rt-tools-ui-kit-v2-date-range.d.ts +102 -84
- package/types/rt-tools-ui-kit-v2-delta-view.d.ts +16 -13
- package/types/rt-tools-ui-kit-v2-detail-list.d.ts +23 -16
- package/types/rt-tools-ui-kit-v2-dialog.d.ts +130 -101
- package/types/rt-tools-ui-kit-v2-dot-field.d.ts +10 -13
- package/types/rt-tools-ui-kit-v2-download-link.d.ts +22 -17
- package/types/rt-tools-ui-kit-v2-draggable-tree.d.ts +132 -0
- package/types/rt-tools-ui-kit-v2-dynamic-list.d.ts +185 -96
- package/types/rt-tools-ui-kit-v2-dynamic-selector.d.ts +904 -404
- package/types/rt-tools-ui-kit-v2-empty-state.d.ts +48 -19
- package/types/rt-tools-ui-kit-v2-expansion-panel.d.ts +67 -39
- package/types/rt-tools-ui-kit-v2-field.d.ts +90 -49
- package/types/rt-tools-ui-kit-v2-file-card.d.ts +115 -75
- package/types/rt-tools-ui-kit-v2-file-drop.d.ts +75 -48
- package/types/rt-tools-ui-kit-v2-file-input.d.ts +53 -36
- package/types/rt-tools-ui-kit-v2-file-list.d.ts +5 -8
- package/types/rt-tools-ui-kit-v2-filter-control.d.ts +83 -49
- package/types/rt-tools-ui-kit-v2-form-control.d.ts +102 -74
- package/types/rt-tools-ui-kit-v2-header.d.ts +40 -22
- package/types/rt-tools-ui-kit-v2-hybrid-tree-selector.d.ts +14 -0
- package/types/rt-tools-ui-kit-v2-hybrid-tree.d.ts +72 -0
- package/types/rt-tools-ui-kit-v2-icon-button.d.ts +190 -90
- package/types/rt-tools-ui-kit-v2-icon.d.ts +160 -129
- package/types/rt-tools-ui-kit-v2-image-cropper.d.ts +151 -111
- package/types/rt-tools-ui-kit-v2-image-upload.d.ts +159 -85
- package/types/rt-tools-ui-kit-v2-info-item.d.ts +26 -13
- package/types/rt-tools-ui-kit-v2-inline-edit.d.ts +194 -0
- package/types/rt-tools-ui-kit-v2-input-number.d.ts +102 -53
- package/types/rt-tools-ui-kit-v2-input.d.ts +82 -43
- package/types/rt-tools-ui-kit-v2-live-badge.d.ts +30 -17
- package/types/rt-tools-ui-kit-v2-logo.d.ts +49 -32
- package/types/rt-tools-ui-kit-v2-markdown-text.d.ts +26 -17
- package/types/rt-tools-ui-kit-v2-menu.d.ts +272 -155
- package/types/rt-tools-ui-kit-v2-message.d.ts +59 -33
- package/types/rt-tools-ui-kit-v2-money-list.d.ts +36 -18
- package/types/rt-tools-ui-kit-v2-multiselect.d.ts +114 -80
- package/types/rt-tools-ui-kit-v2-night-grid.d.ts +34 -25
- package/types/rt-tools-ui-kit-v2-note.d.ts +12 -9
- package/types/rt-tools-ui-kit-v2-notifications-bell.d.ts +37 -16
- package/types/rt-tools-ui-kit-v2-page-header.d.ts +218 -150
- package/types/rt-tools-ui-kit-v2-pagination.d.ts +99 -63
- package/types/rt-tools-ui-kit-v2-photo-viewer.d.ts +61 -66
- package/types/rt-tools-ui-kit-v2-popover.d.ts +116 -55
- package/types/rt-tools-ui-kit-v2-profile-menu.d.ts +103 -0
- package/types/rt-tools-ui-kit-v2-prompt-suggestion.d.ts +26 -16
- package/types/rt-tools-ui-kit-v2-radio-button.d.ts +85 -43
- package/types/rt-tools-ui-kit-v2-radius.d.ts +18 -15
- package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +931 -590
- package/types/rt-tools-ui-kit-v2-ripple.d.ts +28 -25
- package/types/rt-tools-ui-kit-v2-scroll-area.d.ts +60 -58
- package/types/rt-tools-ui-kit-v2-section-nav.d.ts +32 -22
- package/types/rt-tools-ui-kit-v2-select.d.ts +182 -139
- package/types/rt-tools-ui-kit-v2-side-menu.d.ts +452 -349
- package/types/rt-tools-ui-kit-v2-skeleton-wrapper.d.ts +53 -20
- package/types/rt-tools-ui-kit-v2-skeleton.d.ts +55 -26
- package/types/rt-tools-ui-kit-v2-speed-menu.d.ts +131 -0
- package/types/rt-tools-ui-kit-v2-spinner.d.ts +56 -28
- package/types/rt-tools-ui-kit-v2-split-button.d.ts +96 -55
- package/types/rt-tools-ui-kit-v2-stat-tile.d.ts +88 -60
- package/types/rt-tools-ui-kit-v2-stepper.d.ts +50 -37
- package/types/rt-tools-ui-kit-v2-table.d.ts +631 -480
- package/types/rt-tools-ui-kit-v2-tabs.d.ts +198 -113
- package/types/rt-tools-ui-kit-v2-tag.d.ts +106 -53
- package/types/rt-tools-ui-kit-v2-textarea.d.ts +48 -25
- package/types/rt-tools-ui-kit-v2-theme-toggle.d.ts +28 -26
- package/types/rt-tools-ui-kit-v2-thread-list.d.ts +154 -94
- package/types/rt-tools-ui-kit-v2-timeline.d.ts +30 -28
- package/types/rt-tools-ui-kit-v2-toast.d.ts +174 -98
- package/types/rt-tools-ui-kit-v2-toggle-button-group.d.ts +132 -86
- package/types/rt-tools-ui-kit-v2-toggle-switch.d.ts +88 -50
- package/types/rt-tools-ui-kit-v2-toolbar.d.ts +30 -27
- package/types/rt-tools-ui-kit-v2-tooltip.d.ts +65 -41
- package/types/rt-tools-ui-kit-v2-tree-selector.d.ts +257 -0
- package/types/rt-tools-ui-kit-v2-tree.d.ts +282 -0
- package/types/rt-tools-ui-kit-v2-welcome-dialog.d.ts +21 -24
- package/types/rt-tools-ui-kit-v2-workspace-details.d.ts +195 -124
- package/types/rt-tools-ui-kit-v2-workspace.d.ts +122 -79
- package/types/rt-tools-ui-kit-v2.d.ts +100 -90
- package/fesm2022/rt-tools-ui-kit-v2.mjs.map +0 -1
|
@@ -1,1639 +1,2265 @@
|
|
|
1
|
-
import { NgTemplateOutlet } from
|
|
2
|
-
import * as i0 from
|
|
3
|
-
import {
|
|
4
|
-
import * as i1 from
|
|
5
|
-
import { FormControl, ReactiveFormsModule } from
|
|
6
|
-
import { takeUntilDestroyed } from
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { isKitIconName, materialPairOf
|
|
11
|
-
import { RtIconButtonComponent } from
|
|
12
|
-
import { RtInputComponent } from
|
|
13
|
-
import { RtScrollAreaComponent, RtScrollAreaContentDirective, RtScrollAreaFooterDirective, RtScrollAreaHeaderDirective } from
|
|
14
|
-
import { RtTooltipDirective } from
|
|
15
|
-
import { CdkDrag, CdkDragHandle, CdkDropList } from
|
|
16
|
-
import { RtExpansionPanelComponent, RtExpansionPanelContentDirective } from
|
|
17
|
-
import { isRecord } from
|
|
18
|
-
|
|
19
|
-
/** Только строки и числа, без повторов, в прежнем порядке. */
|
|
1
|
+
import { NgTemplateOutlet } from "@angular/common";
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
import { ChangeDetectionStrategy, Component, DestroyRef, Directive, ElementRef, ErrorHandler, Injectable, InjectionToken, Injector, Pipe, Renderer2, TemplateRef, ViewEncapsulation, afterNextRender, booleanAttribute, computed, contentChild, effect, inject, input, isDevMode, linkedSignal, makeEnvironmentProviders, numberAttribute, output, signal, viewChild, viewChildren } from "@angular/core";
|
|
4
|
+
import * as i1 from "@angular/forms";
|
|
5
|
+
import { FormControl, ReactiveFormsModule } from "@angular/forms";
|
|
6
|
+
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
|
7
|
+
import { ActivatedRoute, Router, RouterLink } from "@angular/router";
|
|
8
|
+
import { BlockDirective, ElemDirective, LOCAL_STORAGE, ModDirective, PlatformService, WINDOW } from "@rt-tools/core";
|
|
9
|
+
import { BreakpointsService, ERtStorageKeys, rtKitLabel } from "@rt-tools/ui-kit-v2/core";
|
|
10
|
+
import { RtIconComponent, isKitIconName, materialPairOf } from "@rt-tools/ui-kit-v2/icon";
|
|
11
|
+
import { RtIconButtonComponent } from "@rt-tools/ui-kit-v2/icon-button";
|
|
12
|
+
import { RtInputComponent } from "@rt-tools/ui-kit-v2/input";
|
|
13
|
+
import { RtScrollAreaComponent, RtScrollAreaContentDirective, RtScrollAreaFooterDirective, RtScrollAreaHeaderDirective } from "@rt-tools/ui-kit-v2/scroll-area";
|
|
14
|
+
import { RtTooltipDirective } from "@rt-tools/ui-kit-v2/tooltip";
|
|
15
|
+
import { CdkDrag, CdkDragHandle, CdkDropList } from "@angular/cdk/drag-drop";
|
|
16
|
+
import { RtExpansionPanelComponent, RtExpansionPanelContentDirective } from "@rt-tools/ui-kit-v2/expansion-panel";
|
|
17
|
+
import { isRecord } from "@rt-tools/utils";
|
|
20
18
|
function normalizeSideMenuFavorites(values) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return kept;
|
|
26
|
-
}, []);
|
|
19
|
+
return values.reduce((kept, value) => {
|
|
20
|
+
if ((typeof value === "string" || typeof value === "number") && !kept.includes(value)) kept.push(value);
|
|
21
|
+
return kept;
|
|
22
|
+
}, []);
|
|
27
23
|
}
|
|
28
|
-
/**
|
|
29
|
-
* Перенос записи списка с места на место.
|
|
30
|
-
*
|
|
31
|
-
* Номер места вне списка у источника ничего не меняет — переносить нечего; у цели прижимается к
|
|
32
|
-
* краю: рука, бросившая строку ниже последней, хотела поставить её последней.
|
|
33
|
-
*/
|
|
34
24
|
function moveSideMenuFavorite(ids, from, to) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
next.splice(target, 0, moved);
|
|
42
|
-
return next;
|
|
25
|
+
const next = [...ids];
|
|
26
|
+
if (from < 0 || from >= next.length) return next;
|
|
27
|
+
const moved = next.splice(from, 1)[0];
|
|
28
|
+
const target = Math.min(Math.max(to, 0), next.length);
|
|
29
|
+
next.splice(target, 0, moved);
|
|
30
|
+
return next;
|
|
43
31
|
}
|
|
44
|
-
/**
|
|
45
|
-
* Перенос строки блока — места в блоке, а не в списке.
|
|
46
|
-
*
|
|
47
|
-
* Блок показывает только те номера, пункты которых в меню есть, поэтому место в блоке — не место в
|
|
48
|
-
* списке. Видимые номера переставляются между собой и встают в те же ячейки списка, которые
|
|
49
|
-
* занимали; скрытые остаются на своих местах: их пункт вернётся вместе с правом, и человек найдёт
|
|
50
|
-
* его там, куда ставил. Видимый номер, которого в списке нет, пропускается: список могла поменять
|
|
51
|
-
* другая вкладка, а место номера, которого нет, занять нечем.
|
|
52
|
-
*/
|
|
53
32
|
function moveVisibleSideMenuFavorite(ids, visible, from, to) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return placed;
|
|
65
|
-
});
|
|
33
|
+
const listed = new Set(ids);
|
|
34
|
+
const reordered = moveSideMenuFavorite(normalizeSideMenuFavorites(visible), from, to).filter((id) => listed.has(id));
|
|
35
|
+
const slots = new Set(reordered);
|
|
36
|
+
let next = 0;
|
|
37
|
+
return ids.map((id) => {
|
|
38
|
+
if (!slots.has(id)) return id;
|
|
39
|
+
const placed = reordered[next];
|
|
40
|
+
next += 1;
|
|
41
|
+
return placed;
|
|
42
|
+
});
|
|
66
43
|
}
|
|
67
|
-
/**
|
|
68
|
-
* Может ли пункт стоять в избранном: ссылка есть — может; папка без ссылки никуда не ведёт, а
|
|
69
|
-
* пункт с флагом `favoriteDisabled` приложение исключило само.
|
|
70
|
-
*/
|
|
71
44
|
function isSideMenuFavoriteCandidate(item) {
|
|
72
|
-
|
|
45
|
+
return Boolean(item.link?.trim()) && !item.favoriteDisabled;
|
|
73
46
|
}
|
|
74
47
|
function collectLinkedItems(items, byId) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
collectLinkedItems(item.submenu ?? [], byId);
|
|
80
|
-
}
|
|
48
|
+
for (const item of items) {
|
|
49
|
+
if (isSideMenuFavoriteCandidate(item) && !byId.has(item.id)) byId.set(item.id, item);
|
|
50
|
+
collectLinkedItems(item.submenu ?? [], byId);
|
|
51
|
+
}
|
|
81
52
|
}
|
|
82
|
-
/**
|
|
83
|
-
* Пункты меню, стоящие за номерами списка, в порядке списка.
|
|
84
|
-
*
|
|
85
|
-
* Пункт ищется в подменю пунктов полосы, вглубь папок, и берётся первый со ссылкой: избранное,
|
|
86
|
-
* которое никуда не ведёт, — сломанное избранное. Номер без пункта пропускается, но из списка не
|
|
87
|
-
* уходит — это решает сервис, а не меню.
|
|
88
|
-
*/
|
|
89
53
|
function findSideMenuFavoriteItems(menu, ids) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return found;
|
|
98
|
-
}, []);
|
|
54
|
+
const byId = /* @__PURE__ */ new Map();
|
|
55
|
+
collectLinkedItems(menu.flatMap((item) => item.submenu ?? []), byId);
|
|
56
|
+
return ids.reduce((found, id) => {
|
|
57
|
+
const item = byId.get(id);
|
|
58
|
+
if (item) found.push(item);
|
|
59
|
+
return found;
|
|
60
|
+
}, []);
|
|
99
61
|
}
|
|
100
|
-
/**
|
|
101
|
-
* Пункт полосы, чьё подменю сейчас показано, если избранное у него включено.
|
|
102
|
-
*
|
|
103
|
-
* Избранное у каждого пункта своё и по умолчанию выключено: включает его потребитель флагом
|
|
104
|
-
* `favorites` пункта полосы. Показанный набор даёт меню — закреплённый или открытый наведением, —
|
|
105
|
-
* и пустой набор не принадлежит никому: подменю без списка не показывает ничьё избранное.
|
|
106
|
-
*
|
|
107
|
-
* Раздел узнаётся сначала по самому набору, затем по номеру его первого пункта: приложение вправе
|
|
108
|
-
* передать меню заново теми же пунктами в новых объектах — при смене языка или прав, — и набор,
|
|
109
|
-
* который подменю ещё держит, перестаёт совпадать с пунктами полосы по ссылке. Номера пунктов
|
|
110
|
-
* подменю единственны на всё меню — это обязанность потребителя.
|
|
111
|
-
*/
|
|
112
62
|
function sideMenuFavoritesSection(menu, shown) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const section = menu.find((item) => item.submenu === shown) ??
|
|
118
|
-
menu.find((item) => !!item.submenu?.some((child) => child.id === first.id));
|
|
119
|
-
return section?.favorites ? section : null;
|
|
63
|
+
const first = shown[0];
|
|
64
|
+
if (!first) return null;
|
|
65
|
+
const section = menu.find((item) => item.submenu === shown) ?? menu.find((item) => !!item.submenu?.some((child) => child.id === first.id));
|
|
66
|
+
return section?.favorites ? section : null;
|
|
120
67
|
}
|
|
121
|
-
/**
|
|
122
|
-
* Строку отпустили за пределами панели. Пока её тянули, уход указателя с панели не закрывал
|
|
123
|
-
* подменю, открытое наведением, — после броска он должен сработать так, будто случился сейчас.
|
|
124
|
-
*/
|
|
125
68
|
function isSideMenuDropOutside(panel, point) {
|
|
126
|
-
|
|
69
|
+
return point.x < panel.left || point.x > panel.right || point.y < panel.top || point.y > panel.bottom;
|
|
127
70
|
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Отбор пунктов подменю по подстроке подписи.
|
|
131
|
-
*
|
|
132
|
-
* Отбор спускается внутрь папок на любую глубину: потребитель кладёт в папки то, что человек и ищет
|
|
133
|
-
* по имени, и по одному верхнему уровню такой пункт не нашёлся бы.
|
|
134
|
-
*
|
|
135
|
-
* В выдаче стоят только строки, содержащие запрос. Папка остаётся путём к совпавшим детям, а её
|
|
136
|
-
* состав отбирается тем же правилом: иначе одно совпадение по имени папки вытаскивало бы весь её
|
|
137
|
-
* состав. Папка, совпавшая только по имени, остаётся одной строкой без детей.
|
|
138
|
-
*
|
|
139
|
-
* Отобранная папка — новый объект: правка на месте переписала бы набор потребителя, и стёртый
|
|
140
|
-
* запрос вернул бы урезанное меню.
|
|
141
|
-
*/
|
|
142
71
|
function filterSideMenuItems(items, query) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
72
|
+
const needle = query.trim().toLowerCase();
|
|
73
|
+
if (needle === "") return [...items];
|
|
74
|
+
return items.reduce((kept, item) => {
|
|
75
|
+
const isFolder = Boolean(item.submenu?.length);
|
|
76
|
+
const inside = isFolder ? filterSideMenuItems(item.submenu ?? [], query) : [];
|
|
77
|
+
if (inside.length) {
|
|
78
|
+
kept.push({
|
|
79
|
+
...item,
|
|
80
|
+
submenu: inside
|
|
81
|
+
});
|
|
82
|
+
return kept;
|
|
83
|
+
}
|
|
84
|
+
if (item.name?.toLowerCase().includes(needle)) kept.push(isFolder ? {
|
|
85
|
+
...item,
|
|
86
|
+
submenu: []
|
|
87
|
+
} : item);
|
|
88
|
+
return kept;
|
|
89
|
+
}, []);
|
|
159
90
|
}
|
|
160
|
-
/**
|
|
161
|
-
* Папки отобранного списка — те, что должны стоять раскрытыми. Возвращаются номера, а не пункты:
|
|
162
|
-
* отобранный список пересобирается на каждую букву запроса, и ссылка на пункт этого не переживает.
|
|
163
|
-
*/
|
|
164
91
|
function sideMenuIdsToExpand(items) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
return ids;
|
|
170
|
-
}, []);
|
|
92
|
+
return items.reduce((ids, item) => {
|
|
93
|
+
if (item.submenu?.length) ids.push(item.id, ...sideMenuIdsToExpand(item.submenu));
|
|
94
|
+
return ids;
|
|
95
|
+
}, []);
|
|
171
96
|
}
|
|
172
|
-
/**
|
|
173
|
-
* Пределы ширины подменю в пикселях. Уже нижнего не помещается ни одна подпись пункта, шире
|
|
174
|
-
* верхнего подменю закрывает содержимое страницы.
|
|
175
|
-
*/
|
|
176
97
|
const RT_SIDE_MENU_WIDTH_MIN = 120;
|
|
177
98
|
const RT_SIDE_MENU_WIDTH_MAX = 480;
|
|
178
|
-
/** Шаг ширины с клавиатуры: стрелку держат нажатой, и крупный шаг проскакивал бы подпись целиком. */
|
|
179
99
|
const RT_SIDE_MENU_WIDTH_STEP = 16;
|
|
180
|
-
/** Приведение ширины к пределам. */
|
|
181
100
|
function clampSideMenuWidth(width) {
|
|
182
|
-
|
|
101
|
+
return Math.min(480, Math.max(120, width));
|
|
183
102
|
}
|
|
184
|
-
/**
|
|
185
|
-
* Резка подписи на совпавшие и несовпавшие куски.
|
|
186
|
-
*
|
|
187
|
-
* Отмечаются все вхождения: отмеченное одно первое читается как «второго нет». Сравнение без учёта
|
|
188
|
-
* регистра, а куски режутся из оригинала — приведение к нижнему регистру переписало бы названия.
|
|
189
|
-
*/
|
|
190
103
|
function splitSideMenuTitle(name, query) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
104
|
+
if (name === "") return [];
|
|
105
|
+
const needle = query.trim().toLowerCase();
|
|
106
|
+
if (needle === "") return [{
|
|
107
|
+
text: name,
|
|
108
|
+
matched: false
|
|
109
|
+
}];
|
|
110
|
+
const haystack = name.toLowerCase();
|
|
111
|
+
const parts = [];
|
|
112
|
+
let from = 0;
|
|
113
|
+
for (let at = haystack.indexOf(needle, from); at !== -1; at = haystack.indexOf(needle, from)) {
|
|
114
|
+
if (at > from) parts.push({
|
|
115
|
+
text: name.slice(from, at),
|
|
116
|
+
matched: false
|
|
117
|
+
});
|
|
118
|
+
parts.push({
|
|
119
|
+
text: name.slice(at, at + needle.length),
|
|
120
|
+
matched: true
|
|
121
|
+
});
|
|
122
|
+
from = at + needle.length;
|
|
123
|
+
}
|
|
124
|
+
if (from < name.length) parts.push({
|
|
125
|
+
text: name.slice(from),
|
|
126
|
+
matched: false
|
|
127
|
+
});
|
|
128
|
+
return parts;
|
|
129
|
+
}
|
|
130
|
+
function splitTitleByWords(name, query) {
|
|
131
|
+
return query.split(/\s+/).filter((word) => word !== "").reduce((parts, word) => parts.flatMap((part) => part.matched ? [part] : splitSideMenuTitle(part.text, word)), splitSideMenuTitle(name, ""));
|
|
212
132
|
}
|
|
213
|
-
/**
|
|
214
|
-
* Пункты подменю в том порядке, в каком они стоят на экране. Внутрь папки список спускается, только
|
|
215
|
-
* если та раскрыта: ходьба стрелками идёт по видимому, а не по всему набору.
|
|
216
|
-
*/
|
|
217
133
|
function walkSideMenuItems(items, expandedIds) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
return walk;
|
|
224
|
-
}, []);
|
|
134
|
+
return items.reduce((walk, item) => {
|
|
135
|
+
walk.push(item);
|
|
136
|
+
if (item.submenu?.length && expandedIds.includes(item.id)) walk.push(...walkSideMenuItems(item.submenu, expandedIds));
|
|
137
|
+
return walk;
|
|
138
|
+
}, []);
|
|
225
139
|
}
|
|
226
|
-
/**
|
|
227
|
-
* Куда уходит подсветка на шаг стрелкой. Считается по номеру пункта: видимый список пересобирается
|
|
228
|
-
* на каждую букву запроса. Без подсветки вниз берёт первый пункт, вверх — последний. У краёв ходьба
|
|
229
|
-
* останавливается: заворот уводил бы взгляд через всю панель.
|
|
230
|
-
*/
|
|
231
140
|
function stepSideMenuHighlight(walk, highlightedId, step) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
if (at === -1) {
|
|
237
|
-
return step > 0 ? walk[0].id : walk[walk.length - 1].id;
|
|
238
|
-
}
|
|
239
|
-
return walk[Math.min(walk.length - 1, Math.max(0, at + step))].id;
|
|
141
|
+
if (walk.length === 0) return null;
|
|
142
|
+
const at = walk.findIndex((item) => item.id === highlightedId);
|
|
143
|
+
if (at === -1) return step > 0 ? walk[0].id : walk[walk.length - 1].id;
|
|
144
|
+
return walk[Math.min(walk.length - 1, Math.max(0, at + step))].id;
|
|
240
145
|
}
|
|
241
|
-
/**
|
|
242
|
-
* Тяга ширины подменю указательными событиями: мышиных палец и перо не дают. Слушатели висят на
|
|
243
|
-
* ручке, а держит их захват указателя — слушатель на документе терял бы движение над чужим кадром.
|
|
244
|
-
* Указатель, отнятый средой, кончает тягу так же, как отпускание.
|
|
245
|
-
*
|
|
246
|
-
* Возвращает снятие слушателей. Пустое значение — тянуть нечем.
|
|
247
|
-
*/
|
|
248
146
|
function startSideMenuWidthDrag(event, startWidth, listen, hooks) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
// Захват снимается и без отпускания — ручку убрали из разметки; тогда конец тяги — сама потеря.
|
|
268
|
-
const stopLost = listen(handle, 'lostpointercapture', () => hooks.onEnd());
|
|
269
|
-
return () => {
|
|
270
|
-
stopMove();
|
|
271
|
-
stopUp();
|
|
272
|
-
stopCancel();
|
|
273
|
-
stopLost();
|
|
274
|
-
if (typeof handle.releasePointerCapture === 'function' && handle.hasPointerCapture(pointerId)) {
|
|
275
|
-
handle.releasePointerCapture(pointerId);
|
|
276
|
-
}
|
|
277
|
-
};
|
|
147
|
+
const handle = event.currentTarget;
|
|
148
|
+
if (!(handle instanceof HTMLElement) || event.button !== 0) return null;
|
|
149
|
+
const pointerId = event.pointerId;
|
|
150
|
+
const startX = event.clientX;
|
|
151
|
+
if (typeof handle.setPointerCapture === "function") handle.setPointerCapture(pointerId);
|
|
152
|
+
const stopMove = listen(handle, "pointermove", (moveEvent) => {
|
|
153
|
+
if (moveEvent.pointerId === pointerId) hooks.onWidth(clampSideMenuWidth(startWidth + moveEvent.clientX - startX));
|
|
154
|
+
});
|
|
155
|
+
const stopUp = listen(handle, "pointerup", () => hooks.onEnd());
|
|
156
|
+
const stopCancel = listen(handle, "pointercancel", () => hooks.onEnd());
|
|
157
|
+
const stopLost = listen(handle, "lostpointercapture", () => hooks.onEnd());
|
|
158
|
+
return () => {
|
|
159
|
+
stopMove();
|
|
160
|
+
stopUp();
|
|
161
|
+
stopCancel();
|
|
162
|
+
stopLost();
|
|
163
|
+
if (typeof handle.releasePointerCapture === "function" && handle.hasPointerCapture(pointerId)) handle.releasePointerCapture(pointerId);
|
|
164
|
+
};
|
|
278
165
|
}
|
|
279
|
-
/**
|
|
280
|
-
* Ширина, которой панель нарисована. Панели нет или раскладка не посчитана — нижний предел: с нуля
|
|
281
|
-
* тяга уводила бы ширину в отрицательные числа.
|
|
282
|
-
*/
|
|
283
166
|
function drawnSideMenuWidth(panel) {
|
|
284
|
-
|
|
285
|
-
|
|
167
|
+
const width = panel?.getBoundingClientRect().width ?? 0;
|
|
168
|
+
return width > 0 ? width : 120;
|
|
286
169
|
}
|
|
287
|
-
/**
|
|
288
|
-
* Число, которое уходит наружу по концу тяги: большее из натянутого и нарисованного. Нижний предел
|
|
289
|
-
* держит оформление, и панель не бывает уже его, даже если рука ушла левее.
|
|
290
|
-
*/
|
|
291
170
|
function reportedSideMenuWidth(dragged, panel) {
|
|
292
|
-
|
|
171
|
+
return Math.max(dragged, drawnSideMenuWidth(panel));
|
|
293
172
|
}
|
|
294
|
-
/**
|
|
295
|
-
* Новая ширина по нажатой клавише. Пустое значение — клавиша не о ширине, и умолчание не отменяется:
|
|
296
|
-
* иначе ручка съедала бы табуляцию. Влево значит уже при любом направлении письма: ручка стоит у
|
|
297
|
-
* правого края панели.
|
|
298
|
-
*/
|
|
299
173
|
function sideMenuWidthByKey(key, width) {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
case 'End':
|
|
308
|
-
return RT_SIDE_MENU_WIDTH_MAX;
|
|
309
|
-
default:
|
|
310
|
-
return null;
|
|
311
|
-
}
|
|
174
|
+
switch (key) {
|
|
175
|
+
case "ArrowRight": return clampSideMenuWidth(width + 16);
|
|
176
|
+
case "ArrowLeft": return clampSideMenuWidth(width - 16);
|
|
177
|
+
case "Home": return 120;
|
|
178
|
+
case "End": return 480;
|
|
179
|
+
default: return null;
|
|
180
|
+
}
|
|
312
181
|
}
|
|
313
|
-
/**
|
|
314
|
-
* Что показывает закреплённое подменю: выбранный человеком раздел, а пока выбора нет — раздел
|
|
315
|
-
* активного адреса. Выбор впереди активности: иначе до соседнего раздела не добраться.
|
|
316
|
-
*/
|
|
317
182
|
function pinnedSideMenuItems(picked, activeIds, items) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
}
|
|
321
|
-
return items.find((item) => activeIds.includes(item.id) && !!item.submenu?.length)?.submenu ?? [];
|
|
183
|
+
if (picked?.length) return picked;
|
|
184
|
+
return items.find((item) => activeIds.includes(item.id) && !!item.submenu?.length)?.submenu ?? [];
|
|
322
185
|
}
|
|
323
|
-
/**
|
|
324
|
-
* Нажатие, которое браузер открывает сам по адресу ссылки: не левой кнопкой или с клавишей —
|
|
325
|
-
* новая вкладка, окно, загрузка. Строка подменю такое нажатие не перехватывает.
|
|
326
|
-
*/
|
|
327
186
|
function sideMenuPressOpensInBrowser(event) {
|
|
328
|
-
|
|
329
|
-
|
|
187
|
+
const withKey = [
|
|
188
|
+
event.ctrlKey,
|
|
189
|
+
event.metaKey,
|
|
190
|
+
event.shiftKey,
|
|
191
|
+
event.altKey
|
|
192
|
+
].some(Boolean);
|
|
193
|
+
return event.button !== 0 || withKey;
|
|
330
194
|
}
|
|
331
|
-
|
|
332
|
-
/** Номер меню, которому приложение своего не задало. */
|
|
333
|
-
const RT_SIDE_MENU_DEFAULT_ID = 'main';
|
|
334
|
-
/**
|
|
335
|
-
* Номер меню, под которым лежат его настройки. Пустой — тот же, что не заданный: атрибут без
|
|
336
|
-
* значения даёт пустую строку, и настройки легли бы под ключ, которого никто не называл.
|
|
337
|
-
*/
|
|
195
|
+
const RT_SIDE_MENU_DEFAULT_ID = "main";
|
|
338
196
|
function normalizeSideMenuId(menuId) {
|
|
339
|
-
|
|
197
|
+
return menuId?.trim() || "main";
|
|
340
198
|
}
|
|
341
199
|
function isSubMenuMode(value) {
|
|
342
|
-
|
|
200
|
+
return value === "hover" || value === "pinned";
|
|
343
201
|
}
|
|
344
|
-
/**
|
|
345
|
-
* Настройки одного меню из того, что лежит под его номером. Недопустимое поле читается как
|
|
346
|
-
* отсутствие значения, соседние поля остаются: сломанная ширина не стирает режим. Незнакомые поля
|
|
347
|
-
* не удаляются. Ширина приводится к пределам подменю, списки избранного — к номерам без повторов.
|
|
348
|
-
*/
|
|
349
202
|
function normalizeSideMenuSettings(value) {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
else {
|
|
364
|
-
delete settings.subMenuWidth;
|
|
365
|
-
}
|
|
366
|
-
// Список — только строки и числа без повторов; не массив читается отсутствием списка.
|
|
367
|
-
if (Array.isArray(favorites)) {
|
|
368
|
-
settings.favorites = normalizeSideMenuFavorites(favorites);
|
|
369
|
-
}
|
|
370
|
-
else {
|
|
371
|
-
delete settings.favorites;
|
|
372
|
-
}
|
|
373
|
-
if (Array.isArray(collapsed)) {
|
|
374
|
-
settings.favoritesCollapsed = normalizeSideMenuFavorites(collapsed);
|
|
375
|
-
}
|
|
376
|
-
else {
|
|
377
|
-
delete settings.favoritesCollapsed;
|
|
378
|
-
}
|
|
379
|
-
return settings;
|
|
203
|
+
if (!isRecord(value)) return {};
|
|
204
|
+
const settings = { ...value };
|
|
205
|
+
const width = value["subMenuWidth"];
|
|
206
|
+
const favorites = value["favorites"];
|
|
207
|
+
const collapsed = value["favoritesCollapsed"];
|
|
208
|
+
if (!isSubMenuMode(value["subMenuMode"])) delete settings.subMenuMode;
|
|
209
|
+
if (typeof width === "number" && Number.isFinite(width)) settings.subMenuWidth = clampSideMenuWidth(width);
|
|
210
|
+
else delete settings.subMenuWidth;
|
|
211
|
+
if (Array.isArray(favorites)) settings.favorites = normalizeSideMenuFavorites(favorites);
|
|
212
|
+
else delete settings.favorites;
|
|
213
|
+
if (Array.isArray(collapsed)) settings.favoritesCollapsed = normalizeSideMenuFavorites(collapsed);
|
|
214
|
+
else delete settings.favoritesCollapsed;
|
|
215
|
+
return settings;
|
|
380
216
|
}
|
|
381
|
-
/** Запись хранилища как объект. Не JSON, не объект, пустое хранилище — одинаково пустая запись. */
|
|
382
217
|
function parseSideMenuSettingsRecord(raw) {
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
catch {
|
|
391
|
-
return {};
|
|
392
|
-
}
|
|
218
|
+
if (raw === null) return {};
|
|
219
|
+
try {
|
|
220
|
+
const value = JSON.parse(raw);
|
|
221
|
+
return isRecord(value) ? value : {};
|
|
222
|
+
} catch {
|
|
223
|
+
return {};
|
|
224
|
+
}
|
|
393
225
|
}
|
|
394
|
-
/**
|
|
395
|
-
* Настройки всех меню из записи. Меню, чьё значение не объект, пропускается: сломанный угол одного
|
|
396
|
-
* меню не стирает соседние.
|
|
397
|
-
*/
|
|
398
226
|
function readSideMenuSettings(record) {
|
|
399
|
-
|
|
400
|
-
.filter(([, settings]) => isRecord(settings))
|
|
401
|
-
.map(([menuId, settings]) => [menuId, normalizeSideMenuSettings(settings)]));
|
|
227
|
+
return Object.fromEntries(Object.entries(record).filter(([, settings]) => isRecord(settings)).map(([menuId, settings]) => [menuId, normalizeSideMenuSettings(settings)]));
|
|
402
228
|
}
|
|
403
|
-
/**
|
|
404
|
-
* Запись с правкой полей одного меню. Остальные меню и поля уходят такими, какими лежали, даже
|
|
405
|
-
* сломанные: кит правит только то, о чём его попросили.
|
|
406
|
-
*/
|
|
407
229
|
function patchSideMenuSettings(record, menuId, patch) {
|
|
408
|
-
|
|
409
|
-
|
|
230
|
+
const current = record[menuId];
|
|
231
|
+
return {
|
|
232
|
+
...record,
|
|
233
|
+
[menuId]: {
|
|
234
|
+
...isRecord(current) ? current : {},
|
|
235
|
+
...patch
|
|
236
|
+
}
|
|
237
|
+
};
|
|
410
238
|
}
|
|
411
|
-
/** Запись без настроек одного меню. */
|
|
412
239
|
function omitSideMenuSettings(record, menuId) {
|
|
413
|
-
|
|
240
|
+
return Object.fromEntries(Object.entries(record).filter(([id]) => id !== menuId));
|
|
414
241
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
242
|
+
const DEFAULT_FAVORITES_ICONS = {
|
|
243
|
+
remove: "trash",
|
|
244
|
+
drag: "arrows-v"
|
|
245
|
+
};
|
|
246
|
+
const RT_SIDE_MENU_SETTINGS_CONFIG = new InjectionToken("RT_SIDE_MENU_SETTINGS_CONFIG");
|
|
420
247
|
function cached(cache, menuId, read) {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
248
|
+
const id = normalizeSideMenuId(menuId);
|
|
249
|
+
let value = cache.get(id);
|
|
250
|
+
if (!value) {
|
|
251
|
+
value = computed(() => read(id));
|
|
252
|
+
cache.set(id, value);
|
|
253
|
+
}
|
|
254
|
+
return value;
|
|
428
255
|
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
if (!this.#storage) {
|
|
575
|
-
return null;
|
|
576
|
-
}
|
|
577
|
-
try {
|
|
578
|
-
return parseSideMenuSettingsRecord(this.#storage.getItem(this.#key));
|
|
579
|
-
}
|
|
580
|
-
catch {
|
|
581
|
-
return null;
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtSideMenuSettingsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
585
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtSideMenuSettingsService }); }
|
|
586
|
-
}
|
|
587
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtSideMenuSettingsService, decorators: [{
|
|
588
|
-
type: Injectable
|
|
589
|
-
}], ctorParameters: () => [] });
|
|
590
|
-
/**
|
|
591
|
-
* Сервис настроек бокового меню для приложения.
|
|
592
|
-
*
|
|
593
|
-
* ```ts
|
|
594
|
-
* bootstrapApplication(App, { providers: [provideRtSideMenuSettings()] });
|
|
595
|
-
* ```
|
|
596
|
-
*/
|
|
256
|
+
var RtSideMenuSettingsService = class RtSideMenuSettingsService {
|
|
257
|
+
#config;
|
|
258
|
+
#storage;
|
|
259
|
+
#key;
|
|
260
|
+
#menus;
|
|
261
|
+
#modes;
|
|
262
|
+
#widths;
|
|
263
|
+
#favorites;
|
|
264
|
+
#collapsed;
|
|
265
|
+
#record;
|
|
266
|
+
#unsaved;
|
|
267
|
+
#settings;
|
|
268
|
+
constructor() {
|
|
269
|
+
this.#config = inject(RT_SIDE_MENU_SETTINGS_CONFIG, { optional: true }) ?? {};
|
|
270
|
+
this.#storage = inject(LOCAL_STORAGE, { optional: true }) ?? null;
|
|
271
|
+
this.#key = this.#config.storageKey?.trim() || ERtStorageKeys.SideMenu;
|
|
272
|
+
this.#menus = /* @__PURE__ */ new Map();
|
|
273
|
+
this.#modes = /* @__PURE__ */ new Map();
|
|
274
|
+
this.#widths = /* @__PURE__ */ new Map();
|
|
275
|
+
this.#favorites = /* @__PURE__ */ new Map();
|
|
276
|
+
this.#collapsed = /* @__PURE__ */ new Map();
|
|
277
|
+
this.#record = this.#load() ?? {};
|
|
278
|
+
this.#unsaved = false;
|
|
279
|
+
this.#settings = signal(readSideMenuSettings(this.#record), ...ngDevMode ? [{ debugName: "#settings" }] : /* istanbul ignore next */ []);
|
|
280
|
+
this.favoritesIcons = {
|
|
281
|
+
...DEFAULT_FAVORITES_ICONS,
|
|
282
|
+
...this.#config.icons
|
|
283
|
+
};
|
|
284
|
+
this.menuIds = computed(() => Object.keys(this.#settings()), ...ngDevMode ? [{ debugName: "menuIds" }] : /* istanbul ignore next */ []);
|
|
285
|
+
if (!inject(PlatformService).isPlatformBrowser) return;
|
|
286
|
+
const view = inject(WINDOW);
|
|
287
|
+
const onStorage = (event) => {
|
|
288
|
+
if (event.key === this.#key || event.key === null) {
|
|
289
|
+
this.#unsaved = false;
|
|
290
|
+
this.#apply(this.#fresh());
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
view.addEventListener("storage", onStorage);
|
|
294
|
+
inject(DestroyRef).onDestroy(() => view.removeEventListener("storage", onStorage));
|
|
295
|
+
}
|
|
296
|
+
settings(menuId) {
|
|
297
|
+
return cached(this.#menus, menuId, (id) => this.#settings()[id] ?? {});
|
|
298
|
+
}
|
|
299
|
+
subMenuMode(menuId) {
|
|
300
|
+
return cached(this.#modes, menuId, (id) => this.#settings()[id]?.subMenuMode ?? "hover");
|
|
301
|
+
}
|
|
302
|
+
subMenuWidth(menuId) {
|
|
303
|
+
return cached(this.#widths, menuId, (id) => this.#settings()[id]?.subMenuWidth ?? null);
|
|
304
|
+
}
|
|
305
|
+
favoriteIds(menuId) {
|
|
306
|
+
return cached(this.#favorites, menuId, (id) => this.#settings()[id]?.favorites ?? []);
|
|
307
|
+
}
|
|
308
|
+
favoritesCollapsed(menuId) {
|
|
309
|
+
return cached(this.#collapsed, menuId, (id) => this.#settings()[id]?.favoritesCollapsed ?? []);
|
|
310
|
+
}
|
|
311
|
+
setFavoritesCollapsed(menuId, sectionId, collapsed) {
|
|
312
|
+
const others = (this.#freshSettings(menuId).favoritesCollapsed ?? []).filter((id) => id !== sectionId);
|
|
313
|
+
this.#update(menuId, { favoritesCollapsed: collapsed ? [...others, sectionId] : others });
|
|
314
|
+
}
|
|
315
|
+
toggleFavorite(menuId, id) {
|
|
316
|
+
this.#updateFavorites(menuId, (ids) => ids.includes(id) ? ids.filter((kept) => kept !== id) : [...ids, id]);
|
|
317
|
+
}
|
|
318
|
+
removeFavorite(menuId, id) {
|
|
319
|
+
this.#updateFavorites(menuId, (ids) => ids.filter((kept) => kept !== id));
|
|
320
|
+
}
|
|
321
|
+
moveVisibleSideMenuFavorite(menuId, visibleIds, from, to) {
|
|
322
|
+
this.#updateFavorites(menuId, (ids) => moveVisibleSideMenuFavorite(ids, visibleIds, from, to));
|
|
323
|
+
}
|
|
324
|
+
setFavorites(menuId, ids) {
|
|
325
|
+
this.#updateFavorites(menuId, () => normalizeSideMenuFavorites(ids));
|
|
326
|
+
}
|
|
327
|
+
setSubMenuMode(menuId, mode) {
|
|
328
|
+
this.#update(menuId, { subMenuMode: mode });
|
|
329
|
+
}
|
|
330
|
+
setSubMenuWidth(menuId, width) {
|
|
331
|
+
this.#update(menuId, { subMenuWidth: clampSideMenuWidth(width) });
|
|
332
|
+
}
|
|
333
|
+
deleteSettings(menuId) {
|
|
334
|
+
this.#commit(omitSideMenuSettings(this.#fresh(), normalizeSideMenuId(menuId)));
|
|
335
|
+
}
|
|
336
|
+
#update(menuId, patch) {
|
|
337
|
+
const record = this.#fresh();
|
|
338
|
+
const id = normalizeSideMenuId(menuId);
|
|
339
|
+
this.#commit(patchSideMenuSettings(record, id, {
|
|
340
|
+
...normalizeSideMenuSettings(record[id]),
|
|
341
|
+
...patch
|
|
342
|
+
}));
|
|
343
|
+
}
|
|
344
|
+
#updateFavorites(menuId, next) {
|
|
345
|
+
this.#update(menuId, { favorites: next([...this.#freshSettings(menuId).favorites ?? []]) });
|
|
346
|
+
}
|
|
347
|
+
#freshSettings(menuId) {
|
|
348
|
+
return normalizeSideMenuSettings(this.#fresh()[normalizeSideMenuId(menuId)]);
|
|
349
|
+
}
|
|
350
|
+
#commit(record) {
|
|
351
|
+
this.#apply(record);
|
|
352
|
+
try {
|
|
353
|
+
this.#storage?.setItem(this.#key, JSON.stringify(record));
|
|
354
|
+
this.#unsaved = false;
|
|
355
|
+
} catch {
|
|
356
|
+
this.#unsaved = true;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
#apply(record) {
|
|
360
|
+
this.#record = record;
|
|
361
|
+
this.#settings.set(readSideMenuSettings(record));
|
|
362
|
+
}
|
|
363
|
+
#fresh() {
|
|
364
|
+
return this.#unsaved ? this.#record : this.#load() ?? this.#record;
|
|
365
|
+
}
|
|
366
|
+
#load() {
|
|
367
|
+
if (!this.#storage) return null;
|
|
368
|
+
try {
|
|
369
|
+
return parseSideMenuSettingsRecord(this.#storage.getItem(this.#key));
|
|
370
|
+
} catch {
|
|
371
|
+
return null;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
static {
|
|
375
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
376
|
+
minVersion: "12.0.0",
|
|
377
|
+
version: "22.2.2",
|
|
378
|
+
ngImport: i0,
|
|
379
|
+
type: RtSideMenuSettingsService,
|
|
380
|
+
deps: [],
|
|
381
|
+
target: i0.ɵɵFactoryTarget.Injectable
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
static {
|
|
385
|
+
this.ɵprov = i0.ɵɵngDeclareInjectable({
|
|
386
|
+
minVersion: "12.0.0",
|
|
387
|
+
version: "22.2.2",
|
|
388
|
+
ngImport: i0,
|
|
389
|
+
type: RtSideMenuSettingsService
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
394
|
+
minVersion: "12.0.0",
|
|
395
|
+
version: "22.2.2",
|
|
396
|
+
ngImport: i0,
|
|
397
|
+
type: RtSideMenuSettingsService,
|
|
398
|
+
decorators: [{ type: Injectable }],
|
|
399
|
+
ctorParameters: () => []
|
|
400
|
+
});
|
|
597
401
|
function provideRtSideMenuSettings(config = {}) {
|
|
598
|
-
|
|
402
|
+
return makeEnvironmentProviders([{
|
|
403
|
+
provide: RT_SIDE_MENU_SETTINGS_CONFIG,
|
|
404
|
+
useValue: config
|
|
405
|
+
}, RtSideMenuSettingsService]);
|
|
599
406
|
}
|
|
600
|
-
|
|
601
|
-
const RT_SIDE_MENU = new InjectionToken('RT_SIDE_MENU');
|
|
602
|
-
|
|
603
|
-
/**
|
|
604
|
-
* Адрес пункта так, как его строит ссылка роутера: относительно маршрута, на котором стоит меню.
|
|
605
|
-
* Им строка подменю и переходит, и подписывает `href` — для средней кнопки и копирования ссылки.
|
|
606
|
-
*/
|
|
407
|
+
const RT_SIDE_MENU = new InjectionToken("RT_SIDE_MENU");
|
|
607
408
|
function sideMenuLinkTree(router, route, link) {
|
|
608
|
-
|
|
609
|
-
}
|
|
610
|
-
/** `href` строки подменю. Переход строка делает сама: ссылка роутера не дала бы потребителю его взять. */
|
|
611
|
-
class RtSideMenuHrefPipe {
|
|
612
|
-
#router = inject(Router);
|
|
613
|
-
#route = inject(ActivatedRoute, { optional: true });
|
|
614
|
-
transform(link) {
|
|
615
|
-
return link ? this.#router.serializeUrl(sideMenuLinkTree(this.#router, this.#route, link)) : null;
|
|
616
|
-
}
|
|
617
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtSideMenuHrefPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
618
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.6", ngImport: i0, type: RtSideMenuHrefPipe, isStandalone: true, name: "rtSideMenuHref" }); }
|
|
409
|
+
return router.createUrlTree([link], { relativeTo: route ?? void 0 });
|
|
619
410
|
}
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
411
|
+
var RtSideMenuHrefPipe = class RtSideMenuHrefPipe {
|
|
412
|
+
#router = inject(Router);
|
|
413
|
+
#route = inject(ActivatedRoute, { optional: true });
|
|
414
|
+
transform(link) {
|
|
415
|
+
return link ? this.#router.serializeUrl(sideMenuLinkTree(this.#router, this.#route, link)) : null;
|
|
416
|
+
}
|
|
417
|
+
static {
|
|
418
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
419
|
+
minVersion: "12.0.0",
|
|
420
|
+
version: "22.2.2",
|
|
421
|
+
ngImport: i0,
|
|
422
|
+
type: RtSideMenuHrefPipe,
|
|
423
|
+
deps: [],
|
|
424
|
+
target: i0.ɵɵFactoryTarget.Pipe
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
static {
|
|
428
|
+
this.ɵpipe = i0.ɵɵngDeclarePipe({
|
|
429
|
+
minVersion: "14.0.0",
|
|
430
|
+
version: "22.2.2",
|
|
431
|
+
ngImport: i0,
|
|
432
|
+
type: RtSideMenuHrefPipe,
|
|
433
|
+
isStandalone: true,
|
|
434
|
+
name: "rtSideMenuHref"
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
};
|
|
438
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
439
|
+
minVersion: "12.0.0",
|
|
440
|
+
version: "22.2.2",
|
|
441
|
+
ngImport: i0,
|
|
442
|
+
type: RtSideMenuHrefPipe,
|
|
443
|
+
decorators: [{
|
|
444
|
+
type: Pipe,
|
|
445
|
+
args: [{ name: "rtSideMenuHref" }]
|
|
446
|
+
}]
|
|
447
|
+
});
|
|
632
448
|
function sideMenuIconName(icon) {
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
if (isKitIconName(icon)) {
|
|
637
|
-
return icon;
|
|
638
|
-
}
|
|
639
|
-
return materialPairOf(icon);
|
|
449
|
+
if (!icon) return null;
|
|
450
|
+
if (isKitIconName(icon)) return icon;
|
|
451
|
+
return materialPairOf(icon);
|
|
640
452
|
}
|
|
641
|
-
/**
|
|
642
|
-
* Имена значков меню, о которых оно должно предупредить: ни имени кита, ни пары в перечне. И значок
|
|
643
|
-
* пункта, и значок кнопки строки закрывает свой шаблон меню.
|
|
644
|
-
* Без предупреждения такой значок пуст, и пропуск не заметен. Обходит пункты на любую глубину;
|
|
645
|
-
* каждое имя — один раз.
|
|
646
|
-
*/
|
|
647
453
|
function unpairedSideMenuIcons(items, hasOwnIcon) {
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
}
|
|
659
|
-
};
|
|
660
|
-
walk(items);
|
|
661
|
-
return [...found];
|
|
454
|
+
const found = /* @__PURE__ */ new Set();
|
|
455
|
+
const walk = (list) => {
|
|
456
|
+
for (const item of list) {
|
|
457
|
+
if (!hasOwnIcon && item.icon && sideMenuIconName(item.icon) === null) found.add(item.icon);
|
|
458
|
+
if (!hasOwnIcon && item.iconButton?.icon && sideMenuIconName(item.iconButton.icon) === null) found.add(item.iconButton.icon);
|
|
459
|
+
walk(item.submenu ?? []);
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
walk(items);
|
|
463
|
+
return [...found];
|
|
662
464
|
}
|
|
663
|
-
/**
|
|
664
|
-
* Предупреждение разработчику приложения об именах из `unpairedSideMenuIcons`: имя без значка кита и
|
|
665
|
-
* без пары рисует пункт без значка, и пропуск без предупреждения не заметен.
|
|
666
|
-
*/
|
|
667
465
|
function warnUnpairedSideMenuIcons(menuId, items, hasOwnIcon) {
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
'Задайте имя кита или свой значок через <ng-template rtSideMenuIcon>.');
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
/** Значок пункта, который рисует кит: имя кита или пара имени Material; `null` — такого нет. */
|
|
678
|
-
class RtSideMenuIconPipe {
|
|
679
|
-
transform(icon) {
|
|
680
|
-
return sideMenuIconName(icon);
|
|
681
|
-
}
|
|
682
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtSideMenuIconPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
683
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.6", ngImport: i0, type: RtSideMenuIconPipe, isStandalone: true, name: "rtSideMenuIcon" }); }
|
|
684
|
-
}
|
|
685
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtSideMenuIconPipe, decorators: [{
|
|
686
|
-
type: Pipe,
|
|
687
|
-
args: [{
|
|
688
|
-
name: 'rtSideMenuIcon',
|
|
689
|
-
}]
|
|
690
|
-
}] });
|
|
691
|
-
|
|
692
|
-
/** Подпись пункта кусками: отмечено ровно то, чем она совпала с запросом поиска. */
|
|
693
|
-
class RtSideMenuTitlePartsPipe {
|
|
694
|
-
transform(name, query) {
|
|
695
|
-
return splitSideMenuTitle(name ?? '', query);
|
|
696
|
-
}
|
|
697
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtSideMenuTitlePartsPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
698
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.6", ngImport: i0, type: RtSideMenuTitlePartsPipe, isStandalone: true, name: "rtSideMenuTitleParts" }); }
|
|
699
|
-
}
|
|
700
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtSideMenuTitlePartsPipe, decorators: [{
|
|
701
|
-
type: Pipe,
|
|
702
|
-
args: [{
|
|
703
|
-
name: 'rtSideMenuTitleParts',
|
|
704
|
-
}]
|
|
705
|
-
}] });
|
|
706
|
-
|
|
707
|
-
const BEM_BLOCK$2 = 'rt-side-menu-sub-item';
|
|
708
|
-
/** Строка блока избранного и кнопка избранного в ней: фокус уходит на соседнюю до удаления строки. */
|
|
709
|
-
const FAVORITE_ROW = '.rt-side-menu-favorites__row';
|
|
710
|
-
const FAVORITE_BUTTON = '.rt-side-menu-sub-item__favorite button';
|
|
711
|
-
/**
|
|
712
|
-
* Строка подменю: пункт со ссылкой или папка со своими пунктами. Раскрытость, подсветку и запрос
|
|
713
|
-
* строка берёт у меню — своего состояния у неё нет.
|
|
714
|
-
*
|
|
715
|
-
* В разделе, где приложение включило избранное, у пункта со ссылкой стоит звезда; в строке блока
|
|
716
|
-
* избранного — кнопка «убрать» и слот `[rtSideMenuSubItemAction]`, куда блок кладёт ручку.
|
|
717
|
-
*/
|
|
718
|
-
class RtSideMenuSubItemComponent {
|
|
719
|
-
constructor() {
|
|
720
|
-
this.#settings = inject(RtSideMenuSettingsService, { optional: true });
|
|
721
|
-
this.#router = inject(Router);
|
|
722
|
-
this.#route = inject(ActivatedRoute, { optional: true });
|
|
723
|
-
this.#errors = inject(ErrorHandler);
|
|
724
|
-
this.menuRef = inject(RT_SIDE_MENU);
|
|
725
|
-
this.narrow = inject(BreakpointsService).narrow;
|
|
726
|
-
/** Значки кнопок избранного: из настроек провайдера, иначе из набора кита. */
|
|
727
|
-
this.favoritesIcons = this.#settings?.favoritesIcons ?? null;
|
|
728
|
-
this.addLabel = rtKitLabel('sideMenuFavoriteAdd');
|
|
729
|
-
this.removeLabel = rtKitLabel('sideMenuFavoriteRemove');
|
|
730
|
-
/** Избранное включено у раздела, чьё подменю показано, и приложение поставило настройки меню. */
|
|
731
|
-
this.favoritesOn = computed(() => !!this.#settings && sideMenuFavoritesSection(this.menuRef.menuItems(), this.menuRef.shownSubMenu()) !== null, /* @ts-ignore */
|
|
732
|
-
...(ngDevMode ? [{ debugName: "favoritesOn" }] : /* istanbul ignore next */ []));
|
|
733
|
-
this.favoriteIds = computed(() => this.#settings?.favoriteIds(this.menuRef.menuId())() ?? [], /* @ts-ignore */
|
|
734
|
-
...(ngDevMode ? [{ debugName: "favoriteIds" }] : /* istanbul ignore next */ []));
|
|
735
|
-
this.item = input.required(/* @ts-ignore */
|
|
736
|
-
...(ngDevMode ? [{ debugName: "item" }] : /* istanbul ignore next */ []));
|
|
737
|
-
/** Строка стоит в блоке избранного: вместо звезды — «убрать», без номера и подсветки клавиатуры. */
|
|
738
|
-
this.inFavorites = input(false, { ...(ngDevMode ? { debugName: "inFavorites" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
739
|
-
this.clickSubMenuAction = output();
|
|
740
|
-
this.clickSubMenuAdditionalAction = output();
|
|
741
|
-
}
|
|
742
|
-
#settings;
|
|
743
|
-
#router;
|
|
744
|
-
#route;
|
|
745
|
-
#errors;
|
|
746
|
-
/**
|
|
747
|
-
* Нажатие строки уходит потребителю раньше перехода. Потребитель, взявший переход на себя,
|
|
748
|
-
* отменяет умолчание события — тогда строка не переходит. Нажатие с клавишей или не левой
|
|
749
|
-
* кнопкой остаётся браузеру: он открывает адрес строки сам.
|
|
750
|
-
*/
|
|
751
|
-
onClickSubMenu(item, event) {
|
|
752
|
-
this.clickSubMenuAction.emit({ item, event });
|
|
753
|
-
if (event.defaultPrevented || !item.link || sideMenuPressOpensInBrowser(event)) {
|
|
754
|
-
return;
|
|
755
|
-
}
|
|
756
|
-
event.preventDefault();
|
|
757
|
-
// Отказ перехода уходит обработчику ошибок приложения, как у ссылки роутера.
|
|
758
|
-
this.#router
|
|
759
|
-
.navigateByUrl(sideMenuLinkTree(this.#router, this.#route, item.link))
|
|
760
|
-
.catch((error) => this.#errors.handleError(error));
|
|
761
|
-
}
|
|
762
|
-
/** Кнопка потребителя в строке: ни перехода по ссылке строки, ни закрытия подменю. */
|
|
763
|
-
onClickSubMenuAdditional(item, event) {
|
|
764
|
-
event.preventDefault();
|
|
765
|
-
event.stopPropagation();
|
|
766
|
-
this.clickSubMenuAdditionalAction.emit({ data: item.iconButton?.data, event });
|
|
767
|
-
}
|
|
768
|
-
/** Звезда переключает избранное и больше ничего: ни перехода, ни закрытия подменю. */
|
|
769
|
-
onToggleFavorite(item, event) {
|
|
770
|
-
event.preventDefault();
|
|
771
|
-
event.stopPropagation();
|
|
772
|
-
this.#settings?.toggleFavorite(this.menuRef.menuId(), item.id);
|
|
773
|
-
}
|
|
774
|
-
/**
|
|
775
|
-
* «Убрать» в строке блока. Фокус уходит на такую же кнопку соседней строки до того, как строка
|
|
776
|
-
* исчезнет: иначе он падал бы на страницу, и человек с клавиатуры терял бы место.
|
|
777
|
-
*/
|
|
778
|
-
onRemoveFavorite(item, event) {
|
|
779
|
-
event.preventDefault();
|
|
780
|
-
event.stopPropagation();
|
|
781
|
-
const row = event.target instanceof Element ? event.target.closest(FAVORITE_ROW) : null;
|
|
782
|
-
const neighbour = row?.nextElementSibling ?? row?.previousElementSibling;
|
|
783
|
-
neighbour?.querySelector(FAVORITE_BUTTON)?.focus();
|
|
784
|
-
this.#settings?.removeFavorite(this.menuRef.menuId(), item.id);
|
|
785
|
-
}
|
|
786
|
-
onToggleFolder(item) {
|
|
787
|
-
this.menuRef.toggleFolder(item);
|
|
788
|
-
}
|
|
789
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtSideMenuSubItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
790
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtSideMenuSubItemComponent, isStandalone: true, selector: "rt-side-menu-sub-item", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, inFavorites: { classPropertyName: "inFavorites", publicName: "inFavorites", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clickSubMenuAction: "clickSubMenuAction", clickSubMenuAdditionalAction: "clickSubMenuAdditionalAction" }, host: { classAttribute: "rt-side-menu-sub-item" }, ngImport: i0, template: "<ng-container rtBlock=\"rt-side-menu-sub-item\">\n <ng-container [ngTemplateOutlet]=\"rowTpl\" [ngTemplateOutletContext]=\"{ $implicit: item(), depth: 0 }\" />\n <ng-template #rowTpl let-row let-depth=\"depth\">\n @let isActive = menuRef.activeMenuIds().includes(row.id);\n @let isHighlighted = !inFavorites() && menuRef.highlightedMenuId() === row.id;\n @if (row.link) {\n <!--\n \u041D\u043E\u043C\u0435\u0440 \u043F\u0443\u043D\u043A\u0442\u0430 \u043D\u0430 \u0441\u0430\u043C\u043E\u0439 \u0441\u0442\u0440\u043E\u043A\u0435 \u2014 \u043F\u0440\u0438\u0437\u043D\u0430\u043A \u0434\u043B\u044F \u043F\u0440\u0430\u0432\u0438\u043B \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F: \u043F\u043E \u043D\u0435\u043C\u0443 \u043E\u043D\u043E \u043D\u0430\u0445\u043E\u0434\u0438\u0442 \u0441\u0442\u0440\u043E\u043A\u0443,\n \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440 \u0442\u0443, \u0447\u0442\u043E \u043E\u0442\u043A\u0440\u044B\u0432\u0430\u0435\u0442 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443 \u0440\u0430\u0437\u0434\u0435\u043B\u0430. \u0421\u0442\u043E\u0438\u0442 \u0438 \u0443 \u0441\u0442\u0440\u043E\u043A\u0438 \u0431\u043B\u043E\u043A\u0430 \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u0433\u043E.\n \u0421\u0442\u0440\u043E\u043A\u0430 \u0431\u043B\u043E\u043A\u0430 \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u0433\u043E \u0431\u0435\u0437 \u043D\u043E\u043C\u0435\u0440\u0430: \u043F\u043E \u043D\u043E\u043C\u0435\u0440\u0443 \u043A\u043B\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430 \u043D\u0430\u0436\u0438\u043C\u0430\u0435\u0442 \u0441\u0442\u0440\u043E\u043A\u0443 \u0441\u043F\u0438\u0441\u043A\u0430. \u0418 \u0431\u0435\u0437\n \u0440\u043E\u0434\u043D\u043E\u0433\u043E \u043F\u0435\u0440\u0435\u0442\u0430\u0441\u043A\u0438\u0432\u0430\u043D\u0438\u044F \u0441\u0441\u044B\u043B\u043A\u0438: \u043D\u0430\u0436\u0430\u0442\u0438\u0435 \u043D\u0430 \u0440\u0443\u0447\u043A\u0443 \u0432\u043D\u0443\u0442\u0440\u0438 \u0441\u0442\u0440\u043E\u043A\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0437\u0430\u0431\u0438\u0440\u0430\u043B \u0441\u0435\u0431\u0435,\n \u0438 \u043F\u0435\u0440\u0435\u0442\u0430\u0441\u043A\u0438\u0432\u0430\u043D\u0438\u0435 CDK \u043D\u0435 \u043D\u0430\u0447\u0438\u043D\u0430\u043B\u043E\u0441\u044C.\n -->\n <a\n rtElem=\"row\"\n qa-dataid=\"side-menu-sub-item\"\n [id]=\"inFavorites() ? null : row.id\"\n [attr.data-item-id]=\"row.id\"\n [attr.draggable]=\"inFavorites() ? 'false' : null\"\n [attr.href]=\"row.link | rtSideMenuHref\"\n [style.--rt-side-menu-sub-item-depth]=\"depth\"\n [rtMod]=\"{ active: isActive, highlighted: isHighlighted }\"\n [attr.aria-current]=\"isActive ? 'page' : null\"\n (click)=\"onClickSubMenu(row, $event)\">\n @if (row.icon) {\n <ng-container [ngTemplateOutlet]=\"iconTpl\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n }\n\n <span rtElem=\"title\" [rtTooltip]=\"menuRef.subMenuTooltipsShown() ? row.name : ''\">\n <!-- \u041A\u0443\u0441\u043E\u043A \u0431\u0435\u0437 \u043E\u0442\u043C\u0435\u0442\u043A\u0438 \u0442\u043E\u0436\u0435 \u0443\u0437\u0435\u043B: \u0433\u043E\u043B\u0430\u044F \u0438\u043D\u0442\u0435\u0440\u043F\u043E\u043B\u044F\u0446\u0438\u044F \u0440\u0430\u0437\u0440\u044B\u0432\u0430\u043B\u0430 \u0431\u044B \u043F\u043E\u0434\u043F\u0438\u0441\u044C \u043F\u0440\u043E\u0431\u0435\u043B\u0430\u043C\u0438. -->\n @for (part of row.name | rtSideMenuTitleParts: menuRef.subMenuQuery(); track $index) {\n @if (part.matched) {\n <span rtElem=\"match\">{{ part.text }}</span>\n } @else {\n <span rtElem=\"part\">{{ part.text }}</span>\n }\n }\n </span>\n\n <!--\n \u0421\u0442\u0440\u043E\u043A\u0430 \u0431\u043B\u043E\u043A\u0430 \u043D\u0435\u0441\u0451\u0442 \u00AB\u0443\u0431\u0440\u0430\u0442\u044C\u00BB, \u0430 \u043D\u0435 \u0437\u0432\u0435\u0437\u0434\u0443: \u0432\u0441\u0451 \u0432 \u0431\u043B\u043E\u043A\u0435 \u0443\u0436\u0435 \u0432 \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u043C. \u0417\u0432\u0435\u0437\u0434\u0430 \u2014\n \u0443 \u043F\u0443\u043D\u043A\u0442\u0430 \u0441\u043E \u0441\u0432\u043E\u0438\u043C \u0430\u0434\u0440\u0435\u0441\u043E\u043C \u0432 \u0440\u0430\u0437\u0434\u0435\u043B\u0435 \u0441 \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u044B\u043C: \u043F\u043E\u043B\u0430\u044F \u2014 \u043D\u0435 \u0432 \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u043C,\n \u0437\u0430\u043A\u0440\u0430\u0448\u0435\u043D\u043D\u0430\u044F \u0446\u0432\u0435\u0442\u043E\u043C \u0442\u0435\u043C\u044B \u2014 \u0432 \u043D\u0451\u043C. \u0418\u043C\u044F \u043A\u043D\u043E\u043F\u043A\u0438 \u043D\u0430\u0437\u044B\u0432\u0430\u0435\u0442 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0435\u0435 \u043D\u0430\u0436\u0430\u0442\u0438\u0435.\n -->\n @if (inFavorites() && favoritesIcons) {\n <rt-icon-button\n rtElem=\"favorite\"\n qa-dataid=\"side-menu-favorite-remove\"\n size=\"sm\"\n [rtMod]=\"{ remove: true }\"\n [icon]=\"favoritesIcons.remove\"\n [ariaLabel]=\"removeLabel()\"\n [tooltip]=\"narrow() || !menuRef.subMenuTooltipsShown() ? '' : removeLabel()\"\n (clicked)=\"onRemoveFavorite(row, $event)\" />\n } @else if (favoritesOn() && !row.favoriteDisabled) {\n @let isFavorite = favoriteIds().includes(row.id);\n <rt-icon-button\n rtElem=\"favorite\"\n qa-dataid=\"side-menu-favorite-star\"\n size=\"sm\"\n [rtMod]=\"{ on: isFavorite }\"\n [icon]=\"isFavorite ? 'star-fill' : 'star'\"\n [iconFill]=\"isFavorite\"\n [ariaLabel]=\"isFavorite ? removeLabel() : addLabel()\"\n [tooltip]=\"narrow() || !menuRef.subMenuTooltipsShown() ? '' : isFavorite ? removeLabel() : addLabel()\"\n (clicked)=\"onToggleFavorite(row, $event)\" />\n }\n\n <!-- \u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044F, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u0441\u0442\u0440\u043E\u043A\u0435 \u043F\u0435\u0440\u0435\u0434\u0430\u0451\u0442 \u0432\u043B\u0430\u0434\u0435\u043B\u0435\u0446: \u0431\u043B\u043E\u043A \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u0433\u043E \u043A\u043B\u0430\u0434\u0451\u0442 \u0441\u044E\u0434\u0430 \u0440\u0443\u0447\u043A\u0443. -->\n <ng-content select=\"[rtSideMenuSubItemAction]\" />\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B\u044F \u0432\u0438\u0434\u043D\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u0438 \u0441\u0442\u043E\u0438\u0442 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0439: \u043A\u043D\u043E\u043F\u043A\u0438 \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u0433\u043E \u0432\u0441\u0442\u0430\u044E\u0442 \u043F\u0435\u0440\u0435\u0434 \u043D\u0435\u0439. -->\n @if (row.iconButton?.icon; as buttonIcon) {\n <!-- \u0418\u043C\u044F \u0431\u0435\u0437 \u0437\u043D\u0430\u0447\u043A\u0430 \u043A\u0438\u0442\u0430 \u0431\u0435\u0440\u0451\u0442 \u0441\u0432\u043E\u0439 \u0448\u0430\u0431\u043B\u043E\u043D \u043C\u0435\u043D\u044E, \u043A\u0430\u043A \u0437\u043D\u0430\u0447\u043E\u043A \u0441\u0442\u0440\u043E\u043A\u0438. \u0411\u0435\u0437 \u0448\u0430\u0431\u043B\u043E\u043D\u0430 \u043A\u043D\u043E\u043F\u043A\u0430 \u043F\u0443\u0441\u0442\u0430 \u0438\n \u043D\u0435\u0437\u043D\u0430\u043A\u043E\u043C\u043E\u0433\u043E \u0438\u043C\u0435\u043D\u0438 \u0437\u043D\u0430\u0447\u043A\u0443 \u043D\u0435 \u043F\u0435\u0440\u0435\u0434\u0430\u0451\u0442: \u0437\u043D\u0430\u0447\u043A\u0430 \u0441 \u0442\u0430\u043A\u0438\u043C \u0438\u043C\u0435\u043D\u0435\u043C \u043D\u0435\u0442, \u0438 \u0436\u0434\u0430\u0442\u044C \u0435\u0433\u043E \u043D\u0435\u043A\u043E\u043C\u0443. -->\n @let buttonKitIcon = buttonIcon | rtSideMenuIcon;\n @let buttonOwnTpl = buttonKitIcon ? null : menuRef.ownIconTpl();\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"side-menu-sub-item-action\"\n size=\"sm\"\n [icon]=\"buttonKitIcon\"\n [iconFill]=\"menuRef.subItemIconFill()\"\n [ariaLabel]=\"row.name ?? ''\"\n (clicked)=\"onClickSubMenuAdditional(row, $event)\">\n @if (buttonOwnTpl) {\n <span rtElem=\"own-icon\" qa-dataid=\"side-menu-own-button-icon\" aria-hidden=\"true\">\n <ng-container\n [ngTemplateOutlet]=\"buttonOwnTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: row, icon: buttonIcon, slot: 'iconButton' }\" />\n </span>\n }\n </rt-icon-button>\n }\n </a>\n } @else if (row.submenu) {\n <!--\n \u041F\u0430\u043F\u043A\u0430 \u2014 \u0440\u0430\u0441\u043A\u0440\u044B\u0432\u0430\u044E\u0449\u0430\u044F\u0441\u044F \u043F\u0430\u043D\u0435\u043B\u044C \u043A\u0438\u0442\u0430. \u0420\u0438\u0441\u0443\u0435\u0442\u0441\u044F \u0438 \u0441 \u043F\u0443\u0441\u0442\u044B\u043C \u0441\u043E\u0441\u0442\u0430\u0432\u043E\u043C: \u043E\u0442\u0431\u043E\u0440 \u043E\u0441\u0442\u0430\u0432\u043B\u044F\u0435\u0442 \u0442\u0430\u043A\n \u0442\u0443, \u0447\u0442\u043E \u0441\u043E\u0432\u043F\u0430\u043B\u0430 \u043F\u043E\u0434\u043F\u0438\u0441\u044C\u044E. \u0428\u0435\u0432\u0440\u043E\u043D\u0430 \u0443 \u0442\u0430\u043A\u043E\u0439 \u043F\u0430\u043F\u043A\u0438 \u043D\u0435\u0442 \u2014 \u0440\u0430\u0441\u043A\u0440\u044B\u0432\u0430\u0442\u044C \u043D\u0435\u0447\u0435\u0433\u043E. \u0420\u0430\u0441\u043A\u0440\u044B\u0442\u0438\u0435\n \u0434\u0435\u0440\u0436\u0438\u0442 \u043C\u0435\u043D\u044E: \u043F\u0430\u043D\u0435\u043B\u044C \u0441\u043E\u043E\u0431\u0449\u0430\u0435\u0442 \u043E \u043D\u0430\u0436\u0430\u0442\u0438\u0438, \u043C\u0435\u043D\u044E \u043F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0430\u0435\u0442 \u043F\u0430\u043F\u043A\u0443. \u041A\u043D\u043E\u043F\u043A\u0435 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430\n \u043E\u0442\u0434\u0430\u043D \u043D\u043E\u043C\u0435\u0440 \u043F\u0443\u043D\u043A\u0442\u0430 \u2014 \u043F\u043E \u043D\u0435\u043C\u0443 \u043A\u043B\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430 \u043C\u0435\u043D\u044E \u043D\u0430\u0436\u0438\u043C\u0430\u0435\u0442 \u0441\u0442\u0440\u043E\u043A\u0443.\n -->\n @let isOpen = menuRef.expandedMenuIds().includes(row.id);\n <rt-expansion-panel\n rtElem=\"folder\"\n appearance=\"plain\"\n [headerId]=\"'' + row.id\"\n [attr.data-item-id]=\"row.id\"\n [hideToggle]=\"!row.submenu.length\"\n [expanded]=\"isOpen\"\n [style.--rt-side-menu-sub-item-depth]=\"depth\"\n [rtMod]=\"{ highlighted: isHighlighted }\"\n (expandedChange)=\"onToggleFolder(row)\">\n @if (row.icon) {\n <ng-container [ngTemplateOutlet]=\"iconTpl\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n }\n\n <span rtElem=\"title\" qa-dataid=\"side-menu-folder\" [rtTooltip]=\"menuRef.subMenuTooltipsShown() ? row.name : ''\">\n @for (part of row.name | rtSideMenuTitleParts: menuRef.subMenuQuery(); track $index) {\n @if (part.matched) {\n <span rtElem=\"match\">{{ part.text }}</span>\n } @else {\n <span rtElem=\"part\">{{ part.text }}</span>\n }\n }\n </span>\n\n <ng-template rtExpansionPanelContent>\n <div rtElem=\"children\" role=\"group\">\n @for (child of row.submenu; track child.id) {\n <ng-container [ngTemplateOutlet]=\"rowTpl\" [ngTemplateOutletContext]=\"{ $implicit: child, depth: depth + 1 }\" />\n }\n </div>\n </ng-template>\n </rt-expansion-panel>\n }\n </ng-template>\n\n <!-- \u0417\u043D\u0430\u0447\u043E\u043A \u0441\u0442\u0440\u043E\u043A\u0438: \u0438\u043C\u044F \u043A\u0438\u0442\u0430 \u0438\u043B\u0438 \u043F\u0430\u0440\u0430 \u0438\u043C\u0435\u043D\u0438 Material, \u0430 \u0438\u043C\u044F, \u043A\u043E\u0442\u043E\u0440\u043E\u0433\u043E \u043A\u0438\u0442 \u043D\u0435 \u0440\u0438\u0441\u0443\u0435\u0442, \u2014 \u0441\u0432\u043E\u0439 \u0448\u0430\u0431\u043B\u043E\u043D \u043C\u0435\u043D\u044E. -->\n <ng-template #iconTpl let-row>\n @let kitIcon = row.icon | rtSideMenuIcon;\n @if (kitIcon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"kitIcon\" [fill]=\"menuRef.subItemIconFill()\" />\n } @else if (menuRef.ownIconTpl(); as own) {\n <span rtElem=\"own-icon\" qa-dataid=\"side-menu-own-icon\" aria-hidden=\"true\">\n <ng-container [ngTemplateOutlet]=\"own\" [ngTemplateOutletContext]=\"{ $implicit: row, icon: row.icon, slot: 'icon' }\" />\n </span>\n }\n </ng-template>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-side-menu-sub-item{--rt-side-menu-sub-item-radius: var(--rt-radius-full);--rt-side-menu-sub-item-transition-duration: var(--rt-duration-fast);--rt-side-menu-sub-item-match-bg: var(--rt-yellow-400);--rt-side-menu-sub-item-match-color: var(--rt-neutral-950);--rt-side-menu-sub-item-match-radius: var(--rt-radius-xs);--rt-side-menu-sub-item-min-height: var(--rt-control-height-md);--rt-side-menu-sub-item-font-size: var(--rt-text-sm);--rt-side-menu-sub-item-padding-start: var(--rt-space-md);--rt-side-menu-sub-item-padding-end: var(--rt-space-sm);--rt-side-menu-sub-item-color: var(--rt-color-text-primary);--rt-side-menu-sub-item-gap: var(--rt-space-sm);--rt-side-menu-sub-item-folder-padding-start: var(--rt-side-menu-sub-item-padding-start);--rt-side-menu-sub-item-chevron-color: var(--rt-color-text-muted);--rt-side-menu-sub-item-icon-size: var(--rt-icon-step-sm);--rt-side-menu-sub-item-button-radius: var(--rt-radius-md);--rt-side-menu-sub-item-button-icon-size: var(--rt-icon-step-sm);--rt-side-menu-sub-item-action-size: var(--rt-control-height-sm);--rt-side-menu-sub-item-favorite-size: var(--rt-control-height-sm);--rt-side-menu-sub-item-favorite-color: var(--rt-color-text-primary);display:block;letter-spacing:var(--rt-side-menu-sub-item-letter-spacing, inherit)}.rt-side-menu-sub-item__row{--rt-side-menu-sub-item-depth: 0;display:flex;width:100%;min-height:var(--rt-side-menu-sub-item-min-height);box-sizing:border-box;align-items:center;border:0;border-radius:var(--rt-side-menu-sub-item-radius);background:transparent;color:var(--rt-side-menu-sub-item-color);cursor:pointer;font:inherit;font-size:var(--rt-side-menu-sub-item-font-size);gap:var(--rt-side-menu-sub-item-gap);padding-block:var(--rt-space-2);padding-inline:calc(var(--rt-side-menu-sub-item-padding-start) * (1 + var(--rt-side-menu-sub-item-depth))) var(--rt-side-menu-sub-item-padding-end);text-align:start;text-decoration:none;transition:background-color var(--rt-side-menu-sub-item-transition-duration) ease}.rt-side-menu-sub-item__row:hover,.rt-side-menu-sub-item__row:active,.rt-side-menu-sub-item__row--highlighted{background:var(--rt-side-menu-item-bg-hover)}.rt-side-menu-sub-item__row:focus-visible{outline:var(--rt-focus-ring-width) solid var(--rt-focus-ring-color);outline-offset:calc(var(--rt-focus-ring-width) * -1)}.rt-side-menu-sub-item__row--active{background:var(--rt-side-menu-item-bg-active);color:var(--rt-side-menu-item-color-active)}.rt-side-menu-sub-item__icon{--rt-icon-step-sm: var(--rt-side-menu-sub-item-icon-size);flex-shrink:0;color:inherit}.rt-side-menu-sub-item__own-icon{--rt-side-menu-sub-item-own-icon-size: var(--rt-size-4);display:inline-flex;width:var(--rt-side-menu-sub-item-own-icon-size);height:var(--rt-side-menu-sub-item-own-icon-size);flex-shrink:0;align-items:center;justify-content:center;color:inherit;line-height:1}.rt-side-menu-sub-item__own-icon>*{max-width:100%;max-height:100%}.rt-side-menu-sub-item__title{overflow:hidden;min-width:0;flex:1 1 auto;text-overflow:ellipsis;white-space:nowrap}.rt-side-menu-sub-item__part{color:inherit}.rt-side-menu-sub-item__match{border-radius:var(--rt-side-menu-sub-item-match-radius);background:var(--rt-side-menu-sub-item-match-bg);color:var(--rt-side-menu-sub-item-match-color)}.rt-side-menu-sub-item__action{--rt-side-menu-sub-item-action-ring-width: var(--rt-border-width-thin);--rt-side-menu-sub-item-action-radius: var(--rt-radius-full);flex-shrink:0;border-radius:var(--rt-side-menu-sub-item-action-radius);outline:var(--rt-side-menu-sub-item-action-ring-width) solid transparent;outline-offset:calc(var(--rt-side-menu-sub-item-action-ring-width) * -1)}.rt-side-menu-sub-item__action:hover{outline-color:var(--rt-color-border-strong)}.rt-side-menu-sub-item__action>.rt-icon-button{--rt-icon-button-size-step: var(--rt-side-menu-sub-item-action-size)}.rt-side-menu-sub-item__action,.rt-side-menu-sub-item__favorite{--rt-icon-step-sm: var(--rt-side-menu-sub-item-button-icon-size)}.rt-side-menu-sub-item__action>.rt-icon-button,.rt-side-menu-sub-item__favorite>.rt-icon-button{--rt-icon-button-radius: var(--rt-side-menu-sub-item-button-radius)}.rt-side-menu-sub-item__favorite{--rt-icon-button-color: var(--rt-side-menu-sub-item-favorite-color);flex-shrink:0;opacity:0}.rt-side-menu-sub-item__favorite>.rt-icon-button{--rt-icon-button-size-step: var(--rt-side-menu-sub-item-favorite-size)}.rt-side-menu-sub-item__favorite--on{--rt-icon-button-color: var(--rt-color-action-primary);opacity:1}@media(hover:hover){.rt-side-menu-sub-item__favorite--remove:hover{--rt-icon-button-color: var(--rt-color-state-danger)}}.rt-side-menu-sub-item__favorite--remove:has(:focus-visible){--rt-icon-button-color: var(--rt-color-state-danger)}@media(hover:none){.rt-side-menu-sub-item__favorite{opacity:1}}.rt-side-menu-sub-item__row:hover .rt-side-menu-sub-item__favorite,.rt-side-menu-sub-item__row:focus-visible .rt-side-menu-sub-item__favorite,.rt-side-menu-sub-item__row:has(:focus-visible) .rt-side-menu-sub-item__favorite{opacity:1}.rt-side-menu-sub-item__folder.rt-expansion-panel{--rt-expansion-panel-duration: var(--rt-side-menu-sub-item-transition-duration);--rt-expansion-panel-header-radius: var(--rt-side-menu-sub-item-radius);--rt-expansion-panel-header-min-height: var(--rt-side-menu-sub-item-min-height);--rt-expansion-panel-header-padding-block: var(--rt-space-2);--rt-expansion-panel-header-padding-start: calc( var(--rt-side-menu-sub-item-folder-padding-start) * (1 + var(--rt-side-menu-sub-item-depth)) );--rt-expansion-panel-header-padding-end: var(--rt-side-menu-sub-item-padding-end);--rt-expansion-panel-header-gap: var(--rt-side-menu-sub-item-gap);--rt-expansion-panel-chevron-color: var(--rt-side-menu-sub-item-chevron-color);--rt-expansion-panel-header-font-size: var(--rt-side-menu-sub-item-font-size);--rt-expansion-panel-header-color: var(--rt-side-menu-sub-item-color);--rt-expansion-panel-header-bg: transparent;--rt-expansion-panel-header-hover-bg: var(--rt-side-menu-item-bg-hover)}.rt-side-menu-sub-item__folder--highlighted.rt-expansion-panel{--rt-expansion-panel-header-bg: var(--rt-side-menu-item-bg-hover)}.rt-side-menu-sub-item__children{display:flex;flex-direction:column}@media(hover:hover){.rt-side-menu--favorite-actions-none .rt-side-menu-sub-item__favorite:not(.rt-side-menu-sub-item__favorite--on){overflow:hidden;width:0;margin-inline-start:calc(var(--rt-space-sm) * -1)}.rt-side-menu--favorite-actions-none .rt-side-menu-sub-item__row:hover .rt-side-menu-sub-item__favorite,.rt-side-menu--favorite-actions-none .rt-side-menu-sub-item__row:focus-visible .rt-side-menu-sub-item__favorite,.rt-side-menu--favorite-actions-none .rt-side-menu-sub-item__row:has(:focus-visible) .rt-side-menu-sub-item__favorite{overflow:visible;width:auto;margin-inline-start:0}}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }, { kind: "directive", type: ModDirective, selector: "[rtMod]" }, { kind: "component", type: RtExpansionPanelComponent, selector: "rt-expansion-panel", inputs: ["expanded", "disabled", "hideToggle", "appearance", "headerId", "ariaLabel"], outputs: ["expandedChange"] }, { kind: "directive", type: RtExpansionPanelContentDirective, selector: "ng-template[rtExpansionPanelContent]" }, { kind: "component", type: RtIconComponent, selector: "rt-icon", inputs: ["name", "glyph", "glyphStrategy", "size", "color", "fill", "spin", "rotate"] }, { kind: "component", type: RtIconButtonComponent, selector: "rt-icon-button", inputs: ["icon", "glyph", "ariaLabel", "variant", "iconColor", "iconFill", "size", "iconSize", "type", "tooltip", "tabIndex", "loading", "disabled", "active", "indicator"], outputs: ["clicked"] }, { kind: "directive", type: RtTooltipDirective, selector: "[rtTooltip]", inputs: ["rtTooltip", "rtTooltipPlacement", "rtTooltipWhenTruncated"], exportAs: ["rtTooltip"] }, { kind: "pipe", type: RtSideMenuTitlePartsPipe, name: "rtSideMenuTitleParts" }, { kind: "pipe", type: RtSideMenuIconPipe, name: "rtSideMenuIcon" }, { kind: "pipe", type: RtSideMenuHrefPipe, name: "rtSideMenuHref" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
466
|
+
const unpaired = unpairedSideMenuIcons(items, hasOwnIcon);
|
|
467
|
+
if (unpaired.length) {
|
|
468
|
+
const names = unpaired.map((name) => `«${name}»`).join(", ");
|
|
469
|
+
console.warn(`rt-side-menu «${menuId}»: значков ${names} нет ни в наборе кита, ни в перечне имён Material. Задайте имя кита или свой значок через <ng-template rtSideMenuIcon>.`);
|
|
470
|
+
}
|
|
791
471
|
}
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
], template: "<ng-container rtBlock=\"rt-side-menu-sub-item\">\n <ng-container [ngTemplateOutlet]=\"rowTpl\" [ngTemplateOutletContext]=\"{ $implicit: item(), depth: 0 }\" />\n <ng-template #rowTpl let-row let-depth=\"depth\">\n @let isActive = menuRef.activeMenuIds().includes(row.id);\n @let isHighlighted = !inFavorites() && menuRef.highlightedMenuId() === row.id;\n @if (row.link) {\n <!--\n \u041D\u043E\u043C\u0435\u0440 \u043F\u0443\u043D\u043A\u0442\u0430 \u043D\u0430 \u0441\u0430\u043C\u043E\u0439 \u0441\u0442\u0440\u043E\u043A\u0435 \u2014 \u043F\u0440\u0438\u0437\u043D\u0430\u043A \u0434\u043B\u044F \u043F\u0440\u0430\u0432\u0438\u043B \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F: \u043F\u043E \u043D\u0435\u043C\u0443 \u043E\u043D\u043E \u043D\u0430\u0445\u043E\u0434\u0438\u0442 \u0441\u0442\u0440\u043E\u043A\u0443,\n \u043D\u0430\u043F\u0440\u0438\u043C\u0435\u0440 \u0442\u0443, \u0447\u0442\u043E \u043E\u0442\u043A\u0440\u044B\u0432\u0430\u0435\u0442 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443 \u0440\u0430\u0437\u0434\u0435\u043B\u0430. \u0421\u0442\u043E\u0438\u0442 \u0438 \u0443 \u0441\u0442\u0440\u043E\u043A\u0438 \u0431\u043B\u043E\u043A\u0430 \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u0433\u043E.\n \u0421\u0442\u0440\u043E\u043A\u0430 \u0431\u043B\u043E\u043A\u0430 \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u0433\u043E \u0431\u0435\u0437 \u043D\u043E\u043C\u0435\u0440\u0430: \u043F\u043E \u043D\u043E\u043C\u0435\u0440\u0443 \u043A\u043B\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430 \u043D\u0430\u0436\u0438\u043C\u0430\u0435\u0442 \u0441\u0442\u0440\u043E\u043A\u0443 \u0441\u043F\u0438\u0441\u043A\u0430. \u0418 \u0431\u0435\u0437\n \u0440\u043E\u0434\u043D\u043E\u0433\u043E \u043F\u0435\u0440\u0435\u0442\u0430\u0441\u043A\u0438\u0432\u0430\u043D\u0438\u044F \u0441\u0441\u044B\u043B\u043A\u0438: \u043D\u0430\u0436\u0430\u0442\u0438\u0435 \u043D\u0430 \u0440\u0443\u0447\u043A\u0443 \u0432\u043D\u0443\u0442\u0440\u0438 \u0441\u0442\u0440\u043E\u043A\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0437\u0430\u0431\u0438\u0440\u0430\u043B \u0441\u0435\u0431\u0435,\n \u0438 \u043F\u0435\u0440\u0435\u0442\u0430\u0441\u043A\u0438\u0432\u0430\u043D\u0438\u0435 CDK \u043D\u0435 \u043D\u0430\u0447\u0438\u043D\u0430\u043B\u043E\u0441\u044C.\n -->\n <a\n rtElem=\"row\"\n qa-dataid=\"side-menu-sub-item\"\n [id]=\"inFavorites() ? null : row.id\"\n [attr.data-item-id]=\"row.id\"\n [attr.draggable]=\"inFavorites() ? 'false' : null\"\n [attr.href]=\"row.link | rtSideMenuHref\"\n [style.--rt-side-menu-sub-item-depth]=\"depth\"\n [rtMod]=\"{ active: isActive, highlighted: isHighlighted }\"\n [attr.aria-current]=\"isActive ? 'page' : null\"\n (click)=\"onClickSubMenu(row, $event)\">\n @if (row.icon) {\n <ng-container [ngTemplateOutlet]=\"iconTpl\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n }\n\n <span rtElem=\"title\" [rtTooltip]=\"menuRef.subMenuTooltipsShown() ? row.name : ''\">\n <!-- \u041A\u0443\u0441\u043E\u043A \u0431\u0435\u0437 \u043E\u0442\u043C\u0435\u0442\u043A\u0438 \u0442\u043E\u0436\u0435 \u0443\u0437\u0435\u043B: \u0433\u043E\u043B\u0430\u044F \u0438\u043D\u0442\u0435\u0440\u043F\u043E\u043B\u044F\u0446\u0438\u044F \u0440\u0430\u0437\u0440\u044B\u0432\u0430\u043B\u0430 \u0431\u044B \u043F\u043E\u0434\u043F\u0438\u0441\u044C \u043F\u0440\u043E\u0431\u0435\u043B\u0430\u043C\u0438. -->\n @for (part of row.name | rtSideMenuTitleParts: menuRef.subMenuQuery(); track $index) {\n @if (part.matched) {\n <span rtElem=\"match\">{{ part.text }}</span>\n } @else {\n <span rtElem=\"part\">{{ part.text }}</span>\n }\n }\n </span>\n\n <!--\n \u0421\u0442\u0440\u043E\u043A\u0430 \u0431\u043B\u043E\u043A\u0430 \u043D\u0435\u0441\u0451\u0442 \u00AB\u0443\u0431\u0440\u0430\u0442\u044C\u00BB, \u0430 \u043D\u0435 \u0437\u0432\u0435\u0437\u0434\u0443: \u0432\u0441\u0451 \u0432 \u0431\u043B\u043E\u043A\u0435 \u0443\u0436\u0435 \u0432 \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u043C. \u0417\u0432\u0435\u0437\u0434\u0430 \u2014\n \u0443 \u043F\u0443\u043D\u043A\u0442\u0430 \u0441\u043E \u0441\u0432\u043E\u0438\u043C \u0430\u0434\u0440\u0435\u0441\u043E\u043C \u0432 \u0440\u0430\u0437\u0434\u0435\u043B\u0435 \u0441 \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u044B\u043C: \u043F\u043E\u043B\u0430\u044F \u2014 \u043D\u0435 \u0432 \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u043C,\n \u0437\u0430\u043A\u0440\u0430\u0448\u0435\u043D\u043D\u0430\u044F \u0446\u0432\u0435\u0442\u043E\u043C \u0442\u0435\u043C\u044B \u2014 \u0432 \u043D\u0451\u043C. \u0418\u043C\u044F \u043A\u043D\u043E\u043F\u043A\u0438 \u043D\u0430\u0437\u044B\u0432\u0430\u0435\u0442 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0435\u0435 \u043D\u0430\u0436\u0430\u0442\u0438\u0435.\n -->\n @if (inFavorites() && favoritesIcons) {\n <rt-icon-button\n rtElem=\"favorite\"\n qa-dataid=\"side-menu-favorite-remove\"\n size=\"sm\"\n [rtMod]=\"{ remove: true }\"\n [icon]=\"favoritesIcons.remove\"\n [ariaLabel]=\"removeLabel()\"\n [tooltip]=\"narrow() || !menuRef.subMenuTooltipsShown() ? '' : removeLabel()\"\n (clicked)=\"onRemoveFavorite(row, $event)\" />\n } @else if (favoritesOn() && !row.favoriteDisabled) {\n @let isFavorite = favoriteIds().includes(row.id);\n <rt-icon-button\n rtElem=\"favorite\"\n qa-dataid=\"side-menu-favorite-star\"\n size=\"sm\"\n [rtMod]=\"{ on: isFavorite }\"\n [icon]=\"isFavorite ? 'star-fill' : 'star'\"\n [iconFill]=\"isFavorite\"\n [ariaLabel]=\"isFavorite ? removeLabel() : addLabel()\"\n [tooltip]=\"narrow() || !menuRef.subMenuTooltipsShown() ? '' : isFavorite ? removeLabel() : addLabel()\"\n (clicked)=\"onToggleFavorite(row, $event)\" />\n }\n\n <!-- \u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044F, \u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u0441\u0442\u0440\u043E\u043A\u0435 \u043F\u0435\u0440\u0435\u0434\u0430\u0451\u0442 \u0432\u043B\u0430\u0434\u0435\u043B\u0435\u0446: \u0431\u043B\u043E\u043A \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u0433\u043E \u043A\u043B\u0430\u0434\u0451\u0442 \u0441\u044E\u0434\u0430 \u0440\u0443\u0447\u043A\u0443. -->\n <ng-content select=\"[rtSideMenuSubItemAction]\" />\n\n <!-- \u041A\u043D\u043E\u043F\u043A\u0430 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B\u044F \u0432\u0438\u0434\u043D\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u0438 \u0441\u0442\u043E\u0438\u0442 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0439: \u043A\u043D\u043E\u043F\u043A\u0438 \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u0433\u043E \u0432\u0441\u0442\u0430\u044E\u0442 \u043F\u0435\u0440\u0435\u0434 \u043D\u0435\u0439. -->\n @if (row.iconButton?.icon; as buttonIcon) {\n <!-- \u0418\u043C\u044F \u0431\u0435\u0437 \u0437\u043D\u0430\u0447\u043A\u0430 \u043A\u0438\u0442\u0430 \u0431\u0435\u0440\u0451\u0442 \u0441\u0432\u043E\u0439 \u0448\u0430\u0431\u043B\u043E\u043D \u043C\u0435\u043D\u044E, \u043A\u0430\u043A \u0437\u043D\u0430\u0447\u043E\u043A \u0441\u0442\u0440\u043E\u043A\u0438. \u0411\u0435\u0437 \u0448\u0430\u0431\u043B\u043E\u043D\u0430 \u043A\u043D\u043E\u043F\u043A\u0430 \u043F\u0443\u0441\u0442\u0430 \u0438\n \u043D\u0435\u0437\u043D\u0430\u043A\u043E\u043C\u043E\u0433\u043E \u0438\u043C\u0435\u043D\u0438 \u0437\u043D\u0430\u0447\u043A\u0443 \u043D\u0435 \u043F\u0435\u0440\u0435\u0434\u0430\u0451\u0442: \u0437\u043D\u0430\u0447\u043A\u0430 \u0441 \u0442\u0430\u043A\u0438\u043C \u0438\u043C\u0435\u043D\u0435\u043C \u043D\u0435\u0442, \u0438 \u0436\u0434\u0430\u0442\u044C \u0435\u0433\u043E \u043D\u0435\u043A\u043E\u043C\u0443. -->\n @let buttonKitIcon = buttonIcon | rtSideMenuIcon;\n @let buttonOwnTpl = buttonKitIcon ? null : menuRef.ownIconTpl();\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"side-menu-sub-item-action\"\n size=\"sm\"\n [icon]=\"buttonKitIcon\"\n [iconFill]=\"menuRef.subItemIconFill()\"\n [ariaLabel]=\"row.name ?? ''\"\n (clicked)=\"onClickSubMenuAdditional(row, $event)\">\n @if (buttonOwnTpl) {\n <span rtElem=\"own-icon\" qa-dataid=\"side-menu-own-button-icon\" aria-hidden=\"true\">\n <ng-container\n [ngTemplateOutlet]=\"buttonOwnTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: row, icon: buttonIcon, slot: 'iconButton' }\" />\n </span>\n }\n </rt-icon-button>\n }\n </a>\n } @else if (row.submenu) {\n <!--\n \u041F\u0430\u043F\u043A\u0430 \u2014 \u0440\u0430\u0441\u043A\u0440\u044B\u0432\u0430\u044E\u0449\u0430\u044F\u0441\u044F \u043F\u0430\u043D\u0435\u043B\u044C \u043A\u0438\u0442\u0430. \u0420\u0438\u0441\u0443\u0435\u0442\u0441\u044F \u0438 \u0441 \u043F\u0443\u0441\u0442\u044B\u043C \u0441\u043E\u0441\u0442\u0430\u0432\u043E\u043C: \u043E\u0442\u0431\u043E\u0440 \u043E\u0441\u0442\u0430\u0432\u043B\u044F\u0435\u0442 \u0442\u0430\u043A\n \u0442\u0443, \u0447\u0442\u043E \u0441\u043E\u0432\u043F\u0430\u043B\u0430 \u043F\u043E\u0434\u043F\u0438\u0441\u044C\u044E. \u0428\u0435\u0432\u0440\u043E\u043D\u0430 \u0443 \u0442\u0430\u043A\u043E\u0439 \u043F\u0430\u043F\u043A\u0438 \u043D\u0435\u0442 \u2014 \u0440\u0430\u0441\u043A\u0440\u044B\u0432\u0430\u0442\u044C \u043D\u0435\u0447\u0435\u0433\u043E. \u0420\u0430\u0441\u043A\u0440\u044B\u0442\u0438\u0435\n \u0434\u0435\u0440\u0436\u0438\u0442 \u043C\u0435\u043D\u044E: \u043F\u0430\u043D\u0435\u043B\u044C \u0441\u043E\u043E\u0431\u0449\u0430\u0435\u0442 \u043E \u043D\u0430\u0436\u0430\u0442\u0438\u0438, \u043C\u0435\u043D\u044E \u043F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0430\u0435\u0442 \u043F\u0430\u043F\u043A\u0443. \u041A\u043D\u043E\u043F\u043A\u0435 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430\n \u043E\u0442\u0434\u0430\u043D \u043D\u043E\u043C\u0435\u0440 \u043F\u0443\u043D\u043A\u0442\u0430 \u2014 \u043F\u043E \u043D\u0435\u043C\u0443 \u043A\u043B\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u0430 \u043C\u0435\u043D\u044E \u043D\u0430\u0436\u0438\u043C\u0430\u0435\u0442 \u0441\u0442\u0440\u043E\u043A\u0443.\n -->\n @let isOpen = menuRef.expandedMenuIds().includes(row.id);\n <rt-expansion-panel\n rtElem=\"folder\"\n appearance=\"plain\"\n [headerId]=\"'' + row.id\"\n [attr.data-item-id]=\"row.id\"\n [hideToggle]=\"!row.submenu.length\"\n [expanded]=\"isOpen\"\n [style.--rt-side-menu-sub-item-depth]=\"depth\"\n [rtMod]=\"{ highlighted: isHighlighted }\"\n (expandedChange)=\"onToggleFolder(row)\">\n @if (row.icon) {\n <ng-container [ngTemplateOutlet]=\"iconTpl\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n }\n\n <span rtElem=\"title\" qa-dataid=\"side-menu-folder\" [rtTooltip]=\"menuRef.subMenuTooltipsShown() ? row.name : ''\">\n @for (part of row.name | rtSideMenuTitleParts: menuRef.subMenuQuery(); track $index) {\n @if (part.matched) {\n <span rtElem=\"match\">{{ part.text }}</span>\n } @else {\n <span rtElem=\"part\">{{ part.text }}</span>\n }\n }\n </span>\n\n <ng-template rtExpansionPanelContent>\n <div rtElem=\"children\" role=\"group\">\n @for (child of row.submenu; track child.id) {\n <ng-container [ngTemplateOutlet]=\"rowTpl\" [ngTemplateOutletContext]=\"{ $implicit: child, depth: depth + 1 }\" />\n }\n </div>\n </ng-template>\n </rt-expansion-panel>\n }\n </ng-template>\n\n <!-- \u0417\u043D\u0430\u0447\u043E\u043A \u0441\u0442\u0440\u043E\u043A\u0438: \u0438\u043C\u044F \u043A\u0438\u0442\u0430 \u0438\u043B\u0438 \u043F\u0430\u0440\u0430 \u0438\u043C\u0435\u043D\u0438 Material, \u0430 \u0438\u043C\u044F, \u043A\u043E\u0442\u043E\u0440\u043E\u0433\u043E \u043A\u0438\u0442 \u043D\u0435 \u0440\u0438\u0441\u0443\u0435\u0442, \u2014 \u0441\u0432\u043E\u0439 \u0448\u0430\u0431\u043B\u043E\u043D \u043C\u0435\u043D\u044E. -->\n <ng-template #iconTpl let-row>\n @let kitIcon = row.icon | rtSideMenuIcon;\n @if (kitIcon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"kitIcon\" [fill]=\"menuRef.subItemIconFill()\" />\n } @else if (menuRef.ownIconTpl(); as own) {\n <span rtElem=\"own-icon\" qa-dataid=\"side-menu-own-icon\" aria-hidden=\"true\">\n <ng-container [ngTemplateOutlet]=\"own\" [ngTemplateOutletContext]=\"{ $implicit: row, icon: row.icon, slot: 'icon' }\" />\n </span>\n }\n </ng-template>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-side-menu-sub-item{--rt-side-menu-sub-item-radius: var(--rt-radius-full);--rt-side-menu-sub-item-transition-duration: var(--rt-duration-fast);--rt-side-menu-sub-item-match-bg: var(--rt-yellow-400);--rt-side-menu-sub-item-match-color: var(--rt-neutral-950);--rt-side-menu-sub-item-match-radius: var(--rt-radius-xs);--rt-side-menu-sub-item-min-height: var(--rt-control-height-md);--rt-side-menu-sub-item-font-size: var(--rt-text-sm);--rt-side-menu-sub-item-padding-start: var(--rt-space-md);--rt-side-menu-sub-item-padding-end: var(--rt-space-sm);--rt-side-menu-sub-item-color: var(--rt-color-text-primary);--rt-side-menu-sub-item-gap: var(--rt-space-sm);--rt-side-menu-sub-item-folder-padding-start: var(--rt-side-menu-sub-item-padding-start);--rt-side-menu-sub-item-chevron-color: var(--rt-color-text-muted);--rt-side-menu-sub-item-icon-size: var(--rt-icon-step-sm);--rt-side-menu-sub-item-button-radius: var(--rt-radius-md);--rt-side-menu-sub-item-button-icon-size: var(--rt-icon-step-sm);--rt-side-menu-sub-item-action-size: var(--rt-control-height-sm);--rt-side-menu-sub-item-favorite-size: var(--rt-control-height-sm);--rt-side-menu-sub-item-favorite-color: var(--rt-color-text-primary);display:block;letter-spacing:var(--rt-side-menu-sub-item-letter-spacing, inherit)}.rt-side-menu-sub-item__row{--rt-side-menu-sub-item-depth: 0;display:flex;width:100%;min-height:var(--rt-side-menu-sub-item-min-height);box-sizing:border-box;align-items:center;border:0;border-radius:var(--rt-side-menu-sub-item-radius);background:transparent;color:var(--rt-side-menu-sub-item-color);cursor:pointer;font:inherit;font-size:var(--rt-side-menu-sub-item-font-size);gap:var(--rt-side-menu-sub-item-gap);padding-block:var(--rt-space-2);padding-inline:calc(var(--rt-side-menu-sub-item-padding-start) * (1 + var(--rt-side-menu-sub-item-depth))) var(--rt-side-menu-sub-item-padding-end);text-align:start;text-decoration:none;transition:background-color var(--rt-side-menu-sub-item-transition-duration) ease}.rt-side-menu-sub-item__row:hover,.rt-side-menu-sub-item__row:active,.rt-side-menu-sub-item__row--highlighted{background:var(--rt-side-menu-item-bg-hover)}.rt-side-menu-sub-item__row:focus-visible{outline:var(--rt-focus-ring-width) solid var(--rt-focus-ring-color);outline-offset:calc(var(--rt-focus-ring-width) * -1)}.rt-side-menu-sub-item__row--active{background:var(--rt-side-menu-item-bg-active);color:var(--rt-side-menu-item-color-active)}.rt-side-menu-sub-item__icon{--rt-icon-step-sm: var(--rt-side-menu-sub-item-icon-size);flex-shrink:0;color:inherit}.rt-side-menu-sub-item__own-icon{--rt-side-menu-sub-item-own-icon-size: var(--rt-size-4);display:inline-flex;width:var(--rt-side-menu-sub-item-own-icon-size);height:var(--rt-side-menu-sub-item-own-icon-size);flex-shrink:0;align-items:center;justify-content:center;color:inherit;line-height:1}.rt-side-menu-sub-item__own-icon>*{max-width:100%;max-height:100%}.rt-side-menu-sub-item__title{overflow:hidden;min-width:0;flex:1 1 auto;text-overflow:ellipsis;white-space:nowrap}.rt-side-menu-sub-item__part{color:inherit}.rt-side-menu-sub-item__match{border-radius:var(--rt-side-menu-sub-item-match-radius);background:var(--rt-side-menu-sub-item-match-bg);color:var(--rt-side-menu-sub-item-match-color)}.rt-side-menu-sub-item__action{--rt-side-menu-sub-item-action-ring-width: var(--rt-border-width-thin);--rt-side-menu-sub-item-action-radius: var(--rt-radius-full);flex-shrink:0;border-radius:var(--rt-side-menu-sub-item-action-radius);outline:var(--rt-side-menu-sub-item-action-ring-width) solid transparent;outline-offset:calc(var(--rt-side-menu-sub-item-action-ring-width) * -1)}.rt-side-menu-sub-item__action:hover{outline-color:var(--rt-color-border-strong)}.rt-side-menu-sub-item__action>.rt-icon-button{--rt-icon-button-size-step: var(--rt-side-menu-sub-item-action-size)}.rt-side-menu-sub-item__action,.rt-side-menu-sub-item__favorite{--rt-icon-step-sm: var(--rt-side-menu-sub-item-button-icon-size)}.rt-side-menu-sub-item__action>.rt-icon-button,.rt-side-menu-sub-item__favorite>.rt-icon-button{--rt-icon-button-radius: var(--rt-side-menu-sub-item-button-radius)}.rt-side-menu-sub-item__favorite{--rt-icon-button-color: var(--rt-side-menu-sub-item-favorite-color);flex-shrink:0;opacity:0}.rt-side-menu-sub-item__favorite>.rt-icon-button{--rt-icon-button-size-step: var(--rt-side-menu-sub-item-favorite-size)}.rt-side-menu-sub-item__favorite--on{--rt-icon-button-color: var(--rt-color-action-primary);opacity:1}@media(hover:hover){.rt-side-menu-sub-item__favorite--remove:hover{--rt-icon-button-color: var(--rt-color-state-danger)}}.rt-side-menu-sub-item__favorite--remove:has(:focus-visible){--rt-icon-button-color: var(--rt-color-state-danger)}@media(hover:none){.rt-side-menu-sub-item__favorite{opacity:1}}.rt-side-menu-sub-item__row:hover .rt-side-menu-sub-item__favorite,.rt-side-menu-sub-item__row:focus-visible .rt-side-menu-sub-item__favorite,.rt-side-menu-sub-item__row:has(:focus-visible) .rt-side-menu-sub-item__favorite{opacity:1}.rt-side-menu-sub-item__folder.rt-expansion-panel{--rt-expansion-panel-duration: var(--rt-side-menu-sub-item-transition-duration);--rt-expansion-panel-header-radius: var(--rt-side-menu-sub-item-radius);--rt-expansion-panel-header-min-height: var(--rt-side-menu-sub-item-min-height);--rt-expansion-panel-header-padding-block: var(--rt-space-2);--rt-expansion-panel-header-padding-start: calc( var(--rt-side-menu-sub-item-folder-padding-start) * (1 + var(--rt-side-menu-sub-item-depth)) );--rt-expansion-panel-header-padding-end: var(--rt-side-menu-sub-item-padding-end);--rt-expansion-panel-header-gap: var(--rt-side-menu-sub-item-gap);--rt-expansion-panel-chevron-color: var(--rt-side-menu-sub-item-chevron-color);--rt-expansion-panel-header-font-size: var(--rt-side-menu-sub-item-font-size);--rt-expansion-panel-header-color: var(--rt-side-menu-sub-item-color);--rt-expansion-panel-header-bg: transparent;--rt-expansion-panel-header-hover-bg: var(--rt-side-menu-item-bg-hover)}.rt-side-menu-sub-item__folder--highlighted.rt-expansion-panel{--rt-expansion-panel-header-bg: var(--rt-side-menu-item-bg-hover)}.rt-side-menu-sub-item__children{display:flex;flex-direction:column}@media(hover:hover){.rt-side-menu--favorite-actions-none .rt-side-menu-sub-item__favorite:not(.rt-side-menu-sub-item__favorite--on){overflow:hidden;width:0;margin-inline-start:calc(var(--rt-space-sm) * -1)}.rt-side-menu--favorite-actions-none .rt-side-menu-sub-item__row:hover .rt-side-menu-sub-item__favorite,.rt-side-menu--favorite-actions-none .rt-side-menu-sub-item__row:focus-visible .rt-side-menu-sub-item__favorite,.rt-side-menu--favorite-actions-none .rt-side-menu-sub-item__row:has(:focus-visible) .rt-side-menu-sub-item__favorite{overflow:visible;width:auto;margin-inline-start:0}}}\n"] }]
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtSideMenuComponent, isStandalone: true, selector: "rt-side-menu", inputs: { activeMenuIds: { classPropertyName: "activeMenuIds", publicName: "activeMenuIds", isSignal: true, isRequired: true, transformFunction: null }, menuItems: { classPropertyName: "menuItems", publicName: "menuItems", isSignal: true, isRequired: false, transformFunction: null }, subMenuMode: { classPropertyName: "subMenuMode", publicName: "subMenuMode", isSignal: true, isRequired: false, transformFunction: null }, subMenuWidth: { classPropertyName: "subMenuWidth", publicName: "subMenuWidth", isSignal: true, isRequired: false, transformFunction: null }, menuId: { classPropertyName: "menuId", publicName: "menuId", isSignal: true, isRequired: false, transformFunction: null }, favoritesCount: { classPropertyName: "favoritesCount", publicName: "favoritesCount", isSignal: true, isRequired: false, transformFunction: null }, favoriteActionsReserve: { classPropertyName: "favoriteActionsReserve", publicName: "favoriteActionsReserve", isSignal: true, isRequired: false, transformFunction: null }, isFavoritesSearchShown: { classPropertyName: "isFavoritesSearchShown", publicName: "isFavoritesSearchShown", isSignal: true, isRequired: false, transformFunction: null }, pinShown: { classPropertyName: "pinShown", publicName: "pinShown", isSignal: true, isRequired: false, transformFunction: null }, subMenuCloseDelay: { classPropertyName: "subMenuCloseDelay", publicName: "subMenuCloseDelay", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { subMenuModeChange: "subMenuModeChange", subMenuWidthChange: "subMenuWidthChange", subMenuResizeStart: "subMenuResizeStart", subMenuResizeEnd: "subMenuResizeEnd", closeMobileMenuAction: "closeMobileMenuAction", clickSubMenuAction: "clickSubMenuAction", clickSubMenuAdditionalAction: "clickSubMenuAdditionalAction" }, host: { properties: { "class.rt-side-menu--pinned": "isPinned()", "style.--rt-side-menu-panel-dragged-width": "panelWidthStyle()", "class.rt-side-menu--favorite-actions-none": "favoriteActionsReserve() === 'none'" }, classAttribute: "rt-side-menu" }, providers: [{ provide: RT_SIDE_MENU, useExisting: RtSideMenuComponent }], queries: [{ propertyName: "headerTpl", first: true, predicate: RtSideMenuHeaderDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "footerTpl", first: true, predicate: RtSideMenuFooterDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "ownIconTpl", first: true, predicate: RtSideMenuIconDirective, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "panelRef", first: true, predicate: ["panel"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ng-container rtBlock=\"rt-side-menu\">\n @if (narrow()) {\n <!-- \u0423\u0437\u043A\u0438\u0439 \u044D\u043A\u0440\u0430\u043D: \u043E\u0434\u0438\u043D \u0441\u0442\u043E\u043B\u0431\u0435\u0446 \u2014 \u0433\u043B\u0430\u0432\u043D\u044B\u0435 \u043F\u0443\u043D\u043A\u0442\u044B \u0438\u043B\u0438 \u043F\u043E\u0434\u043C\u0435\u043D\u044E \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u043E\u0433\u043E \u0440\u0430\u0437\u0434\u0435\u043B\u0430 \u0441 \u043A\u043D\u043E\u043F\u043A\u043E\u0439 \u043D\u0430\u0437\u0430\u0434. -->\n <rt-scroll-area rtElem=\"mobile\" [isScrollHintShown]=\"true\">\n @if (headerTpl(); as header) {\n <ng-container *rtScrollAreaHeader>\n <ng-container [ngTemplateOutlet]=\"header\" />\n </ng-container>\n }\n\n <ng-container *rtScrollAreaContent>\n @if (selectedSubMenu()?.length) {\n <div rtElem=\"mobile-sub\">\n <button type=\"button\" rtElem=\"back\" qa-dataid=\"side-menu-back\" (click)=\"onBackToMainMenu()\">\n <rt-icon rtElem=\"back-icon\" size=\"sm\" name=\"arrow-left\" />\n <span rtElem=\"back-label\">{{ backLabel() }}</span>\n </button>\n\n <ng-container [ngTemplateOutlet]=\"subMenuTpl\" />\n </div>\n } @else {\n <nav rtElem=\"mobile-list\">\n @for (item of menuItems(); track item.id) {\n <ng-container [ngTemplateOutlet]=\"mobileItemTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n }\n </nav>\n }\n </ng-container>\n\n @if (footerTpl(); as footer) {\n <ng-container *rtScrollAreaFooter>\n <ng-container [ngTemplateOutlet]=\"footer\" />\n </ng-container>\n }\n </rt-scroll-area>\n } @else {\n <rt-scroll-area rtElem=\"rail\" [isScrollHintShown]=\"true\">\n @if (headerTpl(); as header) {\n <ng-container *rtScrollAreaHeader>\n <ng-container [ngTemplateOutlet]=\"header\" />\n </ng-container>\n }\n\n <ng-container *rtScrollAreaContent>\n <nav rtElem=\"rail-list\">\n @for (item of menuItems(); track item.id) {\n <ng-container [ngTemplateOutlet]=\"railItemTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n }\n </nav>\n </ng-container>\n\n @if (footerTpl(); as footer) {\n <ng-container *rtScrollAreaFooter>\n <ng-container [ngTemplateOutlet]=\"footer\" />\n </ng-container>\n }\n </rt-scroll-area>\n\n @if (subMenuOpened()) {\n @if (isSearchHeld()) {\n <!-- \u041F\u043E\u0434\u043B\u043E\u0436\u043A\u0430 \u043D\u0435\u0437\u0430\u043A\u0440\u0435\u043F\u043B\u0451\u043D\u043D\u043E\u0439 \u043F\u0430\u043D\u0435\u043B\u0438: \u043F\u043E\u0434\u043C\u0435\u043D\u044E, \u0432\u0437\u044F\u0442\u043E\u0435 \u043F\u043E\u043B\u0435\u043C \u043F\u043E\u0438\u0441\u043A\u0430, \u0437\u0430\u043A\u0440\u044B\u0432\u0430\u0435\u0442 \u043D\u0430\u0436\u0430\u0442\u0438\u0435 \u0441\u043D\u0430\u0440\u0443\u0436\u0438. -->\n <div\n rtElem=\"backdrop\"\n qa-dataid=\"side-menu-backdrop\"\n tabindex=\"-1\"\n (click)=\"closeSubMenu()\"\n (keydown.escape)=\"closeSubMenu()\"></div>\n }\n\n <div\n #panel\n rtElem=\"panel\"\n qa-dataid=\"side-menu-panel\"\n [rtMod]=\"{ pinned: isPinned(), held: isSearchHeld() }\"\n (mouseenter)=\"cancelSubMenuClose()\"\n (mouseleave)=\"toggleSubMenu()\">\n <div rtElem=\"panel-head\">\n <rt-input\n rtElem=\"search\"\n qa-dataid=\"side-menu-search\"\n iconLeft=\"search\"\n [size]=\"searchSize()\"\n [appearance]=\"searchAppearance()\"\n [placeholder]=\"searchLabel()\"\n [ariaLabel]=\"searchLabel()\"\n [formControl]=\"searchControl\"\n (focusin)=\"onSearchHold()\"\n (keydown)=\"onSearchKeydown($event)\" />\n\n @if (pinShown()) {\n <rt-icon-button\n rtElem=\"pin\"\n qa-dataid=\"side-menu-pin\"\n size=\"sm\"\n icon=\"pin\"\n [iconFill]=\"isPinned()\"\n [active]=\"isPinned()\"\n [ariaLabel]=\"isPinned() ? unpinLabel() : pinLabel()\"\n [tooltip]=\"isPinned() ? unpinLabel() : pinLabel()\"\n (clicked)=\"onSubMenuModeToggle()\" />\n }\n </div>\n\n <rt-scroll-area rtElem=\"panel-body\" [isScrollHintShown]=\"panelScrollHintShown()\">\n <ng-container *rtScrollAreaContent>\n <ng-container [ngTemplateOutlet]=\"subMenuTpl\" />\n </ng-container>\n </rt-scroll-area>\n </div>\n\n @if (isPinned()) {\n <!-- \u0420\u0443\u0447\u043A\u0430 \u0435\u0441\u0442\u044C \u0442\u043E\u043B\u044C\u043A\u043E \u0443 \u0437\u0430\u043A\u0440\u0435\u043F\u043B\u0451\u043D\u043D\u043E\u0433\u043E \u043F\u043E\u0434\u043C\u0435\u043D\u044E: \u043D\u0435\u0437\u0430\u043A\u0440\u0435\u043F\u043B\u0451\u043D\u043D\u043E\u0435 \u0443\u0445\u043E\u0434\u0438\u0442 \u0440\u0430\u043D\u044C\u0448\u0435, \u0447\u0435\u043C \u0434\u043E \u043A\u0440\u0430\u044F \u0434\u043E\u0435\u0434\u0435\u0442 \u0440\u0443\u043A\u0430. -->\n <div\n rtElem=\"resizer\"\n qa-dataid=\"side-menu-resize\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n tabindex=\"0\"\n [attr.aria-label]=\"resizeLabel()\"\n [attr.aria-valuenow]=\"resizeValueNow()\"\n [attr.aria-valuemin]=\"resizeValueNow() === null ? null : resizeValueMin\"\n [attr.aria-valuemax]=\"resizeValueNow() === null ? null : resizeValueMax\"\n (pointerdown)=\"onResizeStart($event)\"\n (keydown)=\"onResizeKeydown($event)\"></div>\n }\n }\n }\n <ng-template #subMenuTpl>\n @if (narrow()) {\n <rt-input\n rtElem=\"search\"\n qa-dataid=\"side-menu-search\"\n iconLeft=\"search\"\n [size]=\"searchSize()\"\n [appearance]=\"searchAppearance()\"\n [placeholder]=\"searchLabel()\"\n [ariaLabel]=\"searchLabel()\"\n [formControl]=\"searchControl\"\n (keydown)=\"onSearchKeydown($event)\" />\n }\n\n @if (isNothingFound()) {\n <div rtElem=\"empty\" qa-dataid=\"side-menu-empty\">{{ nothingFoundLabel() }}</div>\n }\n\n <div rtElem=\"sub-list\">\n <!-- \u0411\u043B\u043E\u043A \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u0433\u043E \u0440\u0430\u0437\u0434\u0435\u043B\u0430: \u0441\u0430\u043C \u0440\u0435\u0448\u0430\u0435\u0442, \u0435\u0441\u0442\u044C \u043B\u0438 \u0435\u043C\u0443 \u0447\u0442\u043E \u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C, \u0438 \u0431\u0435\u0437 \u0441\u0442\u0440\u043E\u043A \u043C\u0435\u0441\u0442\u0430 \u043D\u0435 \u0437\u0430\u043D\u0438\u043C\u0430\u0435\u0442. -->\n <rt-side-menu-favorites\n (clickSubMenuAction)=\"onClickSubMenu($event)\"\n (clickSubMenuAdditionalAction)=\"onClickSubMenuAdditional($event)\" />\n\n @for (item of visibleSubMenuItems(); track item.id) {\n <rt-side-menu-sub-item\n [item]=\"item\"\n (clickSubMenuAction)=\"onClickSubMenu($event)\"\n (clickSubMenuAdditionalAction)=\"onClickSubMenuAdditional($event)\" />\n }\n </div>\n </ng-template>\n\n <ng-template #railItemTpl let-item>\n @let isActive = activeRailIds().includes(item.id);\n <!-- \u0411\u0435\u0437 \u043F\u043E\u0434\u043F\u0438\u0441\u0435\u0439 \u043F\u043E\u0434 \u0437\u043D\u0430\u0447\u043A\u0430\u043C\u0438 \u0438\u043C\u044F \u043F\u0443\u043D\u043A\u0442\u0430 \u2014 \u0432 \u043F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0435 \u0441\u043F\u0440\u0430\u0432\u0430; \u0432\u044B\u043A\u043B\u044E\u0447\u0435\u043D\u043D\u044B\u0435 \u043F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0438 \u0433\u0430\u0441\u044F\u0442 \u0438 \u0435\u0451. -->\n @let railTip = railTitlesShown() || !subMenuTooltipsShown() ? '' : item.name;\n @if (item.link) {\n <a\n rtElem=\"rail-item\"\n qa-dataid=\"side-menu-item\"\n rtTooltipPlacement=\"right\"\n [routerLink]=\"item.link\"\n [rtMod]=\"{ active: isActive }\"\n [attr.aria-current]=\"isActive ? 'page' : null\"\n [attr.aria-label]=\"railTitlesShown() ? null : item.name\"\n [rtTooltip]=\"railTip\"\n (mouseenter)=\"toggleSubMenu(item)\"\n (click)=\"onClickMenu(item)\">\n <ng-container [ngTemplateOutlet]=\"railItemBodyTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n </a>\n } @else {\n <button\n type=\"button\"\n rtElem=\"rail-item\"\n qa-dataid=\"side-menu-item\"\n rtTooltipPlacement=\"right\"\n [rtMod]=\"{ active: isActive }\"\n [attr.aria-label]=\"railTitlesShown() ? null : item.name\"\n [rtTooltip]=\"railTip\"\n [attr.aria-expanded]=\"item.submenu?.length ? subMenuOpened() && selectedItem() === item : null\"\n (mouseenter)=\"toggleSubMenu(item)\"\n (click)=\"onClickMenu(item)\">\n <ng-container [ngTemplateOutlet]=\"railItemBodyTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n </button>\n }\n </ng-template>\n\n <ng-template #railItemBodyTpl let-item>\n @if (item.icon) {\n <!-- \u0418\u043C\u044F Material \u043F\u0435\u0440\u0432\u043E\u0433\u043E \u043A\u0438\u0442\u0430 \u0440\u0438\u0441\u0443\u0435\u0442\u0441\u044F \u0441\u0432\u043E\u0435\u0439 \u043F\u0430\u0440\u043E\u0439; \u0438\u043C\u044F, \u043A\u043E\u0442\u043E\u0440\u043E\u0433\u043E \u043A\u0438\u0442 \u043D\u0435 \u0440\u0438\u0441\u0443\u0435\u0442, \u2014 \u0441\u0432\u043E\u0438\u043C \u0448\u0430\u0431\u043B\u043E\u043D\u043E\u043C \u043C\u0435\u043D\u044E. -->\n @let kitIcon = item.icon | rtSideMenuIcon;\n <span rtElem=\"rail-icon\">\n @if (kitIcon) {\n <rt-icon [name]=\"kitIcon\" [fill]=\"railIconFill()\" />\n } @else if (ownIconTpl(); as own) {\n <span rtElem=\"own-icon\" qa-dataid=\"side-menu-own-icon\" aria-hidden=\"true\">\n <ng-container\n [ngTemplateOutlet]=\"own\"\n [ngTemplateOutletContext]=\"{ $implicit: item, icon: item.icon, slot: 'icon' }\" />\n </span>\n }\n </span>\n }\n\n @if (item.name && railTitlesShown()) {\n <span rtElem=\"rail-title\">{{ item.name }}</span>\n }\n </ng-template>\n\n <ng-template #mobileItemTpl let-item>\n @let isActive = activeRailIds().includes(item.id);\n @if (item.link && !item.submenu?.length) {\n <a\n rtElem=\"mobile-item\"\n qa-dataid=\"side-menu-item\"\n [routerLink]=\"item.link\"\n [rtMod]=\"{ active: isActive }\"\n [attr.aria-current]=\"isActive ? 'page' : null\"\n (click)=\"onClickMenu(item)\">\n <ng-container [ngTemplateOutlet]=\"mobileItemBodyTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n </a>\n } @else {\n <button\n type=\"button\"\n rtElem=\"mobile-item\"\n qa-dataid=\"side-menu-item\"\n [rtMod]=\"{ active: isActive }\"\n (click)=\"onClickMenu(item)\">\n <ng-container [ngTemplateOutlet]=\"mobileItemBodyTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n </button>\n }\n </ng-template>\n\n <ng-template #mobileItemBodyTpl let-item>\n @if (item.icon) {\n @let kitIcon = item.icon | rtSideMenuIcon;\n @if (kitIcon) {\n <rt-icon rtElem=\"mobile-icon\" [name]=\"kitIcon\" />\n } @else if (ownIconTpl(); as own) {\n <span rtElem=\"own-icon\" qa-dataid=\"side-menu-own-icon\" aria-hidden=\"true\">\n <ng-container [ngTemplateOutlet]=\"own\" [ngTemplateOutletContext]=\"{ $implicit: item, icon: item.icon, slot: 'icon' }\" />\n </span>\n }\n }\n\n <span rtElem=\"mobile-title\" [rtTooltip]=\"item.name\">{{ item.name }}</span>\n\n @if (item.submenu?.length) {\n <!-- \u0421\u0442\u0440\u0435\u043B\u043A\u0430 \u0440\u0430\u0437\u0434\u0435\u043B\u0430, \u043A\u0430\u043A \u0443 \u043F\u0435\u0440\u0432\u043E\u0433\u043E \u043A\u0438\u0442\u0430: \u043D\u0430\u0436\u0430\u0442\u0438\u0435 \u0443\u0432\u043E\u0434\u0438\u0442 \u0432 \u043F\u043E\u0434\u043C\u0435\u043D\u044E, \u0430 \u043D\u0435 \u0440\u0430\u0441\u043A\u0440\u044B\u0432\u0430\u0435\u0442 \u043D\u0430 \u043C\u0435\u0441\u0442\u0435. -->\n <rt-icon rtElem=\"mobile-chevron\" size=\"sm\" name=\"arrow-right\" />\n }\n </ng-template>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-side-menu,.rt-side-menu-favorites__row.cdk-drag-preview{--rt-side-menu-item-color: currentcolor;--rt-side-menu-item-bg-hover: var(--rt-color-bg-hover);--rt-side-menu-item-bg-active: var(--rt-color-action-primary-subtle);--rt-side-menu-item-color-active: var(--rt-color-action-primary-on-surface)}.rt-side-menu{--rt-side-menu-rail-width: 5.5rem;--rt-side-menu-panel-width: 15rem;--rt-side-menu-panel-held-width: 30rem;--rt-side-menu-mobile-width: 15rem;--rt-side-menu-panel-radius: var(--rt-radius-lg);--rt-side-menu-panel-shadow: var(--rt-shadow-nav-panel);--rt-side-menu-item-radius: var(--rt-radius-full);--rt-side-menu-resizer-border-width: var(--rt-border-width-thick);--rt-side-menu-panel-border-width: var(--rt-border-width-thin);--rt-side-menu-transition-duration: var(--rt-duration-fast);--rt-side-menu-rail-icon-size: var(--rt-icon-step-md);--rt-side-menu-rail-gap: var(--rt-space-md);--rt-side-menu-rail-bg: var(--rt-color-bg-surface);--rt-side-menu-rail-border-width: var(--rt-side-menu-panel-border-width);--rt-side-menu-panel-bg: var(--rt-color-bg-surface);--rt-side-menu-panel-head-padding: var(--rt-space-sm);--rt-side-menu-sub-list-padding-inline: var(--rt-space-2);--rt-side-menu-empty-padding: var(--rt-space-md);--rt-side-menu-panel-dragged-width: 0px;--rt-side-menu-panel-shown-width: max(var(--rt-side-menu-panel-width), var(--rt-side-menu-panel-dragged-width));position:relative;display:flex;height:100%;color:var(--rt-color-text-primary)}.rt-side-menu__rail{max-width:var(--rt-side-menu-rail-width);height:100%;box-sizing:border-box;flex:0 0 var(--rt-side-menu-rail-width);border-right:var(--rt-side-menu-rail-border-width) solid var(--rt-color-border-default);background:var(--rt-side-menu-rail-bg)}.rt-side-menu__rail .rt-scroll-area__body{padding-inline:var(--rt-space-1)}.rt-side-menu__rail-list{display:flex;flex-direction:column;align-items:center;gap:var(--rt-side-menu-rail-gap);padding-block:var(--rt-space-sm)}.rt-side-menu__rail-item{display:flex;width:100%;flex-direction:column;align-items:center;padding:0;border:0;background:transparent;color:var(--rt-side-menu-item-color);cursor:pointer;font:inherit;gap:var(--rt-space-1);text-decoration:none}.rt-side-menu__rail-item:focus-visible{outline:none}.rt-side-menu__rail-item:focus-visible .rt-side-menu__rail-icon{outline:var(--rt-focus-ring-width) solid var(--rt-focus-ring-color)}.rt-side-menu__rail-item:hover .rt-side-menu__rail-icon,.rt-side-menu__rail-item:active .rt-side-menu__rail-icon{background:var(--rt-side-menu-item-bg-hover)}.rt-side-menu__rail-item--active .rt-side-menu__rail-icon,.rt-side-menu__rail-item--active:hover .rt-side-menu__rail-icon{background:var(--rt-side-menu-item-bg-active);color:var(--rt-side-menu-item-color-active)}.rt-side-menu__rail-icon{--rt-icon-step-md: var(--rt-side-menu-rail-icon-size);display:flex;width:3.5rem;height:2rem;align-items:center;justify-content:center;border-radius:var(--rt-side-menu-item-radius);transition:background-color var(--rt-side-menu-transition-duration) ease}.rt-side-menu__rail-title{max-width:100%;font-size:var(--rt-text-xs);line-height:var(--rt-leading-snug);overflow-wrap:anywhere;text-align:center}.rt-side-menu__backdrop{position:fixed;z-index:var(--rt-z-dropdown);inset:0;inset-inline-start:var(--rt-side-menu-rail-width)}.rt-side-menu__panel{position:absolute;z-index:var(--rt-z-dropdown);top:0;left:var(--rt-side-menu-rail-width);display:flex;width:var(--rt-side-menu-panel-shown-width);height:100%;box-sizing:border-box;flex-direction:column;border-radius:0 var(--rt-side-menu-panel-radius) var(--rt-side-menu-panel-radius) 0;border-left:var(--rt-side-menu-panel-border-width) solid var(--rt-color-border-default);background:var(--rt-side-menu-panel-bg);box-shadow:var(--rt-side-menu-panel-shadow)}.rt-side-menu__panel--held{width:max(var(--rt-side-menu-panel-held-width),var(--rt-side-menu-panel-shown-width))}.rt-side-menu__panel--pinned{--rt-side-menu-panel-radius: 0;--rt-side-menu-panel-shadow: var(--rt-shadow-none);position:relative;left:0;flex-shrink:0}.rt-side-menu__panel-head{display:flex;align-items:center;padding:var(--rt-side-menu-panel-head-padding);gap:var(--rt-space-2)}.rt-side-menu__search{min-width:0;flex:1 1 auto}.rt-side-menu__pin{flex-shrink:0}.rt-side-menu__panel-body{min-height:0;flex:1 1 auto}.rt-side-menu__sub-list{display:flex;flex-direction:column;padding-block-end:var(--rt-space-sm);padding-inline:var(--rt-side-menu-sub-list-padding-inline)}.rt-side-menu__empty{padding:var(--rt-side-menu-empty-padding);color:var(--rt-color-text-muted);font-size:var(--rt-text-xs)}.rt-side-menu__resizer{position:absolute;z-index:var(--rt-z-dropdown);top:0;bottom:0;left:calc(var(--rt-side-menu-rail-width) + var(--rt-side-menu-panel-shown-width) - var(--rt-space-2));width:var(--rt-space-sm);cursor:col-resize}.rt-side-menu__resizer:before{position:absolute;top:0;bottom:0;left:50%;border-left:var(--rt-side-menu-resizer-border-width) solid transparent;content:\"\"}.rt-side-menu__resizer:hover:before,.rt-side-menu__resizer:focus-visible:before{border-left-color:var(--rt-color-border-strong)}.rt-side-menu__resizer:focus-visible{outline:none}.rt-side-menu__mobile{min-width:0;max-width:100%;height:100%;flex:0 0 var(--rt-side-menu-mobile-width);background:var(--rt-color-bg-surface)}.rt-side-menu__mobile .rt-scroll-area__body{padding-inline:0}.rt-side-menu__mobile-list,.rt-side-menu__mobile-sub{display:flex;flex-direction:column;padding:var(--rt-space-sm);gap:var(--rt-space-1)}.rt-side-menu__mobile-item,.rt-side-menu__back{display:flex;width:100%;min-height:var(--rt-control-height-lg);box-sizing:border-box;align-items:center;border:0;border-radius:var(--rt-side-menu-item-radius);background:transparent;color:var(--rt-side-menu-item-color);cursor:pointer;font:inherit;font-size:var(--rt-text-sm);gap:calc(var(--rt-space-sm) + var(--rt-space-xs));padding-inline:var(--rt-space-md);text-align:start;text-decoration:none}.rt-side-menu__mobile-item:hover,.rt-side-menu__back:hover{background:var(--rt-side-menu-item-bg-hover)}.rt-side-menu__mobile-item:focus-visible,.rt-side-menu__back:focus-visible{outline:var(--rt-focus-ring-width) solid var(--rt-focus-ring-color);outline-offset:calc(var(--rt-focus-ring-width) * -1)}.rt-side-menu__mobile-item--active,.rt-side-menu__back--active{background:var(--rt-side-menu-item-bg-active);color:var(--rt-side-menu-item-color-active)}.rt-side-menu__own-icon{--rt-side-menu-own-icon-size: var(--rt-size-5);display:inline-flex;width:var(--rt-side-menu-own-icon-size);height:var(--rt-side-menu-own-icon-size);flex-shrink:0;align-items:center;justify-content:center;color:inherit;line-height:1}.rt-side-menu__own-icon>*{max-width:100%;max-height:100%}.rt-side-menu__mobile-icon,.rt-side-menu__back-icon,.rt-side-menu__mobile-chevron{flex-shrink:0}.rt-side-menu__mobile-title,.rt-side-menu__back-label{overflow:hidden;min-width:0;flex:1 1 auto;text-overflow:ellipsis;white-space:nowrap}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }, { kind: "directive", type: ModDirective, selector: "[rtMod]" }, { kind: "component", type: RtIconComponent, selector: "rt-icon", inputs: ["name", "glyph", "glyphStrategy", "size", "color", "fill", "spin", "rotate"] }, { kind: "component", type: RtIconButtonComponent, selector: "rt-icon-button", inputs: ["icon", "glyph", "ariaLabel", "variant", "iconColor", "iconFill", "size", "iconSize", "type", "tooltip", "tabIndex", "loading", "disabled", "active", "indicator"], outputs: ["clicked"] }, { kind: "component", type: RtInputComponent, selector: "rt-input", inputs: ["appearance", "type", "placeholder", "iconLeft", "iconRight", "passwordToggle", "autocomplete"] }, { kind: "component", type: RtScrollAreaComponent, selector: "rt-scroll-area", inputs: ["isScrollHintShown"] }, { kind: "directive", type: RtScrollAreaContentDirective, selector: "[rtScrollAreaContent]" }, { kind: "directive", type: RtScrollAreaFooterDirective, selector: "[rtScrollAreaFooter]" }, { kind: "directive", type: RtScrollAreaHeaderDirective, selector: "[rtScrollAreaHeader]" }, { kind: "directive", type: RtTooltipDirective, selector: "[rtTooltip]", inputs: ["rtTooltip", "rtTooltipPlacement", "rtTooltipWhenTruncated"], exportAs: ["rtTooltip"] }, { kind: "component", type: RtSideMenuFavoritesComponent, selector: "rt-side-menu-favorites", outputs: ["clickSubMenuAction", "clickSubMenuAdditionalAction"] }, { kind: "component", type: RtSideMenuSubItemComponent, selector: "rt-side-menu-sub-item", inputs: ["item", "inFavorites"], outputs: ["clickSubMenuAction", "clickSubMenuAdditionalAction"] }, { kind: "pipe", type: RtSideMenuIconPipe, name: "rtSideMenuIcon" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
], template: "<ng-container rtBlock=\"rt-side-menu\">\n @if (narrow()) {\n <!-- \u0423\u0437\u043A\u0438\u0439 \u044D\u043A\u0440\u0430\u043D: \u043E\u0434\u0438\u043D \u0441\u0442\u043E\u043B\u0431\u0435\u0446 \u2014 \u0433\u043B\u0430\u0432\u043D\u044B\u0435 \u043F\u0443\u043D\u043A\u0442\u044B \u0438\u043B\u0438 \u043F\u043E\u0434\u043C\u0435\u043D\u044E \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u043E\u0433\u043E \u0440\u0430\u0437\u0434\u0435\u043B\u0430 \u0441 \u043A\u043D\u043E\u043F\u043A\u043E\u0439 \u043D\u0430\u0437\u0430\u0434. -->\n <rt-scroll-area rtElem=\"mobile\" [isScrollHintShown]=\"true\">\n @if (headerTpl(); as header) {\n <ng-container *rtScrollAreaHeader>\n <ng-container [ngTemplateOutlet]=\"header\" />\n </ng-container>\n }\n\n <ng-container *rtScrollAreaContent>\n @if (selectedSubMenu()?.length) {\n <div rtElem=\"mobile-sub\">\n <button type=\"button\" rtElem=\"back\" qa-dataid=\"side-menu-back\" (click)=\"onBackToMainMenu()\">\n <rt-icon rtElem=\"back-icon\" size=\"sm\" name=\"arrow-left\" />\n <span rtElem=\"back-label\">{{ backLabel() }}</span>\n </button>\n\n <ng-container [ngTemplateOutlet]=\"subMenuTpl\" />\n </div>\n } @else {\n <nav rtElem=\"mobile-list\">\n @for (item of menuItems(); track item.id) {\n <ng-container [ngTemplateOutlet]=\"mobileItemTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n }\n </nav>\n }\n </ng-container>\n\n @if (footerTpl(); as footer) {\n <ng-container *rtScrollAreaFooter>\n <ng-container [ngTemplateOutlet]=\"footer\" />\n </ng-container>\n }\n </rt-scroll-area>\n } @else {\n <rt-scroll-area rtElem=\"rail\" [isScrollHintShown]=\"true\">\n @if (headerTpl(); as header) {\n <ng-container *rtScrollAreaHeader>\n <ng-container [ngTemplateOutlet]=\"header\" />\n </ng-container>\n }\n\n <ng-container *rtScrollAreaContent>\n <nav rtElem=\"rail-list\">\n @for (item of menuItems(); track item.id) {\n <ng-container [ngTemplateOutlet]=\"railItemTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n }\n </nav>\n </ng-container>\n\n @if (footerTpl(); as footer) {\n <ng-container *rtScrollAreaFooter>\n <ng-container [ngTemplateOutlet]=\"footer\" />\n </ng-container>\n }\n </rt-scroll-area>\n\n @if (subMenuOpened()) {\n @if (isSearchHeld()) {\n <!-- \u041F\u043E\u0434\u043B\u043E\u0436\u043A\u0430 \u043D\u0435\u0437\u0430\u043A\u0440\u0435\u043F\u043B\u0451\u043D\u043D\u043E\u0439 \u043F\u0430\u043D\u0435\u043B\u0438: \u043F\u043E\u0434\u043C\u0435\u043D\u044E, \u0432\u0437\u044F\u0442\u043E\u0435 \u043F\u043E\u043B\u0435\u043C \u043F\u043E\u0438\u0441\u043A\u0430, \u0437\u0430\u043A\u0440\u044B\u0432\u0430\u0435\u0442 \u043D\u0430\u0436\u0430\u0442\u0438\u0435 \u0441\u043D\u0430\u0440\u0443\u0436\u0438. -->\n <div\n rtElem=\"backdrop\"\n qa-dataid=\"side-menu-backdrop\"\n tabindex=\"-1\"\n (click)=\"closeSubMenu()\"\n (keydown.escape)=\"closeSubMenu()\"></div>\n }\n\n <div\n #panel\n rtElem=\"panel\"\n qa-dataid=\"side-menu-panel\"\n [rtMod]=\"{ pinned: isPinned(), held: isSearchHeld() }\"\n (mouseenter)=\"cancelSubMenuClose()\"\n (mouseleave)=\"toggleSubMenu()\">\n <div rtElem=\"panel-head\">\n <rt-input\n rtElem=\"search\"\n qa-dataid=\"side-menu-search\"\n iconLeft=\"search\"\n [size]=\"searchSize()\"\n [appearance]=\"searchAppearance()\"\n [placeholder]=\"searchLabel()\"\n [ariaLabel]=\"searchLabel()\"\n [formControl]=\"searchControl\"\n (focusin)=\"onSearchHold()\"\n (keydown)=\"onSearchKeydown($event)\" />\n\n @if (pinShown()) {\n <rt-icon-button\n rtElem=\"pin\"\n qa-dataid=\"side-menu-pin\"\n size=\"sm\"\n icon=\"pin\"\n [iconFill]=\"isPinned()\"\n [active]=\"isPinned()\"\n [ariaLabel]=\"isPinned() ? unpinLabel() : pinLabel()\"\n [tooltip]=\"isPinned() ? unpinLabel() : pinLabel()\"\n (clicked)=\"onSubMenuModeToggle()\" />\n }\n </div>\n\n <rt-scroll-area rtElem=\"panel-body\" [isScrollHintShown]=\"panelScrollHintShown()\">\n <ng-container *rtScrollAreaContent>\n <ng-container [ngTemplateOutlet]=\"subMenuTpl\" />\n </ng-container>\n </rt-scroll-area>\n </div>\n\n @if (isPinned()) {\n <!-- \u0420\u0443\u0447\u043A\u0430 \u0435\u0441\u0442\u044C \u0442\u043E\u043B\u044C\u043A\u043E \u0443 \u0437\u0430\u043A\u0440\u0435\u043F\u043B\u0451\u043D\u043D\u043E\u0433\u043E \u043F\u043E\u0434\u043C\u0435\u043D\u044E: \u043D\u0435\u0437\u0430\u043A\u0440\u0435\u043F\u043B\u0451\u043D\u043D\u043E\u0435 \u0443\u0445\u043E\u0434\u0438\u0442 \u0440\u0430\u043D\u044C\u0448\u0435, \u0447\u0435\u043C \u0434\u043E \u043A\u0440\u0430\u044F \u0434\u043E\u0435\u0434\u0435\u0442 \u0440\u0443\u043A\u0430. -->\n <div\n rtElem=\"resizer\"\n qa-dataid=\"side-menu-resize\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n tabindex=\"0\"\n [attr.aria-label]=\"resizeLabel()\"\n [attr.aria-valuenow]=\"resizeValueNow()\"\n [attr.aria-valuemin]=\"resizeValueNow() === null ? null : resizeValueMin\"\n [attr.aria-valuemax]=\"resizeValueNow() === null ? null : resizeValueMax\"\n (pointerdown)=\"onResizeStart($event)\"\n (keydown)=\"onResizeKeydown($event)\"></div>\n }\n }\n }\n <ng-template #subMenuTpl>\n @if (narrow()) {\n <rt-input\n rtElem=\"search\"\n qa-dataid=\"side-menu-search\"\n iconLeft=\"search\"\n [size]=\"searchSize()\"\n [appearance]=\"searchAppearance()\"\n [placeholder]=\"searchLabel()\"\n [ariaLabel]=\"searchLabel()\"\n [formControl]=\"searchControl\"\n (keydown)=\"onSearchKeydown($event)\" />\n }\n\n @if (isNothingFound()) {\n <div rtElem=\"empty\" qa-dataid=\"side-menu-empty\">{{ nothingFoundLabel() }}</div>\n }\n\n <div rtElem=\"sub-list\">\n <!-- \u0411\u043B\u043E\u043A \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u0433\u043E \u0440\u0430\u0437\u0434\u0435\u043B\u0430: \u0441\u0430\u043C \u0440\u0435\u0448\u0430\u0435\u0442, \u0435\u0441\u0442\u044C \u043B\u0438 \u0435\u043C\u0443 \u0447\u0442\u043E \u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C, \u0438 \u0431\u0435\u0437 \u0441\u0442\u0440\u043E\u043A \u043C\u0435\u0441\u0442\u0430 \u043D\u0435 \u0437\u0430\u043D\u0438\u043C\u0430\u0435\u0442. -->\n <rt-side-menu-favorites\n (clickSubMenuAction)=\"onClickSubMenu($event)\"\n (clickSubMenuAdditionalAction)=\"onClickSubMenuAdditional($event)\" />\n\n @for (item of visibleSubMenuItems(); track item.id) {\n <rt-side-menu-sub-item\n [item]=\"item\"\n (clickSubMenuAction)=\"onClickSubMenu($event)\"\n (clickSubMenuAdditionalAction)=\"onClickSubMenuAdditional($event)\" />\n }\n </div>\n </ng-template>\n\n <ng-template #railItemTpl let-item>\n @let isActive = activeRailIds().includes(item.id);\n <!-- \u0411\u0435\u0437 \u043F\u043E\u0434\u043F\u0438\u0441\u0435\u0439 \u043F\u043E\u0434 \u0437\u043D\u0430\u0447\u043A\u0430\u043C\u0438 \u0438\u043C\u044F \u043F\u0443\u043D\u043A\u0442\u0430 \u2014 \u0432 \u043F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0435 \u0441\u043F\u0440\u0430\u0432\u0430; \u0432\u044B\u043A\u043B\u044E\u0447\u0435\u043D\u043D\u044B\u0435 \u043F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0438 \u0433\u0430\u0441\u044F\u0442 \u0438 \u0435\u0451. -->\n @let railTip = railTitlesShown() || !subMenuTooltipsShown() ? '' : item.name;\n @if (item.link) {\n <a\n rtElem=\"rail-item\"\n qa-dataid=\"side-menu-item\"\n rtTooltipPlacement=\"right\"\n [routerLink]=\"item.link\"\n [rtMod]=\"{ active: isActive }\"\n [attr.aria-current]=\"isActive ? 'page' : null\"\n [attr.aria-label]=\"railTitlesShown() ? null : item.name\"\n [rtTooltip]=\"railTip\"\n (mouseenter)=\"toggleSubMenu(item)\"\n (click)=\"onClickMenu(item)\">\n <ng-container [ngTemplateOutlet]=\"railItemBodyTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n </a>\n } @else {\n <button\n type=\"button\"\n rtElem=\"rail-item\"\n qa-dataid=\"side-menu-item\"\n rtTooltipPlacement=\"right\"\n [rtMod]=\"{ active: isActive }\"\n [attr.aria-label]=\"railTitlesShown() ? null : item.name\"\n [rtTooltip]=\"railTip\"\n [attr.aria-expanded]=\"item.submenu?.length ? subMenuOpened() && selectedItem() === item : null\"\n (mouseenter)=\"toggleSubMenu(item)\"\n (click)=\"onClickMenu(item)\">\n <ng-container [ngTemplateOutlet]=\"railItemBodyTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n </button>\n }\n </ng-template>\n\n <ng-template #railItemBodyTpl let-item>\n @if (item.icon) {\n <!-- \u0418\u043C\u044F Material \u043F\u0435\u0440\u0432\u043E\u0433\u043E \u043A\u0438\u0442\u0430 \u0440\u0438\u0441\u0443\u0435\u0442\u0441\u044F \u0441\u0432\u043E\u0435\u0439 \u043F\u0430\u0440\u043E\u0439; \u0438\u043C\u044F, \u043A\u043E\u0442\u043E\u0440\u043E\u0433\u043E \u043A\u0438\u0442 \u043D\u0435 \u0440\u0438\u0441\u0443\u0435\u0442, \u2014 \u0441\u0432\u043E\u0438\u043C \u0448\u0430\u0431\u043B\u043E\u043D\u043E\u043C \u043C\u0435\u043D\u044E. -->\n @let kitIcon = item.icon | rtSideMenuIcon;\n <span rtElem=\"rail-icon\">\n @if (kitIcon) {\n <rt-icon [name]=\"kitIcon\" [fill]=\"railIconFill()\" />\n } @else if (ownIconTpl(); as own) {\n <span rtElem=\"own-icon\" qa-dataid=\"side-menu-own-icon\" aria-hidden=\"true\">\n <ng-container\n [ngTemplateOutlet]=\"own\"\n [ngTemplateOutletContext]=\"{ $implicit: item, icon: item.icon, slot: 'icon' }\" />\n </span>\n }\n </span>\n }\n\n @if (item.name && railTitlesShown()) {\n <span rtElem=\"rail-title\">{{ item.name }}</span>\n }\n </ng-template>\n\n <ng-template #mobileItemTpl let-item>\n @let isActive = activeRailIds().includes(item.id);\n @if (item.link && !item.submenu?.length) {\n <a\n rtElem=\"mobile-item\"\n qa-dataid=\"side-menu-item\"\n [routerLink]=\"item.link\"\n [rtMod]=\"{ active: isActive }\"\n [attr.aria-current]=\"isActive ? 'page' : null\"\n (click)=\"onClickMenu(item)\">\n <ng-container [ngTemplateOutlet]=\"mobileItemBodyTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n </a>\n } @else {\n <button\n type=\"button\"\n rtElem=\"mobile-item\"\n qa-dataid=\"side-menu-item\"\n [rtMod]=\"{ active: isActive }\"\n (click)=\"onClickMenu(item)\">\n <ng-container [ngTemplateOutlet]=\"mobileItemBodyTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n </button>\n }\n </ng-template>\n\n <ng-template #mobileItemBodyTpl let-item>\n @if (item.icon) {\n @let kitIcon = item.icon | rtSideMenuIcon;\n @if (kitIcon) {\n <rt-icon rtElem=\"mobile-icon\" [name]=\"kitIcon\" />\n } @else if (ownIconTpl(); as own) {\n <span rtElem=\"own-icon\" qa-dataid=\"side-menu-own-icon\" aria-hidden=\"true\">\n <ng-container [ngTemplateOutlet]=\"own\" [ngTemplateOutletContext]=\"{ $implicit: item, icon: item.icon, slot: 'icon' }\" />\n </span>\n }\n }\n\n <span rtElem=\"mobile-title\" [rtTooltip]=\"item.name\">{{ item.name }}</span>\n\n @if (item.submenu?.length) {\n <!-- \u0421\u0442\u0440\u0435\u043B\u043A\u0430 \u0440\u0430\u0437\u0434\u0435\u043B\u0430, \u043A\u0430\u043A \u0443 \u043F\u0435\u0440\u0432\u043E\u0433\u043E \u043A\u0438\u0442\u0430: \u043D\u0430\u0436\u0430\u0442\u0438\u0435 \u0443\u0432\u043E\u0434\u0438\u0442 \u0432 \u043F\u043E\u0434\u043C\u0435\u043D\u044E, \u0430 \u043D\u0435 \u0440\u0430\u0441\u043A\u0440\u044B\u0432\u0430\u0435\u0442 \u043D\u0430 \u043C\u0435\u0441\u0442\u0435. -->\n <rt-icon rtElem=\"mobile-chevron\" size=\"sm\" name=\"arrow-right\" />\n }\n </ng-template>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-side-menu,.rt-side-menu-favorites__row.cdk-drag-preview{--rt-side-menu-item-color: currentcolor;--rt-side-menu-item-bg-hover: var(--rt-color-bg-hover);--rt-side-menu-item-bg-active: var(--rt-color-action-primary-subtle);--rt-side-menu-item-color-active: var(--rt-color-action-primary-on-surface)}.rt-side-menu{--rt-side-menu-rail-width: 5.5rem;--rt-side-menu-panel-width: 15rem;--rt-side-menu-panel-held-width: 30rem;--rt-side-menu-mobile-width: 15rem;--rt-side-menu-panel-radius: var(--rt-radius-lg);--rt-side-menu-panel-shadow: var(--rt-shadow-nav-panel);--rt-side-menu-item-radius: var(--rt-radius-full);--rt-side-menu-resizer-border-width: var(--rt-border-width-thick);--rt-side-menu-panel-border-width: var(--rt-border-width-thin);--rt-side-menu-transition-duration: var(--rt-duration-fast);--rt-side-menu-rail-icon-size: var(--rt-icon-step-md);--rt-side-menu-rail-gap: var(--rt-space-md);--rt-side-menu-rail-bg: var(--rt-color-bg-surface);--rt-side-menu-rail-border-width: var(--rt-side-menu-panel-border-width);--rt-side-menu-panel-bg: var(--rt-color-bg-surface);--rt-side-menu-panel-head-padding: var(--rt-space-sm);--rt-side-menu-sub-list-padding-inline: var(--rt-space-2);--rt-side-menu-empty-padding: var(--rt-space-md);--rt-side-menu-panel-dragged-width: 0px;--rt-side-menu-panel-shown-width: max(var(--rt-side-menu-panel-width), var(--rt-side-menu-panel-dragged-width));position:relative;display:flex;height:100%;color:var(--rt-color-text-primary)}.rt-side-menu__rail{max-width:var(--rt-side-menu-rail-width);height:100%;box-sizing:border-box;flex:0 0 var(--rt-side-menu-rail-width);border-right:var(--rt-side-menu-rail-border-width) solid var(--rt-color-border-default);background:var(--rt-side-menu-rail-bg)}.rt-side-menu__rail .rt-scroll-area__body{padding-inline:var(--rt-space-1)}.rt-side-menu__rail-list{display:flex;flex-direction:column;align-items:center;gap:var(--rt-side-menu-rail-gap);padding-block:var(--rt-space-sm)}.rt-side-menu__rail-item{display:flex;width:100%;flex-direction:column;align-items:center;padding:0;border:0;background:transparent;color:var(--rt-side-menu-item-color);cursor:pointer;font:inherit;gap:var(--rt-space-1);text-decoration:none}.rt-side-menu__rail-item:focus-visible{outline:none}.rt-side-menu__rail-item:focus-visible .rt-side-menu__rail-icon{outline:var(--rt-focus-ring-width) solid var(--rt-focus-ring-color)}.rt-side-menu__rail-item:hover .rt-side-menu__rail-icon,.rt-side-menu__rail-item:active .rt-side-menu__rail-icon{background:var(--rt-side-menu-item-bg-hover)}.rt-side-menu__rail-item--active .rt-side-menu__rail-icon,.rt-side-menu__rail-item--active:hover .rt-side-menu__rail-icon{background:var(--rt-side-menu-item-bg-active);color:var(--rt-side-menu-item-color-active)}.rt-side-menu__rail-icon{--rt-icon-step-md: var(--rt-side-menu-rail-icon-size);display:flex;width:3.5rem;height:2rem;align-items:center;justify-content:center;border-radius:var(--rt-side-menu-item-radius);transition:background-color var(--rt-side-menu-transition-duration) ease}.rt-side-menu__rail-title{max-width:100%;font-size:var(--rt-text-xs);line-height:var(--rt-leading-snug);overflow-wrap:anywhere;text-align:center}.rt-side-menu__backdrop{position:fixed;z-index:var(--rt-z-dropdown);inset:0;inset-inline-start:var(--rt-side-menu-rail-width)}.rt-side-menu__panel{position:absolute;z-index:var(--rt-z-dropdown);top:0;left:var(--rt-side-menu-rail-width);display:flex;width:var(--rt-side-menu-panel-shown-width);height:100%;box-sizing:border-box;flex-direction:column;border-radius:0 var(--rt-side-menu-panel-radius) var(--rt-side-menu-panel-radius) 0;border-left:var(--rt-side-menu-panel-border-width) solid var(--rt-color-border-default);background:var(--rt-side-menu-panel-bg);box-shadow:var(--rt-side-menu-panel-shadow)}.rt-side-menu__panel--held{width:max(var(--rt-side-menu-panel-held-width),var(--rt-side-menu-panel-shown-width))}.rt-side-menu__panel--pinned{--rt-side-menu-panel-radius: 0;--rt-side-menu-panel-shadow: var(--rt-shadow-none);position:relative;left:0;flex-shrink:0}.rt-side-menu__panel-head{display:flex;align-items:center;padding:var(--rt-side-menu-panel-head-padding);gap:var(--rt-space-2)}.rt-side-menu__search{min-width:0;flex:1 1 auto}.rt-side-menu__pin{flex-shrink:0}.rt-side-menu__panel-body{min-height:0;flex:1 1 auto}.rt-side-menu__sub-list{display:flex;flex-direction:column;padding-block-end:var(--rt-space-sm);padding-inline:var(--rt-side-menu-sub-list-padding-inline)}.rt-side-menu__empty{padding:var(--rt-side-menu-empty-padding);color:var(--rt-color-text-muted);font-size:var(--rt-text-xs)}.rt-side-menu__resizer{position:absolute;z-index:var(--rt-z-dropdown);top:0;bottom:0;left:calc(var(--rt-side-menu-rail-width) + var(--rt-side-menu-panel-shown-width) - var(--rt-space-2));width:var(--rt-space-sm);cursor:col-resize}.rt-side-menu__resizer:before{position:absolute;top:0;bottom:0;left:50%;border-left:var(--rt-side-menu-resizer-border-width) solid transparent;content:\"\"}.rt-side-menu__resizer:hover:before,.rt-side-menu__resizer:focus-visible:before{border-left-color:var(--rt-color-border-strong)}.rt-side-menu__resizer:focus-visible{outline:none}.rt-side-menu__mobile{min-width:0;max-width:100%;height:100%;flex:0 0 var(--rt-side-menu-mobile-width);background:var(--rt-color-bg-surface)}.rt-side-menu__mobile .rt-scroll-area__body{padding-inline:0}.rt-side-menu__mobile-list,.rt-side-menu__mobile-sub{display:flex;flex-direction:column;padding:var(--rt-space-sm);gap:var(--rt-space-1)}.rt-side-menu__mobile-item,.rt-side-menu__back{display:flex;width:100%;min-height:var(--rt-control-height-lg);box-sizing:border-box;align-items:center;border:0;border-radius:var(--rt-side-menu-item-radius);background:transparent;color:var(--rt-side-menu-item-color);cursor:pointer;font:inherit;font-size:var(--rt-text-sm);gap:calc(var(--rt-space-sm) + var(--rt-space-xs));padding-inline:var(--rt-space-md);text-align:start;text-decoration:none}.rt-side-menu__mobile-item:hover,.rt-side-menu__back:hover{background:var(--rt-side-menu-item-bg-hover)}.rt-side-menu__mobile-item:focus-visible,.rt-side-menu__back:focus-visible{outline:var(--rt-focus-ring-width) solid var(--rt-focus-ring-color);outline-offset:calc(var(--rt-focus-ring-width) * -1)}.rt-side-menu__mobile-item--active,.rt-side-menu__back--active{background:var(--rt-side-menu-item-bg-active);color:var(--rt-side-menu-item-color-active)}.rt-side-menu__own-icon{--rt-side-menu-own-icon-size: var(--rt-size-5);display:inline-flex;width:var(--rt-side-menu-own-icon-size);height:var(--rt-side-menu-own-icon-size);flex-shrink:0;align-items:center;justify-content:center;color:inherit;line-height:1}.rt-side-menu__own-icon>*{max-width:100%;max-height:100%}.rt-side-menu__mobile-icon,.rt-side-menu__back-icon,.rt-side-menu__mobile-chevron{flex-shrink:0}.rt-side-menu__mobile-title,.rt-side-menu__back-label{overflow:hidden;min-width:0;flex:1 1 auto;text-overflow:ellipsis;white-space:nowrap}}\n"] }]
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
472
|
+
var RtSideMenuIconPipe = class RtSideMenuIconPipe {
|
|
473
|
+
transform(icon) {
|
|
474
|
+
return sideMenuIconName(icon);
|
|
475
|
+
}
|
|
476
|
+
static {
|
|
477
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
478
|
+
minVersion: "12.0.0",
|
|
479
|
+
version: "22.2.2",
|
|
480
|
+
ngImport: i0,
|
|
481
|
+
type: RtSideMenuIconPipe,
|
|
482
|
+
deps: [],
|
|
483
|
+
target: i0.ɵɵFactoryTarget.Pipe
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
static {
|
|
487
|
+
this.ɵpipe = i0.ɵɵngDeclarePipe({
|
|
488
|
+
minVersion: "14.0.0",
|
|
489
|
+
version: "22.2.2",
|
|
490
|
+
ngImport: i0,
|
|
491
|
+
type: RtSideMenuIconPipe,
|
|
492
|
+
isStandalone: true,
|
|
493
|
+
name: "rtSideMenuIcon"
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
498
|
+
minVersion: "12.0.0",
|
|
499
|
+
version: "22.2.2",
|
|
500
|
+
ngImport: i0,
|
|
501
|
+
type: RtSideMenuIconPipe,
|
|
502
|
+
decorators: [{
|
|
503
|
+
type: Pipe,
|
|
504
|
+
args: [{ name: "rtSideMenuIcon" }]
|
|
505
|
+
}]
|
|
506
|
+
});
|
|
507
|
+
var RtSideMenuTitlePartsPipe = class RtSideMenuTitlePartsPipe {
|
|
508
|
+
transform(name, query) {
|
|
509
|
+
return splitSideMenuTitle(name ?? "", query);
|
|
510
|
+
}
|
|
511
|
+
static {
|
|
512
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
513
|
+
minVersion: "12.0.0",
|
|
514
|
+
version: "22.2.2",
|
|
515
|
+
ngImport: i0,
|
|
516
|
+
type: RtSideMenuTitlePartsPipe,
|
|
517
|
+
deps: [],
|
|
518
|
+
target: i0.ɵɵFactoryTarget.Pipe
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
static {
|
|
522
|
+
this.ɵpipe = i0.ɵɵngDeclarePipe({
|
|
523
|
+
minVersion: "14.0.0",
|
|
524
|
+
version: "22.2.2",
|
|
525
|
+
ngImport: i0,
|
|
526
|
+
type: RtSideMenuTitlePartsPipe,
|
|
527
|
+
isStandalone: true,
|
|
528
|
+
name: "rtSideMenuTitleParts"
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
};
|
|
532
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
533
|
+
minVersion: "12.0.0",
|
|
534
|
+
version: "22.2.2",
|
|
535
|
+
ngImport: i0,
|
|
536
|
+
type: RtSideMenuTitlePartsPipe,
|
|
537
|
+
decorators: [{
|
|
538
|
+
type: Pipe,
|
|
539
|
+
args: [{ name: "rtSideMenuTitleParts" }]
|
|
540
|
+
}]
|
|
541
|
+
});
|
|
542
|
+
const BEM_BLOCK$2 = "rt-side-menu-sub-item";
|
|
543
|
+
const FAVORITE_ROW = ".rt-side-menu-favorites__row";
|
|
544
|
+
const FAVORITE_BUTTON = ".rt-side-menu-sub-item__favorite button";
|
|
545
|
+
var RtSideMenuSubItemComponent = class RtSideMenuSubItemComponent {
|
|
546
|
+
constructor() {
|
|
547
|
+
this.#settings = inject(RtSideMenuSettingsService, { optional: true });
|
|
548
|
+
this.#router = inject(Router);
|
|
549
|
+
this.#route = inject(ActivatedRoute, { optional: true });
|
|
550
|
+
this.#errors = inject(ErrorHandler);
|
|
551
|
+
this.menuRef = inject(RT_SIDE_MENU);
|
|
552
|
+
this.narrow = inject(BreakpointsService).narrow;
|
|
553
|
+
this.favoritesIcons = this.#settings?.favoritesIcons ?? null;
|
|
554
|
+
this.addLabel = rtKitLabel("sideMenuFavoriteAdd");
|
|
555
|
+
this.removeLabel = rtKitLabel("sideMenuFavoriteRemove");
|
|
556
|
+
this.favoritesOn = computed(() => !!this.#settings && sideMenuFavoritesSection(this.menuRef.menuItems(), this.menuRef.shownSubMenu()) !== null, ...ngDevMode ? [{ debugName: "favoritesOn" }] : /* istanbul ignore next */ []);
|
|
557
|
+
this.favoriteIds = computed(() => this.#settings?.favoriteIds(this.menuRef.menuId())() ?? [], ...ngDevMode ? [{ debugName: "favoriteIds" }] : /* istanbul ignore next */ []);
|
|
558
|
+
this.item = input.required(...ngDevMode ? [{ debugName: "item" }] : /* istanbul ignore next */ []);
|
|
559
|
+
this.inFavorites = input(false, {
|
|
560
|
+
...ngDevMode ? { debugName: "inFavorites" } : /* istanbul ignore next */ {},
|
|
561
|
+
transform: booleanAttribute
|
|
562
|
+
});
|
|
563
|
+
this.clickSubMenuAction = output();
|
|
564
|
+
this.clickSubMenuAdditionalAction = output();
|
|
565
|
+
}
|
|
566
|
+
#settings;
|
|
567
|
+
#router;
|
|
568
|
+
#route;
|
|
569
|
+
#errors;
|
|
570
|
+
onClickSubMenu(item, event) {
|
|
571
|
+
this.clickSubMenuAction.emit({
|
|
572
|
+
item,
|
|
573
|
+
event
|
|
574
|
+
});
|
|
575
|
+
if (event.defaultPrevented || !item.link || sideMenuPressOpensInBrowser(event)) return;
|
|
576
|
+
event.preventDefault();
|
|
577
|
+
this.#router.navigateByUrl(sideMenuLinkTree(this.#router, this.#route, item.link)).catch((error) => this.#errors.handleError(error));
|
|
578
|
+
}
|
|
579
|
+
onClickSubMenuAdditional(item, event) {
|
|
580
|
+
event.preventDefault();
|
|
581
|
+
event.stopPropagation();
|
|
582
|
+
this.clickSubMenuAdditionalAction.emit({
|
|
583
|
+
data: item.iconButton?.data,
|
|
584
|
+
event
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
onToggleFavorite(item, event) {
|
|
588
|
+
event.preventDefault();
|
|
589
|
+
event.stopPropagation();
|
|
590
|
+
this.#settings?.toggleFavorite(this.menuRef.menuId(), item.id);
|
|
591
|
+
}
|
|
592
|
+
onRemoveFavorite(item, event) {
|
|
593
|
+
event.preventDefault();
|
|
594
|
+
event.stopPropagation();
|
|
595
|
+
const row = event.target instanceof Element ? event.target.closest(FAVORITE_ROW) : null;
|
|
596
|
+
(row?.nextElementSibling ?? row?.previousElementSibling)?.querySelector(FAVORITE_BUTTON)?.focus();
|
|
597
|
+
this.#settings?.removeFavorite(this.menuRef.menuId(), item.id);
|
|
598
|
+
}
|
|
599
|
+
onToggleFolder(item) {
|
|
600
|
+
this.menuRef.toggleFolder(item);
|
|
601
|
+
}
|
|
602
|
+
static {
|
|
603
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
604
|
+
minVersion: "12.0.0",
|
|
605
|
+
version: "22.2.2",
|
|
606
|
+
ngImport: i0,
|
|
607
|
+
type: RtSideMenuSubItemComponent,
|
|
608
|
+
deps: [],
|
|
609
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
static {
|
|
613
|
+
this.ɵcmp = i0.ɵɵngDeclareComponent({
|
|
614
|
+
minVersion: "17.0.0",
|
|
615
|
+
version: "22.2.2",
|
|
616
|
+
type: RtSideMenuSubItemComponent,
|
|
617
|
+
isStandalone: true,
|
|
618
|
+
selector: "rt-side-menu-sub-item",
|
|
619
|
+
inputs: {
|
|
620
|
+
item: {
|
|
621
|
+
classPropertyName: "item",
|
|
622
|
+
publicName: "item",
|
|
623
|
+
isSignal: true,
|
|
624
|
+
isRequired: true,
|
|
625
|
+
transformFunction: null
|
|
626
|
+
},
|
|
627
|
+
inFavorites: {
|
|
628
|
+
classPropertyName: "inFavorites",
|
|
629
|
+
publicName: "inFavorites",
|
|
630
|
+
isSignal: true,
|
|
631
|
+
isRequired: false,
|
|
632
|
+
transformFunction: null
|
|
633
|
+
}
|
|
634
|
+
},
|
|
635
|
+
outputs: {
|
|
636
|
+
clickSubMenuAction: "clickSubMenuAction",
|
|
637
|
+
clickSubMenuAdditionalAction: "clickSubMenuAdditionalAction"
|
|
638
|
+
},
|
|
639
|
+
host: { classAttribute: "rt-side-menu-sub-item" },
|
|
640
|
+
ngImport: i0,
|
|
641
|
+
template: "<ng-container rtBlock=\"rt-side-menu-sub-item\">\n <ng-container [ngTemplateOutlet]=\"rowTpl\" [ngTemplateOutletContext]=\"{ $implicit: item(), depth: 0 }\" />\n <ng-template #rowTpl let-row let-depth=\"depth\">\n @let isActive = menuRef.activeMenuIds().includes(row.id);\n @let isHighlighted = !inFavorites() && menuRef.highlightedMenuId() === row.id;\n @if (row.link) {\n <!--\n Номер пункта на самой строке — признак для правил приложения: по нему оно находит строку,\n например ту, что открывает страницу раздела. Стоит и у строки блока избранного.\n Строка блока избранного без номера: по номеру клавиатура нажимает строку списка. И без\n родного перетаскивания ссылки: нажатие на ручку внутри строки браузер забирал себе,\n и перетаскивание CDK не начиналось.\n -->\n <a\n rtElem=\"row\"\n qa-dataid=\"side-menu-sub-item\"\n [id]=\"inFavorites() ? null : row.id\"\n [attr.data-item-id]=\"row.id\"\n [attr.draggable]=\"inFavorites() ? 'false' : null\"\n [attr.href]=\"row.link | rtSideMenuHref\"\n [style.--rt-side-menu-sub-item-depth]=\"depth\"\n [rtMod]=\"{ active: isActive, highlighted: isHighlighted }\"\n [attr.aria-current]=\"isActive ? 'page' : null\"\n (click)=\"onClickSubMenu(row, $event)\">\n @if (row.icon) {\n <ng-container [ngTemplateOutlet]=\"iconTpl\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n }\n\n <span rtElem=\"title\" [rtTooltip]=\"menuRef.subMenuTooltipsShown() ? row.name : ''\">\n <!-- Кусок без отметки тоже узел: голая интерполяция разрывала бы подпись пробелами. -->\n @for (part of row.name | rtSideMenuTitleParts: menuRef.subMenuQuery(); track $index) {\n @if (part.matched) {\n <span rtElem=\"match\">{{ part.text }}</span>\n } @else {\n <span rtElem=\"part\">{{ part.text }}</span>\n }\n }\n </span>\n\n <!--\n Строка блока несёт «убрать», а не звезду: всё в блоке уже в избранном. Звезда —\n у пункта со своим адресом в разделе с избранным: полая — не в избранном,\n закрашенная цветом темы — в нём. Имя кнопки называет следующее нажатие.\n -->\n @if (inFavorites() && favoritesIcons) {\n <rt-icon-button\n rtElem=\"favorite\"\n qa-dataid=\"side-menu-favorite-remove\"\n size=\"sm\"\n [rtMod]=\"{ remove: true }\"\n [icon]=\"favoritesIcons.remove\"\n [ariaLabel]=\"removeLabel()\"\n [tooltip]=\"narrow() || !menuRef.subMenuTooltipsShown() ? '' : removeLabel()\"\n (clicked)=\"onRemoveFavorite(row, $event)\" />\n } @else if (favoritesOn() && !row.favoriteDisabled) {\n @let isFavorite = favoriteIds().includes(row.id);\n <rt-icon-button\n rtElem=\"favorite\"\n qa-dataid=\"side-menu-favorite-star\"\n size=\"sm\"\n [rtMod]=\"{ on: isFavorite }\"\n [icon]=\"isFavorite ? 'star-fill' : 'star'\"\n [iconFill]=\"isFavorite\"\n [ariaLabel]=\"isFavorite ? removeLabel() : addLabel()\"\n [tooltip]=\"narrow() || !menuRef.subMenuTooltipsShown() ? '' : isFavorite ? removeLabel() : addLabel()\"\n (clicked)=\"onToggleFavorite(row, $event)\" />\n }\n\n <!-- Действия, которые строке передаёт владелец: блок избранного кладёт сюда ручку. -->\n <ng-content select=\"[rtSideMenuSubItemAction]\" />\n\n <!-- Кнопка потребителя видна всегда и стоит последней: кнопки избранного встают перед ней. -->\n @if (row.iconButton?.icon; as buttonIcon) {\n <!-- Имя без значка кита берёт свой шаблон меню, как значок строки. Без шаблона кнопка пуста и\n незнакомого имени значку не передаёт: значка с таким именем нет, и ждать его некому. -->\n @let buttonKitIcon = buttonIcon | rtSideMenuIcon;\n @let buttonOwnTpl = buttonKitIcon ? null : menuRef.ownIconTpl();\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"side-menu-sub-item-action\"\n size=\"sm\"\n [icon]=\"buttonKitIcon\"\n [iconFill]=\"menuRef.subItemIconFill()\"\n [ariaLabel]=\"row.name ?? ''\"\n (clicked)=\"onClickSubMenuAdditional(row, $event)\">\n @if (buttonOwnTpl) {\n <span rtElem=\"own-icon\" qa-dataid=\"side-menu-own-button-icon\" aria-hidden=\"true\">\n <ng-container\n [ngTemplateOutlet]=\"buttonOwnTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: row, icon: buttonIcon, slot: 'iconButton' }\" />\n </span>\n }\n </rt-icon-button>\n }\n </a>\n } @else if (row.submenu) {\n <!--\n Папка — раскрывающаяся панель кита. Рисуется и с пустым составом: отбор оставляет так\n ту, что совпала подписью. Шеврона у такой папки нет — раскрывать нечего. Раскрытие\n держит меню: панель сообщает о нажатии, меню переключает папку. Кнопке заголовка\n отдан номер пункта — по нему клавиатура меню нажимает строку.\n -->\n @let isOpen = menuRef.expandedMenuIds().includes(row.id);\n <rt-expansion-panel\n rtElem=\"folder\"\n appearance=\"plain\"\n [headerId]=\"'' + row.id\"\n [attr.data-item-id]=\"row.id\"\n [hideToggle]=\"!row.submenu.length\"\n [expanded]=\"isOpen\"\n [style.--rt-side-menu-sub-item-depth]=\"depth\"\n [rtMod]=\"{ highlighted: isHighlighted }\"\n (expandedChange)=\"onToggleFolder(row)\">\n @if (row.icon) {\n <ng-container [ngTemplateOutlet]=\"iconTpl\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n }\n\n <span rtElem=\"title\" qa-dataid=\"side-menu-folder\" [rtTooltip]=\"menuRef.subMenuTooltipsShown() ? row.name : ''\">\n @for (part of row.name | rtSideMenuTitleParts: menuRef.subMenuQuery(); track $index) {\n @if (part.matched) {\n <span rtElem=\"match\">{{ part.text }}</span>\n } @else {\n <span rtElem=\"part\">{{ part.text }}</span>\n }\n }\n </span>\n\n <ng-template rtExpansionPanelContent>\n <div rtElem=\"children\" role=\"group\">\n @for (child of row.submenu; track child.id) {\n <ng-container [ngTemplateOutlet]=\"rowTpl\" [ngTemplateOutletContext]=\"{ $implicit: child, depth: depth + 1 }\" />\n }\n </div>\n </ng-template>\n </rt-expansion-panel>\n }\n </ng-template>\n\n <!-- Значок строки: имя кита или пара имени Material, а имя, которого кит не рисует, — свой шаблон меню. -->\n <ng-template #iconTpl let-row>\n @let kitIcon = row.icon | rtSideMenuIcon;\n @if (kitIcon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"kitIcon\" [fill]=\"menuRef.subItemIconFill()\" />\n } @else if (menuRef.ownIconTpl(); as own) {\n <span rtElem=\"own-icon\" qa-dataid=\"side-menu-own-icon\" aria-hidden=\"true\">\n <ng-container [ngTemplateOutlet]=\"own\" [ngTemplateOutletContext]=\"{ $implicit: row, icon: row.icon, slot: 'icon' }\" />\n </span>\n }\n </ng-template>\n</ng-container>\n",
|
|
642
|
+
styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-side-menu-sub-item{--rt-side-menu-sub-item-radius: var(--rt-radius-full);--rt-side-menu-sub-item-transition-duration: var(--rt-duration-fast);--rt-side-menu-sub-item-match-bg: var(--rt-yellow-400);--rt-side-menu-sub-item-match-color: var(--rt-neutral-950);--rt-side-menu-sub-item-match-radius: var(--rt-radius-xs);--rt-side-menu-sub-item-min-height: var(--rt-control-height-md);--rt-side-menu-sub-item-font-size: var(--rt-text-sm);--rt-side-menu-sub-item-padding-start: var(--rt-space-md);--rt-side-menu-sub-item-padding-end: var(--rt-space-sm);--rt-side-menu-sub-item-color: var(--rt-color-text-primary);--rt-side-menu-sub-item-gap: var(--rt-space-sm);--rt-side-menu-sub-item-folder-padding-start: var(--rt-side-menu-sub-item-padding-start);--rt-side-menu-sub-item-chevron-color: var(--rt-color-text-muted);--rt-side-menu-sub-item-icon-size: var(--rt-icon-step-sm);--rt-side-menu-sub-item-button-radius: var(--rt-radius-md);--rt-side-menu-sub-item-button-icon-size: var(--rt-icon-step-sm);--rt-side-menu-sub-item-action-size: var(--rt-control-height-sm);--rt-side-menu-sub-item-favorite-size: var(--rt-control-height-sm);--rt-side-menu-sub-item-favorite-color: var(--rt-color-text-primary);display:block;letter-spacing:var(--rt-side-menu-sub-item-letter-spacing, inherit)}.rt-side-menu-sub-item__row{--rt-side-menu-sub-item-depth: 0;display:flex;width:100%;min-height:var(--rt-side-menu-sub-item-min-height);box-sizing:border-box;align-items:center;border:0;border-radius:var(--rt-side-menu-sub-item-radius);background:transparent;color:var(--rt-side-menu-sub-item-color);cursor:pointer;font:inherit;font-size:var(--rt-side-menu-sub-item-font-size);gap:var(--rt-side-menu-sub-item-gap);padding-block:var(--rt-space-2);padding-inline:calc(var(--rt-side-menu-sub-item-padding-start) * (1 + var(--rt-side-menu-sub-item-depth))) var(--rt-side-menu-sub-item-padding-end);text-align:start;text-decoration:none;transition:background-color var(--rt-side-menu-sub-item-transition-duration) ease}.rt-side-menu-sub-item__row:hover,.rt-side-menu-sub-item__row:active,.rt-side-menu-sub-item__row--highlighted{background:var(--rt-side-menu-item-bg-hover)}.rt-side-menu-sub-item__row:focus-visible{outline:var(--rt-focus-ring-width) solid var(--rt-focus-ring-color);outline-offset:calc(var(--rt-focus-ring-width) * -1)}.rt-side-menu-sub-item__row--active{background:var(--rt-side-menu-item-bg-active);color:var(--rt-side-menu-item-color-active)}.rt-side-menu-sub-item__icon{--rt-icon-step-sm: var(--rt-side-menu-sub-item-icon-size);flex-shrink:0;color:inherit}.rt-side-menu-sub-item__own-icon{--rt-side-menu-sub-item-own-icon-size: var(--rt-size-4);display:inline-flex;width:var(--rt-side-menu-sub-item-own-icon-size);height:var(--rt-side-menu-sub-item-own-icon-size);flex-shrink:0;align-items:center;justify-content:center;color:inherit;line-height:1}.rt-side-menu-sub-item__own-icon>*{max-width:100%;max-height:100%}.rt-side-menu-sub-item__title{overflow:hidden;min-width:0;flex:1 1 auto;text-overflow:ellipsis;white-space:nowrap}.rt-side-menu-sub-item__part{color:inherit}.rt-side-menu-sub-item__match{border-radius:var(--rt-side-menu-sub-item-match-radius);background:var(--rt-side-menu-sub-item-match-bg);color:var(--rt-side-menu-sub-item-match-color)}.rt-side-menu-sub-item__action{--rt-side-menu-sub-item-action-ring-width: var(--rt-border-width-thin);--rt-side-menu-sub-item-action-radius: var(--rt-radius-full);flex-shrink:0;border-radius:var(--rt-side-menu-sub-item-action-radius);outline:var(--rt-side-menu-sub-item-action-ring-width) solid transparent;outline-offset:calc(var(--rt-side-menu-sub-item-action-ring-width) * -1)}.rt-side-menu-sub-item__action:hover{outline-color:var(--rt-color-border-strong)}.rt-side-menu-sub-item__action>.rt-icon-button{--rt-icon-button-size-step: var(--rt-side-menu-sub-item-action-size)}.rt-side-menu-sub-item__action,.rt-side-menu-sub-item__favorite{--rt-icon-step-sm: var(--rt-side-menu-sub-item-button-icon-size)}.rt-side-menu-sub-item__action>.rt-icon-button,.rt-side-menu-sub-item__favorite>.rt-icon-button{--rt-icon-button-radius: var(--rt-side-menu-sub-item-button-radius)}.rt-side-menu-sub-item__favorite{--rt-icon-button-color: var(--rt-side-menu-sub-item-favorite-color);flex-shrink:0;opacity:0}.rt-side-menu-sub-item__favorite>.rt-icon-button{--rt-icon-button-size-step: var(--rt-side-menu-sub-item-favorite-size)}.rt-side-menu-sub-item__favorite--on{--rt-icon-button-color: var(--rt-color-action-primary);opacity:1}@media(hover:hover){.rt-side-menu-sub-item__favorite--remove:hover{--rt-icon-button-color: var(--rt-color-state-danger)}}.rt-side-menu-sub-item__favorite--remove:has(:focus-visible){--rt-icon-button-color: var(--rt-color-state-danger)}@media(hover:none){.rt-side-menu-sub-item__favorite{opacity:1}}.rt-side-menu-sub-item__row:hover .rt-side-menu-sub-item__favorite,.rt-side-menu-sub-item__row:focus-visible .rt-side-menu-sub-item__favorite,.rt-side-menu-sub-item__row:has(:focus-visible) .rt-side-menu-sub-item__favorite{opacity:1}.rt-side-menu-sub-item__folder.rt-expansion-panel{--rt-expansion-panel-duration: var(--rt-side-menu-sub-item-transition-duration);--rt-expansion-panel-header-radius: var(--rt-side-menu-sub-item-radius);--rt-expansion-panel-header-min-height: var(--rt-side-menu-sub-item-min-height);--rt-expansion-panel-header-padding-block: var(--rt-space-2);--rt-expansion-panel-header-padding-start: calc( var(--rt-side-menu-sub-item-folder-padding-start) * (1 + var(--rt-side-menu-sub-item-depth)) );--rt-expansion-panel-header-padding-end: var(--rt-side-menu-sub-item-padding-end);--rt-expansion-panel-header-gap: var(--rt-side-menu-sub-item-gap);--rt-expansion-panel-chevron-color: var(--rt-side-menu-sub-item-chevron-color);--rt-expansion-panel-header-font-size: var(--rt-side-menu-sub-item-font-size);--rt-expansion-panel-header-color: var(--rt-side-menu-sub-item-color);--rt-expansion-panel-header-bg: transparent;--rt-expansion-panel-header-hover-bg: var(--rt-side-menu-item-bg-hover)}.rt-side-menu-sub-item__folder--highlighted.rt-expansion-panel{--rt-expansion-panel-header-bg: var(--rt-side-menu-item-bg-hover)}.rt-side-menu-sub-item__children{display:flex;flex-direction:column}@media(hover:hover){.rt-side-menu--favorite-actions-none .rt-side-menu-sub-item__favorite:not(.rt-side-menu-sub-item__favorite--on){overflow:hidden;width:0;margin-inline-start:calc(var(--rt-space-sm) * -1)}.rt-side-menu--favorite-actions-none .rt-side-menu-sub-item__row:hover .rt-side-menu-sub-item__favorite,.rt-side-menu--favorite-actions-none .rt-side-menu-sub-item__row:focus-visible .rt-side-menu-sub-item__favorite,.rt-side-menu--favorite-actions-none .rt-side-menu-sub-item__row:has(:focus-visible) .rt-side-menu-sub-item__favorite{overflow:visible;width:auto;margin-inline-start:0}}}\n"],
|
|
643
|
+
dependencies: [
|
|
644
|
+
{
|
|
645
|
+
kind: "directive",
|
|
646
|
+
type: NgTemplateOutlet,
|
|
647
|
+
selector: "[ngTemplateOutlet]",
|
|
648
|
+
inputs: [
|
|
649
|
+
"ngTemplateOutletContext",
|
|
650
|
+
"ngTemplateOutlet",
|
|
651
|
+
"ngTemplateOutletInjector"
|
|
652
|
+
]
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
kind: "directive",
|
|
656
|
+
type: BlockDirective,
|
|
657
|
+
selector: "[rtBlock]",
|
|
658
|
+
inputs: ["rtMod"]
|
|
659
|
+
},
|
|
660
|
+
{
|
|
661
|
+
kind: "directive",
|
|
662
|
+
type: ElemDirective,
|
|
663
|
+
selector: "[rtElem]",
|
|
664
|
+
inputs: ["rtMod"]
|
|
665
|
+
},
|
|
666
|
+
{
|
|
667
|
+
kind: "directive",
|
|
668
|
+
type: ModDirective,
|
|
669
|
+
selector: "[rtMod]"
|
|
670
|
+
},
|
|
671
|
+
{
|
|
672
|
+
kind: "component",
|
|
673
|
+
type: RtExpansionPanelComponent,
|
|
674
|
+
selector: "rt-expansion-panel",
|
|
675
|
+
inputs: [
|
|
676
|
+
"expanded",
|
|
677
|
+
"disabled",
|
|
678
|
+
"hideToggle",
|
|
679
|
+
"appearance",
|
|
680
|
+
"headerId",
|
|
681
|
+
"ariaLabel"
|
|
682
|
+
],
|
|
683
|
+
outputs: ["expandedChange"]
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
kind: "directive",
|
|
687
|
+
type: RtExpansionPanelContentDirective,
|
|
688
|
+
selector: "ng-template[rtExpansionPanelContent]"
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
kind: "component",
|
|
692
|
+
type: RtIconComponent,
|
|
693
|
+
selector: "rt-icon",
|
|
694
|
+
inputs: [
|
|
695
|
+
"name",
|
|
696
|
+
"glyph",
|
|
697
|
+
"glyphStrategy",
|
|
698
|
+
"size",
|
|
699
|
+
"color",
|
|
700
|
+
"fill",
|
|
701
|
+
"spin",
|
|
702
|
+
"rotate"
|
|
703
|
+
]
|
|
704
|
+
},
|
|
705
|
+
{
|
|
706
|
+
kind: "component",
|
|
707
|
+
type: RtIconButtonComponent,
|
|
708
|
+
selector: "rt-icon-button",
|
|
709
|
+
inputs: [
|
|
710
|
+
"icon",
|
|
711
|
+
"glyph",
|
|
712
|
+
"ariaLabel",
|
|
713
|
+
"variant",
|
|
714
|
+
"iconColor",
|
|
715
|
+
"iconFill",
|
|
716
|
+
"size",
|
|
717
|
+
"iconSize",
|
|
718
|
+
"type",
|
|
719
|
+
"tooltip",
|
|
720
|
+
"tooltipHideOnClick",
|
|
721
|
+
"tabIndex",
|
|
722
|
+
"loading",
|
|
723
|
+
"disabled",
|
|
724
|
+
"active",
|
|
725
|
+
"expanded",
|
|
726
|
+
"indicator"
|
|
727
|
+
],
|
|
728
|
+
outputs: ["clicked"]
|
|
729
|
+
},
|
|
730
|
+
{
|
|
731
|
+
kind: "directive",
|
|
732
|
+
type: RtTooltipDirective,
|
|
733
|
+
selector: "[rtTooltip]",
|
|
734
|
+
inputs: [
|
|
735
|
+
"rtTooltip",
|
|
736
|
+
"rtTooltipPlacement",
|
|
737
|
+
"rtTooltipWhenTruncated",
|
|
738
|
+
"rtTooltipHideOnClick"
|
|
739
|
+
],
|
|
740
|
+
exportAs: ["rtTooltip"]
|
|
741
|
+
},
|
|
742
|
+
{
|
|
743
|
+
kind: "pipe",
|
|
744
|
+
type: RtSideMenuTitlePartsPipe,
|
|
745
|
+
name: "rtSideMenuTitleParts"
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
kind: "pipe",
|
|
749
|
+
type: RtSideMenuIconPipe,
|
|
750
|
+
name: "rtSideMenuIcon"
|
|
751
|
+
},
|
|
752
|
+
{
|
|
753
|
+
kind: "pipe",
|
|
754
|
+
type: RtSideMenuHrefPipe,
|
|
755
|
+
name: "rtSideMenuHref"
|
|
756
|
+
}
|
|
757
|
+
],
|
|
758
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush,
|
|
759
|
+
encapsulation: i0.ViewEncapsulation.None
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
};
|
|
763
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
764
|
+
minVersion: "12.0.0",
|
|
765
|
+
version: "22.2.2",
|
|
766
|
+
ngImport: i0,
|
|
767
|
+
type: RtSideMenuSubItemComponent,
|
|
768
|
+
decorators: [{
|
|
769
|
+
type: Component,
|
|
770
|
+
args: [{
|
|
771
|
+
selector: "rt-side-menu-sub-item",
|
|
772
|
+
host: { class: BEM_BLOCK$2 },
|
|
773
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
774
|
+
encapsulation: ViewEncapsulation.None,
|
|
775
|
+
imports: [
|
|
776
|
+
NgTemplateOutlet,
|
|
777
|
+
BlockDirective,
|
|
778
|
+
ElemDirective,
|
|
779
|
+
ModDirective,
|
|
780
|
+
RtExpansionPanelComponent,
|
|
781
|
+
RtExpansionPanelContentDirective,
|
|
782
|
+
RtIconComponent,
|
|
783
|
+
RtIconButtonComponent,
|
|
784
|
+
RtTooltipDirective,
|
|
785
|
+
RtSideMenuTitlePartsPipe,
|
|
786
|
+
RtSideMenuIconPipe,
|
|
787
|
+
RtSideMenuHrefPipe
|
|
788
|
+
],
|
|
789
|
+
template: "<ng-container rtBlock=\"rt-side-menu-sub-item\">\n <ng-container [ngTemplateOutlet]=\"rowTpl\" [ngTemplateOutletContext]=\"{ $implicit: item(), depth: 0 }\" />\n <ng-template #rowTpl let-row let-depth=\"depth\">\n @let isActive = menuRef.activeMenuIds().includes(row.id);\n @let isHighlighted = !inFavorites() && menuRef.highlightedMenuId() === row.id;\n @if (row.link) {\n <!--\n Номер пункта на самой строке — признак для правил приложения: по нему оно находит строку,\n например ту, что открывает страницу раздела. Стоит и у строки блока избранного.\n Строка блока избранного без номера: по номеру клавиатура нажимает строку списка. И без\n родного перетаскивания ссылки: нажатие на ручку внутри строки браузер забирал себе,\n и перетаскивание CDK не начиналось.\n -->\n <a\n rtElem=\"row\"\n qa-dataid=\"side-menu-sub-item\"\n [id]=\"inFavorites() ? null : row.id\"\n [attr.data-item-id]=\"row.id\"\n [attr.draggable]=\"inFavorites() ? 'false' : null\"\n [attr.href]=\"row.link | rtSideMenuHref\"\n [style.--rt-side-menu-sub-item-depth]=\"depth\"\n [rtMod]=\"{ active: isActive, highlighted: isHighlighted }\"\n [attr.aria-current]=\"isActive ? 'page' : null\"\n (click)=\"onClickSubMenu(row, $event)\">\n @if (row.icon) {\n <ng-container [ngTemplateOutlet]=\"iconTpl\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n }\n\n <span rtElem=\"title\" [rtTooltip]=\"menuRef.subMenuTooltipsShown() ? row.name : ''\">\n <!-- Кусок без отметки тоже узел: голая интерполяция разрывала бы подпись пробелами. -->\n @for (part of row.name | rtSideMenuTitleParts: menuRef.subMenuQuery(); track $index) {\n @if (part.matched) {\n <span rtElem=\"match\">{{ part.text }}</span>\n } @else {\n <span rtElem=\"part\">{{ part.text }}</span>\n }\n }\n </span>\n\n <!--\n Строка блока несёт «убрать», а не звезду: всё в блоке уже в избранном. Звезда —\n у пункта со своим адресом в разделе с избранным: полая — не в избранном,\n закрашенная цветом темы — в нём. Имя кнопки называет следующее нажатие.\n -->\n @if (inFavorites() && favoritesIcons) {\n <rt-icon-button\n rtElem=\"favorite\"\n qa-dataid=\"side-menu-favorite-remove\"\n size=\"sm\"\n [rtMod]=\"{ remove: true }\"\n [icon]=\"favoritesIcons.remove\"\n [ariaLabel]=\"removeLabel()\"\n [tooltip]=\"narrow() || !menuRef.subMenuTooltipsShown() ? '' : removeLabel()\"\n (clicked)=\"onRemoveFavorite(row, $event)\" />\n } @else if (favoritesOn() && !row.favoriteDisabled) {\n @let isFavorite = favoriteIds().includes(row.id);\n <rt-icon-button\n rtElem=\"favorite\"\n qa-dataid=\"side-menu-favorite-star\"\n size=\"sm\"\n [rtMod]=\"{ on: isFavorite }\"\n [icon]=\"isFavorite ? 'star-fill' : 'star'\"\n [iconFill]=\"isFavorite\"\n [ariaLabel]=\"isFavorite ? removeLabel() : addLabel()\"\n [tooltip]=\"narrow() || !menuRef.subMenuTooltipsShown() ? '' : isFavorite ? removeLabel() : addLabel()\"\n (clicked)=\"onToggleFavorite(row, $event)\" />\n }\n\n <!-- Действия, которые строке передаёт владелец: блок избранного кладёт сюда ручку. -->\n <ng-content select=\"[rtSideMenuSubItemAction]\" />\n\n <!-- Кнопка потребителя видна всегда и стоит последней: кнопки избранного встают перед ней. -->\n @if (row.iconButton?.icon; as buttonIcon) {\n <!-- Имя без значка кита берёт свой шаблон меню, как значок строки. Без шаблона кнопка пуста и\n незнакомого имени значку не передаёт: значка с таким именем нет, и ждать его некому. -->\n @let buttonKitIcon = buttonIcon | rtSideMenuIcon;\n @let buttonOwnTpl = buttonKitIcon ? null : menuRef.ownIconTpl();\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"side-menu-sub-item-action\"\n size=\"sm\"\n [icon]=\"buttonKitIcon\"\n [iconFill]=\"menuRef.subItemIconFill()\"\n [ariaLabel]=\"row.name ?? ''\"\n (clicked)=\"onClickSubMenuAdditional(row, $event)\">\n @if (buttonOwnTpl) {\n <span rtElem=\"own-icon\" qa-dataid=\"side-menu-own-button-icon\" aria-hidden=\"true\">\n <ng-container\n [ngTemplateOutlet]=\"buttonOwnTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: row, icon: buttonIcon, slot: 'iconButton' }\" />\n </span>\n }\n </rt-icon-button>\n }\n </a>\n } @else if (row.submenu) {\n <!--\n Папка — раскрывающаяся панель кита. Рисуется и с пустым составом: отбор оставляет так\n ту, что совпала подписью. Шеврона у такой папки нет — раскрывать нечего. Раскрытие\n держит меню: панель сообщает о нажатии, меню переключает папку. Кнопке заголовка\n отдан номер пункта — по нему клавиатура меню нажимает строку.\n -->\n @let isOpen = menuRef.expandedMenuIds().includes(row.id);\n <rt-expansion-panel\n rtElem=\"folder\"\n appearance=\"plain\"\n [headerId]=\"'' + row.id\"\n [attr.data-item-id]=\"row.id\"\n [hideToggle]=\"!row.submenu.length\"\n [expanded]=\"isOpen\"\n [style.--rt-side-menu-sub-item-depth]=\"depth\"\n [rtMod]=\"{ highlighted: isHighlighted }\"\n (expandedChange)=\"onToggleFolder(row)\">\n @if (row.icon) {\n <ng-container [ngTemplateOutlet]=\"iconTpl\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n }\n\n <span rtElem=\"title\" qa-dataid=\"side-menu-folder\" [rtTooltip]=\"menuRef.subMenuTooltipsShown() ? row.name : ''\">\n @for (part of row.name | rtSideMenuTitleParts: menuRef.subMenuQuery(); track $index) {\n @if (part.matched) {\n <span rtElem=\"match\">{{ part.text }}</span>\n } @else {\n <span rtElem=\"part\">{{ part.text }}</span>\n }\n }\n </span>\n\n <ng-template rtExpansionPanelContent>\n <div rtElem=\"children\" role=\"group\">\n @for (child of row.submenu; track child.id) {\n <ng-container [ngTemplateOutlet]=\"rowTpl\" [ngTemplateOutletContext]=\"{ $implicit: child, depth: depth + 1 }\" />\n }\n </div>\n </ng-template>\n </rt-expansion-panel>\n }\n </ng-template>\n\n <!-- Значок строки: имя кита или пара имени Material, а имя, которого кит не рисует, — свой шаблон меню. -->\n <ng-template #iconTpl let-row>\n @let kitIcon = row.icon | rtSideMenuIcon;\n @if (kitIcon) {\n <rt-icon rtElem=\"icon\" size=\"sm\" [name]=\"kitIcon\" [fill]=\"menuRef.subItemIconFill()\" />\n } @else if (menuRef.ownIconTpl(); as own) {\n <span rtElem=\"own-icon\" qa-dataid=\"side-menu-own-icon\" aria-hidden=\"true\">\n <ng-container [ngTemplateOutlet]=\"own\" [ngTemplateOutletContext]=\"{ $implicit: row, icon: row.icon, slot: 'icon' }\" />\n </span>\n }\n </ng-template>\n</ng-container>\n",
|
|
790
|
+
styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-side-menu-sub-item{--rt-side-menu-sub-item-radius: var(--rt-radius-full);--rt-side-menu-sub-item-transition-duration: var(--rt-duration-fast);--rt-side-menu-sub-item-match-bg: var(--rt-yellow-400);--rt-side-menu-sub-item-match-color: var(--rt-neutral-950);--rt-side-menu-sub-item-match-radius: var(--rt-radius-xs);--rt-side-menu-sub-item-min-height: var(--rt-control-height-md);--rt-side-menu-sub-item-font-size: var(--rt-text-sm);--rt-side-menu-sub-item-padding-start: var(--rt-space-md);--rt-side-menu-sub-item-padding-end: var(--rt-space-sm);--rt-side-menu-sub-item-color: var(--rt-color-text-primary);--rt-side-menu-sub-item-gap: var(--rt-space-sm);--rt-side-menu-sub-item-folder-padding-start: var(--rt-side-menu-sub-item-padding-start);--rt-side-menu-sub-item-chevron-color: var(--rt-color-text-muted);--rt-side-menu-sub-item-icon-size: var(--rt-icon-step-sm);--rt-side-menu-sub-item-button-radius: var(--rt-radius-md);--rt-side-menu-sub-item-button-icon-size: var(--rt-icon-step-sm);--rt-side-menu-sub-item-action-size: var(--rt-control-height-sm);--rt-side-menu-sub-item-favorite-size: var(--rt-control-height-sm);--rt-side-menu-sub-item-favorite-color: var(--rt-color-text-primary);display:block;letter-spacing:var(--rt-side-menu-sub-item-letter-spacing, inherit)}.rt-side-menu-sub-item__row{--rt-side-menu-sub-item-depth: 0;display:flex;width:100%;min-height:var(--rt-side-menu-sub-item-min-height);box-sizing:border-box;align-items:center;border:0;border-radius:var(--rt-side-menu-sub-item-radius);background:transparent;color:var(--rt-side-menu-sub-item-color);cursor:pointer;font:inherit;font-size:var(--rt-side-menu-sub-item-font-size);gap:var(--rt-side-menu-sub-item-gap);padding-block:var(--rt-space-2);padding-inline:calc(var(--rt-side-menu-sub-item-padding-start) * (1 + var(--rt-side-menu-sub-item-depth))) var(--rt-side-menu-sub-item-padding-end);text-align:start;text-decoration:none;transition:background-color var(--rt-side-menu-sub-item-transition-duration) ease}.rt-side-menu-sub-item__row:hover,.rt-side-menu-sub-item__row:active,.rt-side-menu-sub-item__row--highlighted{background:var(--rt-side-menu-item-bg-hover)}.rt-side-menu-sub-item__row:focus-visible{outline:var(--rt-focus-ring-width) solid var(--rt-focus-ring-color);outline-offset:calc(var(--rt-focus-ring-width) * -1)}.rt-side-menu-sub-item__row--active{background:var(--rt-side-menu-item-bg-active);color:var(--rt-side-menu-item-color-active)}.rt-side-menu-sub-item__icon{--rt-icon-step-sm: var(--rt-side-menu-sub-item-icon-size);flex-shrink:0;color:inherit}.rt-side-menu-sub-item__own-icon{--rt-side-menu-sub-item-own-icon-size: var(--rt-size-4);display:inline-flex;width:var(--rt-side-menu-sub-item-own-icon-size);height:var(--rt-side-menu-sub-item-own-icon-size);flex-shrink:0;align-items:center;justify-content:center;color:inherit;line-height:1}.rt-side-menu-sub-item__own-icon>*{max-width:100%;max-height:100%}.rt-side-menu-sub-item__title{overflow:hidden;min-width:0;flex:1 1 auto;text-overflow:ellipsis;white-space:nowrap}.rt-side-menu-sub-item__part{color:inherit}.rt-side-menu-sub-item__match{border-radius:var(--rt-side-menu-sub-item-match-radius);background:var(--rt-side-menu-sub-item-match-bg);color:var(--rt-side-menu-sub-item-match-color)}.rt-side-menu-sub-item__action{--rt-side-menu-sub-item-action-ring-width: var(--rt-border-width-thin);--rt-side-menu-sub-item-action-radius: var(--rt-radius-full);flex-shrink:0;border-radius:var(--rt-side-menu-sub-item-action-radius);outline:var(--rt-side-menu-sub-item-action-ring-width) solid transparent;outline-offset:calc(var(--rt-side-menu-sub-item-action-ring-width) * -1)}.rt-side-menu-sub-item__action:hover{outline-color:var(--rt-color-border-strong)}.rt-side-menu-sub-item__action>.rt-icon-button{--rt-icon-button-size-step: var(--rt-side-menu-sub-item-action-size)}.rt-side-menu-sub-item__action,.rt-side-menu-sub-item__favorite{--rt-icon-step-sm: var(--rt-side-menu-sub-item-button-icon-size)}.rt-side-menu-sub-item__action>.rt-icon-button,.rt-side-menu-sub-item__favorite>.rt-icon-button{--rt-icon-button-radius: var(--rt-side-menu-sub-item-button-radius)}.rt-side-menu-sub-item__favorite{--rt-icon-button-color: var(--rt-side-menu-sub-item-favorite-color);flex-shrink:0;opacity:0}.rt-side-menu-sub-item__favorite>.rt-icon-button{--rt-icon-button-size-step: var(--rt-side-menu-sub-item-favorite-size)}.rt-side-menu-sub-item__favorite--on{--rt-icon-button-color: var(--rt-color-action-primary);opacity:1}@media(hover:hover){.rt-side-menu-sub-item__favorite--remove:hover{--rt-icon-button-color: var(--rt-color-state-danger)}}.rt-side-menu-sub-item__favorite--remove:has(:focus-visible){--rt-icon-button-color: var(--rt-color-state-danger)}@media(hover:none){.rt-side-menu-sub-item__favorite{opacity:1}}.rt-side-menu-sub-item__row:hover .rt-side-menu-sub-item__favorite,.rt-side-menu-sub-item__row:focus-visible .rt-side-menu-sub-item__favorite,.rt-side-menu-sub-item__row:has(:focus-visible) .rt-side-menu-sub-item__favorite{opacity:1}.rt-side-menu-sub-item__folder.rt-expansion-panel{--rt-expansion-panel-duration: var(--rt-side-menu-sub-item-transition-duration);--rt-expansion-panel-header-radius: var(--rt-side-menu-sub-item-radius);--rt-expansion-panel-header-min-height: var(--rt-side-menu-sub-item-min-height);--rt-expansion-panel-header-padding-block: var(--rt-space-2);--rt-expansion-panel-header-padding-start: calc( var(--rt-side-menu-sub-item-folder-padding-start) * (1 + var(--rt-side-menu-sub-item-depth)) );--rt-expansion-panel-header-padding-end: var(--rt-side-menu-sub-item-padding-end);--rt-expansion-panel-header-gap: var(--rt-side-menu-sub-item-gap);--rt-expansion-panel-chevron-color: var(--rt-side-menu-sub-item-chevron-color);--rt-expansion-panel-header-font-size: var(--rt-side-menu-sub-item-font-size);--rt-expansion-panel-header-color: var(--rt-side-menu-sub-item-color);--rt-expansion-panel-header-bg: transparent;--rt-expansion-panel-header-hover-bg: var(--rt-side-menu-item-bg-hover)}.rt-side-menu-sub-item__folder--highlighted.rt-expansion-panel{--rt-expansion-panel-header-bg: var(--rt-side-menu-item-bg-hover)}.rt-side-menu-sub-item__children{display:flex;flex-direction:column}@media(hover:hover){.rt-side-menu--favorite-actions-none .rt-side-menu-sub-item__favorite:not(.rt-side-menu-sub-item__favorite--on){overflow:hidden;width:0;margin-inline-start:calc(var(--rt-space-sm) * -1)}.rt-side-menu--favorite-actions-none .rt-side-menu-sub-item__row:hover .rt-side-menu-sub-item__favorite,.rt-side-menu--favorite-actions-none .rt-side-menu-sub-item__row:focus-visible .rt-side-menu-sub-item__favorite,.rt-side-menu--favorite-actions-none .rt-side-menu-sub-item__row:has(:focus-visible) .rt-side-menu-sub-item__favorite{overflow:visible;width:auto;margin-inline-start:0}}}\n"]
|
|
791
|
+
}]
|
|
792
|
+
}],
|
|
793
|
+
propDecorators: {
|
|
794
|
+
item: [{
|
|
795
|
+
type: i0.Input,
|
|
796
|
+
args: [{
|
|
797
|
+
isSignal: true,
|
|
798
|
+
alias: "item",
|
|
799
|
+
required: true
|
|
800
|
+
}]
|
|
801
|
+
}],
|
|
802
|
+
inFavorites: [{
|
|
803
|
+
type: i0.Input,
|
|
804
|
+
args: [{
|
|
805
|
+
isSignal: true,
|
|
806
|
+
alias: "inFavorites",
|
|
807
|
+
required: false
|
|
808
|
+
}]
|
|
809
|
+
}],
|
|
810
|
+
clickSubMenuAction: [{
|
|
811
|
+
type: i0.Output,
|
|
812
|
+
args: ["clickSubMenuAction"]
|
|
813
|
+
}],
|
|
814
|
+
clickSubMenuAdditionalAction: [{
|
|
815
|
+
type: i0.Output,
|
|
816
|
+
args: ["clickSubMenuAdditionalAction"]
|
|
817
|
+
}]
|
|
818
|
+
}
|
|
819
|
+
});
|
|
820
|
+
const BEM_BLOCK$1 = "rt-side-menu-favorites";
|
|
821
|
+
const SUB_MENU_PANEL = ".rt-side-menu__panel";
|
|
822
|
+
var RtSideMenuFavoritesComponent = class RtSideMenuFavoritesComponent {
|
|
823
|
+
#menu;
|
|
824
|
+
#settings;
|
|
825
|
+
#injector;
|
|
826
|
+
#host;
|
|
827
|
+
#dragging;
|
|
828
|
+
#section;
|
|
829
|
+
constructor() {
|
|
830
|
+
this.#menu = inject(RT_SIDE_MENU);
|
|
831
|
+
this.#settings = inject(RtSideMenuSettingsService, { optional: true });
|
|
832
|
+
this.#injector = inject(Injector);
|
|
833
|
+
this.#host = inject(ElementRef);
|
|
834
|
+
this.#dragging = signal(false, ...ngDevMode ? [{ debugName: "#dragging" }] : /* istanbul ignore next */ []);
|
|
835
|
+
this.#section = computed(() => this.#settings ? sideMenuFavoritesSection(this.#menu.menuItems(), this.#menu.shownSubMenu()) : null, ...ngDevMode ? [{ debugName: "#section" }] : /* istanbul ignore next */ []);
|
|
836
|
+
this.searching = computed(() => this.#menu.subMenuQuery().trim() !== "", ...ngDevMode ? [{ debugName: "searching" }] : /* istanbul ignore next */ []);
|
|
837
|
+
this.rows = computed(() => {
|
|
838
|
+
const section = this.#section();
|
|
839
|
+
if (!this.#settings || !section || this.searching() && !this.#menu.isFavoritesSearchShown()) return [];
|
|
840
|
+
return filterSideMenuItems(findSideMenuFavoriteItems([section], this.#settings.favoriteIds(this.#menu.menuId())()), this.#menu.subMenuQuery());
|
|
841
|
+
}, ...ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []);
|
|
842
|
+
this.collapsed = computed(() => {
|
|
843
|
+
const section = this.#section();
|
|
844
|
+
return !!section && !!this.#settings?.favoritesCollapsed(this.#menu.menuId())().includes(section.id);
|
|
845
|
+
}, ...ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []);
|
|
846
|
+
this.open = linkedSignal({
|
|
847
|
+
...ngDevMode ? { debugName: "open" } : /* istanbul ignore next */ {},
|
|
848
|
+
source: () => ({
|
|
849
|
+
collapsed: this.collapsed(),
|
|
850
|
+
searching: this.searching()
|
|
851
|
+
}),
|
|
852
|
+
computation: (state) => !state.collapsed || state.searching
|
|
853
|
+
});
|
|
854
|
+
this.countShown = computed(() => {
|
|
855
|
+
const mode = this.#menu.favoritesCount();
|
|
856
|
+
return mode === "always" || mode === "collapsed" && !this.open();
|
|
857
|
+
}, ...ngDevMode ? [{ debugName: "countShown" }] : /* istanbul ignore next */ []);
|
|
858
|
+
this.handles = viewChildren("handle", {
|
|
859
|
+
...ngDevMode ? { debugName: "handles" } : /* istanbul ignore next */ {},
|
|
860
|
+
read: ElementRef
|
|
861
|
+
});
|
|
862
|
+
this.dragIcon = this.#settings?.favoritesIcons.drag ?? "arrows-v";
|
|
863
|
+
this.narrow = inject(BreakpointsService).narrow;
|
|
864
|
+
this.titleLabel = rtKitLabel("sideMenuFavorites");
|
|
865
|
+
this.dragLabel = rtKitLabel("sideMenuFavoriteDrag");
|
|
866
|
+
this.expandLabel = rtKitLabel("sideMenuFavoritesExpand");
|
|
867
|
+
this.collapseLabel = rtKitLabel("sideMenuFavoritesCollapse");
|
|
868
|
+
this.clickSubMenuAction = output();
|
|
869
|
+
this.clickSubMenuAdditionalAction = output();
|
|
870
|
+
inject(DestroyRef).onDestroy(() => this.#release());
|
|
871
|
+
}
|
|
872
|
+
onToggle(expanded) {
|
|
873
|
+
const section = this.#section();
|
|
874
|
+
if (this.#settings && section && !this.searching()) this.#settings.setFavoritesCollapsed(this.#menu.menuId(), section.id, !expanded);
|
|
875
|
+
}
|
|
876
|
+
onDragStart() {
|
|
877
|
+
this.#dragging.set(true);
|
|
878
|
+
this.#menu.holdSubMenu(true);
|
|
879
|
+
}
|
|
880
|
+
onDragEnd(event) {
|
|
881
|
+
this.#release();
|
|
882
|
+
const panel = this.#host.nativeElement.closest(SUB_MENU_PANEL);
|
|
883
|
+
if (panel && isSideMenuDropOutside(panel.getBoundingClientRect(), event.dropPoint)) this.#menu.toggleSubMenu();
|
|
884
|
+
}
|
|
885
|
+
onDrop(event) {
|
|
886
|
+
if (event.isPointerOverContainer) this.#move(event.previousIndex, event.currentIndex);
|
|
887
|
+
}
|
|
888
|
+
onHandleKey(event, index, step) {
|
|
889
|
+
event.preventDefault();
|
|
890
|
+
event.stopPropagation();
|
|
891
|
+
const target = index + step;
|
|
892
|
+
if (target < 0 || target >= this.rows().length) return;
|
|
893
|
+
this.#move(index, target);
|
|
894
|
+
afterNextRender(() => this.handles()[target]?.nativeElement.querySelector("button")?.focus(), { injector: this.#injector });
|
|
895
|
+
}
|
|
896
|
+
onHandleClick(event) {
|
|
897
|
+
event.preventDefault();
|
|
898
|
+
event.stopPropagation();
|
|
899
|
+
}
|
|
900
|
+
#release() {
|
|
901
|
+
if (!this.#dragging()) return;
|
|
902
|
+
this.#dragging.set(false);
|
|
903
|
+
this.#menu.holdSubMenu(false);
|
|
904
|
+
}
|
|
905
|
+
#move(from, to) {
|
|
906
|
+
if (!this.#settings || from === to) return;
|
|
907
|
+
const visible = this.rows().map((item) => item.id);
|
|
908
|
+
this.#settings.moveVisibleSideMenuFavorite(this.#menu.menuId(), visible, from, to);
|
|
909
|
+
}
|
|
910
|
+
static {
|
|
911
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
912
|
+
minVersion: "12.0.0",
|
|
913
|
+
version: "22.2.2",
|
|
914
|
+
ngImport: i0,
|
|
915
|
+
type: RtSideMenuFavoritesComponent,
|
|
916
|
+
deps: [],
|
|
917
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
static {
|
|
921
|
+
this.ɵcmp = i0.ɵɵngDeclareComponent({
|
|
922
|
+
minVersion: "17.0.0",
|
|
923
|
+
version: "22.2.2",
|
|
924
|
+
type: RtSideMenuFavoritesComponent,
|
|
925
|
+
isStandalone: true,
|
|
926
|
+
selector: "rt-side-menu-favorites",
|
|
927
|
+
outputs: {
|
|
928
|
+
clickSubMenuAction: "clickSubMenuAction",
|
|
929
|
+
clickSubMenuAdditionalAction: "clickSubMenuAdditionalAction"
|
|
930
|
+
},
|
|
931
|
+
host: { classAttribute: "rt-side-menu-favorites" },
|
|
932
|
+
viewQueries: [{
|
|
933
|
+
propertyName: "handles",
|
|
934
|
+
predicate: ["handle"],
|
|
935
|
+
descendants: true,
|
|
936
|
+
read: ElementRef,
|
|
937
|
+
isSignal: true
|
|
938
|
+
}],
|
|
939
|
+
ngImport: i0,
|
|
940
|
+
template: "<ng-container rtBlock=\"rt-side-menu-favorites\">\n @if (rows().length) {\n <!--\n Блок — раскрывающаяся панель кита, как папка подменю, со звездой вместо значка папки. Имя\n кнопки заголовка называет следующее нажатие; число строк — по входу меню.\n -->\n <rt-expansion-panel\n rtElem=\"panel\"\n appearance=\"plain\"\n [ariaLabel]=\"open() ? collapseLabel() : expandLabel()\"\n [(expanded)]=\"open\"\n (expandedChange)=\"onToggle($event)\">\n <rt-icon rtElem=\"star\" size=\"sm\" name=\"star-fill\" [fill]=\"true\" />\n <span rtElem=\"title\" qa-dataid=\"side-menu-favorites-title\">\n {{ titleLabel() }}\n @if (countShown()) {\n ({{ rows().length }})\n }\n </span>\n\n <ng-template rtExpansionPanelContent>\n <div\n rtElem=\"list\"\n role=\"group\"\n qa-dataid=\"side-menu-favorites\"\n cdkDropList\n cdkDropListLockAxis=\"y\"\n [cdkDropListData]=\"rows()\"\n [attr.aria-label]=\"titleLabel()\"\n (cdkDropListDropped)=\"onDrop($event)\">\n @for (item of rows(); track item.id) {\n <div\n rtElem=\"row\"\n qa-dataid=\"side-menu-favorite-row\"\n cdkDrag\n [attr.data-id]=\"item.id\"\n (cdkDragStarted)=\"onDragStart()\"\n (cdkDragEnded)=\"onDragEnd($event)\">\n <!--\n Ручка стоит внутри строки, последней перед кнопкой потребителя. Строку тянут\n только за ручку: остальная строка — ссылка. С клавиатуры строку переставляют\n стрелки на ручке: перетаскивание CDK клавиш не знает.\n -->\n <rt-side-menu-sub-item\n rtElem=\"item\"\n [item]=\"item\"\n [inFavorites]=\"true\"\n (clickSubMenuAction)=\"clickSubMenuAction.emit($event)\"\n (clickSubMenuAdditionalAction)=\"clickSubMenuAdditionalAction.emit($event)\">\n <rt-icon-button\n #handle\n rtSideMenuSubItemAction\n cdkDragHandle\n rtElem=\"handle\"\n qa-dataid=\"side-menu-favorite-handle\"\n size=\"sm\"\n aria-keyshortcuts=\"ArrowUp ArrowDown\"\n [icon]=\"dragIcon\"\n [ariaLabel]=\"dragLabel()\"\n [tooltip]=\"narrow() ? '' : dragLabel()\"\n (clicked)=\"onHandleClick($event)\"\n (keydown.arrowup)=\"onHandleKey($event, $index, -1)\"\n (keydown.arrowdown)=\"onHandleKey($event, $index, 1)\" />\n </rt-side-menu-sub-item>\n </div>\n }\n </div>\n </ng-template>\n </rt-expansion-panel>\n }\n</ng-container>\n",
|
|
941
|
+
styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-side-menu-favorites{--rt-side-menu-favorites-radius: var(--rt-radius-full);--rt-side-menu-favorites-divider-width: var(--rt-border-width-thin);display:block}.rt-side-menu-favorites:has(.rt-side-menu-favorites__panel){border-bottom:var(--rt-side-menu-favorites-divider-width) solid var(--rt-color-border-subtle);margin-block-end:var(--rt-space-sm);padding-block-end:var(--rt-space-sm)}.rt-side-menu-favorites__panel.rt-expansion-panel{--rt-expansion-panel-duration: var(--rt-duration-fast);--rt-expansion-panel-header-radius: var(--rt-side-menu-favorites-radius);--rt-expansion-panel-header-min-height: var(--rt-control-height-md);--rt-expansion-panel-header-padding-block: var(--rt-space-2);--rt-expansion-panel-header-padding-start: var(--rt-space-1);--rt-expansion-panel-header-padding-end: var(--rt-space-sm);--rt-expansion-panel-header-gap: var(--rt-space-sm);--rt-expansion-panel-header-font-size: var(--rt-text-sm)}.rt-side-menu-favorites__star{flex-shrink:0;color:var(--rt-color-action-primary)}.rt-side-menu-favorites__title{overflow:hidden;min-width:0;flex:1 1 auto;text-overflow:ellipsis;white-space:nowrap}.rt-side-menu-favorites__list{display:flex;flex-direction:column}.rt-side-menu-favorites__item{min-width:0;flex:1 1 auto}.rt-side-menu-favorites__row{display:flex;align-items:center}.rt-side-menu-favorites__row.cdk-drag-preview{--rt-side-menu-favorites-preview-radius: var(--rt-radius-full);--rt-side-menu-favorites-preview-shadow: var(--rt-shadow-md);border-radius:var(--rt-side-menu-favorites-preview-radius);box-shadow:var(--rt-side-menu-favorites-preview-shadow)}.rt-side-menu-favorites__row.cdk-drag-preview .rt-side-menu-favorites__item{min-width:0;flex:1 1 auto;border-radius:var(--rt-side-menu-favorites-preview-radius);background:var(--rt-color-bg-surface)}.rt-side-menu-favorites__row.cdk-drag-placeholder{opacity:0}.rt-side-menu-favorites__handle{--rt-icon-button-color: var(--rt-side-menu-sub-item-favorite-color);--rt-icon-step-sm: var(--rt-side-menu-sub-item-button-icon-size);flex-shrink:0;cursor:grab;opacity:0}.rt-side-menu-favorites__handle>.rt-icon-button{--rt-icon-button-size-step: var(--rt-side-menu-sub-item-favorite-size);--rt-icon-button-radius: var(--rt-side-menu-sub-item-button-radius)}.rt-side-menu-favorites__handle:active{cursor:grabbing}@media(hover:none){.rt-side-menu-favorites__handle{opacity:1}}.rt-side-menu-favorites__row:hover .rt-side-menu-favorites__handle,.rt-side-menu-favorites__row:has(:focus-visible) .rt-side-menu-favorites__handle,.rt-side-menu-favorites__row.cdk-drag-preview .rt-side-menu-favorites__handle{opacity:1}@media(hover:hover){.rt-side-menu--favorite-actions-none .rt-side-menu-favorites__handle{overflow:hidden;width:0;margin-inline-start:calc(var(--rt-space-sm) * -1)}.rt-side-menu--favorite-actions-none .rt-side-menu-favorites__row:hover .rt-side-menu-favorites__handle,.rt-side-menu--favorite-actions-none .rt-side-menu-favorites__row:has(:focus-visible) .rt-side-menu-favorites__handle{overflow:visible;width:auto;margin-inline-start:0}}}\n"],
|
|
942
|
+
dependencies: [
|
|
943
|
+
{
|
|
944
|
+
kind: "directive",
|
|
945
|
+
type: CdkDrag,
|
|
946
|
+
selector: "[cdkDrag]",
|
|
947
|
+
inputs: [
|
|
948
|
+
"cdkDragData",
|
|
949
|
+
"cdkDragLockAxis",
|
|
950
|
+
"cdkDragRootElement",
|
|
951
|
+
"cdkDragBoundary",
|
|
952
|
+
"cdkDragStartDelay",
|
|
953
|
+
"cdkDragFreeDragPosition",
|
|
954
|
+
"cdkDragDisabled",
|
|
955
|
+
"cdkDragConstrainPosition",
|
|
956
|
+
"cdkDragPreviewClass",
|
|
957
|
+
"cdkDragPreviewContainer",
|
|
958
|
+
"cdkDragScale"
|
|
959
|
+
],
|
|
960
|
+
outputs: [
|
|
961
|
+
"cdkDragStarted",
|
|
962
|
+
"cdkDragReleased",
|
|
963
|
+
"cdkDragEnded",
|
|
964
|
+
"cdkDragEntered",
|
|
965
|
+
"cdkDragExited",
|
|
966
|
+
"cdkDragDropped",
|
|
967
|
+
"cdkDragMoved"
|
|
968
|
+
],
|
|
969
|
+
exportAs: ["cdkDrag"]
|
|
970
|
+
},
|
|
971
|
+
{
|
|
972
|
+
kind: "directive",
|
|
973
|
+
type: CdkDragHandle,
|
|
974
|
+
selector: "[cdkDragHandle]",
|
|
975
|
+
inputs: ["cdkDragHandleDisabled"]
|
|
976
|
+
},
|
|
977
|
+
{
|
|
978
|
+
kind: "directive",
|
|
979
|
+
type: CdkDropList,
|
|
980
|
+
selector: "[cdkDropList], cdk-drop-list",
|
|
981
|
+
inputs: [
|
|
982
|
+
"cdkDropListConnectedTo",
|
|
983
|
+
"cdkDropListData",
|
|
984
|
+
"cdkDropListOrientation",
|
|
985
|
+
"id",
|
|
986
|
+
"cdkDropListLockAxis",
|
|
987
|
+
"cdkDropListDisabled",
|
|
988
|
+
"cdkDropListSortingDisabled",
|
|
989
|
+
"cdkDropListEnterPredicate",
|
|
990
|
+
"cdkDropListSortPredicate",
|
|
991
|
+
"cdkDropListAutoScrollDisabled",
|
|
992
|
+
"cdkDropListAutoScrollStep",
|
|
993
|
+
"cdkDropListElementContainer",
|
|
994
|
+
"cdkDropListHasAnchor"
|
|
995
|
+
],
|
|
996
|
+
outputs: [
|
|
997
|
+
"cdkDropListDropped",
|
|
998
|
+
"cdkDropListEntered",
|
|
999
|
+
"cdkDropListExited",
|
|
1000
|
+
"cdkDropListSorted"
|
|
1001
|
+
],
|
|
1002
|
+
exportAs: ["cdkDropList"]
|
|
1003
|
+
},
|
|
1004
|
+
{
|
|
1005
|
+
kind: "directive",
|
|
1006
|
+
type: BlockDirective,
|
|
1007
|
+
selector: "[rtBlock]",
|
|
1008
|
+
inputs: ["rtMod"]
|
|
1009
|
+
},
|
|
1010
|
+
{
|
|
1011
|
+
kind: "directive",
|
|
1012
|
+
type: ElemDirective,
|
|
1013
|
+
selector: "[rtElem]",
|
|
1014
|
+
inputs: ["rtMod"]
|
|
1015
|
+
},
|
|
1016
|
+
{
|
|
1017
|
+
kind: "directive",
|
|
1018
|
+
type: RtExpansionPanelContentDirective,
|
|
1019
|
+
selector: "ng-template[rtExpansionPanelContent]"
|
|
1020
|
+
},
|
|
1021
|
+
{
|
|
1022
|
+
kind: "component",
|
|
1023
|
+
type: RtExpansionPanelComponent,
|
|
1024
|
+
selector: "rt-expansion-panel",
|
|
1025
|
+
inputs: [
|
|
1026
|
+
"expanded",
|
|
1027
|
+
"disabled",
|
|
1028
|
+
"hideToggle",
|
|
1029
|
+
"appearance",
|
|
1030
|
+
"headerId",
|
|
1031
|
+
"ariaLabel"
|
|
1032
|
+
],
|
|
1033
|
+
outputs: ["expandedChange"]
|
|
1034
|
+
},
|
|
1035
|
+
{
|
|
1036
|
+
kind: "component",
|
|
1037
|
+
type: RtIconButtonComponent,
|
|
1038
|
+
selector: "rt-icon-button",
|
|
1039
|
+
inputs: [
|
|
1040
|
+
"icon",
|
|
1041
|
+
"glyph",
|
|
1042
|
+
"ariaLabel",
|
|
1043
|
+
"variant",
|
|
1044
|
+
"iconColor",
|
|
1045
|
+
"iconFill",
|
|
1046
|
+
"size",
|
|
1047
|
+
"iconSize",
|
|
1048
|
+
"type",
|
|
1049
|
+
"tooltip",
|
|
1050
|
+
"tooltipHideOnClick",
|
|
1051
|
+
"tabIndex",
|
|
1052
|
+
"loading",
|
|
1053
|
+
"disabled",
|
|
1054
|
+
"active",
|
|
1055
|
+
"expanded",
|
|
1056
|
+
"indicator"
|
|
1057
|
+
],
|
|
1058
|
+
outputs: ["clicked"]
|
|
1059
|
+
},
|
|
1060
|
+
{
|
|
1061
|
+
kind: "component",
|
|
1062
|
+
type: RtIconComponent,
|
|
1063
|
+
selector: "rt-icon",
|
|
1064
|
+
inputs: [
|
|
1065
|
+
"name",
|
|
1066
|
+
"glyph",
|
|
1067
|
+
"glyphStrategy",
|
|
1068
|
+
"size",
|
|
1069
|
+
"color",
|
|
1070
|
+
"fill",
|
|
1071
|
+
"spin",
|
|
1072
|
+
"rotate"
|
|
1073
|
+
]
|
|
1074
|
+
},
|
|
1075
|
+
{
|
|
1076
|
+
kind: "component",
|
|
1077
|
+
type: RtSideMenuSubItemComponent,
|
|
1078
|
+
selector: "rt-side-menu-sub-item",
|
|
1079
|
+
inputs: ["item", "inFavorites"],
|
|
1080
|
+
outputs: ["clickSubMenuAction", "clickSubMenuAdditionalAction"]
|
|
1081
|
+
}
|
|
1082
|
+
],
|
|
1083
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush,
|
|
1084
|
+
encapsulation: i0.ViewEncapsulation.None
|
|
1085
|
+
});
|
|
1086
|
+
}
|
|
1087
|
+
};
|
|
1088
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
1089
|
+
minVersion: "12.0.0",
|
|
1090
|
+
version: "22.2.2",
|
|
1091
|
+
ngImport: i0,
|
|
1092
|
+
type: RtSideMenuFavoritesComponent,
|
|
1093
|
+
decorators: [{
|
|
1094
|
+
type: Component,
|
|
1095
|
+
args: [{
|
|
1096
|
+
selector: "rt-side-menu-favorites",
|
|
1097
|
+
host: { class: BEM_BLOCK$1 },
|
|
1098
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1099
|
+
encapsulation: ViewEncapsulation.None,
|
|
1100
|
+
imports: [
|
|
1101
|
+
CdkDrag,
|
|
1102
|
+
CdkDragHandle,
|
|
1103
|
+
CdkDropList,
|
|
1104
|
+
BlockDirective,
|
|
1105
|
+
ElemDirective,
|
|
1106
|
+
ModDirective,
|
|
1107
|
+
RtExpansionPanelContentDirective,
|
|
1108
|
+
RtExpansionPanelComponent,
|
|
1109
|
+
RtIconButtonComponent,
|
|
1110
|
+
RtIconComponent,
|
|
1111
|
+
RtSideMenuSubItemComponent
|
|
1112
|
+
],
|
|
1113
|
+
template: "<ng-container rtBlock=\"rt-side-menu-favorites\">\n @if (rows().length) {\n <!--\n Блок — раскрывающаяся панель кита, как папка подменю, со звездой вместо значка папки. Имя\n кнопки заголовка называет следующее нажатие; число строк — по входу меню.\n -->\n <rt-expansion-panel\n rtElem=\"panel\"\n appearance=\"plain\"\n [ariaLabel]=\"open() ? collapseLabel() : expandLabel()\"\n [(expanded)]=\"open\"\n (expandedChange)=\"onToggle($event)\">\n <rt-icon rtElem=\"star\" size=\"sm\" name=\"star-fill\" [fill]=\"true\" />\n <span rtElem=\"title\" qa-dataid=\"side-menu-favorites-title\">\n {{ titleLabel() }}\n @if (countShown()) {\n ({{ rows().length }})\n }\n </span>\n\n <ng-template rtExpansionPanelContent>\n <div\n rtElem=\"list\"\n role=\"group\"\n qa-dataid=\"side-menu-favorites\"\n cdkDropList\n cdkDropListLockAxis=\"y\"\n [cdkDropListData]=\"rows()\"\n [attr.aria-label]=\"titleLabel()\"\n (cdkDropListDropped)=\"onDrop($event)\">\n @for (item of rows(); track item.id) {\n <div\n rtElem=\"row\"\n qa-dataid=\"side-menu-favorite-row\"\n cdkDrag\n [attr.data-id]=\"item.id\"\n (cdkDragStarted)=\"onDragStart()\"\n (cdkDragEnded)=\"onDragEnd($event)\">\n <!--\n Ручка стоит внутри строки, последней перед кнопкой потребителя. Строку тянут\n только за ручку: остальная строка — ссылка. С клавиатуры строку переставляют\n стрелки на ручке: перетаскивание CDK клавиш не знает.\n -->\n <rt-side-menu-sub-item\n rtElem=\"item\"\n [item]=\"item\"\n [inFavorites]=\"true\"\n (clickSubMenuAction)=\"clickSubMenuAction.emit($event)\"\n (clickSubMenuAdditionalAction)=\"clickSubMenuAdditionalAction.emit($event)\">\n <rt-icon-button\n #handle\n rtSideMenuSubItemAction\n cdkDragHandle\n rtElem=\"handle\"\n qa-dataid=\"side-menu-favorite-handle\"\n size=\"sm\"\n aria-keyshortcuts=\"ArrowUp ArrowDown\"\n [icon]=\"dragIcon\"\n [ariaLabel]=\"dragLabel()\"\n [tooltip]=\"narrow() ? '' : dragLabel()\"\n (clicked)=\"onHandleClick($event)\"\n (keydown.arrowup)=\"onHandleKey($event, $index, -1)\"\n (keydown.arrowdown)=\"onHandleKey($event, $index, 1)\" />\n </rt-side-menu-sub-item>\n </div>\n }\n </div>\n </ng-template>\n </rt-expansion-panel>\n }\n</ng-container>\n",
|
|
1114
|
+
styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-side-menu-favorites{--rt-side-menu-favorites-radius: var(--rt-radius-full);--rt-side-menu-favorites-divider-width: var(--rt-border-width-thin);display:block}.rt-side-menu-favorites:has(.rt-side-menu-favorites__panel){border-bottom:var(--rt-side-menu-favorites-divider-width) solid var(--rt-color-border-subtle);margin-block-end:var(--rt-space-sm);padding-block-end:var(--rt-space-sm)}.rt-side-menu-favorites__panel.rt-expansion-panel{--rt-expansion-panel-duration: var(--rt-duration-fast);--rt-expansion-panel-header-radius: var(--rt-side-menu-favorites-radius);--rt-expansion-panel-header-min-height: var(--rt-control-height-md);--rt-expansion-panel-header-padding-block: var(--rt-space-2);--rt-expansion-panel-header-padding-start: var(--rt-space-1);--rt-expansion-panel-header-padding-end: var(--rt-space-sm);--rt-expansion-panel-header-gap: var(--rt-space-sm);--rt-expansion-panel-header-font-size: var(--rt-text-sm)}.rt-side-menu-favorites__star{flex-shrink:0;color:var(--rt-color-action-primary)}.rt-side-menu-favorites__title{overflow:hidden;min-width:0;flex:1 1 auto;text-overflow:ellipsis;white-space:nowrap}.rt-side-menu-favorites__list{display:flex;flex-direction:column}.rt-side-menu-favorites__item{min-width:0;flex:1 1 auto}.rt-side-menu-favorites__row{display:flex;align-items:center}.rt-side-menu-favorites__row.cdk-drag-preview{--rt-side-menu-favorites-preview-radius: var(--rt-radius-full);--rt-side-menu-favorites-preview-shadow: var(--rt-shadow-md);border-radius:var(--rt-side-menu-favorites-preview-radius);box-shadow:var(--rt-side-menu-favorites-preview-shadow)}.rt-side-menu-favorites__row.cdk-drag-preview .rt-side-menu-favorites__item{min-width:0;flex:1 1 auto;border-radius:var(--rt-side-menu-favorites-preview-radius);background:var(--rt-color-bg-surface)}.rt-side-menu-favorites__row.cdk-drag-placeholder{opacity:0}.rt-side-menu-favorites__handle{--rt-icon-button-color: var(--rt-side-menu-sub-item-favorite-color);--rt-icon-step-sm: var(--rt-side-menu-sub-item-button-icon-size);flex-shrink:0;cursor:grab;opacity:0}.rt-side-menu-favorites__handle>.rt-icon-button{--rt-icon-button-size-step: var(--rt-side-menu-sub-item-favorite-size);--rt-icon-button-radius: var(--rt-side-menu-sub-item-button-radius)}.rt-side-menu-favorites__handle:active{cursor:grabbing}@media(hover:none){.rt-side-menu-favorites__handle{opacity:1}}.rt-side-menu-favorites__row:hover .rt-side-menu-favorites__handle,.rt-side-menu-favorites__row:has(:focus-visible) .rt-side-menu-favorites__handle,.rt-side-menu-favorites__row.cdk-drag-preview .rt-side-menu-favorites__handle{opacity:1}@media(hover:hover){.rt-side-menu--favorite-actions-none .rt-side-menu-favorites__handle{overflow:hidden;width:0;margin-inline-start:calc(var(--rt-space-sm) * -1)}.rt-side-menu--favorite-actions-none .rt-side-menu-favorites__row:hover .rt-side-menu-favorites__handle,.rt-side-menu--favorite-actions-none .rt-side-menu-favorites__row:has(:focus-visible) .rt-side-menu-favorites__handle{overflow:visible;width:auto;margin-inline-start:0}}}\n"]
|
|
1115
|
+
}]
|
|
1116
|
+
}],
|
|
1117
|
+
ctorParameters: () => [],
|
|
1118
|
+
propDecorators: {
|
|
1119
|
+
handles: [{
|
|
1120
|
+
type: i0.ViewChildren,
|
|
1121
|
+
args: ["handle", {
|
|
1122
|
+
read: ElementRef,
|
|
1123
|
+
isSignal: true
|
|
1124
|
+
}]
|
|
1125
|
+
}],
|
|
1126
|
+
clickSubMenuAction: [{
|
|
1127
|
+
type: i0.Output,
|
|
1128
|
+
args: ["clickSubMenuAction"]
|
|
1129
|
+
}],
|
|
1130
|
+
clickSubMenuAdditionalAction: [{
|
|
1131
|
+
type: i0.Output,
|
|
1132
|
+
args: ["clickSubMenuAdditionalAction"]
|
|
1133
|
+
}]
|
|
1134
|
+
}
|
|
1135
|
+
});
|
|
1136
|
+
var RtSideMenuCloseTimer = class {
|
|
1137
|
+
#handle = null;
|
|
1138
|
+
constructor(destroyRef) {
|
|
1139
|
+
destroyRef.onDestroy(() => this.cancel());
|
|
1140
|
+
}
|
|
1141
|
+
run(delay, close) {
|
|
1142
|
+
this.cancel();
|
|
1143
|
+
if (delay <= 0) {
|
|
1144
|
+
close();
|
|
1145
|
+
return;
|
|
1146
|
+
}
|
|
1147
|
+
this.#handle = setTimeout(() => {
|
|
1148
|
+
this.#handle = null;
|
|
1149
|
+
close();
|
|
1150
|
+
}, delay);
|
|
1151
|
+
}
|
|
1152
|
+
cancel() {
|
|
1153
|
+
if (this.#handle !== null) {
|
|
1154
|
+
clearTimeout(this.#handle);
|
|
1155
|
+
this.#handle = null;
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
};
|
|
1159
|
+
var RtSubMenuKeyboard = class {
|
|
1160
|
+
#highlightedId;
|
|
1161
|
+
#openedIds;
|
|
1162
|
+
#closedIds;
|
|
1163
|
+
#hooks;
|
|
1164
|
+
constructor(hooks) {
|
|
1165
|
+
this.#highlightedId = signal(null, ...ngDevMode ? [{ debugName: "#highlightedId" }] : /* istanbul ignore next */ []);
|
|
1166
|
+
this.#openedIds = signal([], ...ngDevMode ? [{ debugName: "#openedIds" }] : /* istanbul ignore next */ []);
|
|
1167
|
+
this.#closedIds = signal([], ...ngDevMode ? [{ debugName: "#closedIds" }] : /* istanbul ignore next */ []);
|
|
1168
|
+
this.highlightedId = this.#highlightedId.asReadonly();
|
|
1169
|
+
this.openedIds = this.#openedIds.asReadonly();
|
|
1170
|
+
this.closedIds = this.#closedIds.asReadonly();
|
|
1171
|
+
this.#hooks = hooks;
|
|
1172
|
+
}
|
|
1173
|
+
reset() {
|
|
1174
|
+
this.#highlightedId.set(null);
|
|
1175
|
+
this.#openedIds.set([]);
|
|
1176
|
+
this.#closedIds.set([]);
|
|
1177
|
+
}
|
|
1178
|
+
press(key, items, expandedIds) {
|
|
1179
|
+
const walk = walkSideMenuItems(items, expandedIds);
|
|
1180
|
+
const current = walk.find((item) => item.id === this.#highlightedId()) ?? null;
|
|
1181
|
+
switch (key) {
|
|
1182
|
+
case "ArrowDown":
|
|
1183
|
+
case "ArrowUp":
|
|
1184
|
+
this.#highlightedId.set(stepSideMenuHighlight(walk, this.#highlightedId(), key === "ArrowDown" ? 1 : -1));
|
|
1185
|
+
return true;
|
|
1186
|
+
case "ArrowRight": return this.setFolderOpen(current, true);
|
|
1187
|
+
case "ArrowLeft": return this.setFolderOpen(current, false);
|
|
1188
|
+
case "Enter": return this.#enter(current);
|
|
1189
|
+
case "Escape":
|
|
1190
|
+
this.reset();
|
|
1191
|
+
this.#hooks.clearQuery();
|
|
1192
|
+
return true;
|
|
1193
|
+
default: return false;
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
#enter(item) {
|
|
1197
|
+
if (item === null) return false;
|
|
1198
|
+
if (item.link) {
|
|
1199
|
+
this.#hooks.open(item);
|
|
1200
|
+
return true;
|
|
1201
|
+
}
|
|
1202
|
+
return this.setFolderOpen(item, true);
|
|
1203
|
+
}
|
|
1204
|
+
setFolderOpen(item, open) {
|
|
1205
|
+
if (item === null || !item.submenu?.length) return false;
|
|
1206
|
+
const without = (ids) => ids.filter((id) => id !== item.id);
|
|
1207
|
+
this.#openedIds.update((ids) => open ? [...without(ids), item.id] : without(ids));
|
|
1208
|
+
this.#closedIds.update((ids) => open ? without(ids) : [...without(ids), item.id]);
|
|
1209
|
+
return true;
|
|
1210
|
+
}
|
|
1211
|
+
};
|
|
1212
|
+
var RtSideMenuResize = class {
|
|
1213
|
+
#draggedWidth;
|
|
1214
|
+
#listen;
|
|
1215
|
+
#hooks;
|
|
1216
|
+
#stop;
|
|
1217
|
+
constructor(listen, hooks, destroyRef) {
|
|
1218
|
+
this.#draggedWidth = signal(null, ...ngDevMode ? [{ debugName: "#draggedWidth" }] : /* istanbul ignore next */ []);
|
|
1219
|
+
this.#stop = null;
|
|
1220
|
+
this.draggedWidth = this.#draggedWidth.asReadonly();
|
|
1221
|
+
this.valueNow = computed(() => {
|
|
1222
|
+
const width = this.#draggedWidth() ?? this.#hooks.namedWidth();
|
|
1223
|
+
return width === null ? null : clampSideMenuWidth(width);
|
|
1224
|
+
}, ...ngDevMode ? [{ debugName: "valueNow" }] : /* istanbul ignore next */ []);
|
|
1225
|
+
this.#listen = listen;
|
|
1226
|
+
this.#hooks = hooks;
|
|
1227
|
+
destroyRef?.onDestroy(() => this.finish());
|
|
1228
|
+
}
|
|
1229
|
+
isRunning() {
|
|
1230
|
+
return this.#stop !== null;
|
|
1231
|
+
}
|
|
1232
|
+
pressKey(key, from) {
|
|
1233
|
+
const width = sideMenuWidthByKey(key, from);
|
|
1234
|
+
if (width === null) return false;
|
|
1235
|
+
this.#hooks.askWidth(width);
|
|
1236
|
+
return true;
|
|
1237
|
+
}
|
|
1238
|
+
start(event, startWidth) {
|
|
1239
|
+
if (this.isRunning()) return;
|
|
1240
|
+
const stop = startSideMenuWidthDrag(event, startWidth, this.#listen, {
|
|
1241
|
+
onWidth: (width) => this.#draggedWidth.set(width),
|
|
1242
|
+
onEnd: () => this.finish()
|
|
1243
|
+
});
|
|
1244
|
+
if (stop !== null) {
|
|
1245
|
+
this.#stop = stop;
|
|
1246
|
+
this.#hooks.started();
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
finish() {
|
|
1250
|
+
if (!this.isRunning()) return;
|
|
1251
|
+
const width = this.#draggedWidth();
|
|
1252
|
+
const drawn = width === null ? null : reportedSideMenuWidth(width, this.#hooks.panel());
|
|
1253
|
+
this.#stop?.();
|
|
1254
|
+
this.#stop = null;
|
|
1255
|
+
this.#draggedWidth.set(null);
|
|
1256
|
+
if (drawn !== null) this.#hooks.askWidth(drawn);
|
|
1257
|
+
this.#hooks.ended();
|
|
1258
|
+
}
|
|
1259
|
+
};
|
|
1260
|
+
var RtSideMenuLookBase = class RtSideMenuLookBase {
|
|
1261
|
+
constructor() {
|
|
1262
|
+
this.subMenuTooltipsShown = input(true, {
|
|
1263
|
+
...ngDevMode ? { debugName: "subMenuTooltipsShown" } : /* istanbul ignore next */ {},
|
|
1264
|
+
transform: booleanAttribute
|
|
1265
|
+
});
|
|
1266
|
+
this.railTitlesShown = input(true, {
|
|
1267
|
+
...ngDevMode ? { debugName: "railTitlesShown" } : /* istanbul ignore next */ {},
|
|
1268
|
+
transform: booleanAttribute
|
|
1269
|
+
});
|
|
1270
|
+
this.railIconFill = input(false, {
|
|
1271
|
+
...ngDevMode ? { debugName: "railIconFill" } : /* istanbul ignore next */ {},
|
|
1272
|
+
transform: booleanAttribute
|
|
1273
|
+
});
|
|
1274
|
+
this.subItemIconFill = input(false, {
|
|
1275
|
+
...ngDevMode ? { debugName: "subItemIconFill" } : /* istanbul ignore next */ {},
|
|
1276
|
+
transform: booleanAttribute
|
|
1277
|
+
});
|
|
1278
|
+
this.panelScrollHintShown = input(false, {
|
|
1279
|
+
...ngDevMode ? { debugName: "panelScrollHintShown" } : /* istanbul ignore next */ {},
|
|
1280
|
+
transform: booleanAttribute
|
|
1281
|
+
});
|
|
1282
|
+
this.searchSize = input("sm", ...ngDevMode ? [{ debugName: "searchSize" }] : /* istanbul ignore next */ []);
|
|
1283
|
+
this.searchAppearance = input("outline", ...ngDevMode ? [{ debugName: "searchAppearance" }] : /* istanbul ignore next */ []);
|
|
1284
|
+
}
|
|
1285
|
+
static {
|
|
1286
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
1287
|
+
minVersion: "12.0.0",
|
|
1288
|
+
version: "22.2.2",
|
|
1289
|
+
ngImport: i0,
|
|
1290
|
+
type: RtSideMenuLookBase,
|
|
1291
|
+
deps: [],
|
|
1292
|
+
target: i0.ɵɵFactoryTarget.Directive
|
|
1293
|
+
});
|
|
1294
|
+
}
|
|
1295
|
+
static {
|
|
1296
|
+
this.ɵdir = i0.ɵɵngDeclareDirective({
|
|
1297
|
+
minVersion: "17.1.0",
|
|
1298
|
+
version: "22.2.2",
|
|
1299
|
+
type: RtSideMenuLookBase,
|
|
1300
|
+
isStandalone: true,
|
|
1301
|
+
inputs: {
|
|
1302
|
+
subMenuTooltipsShown: {
|
|
1303
|
+
classPropertyName: "subMenuTooltipsShown",
|
|
1304
|
+
publicName: "subMenuTooltipsShown",
|
|
1305
|
+
isSignal: true,
|
|
1306
|
+
isRequired: false,
|
|
1307
|
+
transformFunction: null
|
|
1308
|
+
},
|
|
1309
|
+
railTitlesShown: {
|
|
1310
|
+
classPropertyName: "railTitlesShown",
|
|
1311
|
+
publicName: "railTitlesShown",
|
|
1312
|
+
isSignal: true,
|
|
1313
|
+
isRequired: false,
|
|
1314
|
+
transformFunction: null
|
|
1315
|
+
},
|
|
1316
|
+
railIconFill: {
|
|
1317
|
+
classPropertyName: "railIconFill",
|
|
1318
|
+
publicName: "railIconFill",
|
|
1319
|
+
isSignal: true,
|
|
1320
|
+
isRequired: false,
|
|
1321
|
+
transformFunction: null
|
|
1322
|
+
},
|
|
1323
|
+
subItemIconFill: {
|
|
1324
|
+
classPropertyName: "subItemIconFill",
|
|
1325
|
+
publicName: "subItemIconFill",
|
|
1326
|
+
isSignal: true,
|
|
1327
|
+
isRequired: false,
|
|
1328
|
+
transformFunction: null
|
|
1329
|
+
},
|
|
1330
|
+
panelScrollHintShown: {
|
|
1331
|
+
classPropertyName: "panelScrollHintShown",
|
|
1332
|
+
publicName: "panelScrollHintShown",
|
|
1333
|
+
isSignal: true,
|
|
1334
|
+
isRequired: false,
|
|
1335
|
+
transformFunction: null
|
|
1336
|
+
},
|
|
1337
|
+
searchSize: {
|
|
1338
|
+
classPropertyName: "searchSize",
|
|
1339
|
+
publicName: "searchSize",
|
|
1340
|
+
isSignal: true,
|
|
1341
|
+
isRequired: false,
|
|
1342
|
+
transformFunction: null
|
|
1343
|
+
},
|
|
1344
|
+
searchAppearance: {
|
|
1345
|
+
classPropertyName: "searchAppearance",
|
|
1346
|
+
publicName: "searchAppearance",
|
|
1347
|
+
isSignal: true,
|
|
1348
|
+
isRequired: false,
|
|
1349
|
+
transformFunction: null
|
|
1350
|
+
}
|
|
1351
|
+
},
|
|
1352
|
+
ngImport: i0
|
|
1353
|
+
});
|
|
1354
|
+
}
|
|
1355
|
+
};
|
|
1356
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
1357
|
+
minVersion: "12.0.0",
|
|
1358
|
+
version: "22.2.2",
|
|
1359
|
+
ngImport: i0,
|
|
1360
|
+
type: RtSideMenuLookBase,
|
|
1361
|
+
decorators: [{ type: Directive }],
|
|
1362
|
+
propDecorators: {
|
|
1363
|
+
subMenuTooltipsShown: [{
|
|
1364
|
+
type: i0.Input,
|
|
1365
|
+
args: [{
|
|
1366
|
+
isSignal: true,
|
|
1367
|
+
alias: "subMenuTooltipsShown",
|
|
1368
|
+
required: false
|
|
1369
|
+
}]
|
|
1370
|
+
}],
|
|
1371
|
+
railTitlesShown: [{
|
|
1372
|
+
type: i0.Input,
|
|
1373
|
+
args: [{
|
|
1374
|
+
isSignal: true,
|
|
1375
|
+
alias: "railTitlesShown",
|
|
1376
|
+
required: false
|
|
1377
|
+
}]
|
|
1378
|
+
}],
|
|
1379
|
+
railIconFill: [{
|
|
1380
|
+
type: i0.Input,
|
|
1381
|
+
args: [{
|
|
1382
|
+
isSignal: true,
|
|
1383
|
+
alias: "railIconFill",
|
|
1384
|
+
required: false
|
|
1385
|
+
}]
|
|
1386
|
+
}],
|
|
1387
|
+
subItemIconFill: [{
|
|
1388
|
+
type: i0.Input,
|
|
1389
|
+
args: [{
|
|
1390
|
+
isSignal: true,
|
|
1391
|
+
alias: "subItemIconFill",
|
|
1392
|
+
required: false
|
|
1393
|
+
}]
|
|
1394
|
+
}],
|
|
1395
|
+
panelScrollHintShown: [{
|
|
1396
|
+
type: i0.Input,
|
|
1397
|
+
args: [{
|
|
1398
|
+
isSignal: true,
|
|
1399
|
+
alias: "panelScrollHintShown",
|
|
1400
|
+
required: false
|
|
1401
|
+
}]
|
|
1402
|
+
}],
|
|
1403
|
+
searchSize: [{
|
|
1404
|
+
type: i0.Input,
|
|
1405
|
+
args: [{
|
|
1406
|
+
isSignal: true,
|
|
1407
|
+
alias: "searchSize",
|
|
1408
|
+
required: false
|
|
1409
|
+
}]
|
|
1410
|
+
}],
|
|
1411
|
+
searchAppearance: [{
|
|
1412
|
+
type: i0.Input,
|
|
1413
|
+
args: [{
|
|
1414
|
+
isSignal: true,
|
|
1415
|
+
alias: "searchAppearance",
|
|
1416
|
+
required: false
|
|
1417
|
+
}]
|
|
1418
|
+
}]
|
|
1419
|
+
}
|
|
1420
|
+
});
|
|
1421
|
+
var RtSideMenuHeaderDirective = class RtSideMenuHeaderDirective {
|
|
1422
|
+
static {
|
|
1423
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
1424
|
+
minVersion: "12.0.0",
|
|
1425
|
+
version: "22.2.2",
|
|
1426
|
+
ngImport: i0,
|
|
1427
|
+
type: RtSideMenuHeaderDirective,
|
|
1428
|
+
deps: [],
|
|
1429
|
+
target: i0.ɵɵFactoryTarget.Directive
|
|
1430
|
+
});
|
|
1431
|
+
}
|
|
1432
|
+
static {
|
|
1433
|
+
this.ɵdir = i0.ɵɵngDeclareDirective({
|
|
1434
|
+
minVersion: "14.0.0",
|
|
1435
|
+
version: "22.2.2",
|
|
1436
|
+
type: RtSideMenuHeaderDirective,
|
|
1437
|
+
isStandalone: true,
|
|
1438
|
+
selector: "[rtSideMenuHeader]",
|
|
1439
|
+
ngImport: i0
|
|
1440
|
+
});
|
|
1441
|
+
}
|
|
1442
|
+
};
|
|
1443
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
1444
|
+
minVersion: "12.0.0",
|
|
1445
|
+
version: "22.2.2",
|
|
1446
|
+
ngImport: i0,
|
|
1447
|
+
type: RtSideMenuHeaderDirective,
|
|
1448
|
+
decorators: [{
|
|
1449
|
+
type: Directive,
|
|
1450
|
+
args: [{ selector: "[rtSideMenuHeader]" }]
|
|
1451
|
+
}]
|
|
1452
|
+
});
|
|
1453
|
+
var RtSideMenuFooterDirective = class RtSideMenuFooterDirective {
|
|
1454
|
+
static {
|
|
1455
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
1456
|
+
minVersion: "12.0.0",
|
|
1457
|
+
version: "22.2.2",
|
|
1458
|
+
ngImport: i0,
|
|
1459
|
+
type: RtSideMenuFooterDirective,
|
|
1460
|
+
deps: [],
|
|
1461
|
+
target: i0.ɵɵFactoryTarget.Directive
|
|
1462
|
+
});
|
|
1463
|
+
}
|
|
1464
|
+
static {
|
|
1465
|
+
this.ɵdir = i0.ɵɵngDeclareDirective({
|
|
1466
|
+
minVersion: "14.0.0",
|
|
1467
|
+
version: "22.2.2",
|
|
1468
|
+
type: RtSideMenuFooterDirective,
|
|
1469
|
+
isStandalone: true,
|
|
1470
|
+
selector: "[rtSideMenuFooter]",
|
|
1471
|
+
ngImport: i0
|
|
1472
|
+
});
|
|
1473
|
+
}
|
|
1474
|
+
};
|
|
1475
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
1476
|
+
minVersion: "12.0.0",
|
|
1477
|
+
version: "22.2.2",
|
|
1478
|
+
ngImport: i0,
|
|
1479
|
+
type: RtSideMenuFooterDirective,
|
|
1480
|
+
decorators: [{
|
|
1481
|
+
type: Directive,
|
|
1482
|
+
args: [{ selector: "[rtSideMenuFooter]" }]
|
|
1483
|
+
}]
|
|
1484
|
+
});
|
|
1485
|
+
var RtSideMenuIconDirective = class RtSideMenuIconDirective {
|
|
1486
|
+
constructor() {
|
|
1487
|
+
this.templateRef = inject(TemplateRef);
|
|
1488
|
+
}
|
|
1489
|
+
static ngTemplateContextGuard(_directive, context) {
|
|
1490
|
+
return true;
|
|
1491
|
+
}
|
|
1492
|
+
static {
|
|
1493
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
1494
|
+
minVersion: "12.0.0",
|
|
1495
|
+
version: "22.2.2",
|
|
1496
|
+
ngImport: i0,
|
|
1497
|
+
type: RtSideMenuIconDirective,
|
|
1498
|
+
deps: [],
|
|
1499
|
+
target: i0.ɵɵFactoryTarget.Directive
|
|
1500
|
+
});
|
|
1501
|
+
}
|
|
1502
|
+
static {
|
|
1503
|
+
this.ɵdir = i0.ɵɵngDeclareDirective({
|
|
1504
|
+
minVersion: "14.0.0",
|
|
1505
|
+
version: "22.2.2",
|
|
1506
|
+
type: RtSideMenuIconDirective,
|
|
1507
|
+
isStandalone: true,
|
|
1508
|
+
selector: "ng-template[rtSideMenuIcon]",
|
|
1509
|
+
ngImport: i0
|
|
1510
|
+
});
|
|
1511
|
+
}
|
|
1512
|
+
};
|
|
1513
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
1514
|
+
minVersion: "12.0.0",
|
|
1515
|
+
version: "22.2.2",
|
|
1516
|
+
ngImport: i0,
|
|
1517
|
+
type: RtSideMenuIconDirective,
|
|
1518
|
+
decorators: [{
|
|
1519
|
+
type: Directive,
|
|
1520
|
+
args: [{ selector: "ng-template[rtSideMenuIcon]" }]
|
|
1521
|
+
}]
|
|
1522
|
+
});
|
|
1523
|
+
const BEM_BLOCK = "rt-side-menu";
|
|
1524
|
+
var RtSideMenuComponent = class RtSideMenuComponent extends RtSideMenuLookBase {
|
|
1525
|
+
#breakpoints;
|
|
1526
|
+
#renderer;
|
|
1527
|
+
#settings;
|
|
1528
|
+
#resize;
|
|
1529
|
+
#closeTimer;
|
|
1530
|
+
#keyboard;
|
|
1531
|
+
#hoverOpened;
|
|
1532
|
+
#searchHeld;
|
|
1533
|
+
#dragHeld;
|
|
1534
|
+
#mode;
|
|
1535
|
+
#width;
|
|
1536
|
+
#pinnedSubMenu;
|
|
1537
|
+
constructor() {
|
|
1538
|
+
super();
|
|
1539
|
+
this.#breakpoints = inject(BreakpointsService);
|
|
1540
|
+
this.#renderer = inject(Renderer2);
|
|
1541
|
+
this.#settings = inject(RtSideMenuSettingsService, { optional: true });
|
|
1542
|
+
this.#resize = new RtSideMenuResize((target, name, handler) => this.#renderer.listen(target, name, handler), {
|
|
1543
|
+
askWidth: (width) => {
|
|
1544
|
+
this.#settings?.setSubMenuWidth(this.menuId(), width);
|
|
1545
|
+
this.subMenuWidthChange.emit(width);
|
|
1546
|
+
},
|
|
1547
|
+
started: () => this.subMenuResizeStart.emit(),
|
|
1548
|
+
ended: () => this.subMenuResizeEnd.emit(),
|
|
1549
|
+
panel: () => this.panelRef()?.nativeElement ?? null,
|
|
1550
|
+
namedWidth: () => this.#width()
|
|
1551
|
+
}, inject(DestroyRef));
|
|
1552
|
+
this.#closeTimer = new RtSideMenuCloseTimer(inject(DestroyRef));
|
|
1553
|
+
this.#keyboard = new RtSubMenuKeyboard({
|
|
1554
|
+
open: (item) => this.#pressRow(item),
|
|
1555
|
+
clearQuery: () => this.searchControl.setValue("")
|
|
1556
|
+
});
|
|
1557
|
+
this.#hoverOpened = signal(false, ...ngDevMode ? [{ debugName: "#hoverOpened" }] : /* istanbul ignore next */ []);
|
|
1558
|
+
this.#searchHeld = signal(false, ...ngDevMode ? [{ debugName: "#searchHeld" }] : /* istanbul ignore next */ []);
|
|
1559
|
+
this.#dragHeld = signal(false, ...ngDevMode ? [{ debugName: "#dragHeld" }] : /* istanbul ignore next */ []);
|
|
1560
|
+
this.#mode = computed(() => this.subMenuMode() ?? (this.pinShown() ? this.#settings?.subMenuMode(this.menuId())() : void 0) ?? "hover", ...ngDevMode ? [{ debugName: "#mode" }] : /* istanbul ignore next */ []);
|
|
1561
|
+
this.#width = computed(() => this.subMenuWidth() ?? this.#settings?.subMenuWidth(this.menuId())() ?? null, ...ngDevMode ? [{ debugName: "#width" }] : /* istanbul ignore next */ []);
|
|
1562
|
+
this.#pinnedSubMenu = computed(() => this.isPinned() ? pinnedSideMenuItems(this.selectedSubMenu(), this.activeMenuIds(), this.menuItems()) : [], ...ngDevMode ? [{ debugName: "#pinnedSubMenu" }] : /* istanbul ignore next */ []);
|
|
1563
|
+
this.searchControl = new FormControl("");
|
|
1564
|
+
this.panelRef = viewChild("panel", ...ngDevMode ? [{ debugName: "panelRef" }] : /* istanbul ignore next */ []);
|
|
1565
|
+
this.headerTpl = contentChild(RtSideMenuHeaderDirective, {
|
|
1566
|
+
...ngDevMode ? { debugName: "headerTpl" } : /* istanbul ignore next */ {},
|
|
1567
|
+
read: TemplateRef
|
|
1568
|
+
});
|
|
1569
|
+
this.footerTpl = contentChild(RtSideMenuFooterDirective, {
|
|
1570
|
+
...ngDevMode ? { debugName: "footerTpl" } : /* istanbul ignore next */ {},
|
|
1571
|
+
read: TemplateRef
|
|
1572
|
+
});
|
|
1573
|
+
this.searchLabel = rtKitLabel("sideMenuSearch");
|
|
1574
|
+
this.pinLabel = rtKitLabel("sideMenuPin");
|
|
1575
|
+
this.unpinLabel = rtKitLabel("sideMenuUnpin");
|
|
1576
|
+
this.nothingFoundLabel = rtKitLabel("sideMenuNothingFound");
|
|
1577
|
+
this.resizeLabel = rtKitLabel("sideMenuResize");
|
|
1578
|
+
this.backLabel = rtKitLabel("sideMenuBack");
|
|
1579
|
+
this.narrow = this.#breakpoints.narrow;
|
|
1580
|
+
this.resizeValueNow = this.#resize.valueNow;
|
|
1581
|
+
this.resizeValueMin = 120;
|
|
1582
|
+
this.resizeValueMax = 480;
|
|
1583
|
+
this.panelWidthStyle = computed(() => {
|
|
1584
|
+
const width = this.#resize.draggedWidth() ?? this.#width();
|
|
1585
|
+
return width === null ? null : `${clampSideMenuWidth(width)}px`;
|
|
1586
|
+
}, ...ngDevMode ? [{ debugName: "panelWidthStyle" }] : /* istanbul ignore next */ []);
|
|
1587
|
+
this.isPinned = computed(() => this.#mode() === "pinned" && !this.narrow(), ...ngDevMode ? [{ debugName: "isPinned" }] : /* istanbul ignore next */ []);
|
|
1588
|
+
this.isSearchHeld = computed(() => this.#searchHeld() && !this.isPinned(), ...ngDevMode ? [{ debugName: "isSearchHeld" }] : /* istanbul ignore next */ []);
|
|
1589
|
+
this.subMenuOpened = computed(() => this.isPinned() ? this.#pinnedSubMenu().length > 0 : this.#hoverOpened(), ...ngDevMode ? [{ debugName: "subMenuOpened" }] : /* istanbul ignore next */ []);
|
|
1590
|
+
this.visibleSubMenuItems = computed(() => filterSideMenuItems(this.shownSubMenu(), this.subMenuQuery()), ...ngDevMode ? [{ debugName: "visibleSubMenuItems" }] : /* istanbul ignore next */ []);
|
|
1591
|
+
this.isNothingFound = computed(() => this.subMenuQuery().trim() !== "" && this.visibleSubMenuItems().length === 0, ...ngDevMode ? [{ debugName: "isNothingFound" }] : /* istanbul ignore next */ []);
|
|
1592
|
+
this.activeRailIds = computed(() => {
|
|
1593
|
+
const selected = this.selectedItem();
|
|
1594
|
+
return selected ? [selected.id] : this.activeMenuIds();
|
|
1595
|
+
}, ...ngDevMode ? [{ debugName: "activeRailIds" }] : /* istanbul ignore next */ []);
|
|
1596
|
+
this.shownSubMenu = computed(() => this.isPinned() ? this.#pinnedSubMenu() : this.selectedSubMenu() ?? [], ...ngDevMode ? [{ debugName: "shownSubMenu" }] : /* istanbul ignore next */ []);
|
|
1597
|
+
this.selectedItem = signal(null, ...ngDevMode ? [{ debugName: "selectedItem" }] : /* istanbul ignore next */ []);
|
|
1598
|
+
this.selectedSubMenu = signal(null, ...ngDevMode ? [{ debugName: "selectedSubMenu" }] : /* istanbul ignore next */ []);
|
|
1599
|
+
this.subMenuQuery = signal("", ...ngDevMode ? [{ debugName: "subMenuQuery" }] : /* istanbul ignore next */ []);
|
|
1600
|
+
this.highlightedMenuId = this.#keyboard.highlightedId;
|
|
1601
|
+
this.expandedMenuIds = computed(() => {
|
|
1602
|
+
const found = this.subMenuQuery().trim() === "" ? [] : sideMenuIdsToExpand(this.visibleSubMenuItems());
|
|
1603
|
+
const closed = this.#keyboard.closedIds();
|
|
1604
|
+
return [
|
|
1605
|
+
...this.activeMenuIds(),
|
|
1606
|
+
...found,
|
|
1607
|
+
...this.#keyboard.openedIds()
|
|
1608
|
+
].filter((id) => !closed.includes(id));
|
|
1609
|
+
}, ...ngDevMode ? [{ debugName: "expandedMenuIds" }] : /* istanbul ignore next */ []);
|
|
1610
|
+
this.activeMenuIds = input.required(...ngDevMode ? [{ debugName: "activeMenuIds" }] : /* istanbul ignore next */ []);
|
|
1611
|
+
this.menuItems = input([], ...ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []);
|
|
1612
|
+
this.subMenuMode = input(void 0, ...ngDevMode ? [{ debugName: "subMenuMode" }] : /* istanbul ignore next */ []);
|
|
1613
|
+
this.subMenuWidth = input(void 0, ...ngDevMode ? [{ debugName: "subMenuWidth" }] : /* istanbul ignore next */ []);
|
|
1614
|
+
this.menuId = input(RT_SIDE_MENU_DEFAULT_ID, {
|
|
1615
|
+
...ngDevMode ? { debugName: "menuId" } : /* istanbul ignore next */ {},
|
|
1616
|
+
transform: normalizeSideMenuId
|
|
1617
|
+
});
|
|
1618
|
+
this.favoritesCount = input("collapsed", ...ngDevMode ? [{ debugName: "favoritesCount" }] : /* istanbul ignore next */ []);
|
|
1619
|
+
this.favoriteActionsReserve = input("none", ...ngDevMode ? [{ debugName: "favoriteActionsReserve" }] : /* istanbul ignore next */ []);
|
|
1620
|
+
this.isFavoritesSearchShown = input(true, {
|
|
1621
|
+
...ngDevMode ? { debugName: "isFavoritesSearchShown" } : /* istanbul ignore next */ {},
|
|
1622
|
+
transform: booleanAttribute
|
|
1623
|
+
});
|
|
1624
|
+
this.pinShown = input(true, {
|
|
1625
|
+
...ngDevMode ? { debugName: "pinShown" } : /* istanbul ignore next */ {},
|
|
1626
|
+
transform: booleanAttribute
|
|
1627
|
+
});
|
|
1628
|
+
this.subMenuCloseDelay = input(0, {
|
|
1629
|
+
...ngDevMode ? { debugName: "subMenuCloseDelay" } : /* istanbul ignore next */ {},
|
|
1630
|
+
transform: (value) => numberAttribute(value, 0)
|
|
1631
|
+
});
|
|
1632
|
+
this.subMenuModeChange = output();
|
|
1633
|
+
this.subMenuWidthChange = output();
|
|
1634
|
+
this.subMenuResizeStart = output();
|
|
1635
|
+
this.subMenuResizeEnd = output();
|
|
1636
|
+
this.closeMobileMenuAction = output();
|
|
1637
|
+
this.clickSubMenuAction = output();
|
|
1638
|
+
this.clickSubMenuAdditionalAction = output();
|
|
1639
|
+
this.ownIconTpl = contentChild(RtSideMenuIconDirective, {
|
|
1640
|
+
...ngDevMode ? { debugName: "ownIconTpl" } : /* istanbul ignore next */ {},
|
|
1641
|
+
read: TemplateRef
|
|
1642
|
+
});
|
|
1643
|
+
this.searchControl.valueChanges.pipe(takeUntilDestroyed()).subscribe((query) => {
|
|
1644
|
+
this.subMenuQuery.set(query ?? "");
|
|
1645
|
+
this.onSearchHold();
|
|
1646
|
+
this.#keyboard.reset();
|
|
1647
|
+
});
|
|
1648
|
+
if (isDevMode()) effect(() => warnUnpairedSideMenuIcons(this.menuId(), this.menuItems(), this.ownIconTpl() !== void 0));
|
|
1649
|
+
}
|
|
1650
|
+
onClickMenu(item) {
|
|
1651
|
+
if (this.isPinned()) {
|
|
1652
|
+
this.#pickPinnedSubMenu(item);
|
|
1653
|
+
this.closeMobileMenu();
|
|
1654
|
+
return;
|
|
1655
|
+
}
|
|
1656
|
+
this.selectedItem.set(item);
|
|
1657
|
+
if (item.submenu) {
|
|
1658
|
+
this.selectedSubMenu.set(item.submenu);
|
|
1659
|
+
this.#hoverOpened.set(true);
|
|
1660
|
+
} else if (this.selectedSubMenu()) this.closeSubMenu();
|
|
1661
|
+
if (item.link) this.closeMobileMenu();
|
|
1662
|
+
}
|
|
1663
|
+
onClickSubMenu({ item, event }) {
|
|
1664
|
+
if (!item.link) return;
|
|
1665
|
+
this.clickSubMenuAction.emit({
|
|
1666
|
+
item,
|
|
1667
|
+
event
|
|
1668
|
+
});
|
|
1669
|
+
if (!this.isPinned()) this.closeSubMenu();
|
|
1670
|
+
this.closeMobileMenu();
|
|
1671
|
+
}
|
|
1672
|
+
onClickSubMenuAdditional(payload) {
|
|
1673
|
+
this.clickSubMenuAdditionalAction.emit(payload);
|
|
1674
|
+
}
|
|
1675
|
+
onBackToMainMenu() {
|
|
1676
|
+
this.selectedItem.set(null);
|
|
1677
|
+
this.selectedSubMenu.set(null);
|
|
1678
|
+
this.searchControl.setValue("", { emitEvent: false });
|
|
1679
|
+
this.subMenuQuery.set("");
|
|
1680
|
+
}
|
|
1681
|
+
toggleSubMenu(item) {
|
|
1682
|
+
if (this.isPinned() || item === void 0 && this.#isHeld()) return;
|
|
1683
|
+
if (item?.submenu) {
|
|
1684
|
+
this.#closeTimer.cancel();
|
|
1685
|
+
this.selectedSubMenu.set(item.submenu);
|
|
1686
|
+
this.#hoverOpened.set(true);
|
|
1687
|
+
} else if (this.selectedItem()?.submenu) {
|
|
1688
|
+
this.#closeTimer.cancel();
|
|
1689
|
+
this.selectedSubMenu.set(this.selectedItem()?.submenu ?? null);
|
|
1690
|
+
} else this.#closeTimer.run(this.subMenuCloseDelay(), () => {
|
|
1691
|
+
if (item !== void 0 || !this.#isHeld()) this.closeSubMenu();
|
|
1692
|
+
});
|
|
1693
|
+
}
|
|
1694
|
+
cancelSubMenuClose() {
|
|
1695
|
+
this.#closeTimer.cancel();
|
|
1696
|
+
}
|
|
1697
|
+
closeSubMenu() {
|
|
1698
|
+
this.#closeTimer.cancel();
|
|
1699
|
+
this.selectedItem.set(null);
|
|
1700
|
+
this.selectedSubMenu.set(null);
|
|
1701
|
+
this.searchControl.setValue("", { emitEvent: false });
|
|
1702
|
+
this.subMenuQuery.set("");
|
|
1703
|
+
this.#hoverOpened.set(false);
|
|
1704
|
+
this.#searchHeld.set(false);
|
|
1705
|
+
this.#keyboard.reset();
|
|
1706
|
+
}
|
|
1707
|
+
holdSubMenu(held) {
|
|
1708
|
+
this.#dragHeld.set(held);
|
|
1709
|
+
}
|
|
1710
|
+
toggleFolder(item) {
|
|
1711
|
+
this.#keyboard.setFolderOpen(item, !this.expandedMenuIds().includes(item.id));
|
|
1712
|
+
}
|
|
1713
|
+
onSearchHold() {
|
|
1714
|
+
if (!this.isPinned()) this.#searchHeld.set(true);
|
|
1715
|
+
}
|
|
1716
|
+
onSearchKeydown(event) {
|
|
1717
|
+
if (this.#keyboard.press(event.key, this.visibleSubMenuItems(), this.expandedMenuIds())) {
|
|
1718
|
+
event.preventDefault();
|
|
1719
|
+
event.stopPropagation();
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
onSubMenuModeToggle() {
|
|
1723
|
+
const mode = this.isPinned() ? "hover" : "pinned";
|
|
1724
|
+
this.#settings?.setSubMenuMode(this.menuId(), mode);
|
|
1725
|
+
this.subMenuModeChange.emit(mode);
|
|
1726
|
+
}
|
|
1727
|
+
onResizeStart(event) {
|
|
1728
|
+
if (!this.isPinned() || this.#resize.isRunning() || event.button !== 0) return;
|
|
1729
|
+
event.preventDefault();
|
|
1730
|
+
this.#resize.start(event, this.#width() ?? drawnSideMenuWidth(this.panelRef()?.nativeElement ?? null));
|
|
1731
|
+
}
|
|
1732
|
+
onResizeKeydown(event) {
|
|
1733
|
+
const from = this.#width() ?? drawnSideMenuWidth(this.panelRef()?.nativeElement ?? null);
|
|
1734
|
+
if (this.isPinned() && this.#resize.pressKey(event.key, from)) event.preventDefault();
|
|
1735
|
+
}
|
|
1736
|
+
closeMobileMenu() {
|
|
1737
|
+
if (this.narrow()) this.closeMobileMenuAction.emit();
|
|
1738
|
+
}
|
|
1739
|
+
#isHeld() {
|
|
1740
|
+
return this.#searchHeld() || this.#dragHeld();
|
|
1741
|
+
}
|
|
1742
|
+
#pickPinnedSubMenu(item) {
|
|
1743
|
+
if (item.submenu?.length) {
|
|
1744
|
+
this.selectedItem.set(item);
|
|
1745
|
+
this.selectedSubMenu.set(item.submenu);
|
|
1746
|
+
} else if (item.link) {
|
|
1747
|
+
this.selectedItem.set(null);
|
|
1748
|
+
this.selectedSubMenu.set(null);
|
|
1749
|
+
} else return;
|
|
1750
|
+
this.searchControl.setValue("", { emitEvent: false });
|
|
1751
|
+
this.subMenuQuery.set("");
|
|
1752
|
+
}
|
|
1753
|
+
#pressRow(item) {
|
|
1754
|
+
Array.from(this.panelRef()?.nativeElement.querySelectorAll("[id]") ?? []).find((row) => row.id === String(item.id))?.click();
|
|
1755
|
+
}
|
|
1756
|
+
static {
|
|
1757
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
1758
|
+
minVersion: "12.0.0",
|
|
1759
|
+
version: "22.2.2",
|
|
1760
|
+
ngImport: i0,
|
|
1761
|
+
type: RtSideMenuComponent,
|
|
1762
|
+
deps: [],
|
|
1763
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
1764
|
+
});
|
|
1765
|
+
}
|
|
1766
|
+
static {
|
|
1767
|
+
this.ɵcmp = i0.ɵɵngDeclareComponent({
|
|
1768
|
+
minVersion: "17.0.0",
|
|
1769
|
+
version: "22.2.2",
|
|
1770
|
+
type: RtSideMenuComponent,
|
|
1771
|
+
isStandalone: true,
|
|
1772
|
+
selector: "rt-side-menu",
|
|
1773
|
+
inputs: {
|
|
1774
|
+
activeMenuIds: {
|
|
1775
|
+
classPropertyName: "activeMenuIds",
|
|
1776
|
+
publicName: "activeMenuIds",
|
|
1777
|
+
isSignal: true,
|
|
1778
|
+
isRequired: true,
|
|
1779
|
+
transformFunction: null
|
|
1780
|
+
},
|
|
1781
|
+
menuItems: {
|
|
1782
|
+
classPropertyName: "menuItems",
|
|
1783
|
+
publicName: "menuItems",
|
|
1784
|
+
isSignal: true,
|
|
1785
|
+
isRequired: false,
|
|
1786
|
+
transformFunction: null
|
|
1787
|
+
},
|
|
1788
|
+
subMenuMode: {
|
|
1789
|
+
classPropertyName: "subMenuMode",
|
|
1790
|
+
publicName: "subMenuMode",
|
|
1791
|
+
isSignal: true,
|
|
1792
|
+
isRequired: false,
|
|
1793
|
+
transformFunction: null
|
|
1794
|
+
},
|
|
1795
|
+
subMenuWidth: {
|
|
1796
|
+
classPropertyName: "subMenuWidth",
|
|
1797
|
+
publicName: "subMenuWidth",
|
|
1798
|
+
isSignal: true,
|
|
1799
|
+
isRequired: false,
|
|
1800
|
+
transformFunction: null
|
|
1801
|
+
},
|
|
1802
|
+
menuId: {
|
|
1803
|
+
classPropertyName: "menuId",
|
|
1804
|
+
publicName: "menuId",
|
|
1805
|
+
isSignal: true,
|
|
1806
|
+
isRequired: false,
|
|
1807
|
+
transformFunction: null
|
|
1808
|
+
},
|
|
1809
|
+
favoritesCount: {
|
|
1810
|
+
classPropertyName: "favoritesCount",
|
|
1811
|
+
publicName: "favoritesCount",
|
|
1812
|
+
isSignal: true,
|
|
1813
|
+
isRequired: false,
|
|
1814
|
+
transformFunction: null
|
|
1815
|
+
},
|
|
1816
|
+
favoriteActionsReserve: {
|
|
1817
|
+
classPropertyName: "favoriteActionsReserve",
|
|
1818
|
+
publicName: "favoriteActionsReserve",
|
|
1819
|
+
isSignal: true,
|
|
1820
|
+
isRequired: false,
|
|
1821
|
+
transformFunction: null
|
|
1822
|
+
},
|
|
1823
|
+
isFavoritesSearchShown: {
|
|
1824
|
+
classPropertyName: "isFavoritesSearchShown",
|
|
1825
|
+
publicName: "isFavoritesSearchShown",
|
|
1826
|
+
isSignal: true,
|
|
1827
|
+
isRequired: false,
|
|
1828
|
+
transformFunction: null
|
|
1829
|
+
},
|
|
1830
|
+
pinShown: {
|
|
1831
|
+
classPropertyName: "pinShown",
|
|
1832
|
+
publicName: "pinShown",
|
|
1833
|
+
isSignal: true,
|
|
1834
|
+
isRequired: false,
|
|
1835
|
+
transformFunction: null
|
|
1836
|
+
},
|
|
1837
|
+
subMenuCloseDelay: {
|
|
1838
|
+
classPropertyName: "subMenuCloseDelay",
|
|
1839
|
+
publicName: "subMenuCloseDelay",
|
|
1840
|
+
isSignal: true,
|
|
1841
|
+
isRequired: false,
|
|
1842
|
+
transformFunction: null
|
|
1843
|
+
}
|
|
1844
|
+
},
|
|
1845
|
+
outputs: {
|
|
1846
|
+
subMenuModeChange: "subMenuModeChange",
|
|
1847
|
+
subMenuWidthChange: "subMenuWidthChange",
|
|
1848
|
+
subMenuResizeStart: "subMenuResizeStart",
|
|
1849
|
+
subMenuResizeEnd: "subMenuResizeEnd",
|
|
1850
|
+
closeMobileMenuAction: "closeMobileMenuAction",
|
|
1851
|
+
clickSubMenuAction: "clickSubMenuAction",
|
|
1852
|
+
clickSubMenuAdditionalAction: "clickSubMenuAdditionalAction"
|
|
1853
|
+
},
|
|
1854
|
+
host: {
|
|
1855
|
+
properties: {
|
|
1856
|
+
"class.rt-side-menu--pinned": "isPinned()",
|
|
1857
|
+
"style.--rt-side-menu-panel-dragged-width": "panelWidthStyle()",
|
|
1858
|
+
"class.rt-side-menu--favorite-actions-none": "favoriteActionsReserve() === 'none'"
|
|
1859
|
+
},
|
|
1860
|
+
classAttribute: "rt-side-menu"
|
|
1861
|
+
},
|
|
1862
|
+
providers: [{
|
|
1863
|
+
provide: RT_SIDE_MENU,
|
|
1864
|
+
useExisting: RtSideMenuComponent
|
|
1865
|
+
}],
|
|
1866
|
+
queries: [
|
|
1867
|
+
{
|
|
1868
|
+
propertyName: "headerTpl",
|
|
1869
|
+
first: true,
|
|
1870
|
+
predicate: RtSideMenuHeaderDirective,
|
|
1871
|
+
descendants: true,
|
|
1872
|
+
read: TemplateRef,
|
|
1873
|
+
isSignal: true
|
|
1874
|
+
},
|
|
1875
|
+
{
|
|
1876
|
+
propertyName: "footerTpl",
|
|
1877
|
+
first: true,
|
|
1878
|
+
predicate: RtSideMenuFooterDirective,
|
|
1879
|
+
descendants: true,
|
|
1880
|
+
read: TemplateRef,
|
|
1881
|
+
isSignal: true
|
|
1882
|
+
},
|
|
1883
|
+
{
|
|
1884
|
+
propertyName: "ownIconTpl",
|
|
1885
|
+
first: true,
|
|
1886
|
+
predicate: RtSideMenuIconDirective,
|
|
1887
|
+
descendants: true,
|
|
1888
|
+
read: TemplateRef,
|
|
1889
|
+
isSignal: true
|
|
1890
|
+
}
|
|
1891
|
+
],
|
|
1892
|
+
viewQueries: [{
|
|
1893
|
+
propertyName: "panelRef",
|
|
1894
|
+
first: true,
|
|
1895
|
+
predicate: ["panel"],
|
|
1896
|
+
descendants: true,
|
|
1897
|
+
isSignal: true
|
|
1898
|
+
}],
|
|
1899
|
+
usesInheritance: true,
|
|
1900
|
+
ngImport: i0,
|
|
1901
|
+
template: "<ng-container rtBlock=\"rt-side-menu\">\n @if (narrow()) {\n <!-- Узкий экран: один столбец — главные пункты или подменю выбранного раздела с кнопкой назад. -->\n <rt-scroll-area rtElem=\"mobile\" [isScrollHintShown]=\"true\">\n @if (headerTpl(); as header) {\n <ng-container *rtScrollAreaHeader>\n <ng-container [ngTemplateOutlet]=\"header\" />\n </ng-container>\n }\n\n <ng-container *rtScrollAreaContent>\n @if (selectedSubMenu()?.length) {\n <div rtElem=\"mobile-sub\">\n <button type=\"button\" rtElem=\"back\" qa-dataid=\"side-menu-back\" (click)=\"onBackToMainMenu()\">\n <rt-icon rtElem=\"back-icon\" size=\"sm\" name=\"arrow-left\" />\n <span rtElem=\"back-label\">{{ backLabel() }}</span>\n </button>\n\n <ng-container [ngTemplateOutlet]=\"subMenuTpl\" />\n </div>\n } @else {\n <nav rtElem=\"mobile-list\">\n @for (item of menuItems(); track item.id) {\n <ng-container [ngTemplateOutlet]=\"mobileItemTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n }\n </nav>\n }\n </ng-container>\n\n @if (footerTpl(); as footer) {\n <ng-container *rtScrollAreaFooter>\n <ng-container [ngTemplateOutlet]=\"footer\" />\n </ng-container>\n }\n </rt-scroll-area>\n } @else {\n <rt-scroll-area rtElem=\"rail\" [isScrollHintShown]=\"true\">\n @if (headerTpl(); as header) {\n <ng-container *rtScrollAreaHeader>\n <ng-container [ngTemplateOutlet]=\"header\" />\n </ng-container>\n }\n\n <ng-container *rtScrollAreaContent>\n <nav rtElem=\"rail-list\">\n @for (item of menuItems(); track item.id) {\n <ng-container [ngTemplateOutlet]=\"railItemTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n }\n </nav>\n </ng-container>\n\n @if (footerTpl(); as footer) {\n <ng-container *rtScrollAreaFooter>\n <ng-container [ngTemplateOutlet]=\"footer\" />\n </ng-container>\n }\n </rt-scroll-area>\n\n @if (subMenuOpened()) {\n @if (isSearchHeld()) {\n <!-- Подложка незакреплённой панели: подменю, взятое полем поиска, закрывает нажатие снаружи. -->\n <div\n rtElem=\"backdrop\"\n qa-dataid=\"side-menu-backdrop\"\n tabindex=\"-1\"\n (click)=\"closeSubMenu()\"\n (keydown.escape)=\"closeSubMenu()\"></div>\n }\n\n <div\n #panel\n rtElem=\"panel\"\n qa-dataid=\"side-menu-panel\"\n [rtMod]=\"{ pinned: isPinned(), held: isSearchHeld() }\"\n (mouseenter)=\"cancelSubMenuClose()\"\n (mouseleave)=\"toggleSubMenu()\">\n <div rtElem=\"panel-head\">\n <rt-input\n rtElem=\"search\"\n qa-dataid=\"side-menu-search\"\n iconLeft=\"search\"\n [size]=\"searchSize()\"\n [appearance]=\"searchAppearance()\"\n [placeholder]=\"searchLabel()\"\n [ariaLabel]=\"searchLabel()\"\n [formControl]=\"searchControl\"\n (focusin)=\"onSearchHold()\"\n (keydown)=\"onSearchKeydown($event)\" />\n\n @if (pinShown()) {\n <rt-icon-button\n rtElem=\"pin\"\n qa-dataid=\"side-menu-pin\"\n size=\"sm\"\n icon=\"pin\"\n [iconFill]=\"isPinned()\"\n [active]=\"isPinned()\"\n [ariaLabel]=\"isPinned() ? unpinLabel() : pinLabel()\"\n [tooltip]=\"isPinned() ? unpinLabel() : pinLabel()\"\n (clicked)=\"onSubMenuModeToggle()\" />\n }\n </div>\n\n <rt-scroll-area rtElem=\"panel-body\" [isScrollHintShown]=\"panelScrollHintShown()\">\n <ng-container *rtScrollAreaContent>\n <ng-container [ngTemplateOutlet]=\"subMenuTpl\" />\n </ng-container>\n </rt-scroll-area>\n </div>\n\n @if (isPinned()) {\n <!-- Ручка есть только у закреплённого подменю: незакреплённое уходит раньше, чем до края доедет рука. -->\n <div\n rtElem=\"resizer\"\n qa-dataid=\"side-menu-resize\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n tabindex=\"0\"\n [attr.aria-label]=\"resizeLabel()\"\n [attr.aria-valuenow]=\"resizeValueNow()\"\n [attr.aria-valuemin]=\"resizeValueNow() === null ? null : resizeValueMin\"\n [attr.aria-valuemax]=\"resizeValueNow() === null ? null : resizeValueMax\"\n (pointerdown)=\"onResizeStart($event)\"\n (keydown)=\"onResizeKeydown($event)\"></div>\n }\n }\n }\n <ng-template #subMenuTpl>\n @if (narrow()) {\n <rt-input\n rtElem=\"search\"\n qa-dataid=\"side-menu-search\"\n iconLeft=\"search\"\n [size]=\"searchSize()\"\n [appearance]=\"searchAppearance()\"\n [placeholder]=\"searchLabel()\"\n [ariaLabel]=\"searchLabel()\"\n [formControl]=\"searchControl\"\n (keydown)=\"onSearchKeydown($event)\" />\n }\n\n @if (isNothingFound()) {\n <div rtElem=\"empty\" qa-dataid=\"side-menu-empty\">{{ nothingFoundLabel() }}</div>\n }\n\n <div rtElem=\"sub-list\">\n <!-- Блок избранного раздела: сам решает, есть ли ему что показать, и без строк места не занимает. -->\n <rt-side-menu-favorites\n (clickSubMenuAction)=\"onClickSubMenu($event)\"\n (clickSubMenuAdditionalAction)=\"onClickSubMenuAdditional($event)\" />\n\n @for (item of visibleSubMenuItems(); track item.id) {\n <rt-side-menu-sub-item\n [item]=\"item\"\n (clickSubMenuAction)=\"onClickSubMenu($event)\"\n (clickSubMenuAdditionalAction)=\"onClickSubMenuAdditional($event)\" />\n }\n </div>\n </ng-template>\n\n <ng-template #railItemTpl let-item>\n @let isActive = activeRailIds().includes(item.id);\n <!-- Без подписей под значками имя пункта — в подсказке справа; выключенные подсказки гасят и её. -->\n @let railTip = railTitlesShown() || !subMenuTooltipsShown() ? '' : item.name;\n @if (item.link) {\n <a\n rtElem=\"rail-item\"\n qa-dataid=\"side-menu-item\"\n rtTooltipPlacement=\"right\"\n [routerLink]=\"item.link\"\n [rtMod]=\"{ active: isActive }\"\n [attr.aria-current]=\"isActive ? 'page' : null\"\n [attr.aria-label]=\"railTitlesShown() ? null : item.name\"\n [rtTooltip]=\"railTip\"\n (mouseenter)=\"toggleSubMenu(item)\"\n (click)=\"onClickMenu(item)\">\n <ng-container [ngTemplateOutlet]=\"railItemBodyTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n </a>\n } @else {\n <button\n type=\"button\"\n rtElem=\"rail-item\"\n qa-dataid=\"side-menu-item\"\n rtTooltipPlacement=\"right\"\n [rtMod]=\"{ active: isActive }\"\n [attr.aria-label]=\"railTitlesShown() ? null : item.name\"\n [rtTooltip]=\"railTip\"\n [attr.aria-expanded]=\"item.submenu?.length ? subMenuOpened() && selectedItem() === item : null\"\n (mouseenter)=\"toggleSubMenu(item)\"\n (click)=\"onClickMenu(item)\">\n <ng-container [ngTemplateOutlet]=\"railItemBodyTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n </button>\n }\n </ng-template>\n\n <ng-template #railItemBodyTpl let-item>\n @if (item.icon) {\n <!-- Имя Material первого кита рисуется своей парой; имя, которого кит не рисует, — своим шаблоном меню. -->\n @let kitIcon = item.icon | rtSideMenuIcon;\n <span rtElem=\"rail-icon\">\n @if (kitIcon) {\n <rt-icon [name]=\"kitIcon\" [fill]=\"railIconFill()\" />\n } @else if (ownIconTpl(); as own) {\n <span rtElem=\"own-icon\" qa-dataid=\"side-menu-own-icon\" aria-hidden=\"true\">\n <ng-container\n [ngTemplateOutlet]=\"own\"\n [ngTemplateOutletContext]=\"{ $implicit: item, icon: item.icon, slot: 'icon' }\" />\n </span>\n }\n </span>\n }\n\n @if (item.name && railTitlesShown()) {\n <span rtElem=\"rail-title\">{{ item.name }}</span>\n }\n </ng-template>\n\n <ng-template #mobileItemTpl let-item>\n @let isActive = activeRailIds().includes(item.id);\n @if (item.link && !item.submenu?.length) {\n <a\n rtElem=\"mobile-item\"\n qa-dataid=\"side-menu-item\"\n [routerLink]=\"item.link\"\n [rtMod]=\"{ active: isActive }\"\n [attr.aria-current]=\"isActive ? 'page' : null\"\n (click)=\"onClickMenu(item)\">\n <ng-container [ngTemplateOutlet]=\"mobileItemBodyTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n </a>\n } @else {\n <button\n type=\"button\"\n rtElem=\"mobile-item\"\n qa-dataid=\"side-menu-item\"\n [rtMod]=\"{ active: isActive }\"\n (click)=\"onClickMenu(item)\">\n <ng-container [ngTemplateOutlet]=\"mobileItemBodyTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n </button>\n }\n </ng-template>\n\n <ng-template #mobileItemBodyTpl let-item>\n @if (item.icon) {\n @let kitIcon = item.icon | rtSideMenuIcon;\n @if (kitIcon) {\n <rt-icon rtElem=\"mobile-icon\" [name]=\"kitIcon\" />\n } @else if (ownIconTpl(); as own) {\n <span rtElem=\"own-icon\" qa-dataid=\"side-menu-own-icon\" aria-hidden=\"true\">\n <ng-container [ngTemplateOutlet]=\"own\" [ngTemplateOutletContext]=\"{ $implicit: item, icon: item.icon, slot: 'icon' }\" />\n </span>\n }\n }\n\n <span rtElem=\"mobile-title\" [rtTooltip]=\"item.name\">{{ item.name }}</span>\n\n @if (item.submenu?.length) {\n <!-- Стрелка раздела, как у первого кита: нажатие уводит в подменю, а не раскрывает на месте. -->\n <rt-icon rtElem=\"mobile-chevron\" size=\"sm\" name=\"arrow-right\" />\n }\n </ng-template>\n</ng-container>\n",
|
|
1902
|
+
styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-side-menu,.rt-side-menu-favorites__row.cdk-drag-preview{--rt-side-menu-item-color: currentcolor;--rt-side-menu-item-bg-hover: var(--rt-color-bg-hover);--rt-side-menu-item-bg-active: var(--rt-color-action-primary-subtle);--rt-side-menu-item-color-active: var(--rt-color-action-primary-on-surface)}.rt-side-menu{--rt-side-menu-rail-width: 5.5rem;--rt-side-menu-panel-width: 15rem;--rt-side-menu-panel-held-width: 30rem;--rt-side-menu-mobile-width: 15rem;--rt-side-menu-panel-radius: var(--rt-radius-lg);--rt-side-menu-panel-shadow: var(--rt-shadow-nav-panel);--rt-side-menu-item-radius: var(--rt-radius-full);--rt-side-menu-resizer-border-width: var(--rt-border-width-thick);--rt-side-menu-panel-border-width: var(--rt-border-width-thin);--rt-side-menu-transition-duration: var(--rt-duration-fast);--rt-side-menu-rail-icon-size: var(--rt-icon-step-md);--rt-side-menu-rail-gap: var(--rt-space-md);--rt-side-menu-rail-bg: var(--rt-color-bg-surface);--rt-side-menu-rail-border-width: var(--rt-side-menu-panel-border-width);--rt-side-menu-panel-bg: var(--rt-color-bg-surface);--rt-side-menu-panel-head-padding: var(--rt-space-sm);--rt-side-menu-sub-list-padding-inline: var(--rt-space-2);--rt-side-menu-empty-padding: var(--rt-space-md);--rt-side-menu-panel-dragged-width: 0px;--rt-side-menu-panel-shown-width: max(var(--rt-side-menu-panel-width), var(--rt-side-menu-panel-dragged-width));position:relative;display:flex;height:100%;color:var(--rt-color-text-primary)}.rt-side-menu__rail{max-width:var(--rt-side-menu-rail-width);height:100%;box-sizing:border-box;flex:0 0 var(--rt-side-menu-rail-width);border-right:var(--rt-side-menu-rail-border-width) solid var(--rt-color-border-default);background:var(--rt-side-menu-rail-bg)}.rt-side-menu__rail .rt-scroll-area__body{padding-inline:var(--rt-space-1)}.rt-side-menu__rail-list{display:flex;flex-direction:column;align-items:center;gap:var(--rt-side-menu-rail-gap);padding-block:var(--rt-space-sm)}.rt-side-menu__rail-item{display:flex;width:100%;flex-direction:column;align-items:center;padding:0;border:0;background:transparent;color:var(--rt-side-menu-item-color);cursor:pointer;font:inherit;gap:var(--rt-space-1);text-decoration:none}.rt-side-menu__rail-item:focus-visible{outline:none}.rt-side-menu__rail-item:focus-visible .rt-side-menu__rail-icon{outline:var(--rt-focus-ring-width) solid var(--rt-focus-ring-color)}.rt-side-menu__rail-item:hover .rt-side-menu__rail-icon,.rt-side-menu__rail-item:active .rt-side-menu__rail-icon{background:var(--rt-side-menu-item-bg-hover)}.rt-side-menu__rail-item--active .rt-side-menu__rail-icon,.rt-side-menu__rail-item--active:hover .rt-side-menu__rail-icon{background:var(--rt-side-menu-item-bg-active);color:var(--rt-side-menu-item-color-active)}.rt-side-menu__rail-icon{--rt-icon-step-md: var(--rt-side-menu-rail-icon-size);display:flex;width:3.5rem;height:2rem;align-items:center;justify-content:center;border-radius:var(--rt-side-menu-item-radius);transition:background-color var(--rt-side-menu-transition-duration) ease}.rt-side-menu__rail-title{max-width:100%;font-size:var(--rt-text-xs);line-height:var(--rt-leading-snug);overflow-wrap:anywhere;text-align:center}.rt-side-menu__backdrop{position:fixed;z-index:var(--rt-z-dropdown);inset:0;inset-inline-start:var(--rt-side-menu-rail-width)}.rt-side-menu__panel{position:absolute;z-index:var(--rt-z-dropdown);top:0;left:var(--rt-side-menu-rail-width);display:flex;width:var(--rt-side-menu-panel-shown-width);height:100%;box-sizing:border-box;flex-direction:column;border-radius:0 var(--rt-side-menu-panel-radius) var(--rt-side-menu-panel-radius) 0;border-left:var(--rt-side-menu-panel-border-width) solid var(--rt-color-border-default);background:var(--rt-side-menu-panel-bg);box-shadow:var(--rt-side-menu-panel-shadow)}.rt-side-menu__panel--held{width:max(var(--rt-side-menu-panel-held-width),var(--rt-side-menu-panel-shown-width))}.rt-side-menu__panel--pinned{--rt-side-menu-panel-radius: 0;--rt-side-menu-panel-shadow: var(--rt-shadow-none);position:relative;left:0;flex-shrink:0}.rt-side-menu__panel-head{display:flex;align-items:center;padding:var(--rt-side-menu-panel-head-padding);gap:var(--rt-space-2)}.rt-side-menu__search{min-width:0;flex:1 1 auto}.rt-side-menu__pin{flex-shrink:0}.rt-side-menu__panel-body{min-height:0;flex:1 1 auto}.rt-side-menu__sub-list{display:flex;flex-direction:column;padding-block-end:var(--rt-space-sm);padding-inline:var(--rt-side-menu-sub-list-padding-inline)}.rt-side-menu__empty{padding:var(--rt-side-menu-empty-padding);color:var(--rt-color-text-muted);font-size:var(--rt-text-xs)}.rt-side-menu__resizer{position:absolute;z-index:var(--rt-z-dropdown);top:0;bottom:0;left:calc(var(--rt-side-menu-rail-width) + var(--rt-side-menu-panel-shown-width) - var(--rt-space-2));width:var(--rt-space-sm);cursor:col-resize}.rt-side-menu__resizer:before{position:absolute;top:0;bottom:0;left:50%;border-left:var(--rt-side-menu-resizer-border-width) solid transparent;content:\"\"}.rt-side-menu__resizer:hover:before,.rt-side-menu__resizer:focus-visible:before{border-left-color:var(--rt-color-border-strong)}.rt-side-menu__resizer:focus-visible{outline:none}.rt-side-menu__mobile{min-width:0;max-width:100%;height:100%;flex:0 0 var(--rt-side-menu-mobile-width);background:var(--rt-color-bg-surface)}.rt-side-menu__mobile .rt-scroll-area__body{padding-inline:0}.rt-side-menu__mobile-list,.rt-side-menu__mobile-sub{display:flex;flex-direction:column;padding:var(--rt-space-sm);gap:var(--rt-space-1)}.rt-side-menu__mobile-item,.rt-side-menu__back{display:flex;width:100%;min-height:var(--rt-control-height-lg);box-sizing:border-box;align-items:center;border:0;border-radius:var(--rt-side-menu-item-radius);background:transparent;color:var(--rt-side-menu-item-color);cursor:pointer;font:inherit;font-size:var(--rt-text-sm);gap:calc(var(--rt-space-sm) + var(--rt-space-xs));padding-inline:var(--rt-space-md);text-align:start;text-decoration:none}.rt-side-menu__mobile-item:hover,.rt-side-menu__back:hover{background:var(--rt-side-menu-item-bg-hover)}.rt-side-menu__mobile-item:focus-visible,.rt-side-menu__back:focus-visible{outline:var(--rt-focus-ring-width) solid var(--rt-focus-ring-color);outline-offset:calc(var(--rt-focus-ring-width) * -1)}.rt-side-menu__mobile-item--active,.rt-side-menu__back--active{background:var(--rt-side-menu-item-bg-active);color:var(--rt-side-menu-item-color-active)}.rt-side-menu__own-icon{--rt-side-menu-own-icon-size: var(--rt-size-5);display:inline-flex;width:var(--rt-side-menu-own-icon-size);height:var(--rt-side-menu-own-icon-size);flex-shrink:0;align-items:center;justify-content:center;color:inherit;line-height:1}.rt-side-menu__own-icon>*{max-width:100%;max-height:100%}.rt-side-menu__mobile-icon,.rt-side-menu__back-icon,.rt-side-menu__mobile-chevron{flex-shrink:0}.rt-side-menu__mobile-title,.rt-side-menu__back-label{overflow:hidden;min-width:0;flex:1 1 auto;text-overflow:ellipsis;white-space:nowrap}}\n"],
|
|
1903
|
+
dependencies: [
|
|
1904
|
+
{
|
|
1905
|
+
kind: "directive",
|
|
1906
|
+
type: NgTemplateOutlet,
|
|
1907
|
+
selector: "[ngTemplateOutlet]",
|
|
1908
|
+
inputs: [
|
|
1909
|
+
"ngTemplateOutletContext",
|
|
1910
|
+
"ngTemplateOutlet",
|
|
1911
|
+
"ngTemplateOutletInjector"
|
|
1912
|
+
]
|
|
1913
|
+
},
|
|
1914
|
+
{
|
|
1915
|
+
kind: "ngmodule",
|
|
1916
|
+
type: ReactiveFormsModule
|
|
1917
|
+
},
|
|
1918
|
+
{
|
|
1919
|
+
kind: "directive",
|
|
1920
|
+
type: i1.NgControlStatus,
|
|
1921
|
+
selector: "[formControlName],[ngModel],[formControl]"
|
|
1922
|
+
},
|
|
1923
|
+
{
|
|
1924
|
+
kind: "directive",
|
|
1925
|
+
type: i1.FormControlDirective,
|
|
1926
|
+
selector: "[formControl]",
|
|
1927
|
+
inputs: [
|
|
1928
|
+
"formControl",
|
|
1929
|
+
"disabled",
|
|
1930
|
+
"ngModel"
|
|
1931
|
+
],
|
|
1932
|
+
outputs: ["ngModelChange"],
|
|
1933
|
+
exportAs: ["ngForm"]
|
|
1934
|
+
},
|
|
1935
|
+
{
|
|
1936
|
+
kind: "directive",
|
|
1937
|
+
type: RouterLink,
|
|
1938
|
+
selector: "[routerLink]",
|
|
1939
|
+
inputs: [
|
|
1940
|
+
"target",
|
|
1941
|
+
"queryParams",
|
|
1942
|
+
"fragment",
|
|
1943
|
+
"queryParamsHandling",
|
|
1944
|
+
"state",
|
|
1945
|
+
"info",
|
|
1946
|
+
"relativeTo",
|
|
1947
|
+
"preserveFragment",
|
|
1948
|
+
"skipLocationChange",
|
|
1949
|
+
"replaceUrl",
|
|
1950
|
+
"browserUrl",
|
|
1951
|
+
"routerLink"
|
|
1952
|
+
]
|
|
1953
|
+
},
|
|
1954
|
+
{
|
|
1955
|
+
kind: "directive",
|
|
1956
|
+
type: BlockDirective,
|
|
1957
|
+
selector: "[rtBlock]",
|
|
1958
|
+
inputs: ["rtMod"]
|
|
1959
|
+
},
|
|
1960
|
+
{
|
|
1961
|
+
kind: "directive",
|
|
1962
|
+
type: ElemDirective,
|
|
1963
|
+
selector: "[rtElem]",
|
|
1964
|
+
inputs: ["rtMod"]
|
|
1965
|
+
},
|
|
1966
|
+
{
|
|
1967
|
+
kind: "directive",
|
|
1968
|
+
type: ModDirective,
|
|
1969
|
+
selector: "[rtMod]"
|
|
1970
|
+
},
|
|
1971
|
+
{
|
|
1972
|
+
kind: "component",
|
|
1973
|
+
type: RtIconComponent,
|
|
1974
|
+
selector: "rt-icon",
|
|
1975
|
+
inputs: [
|
|
1976
|
+
"name",
|
|
1977
|
+
"glyph",
|
|
1978
|
+
"glyphStrategy",
|
|
1979
|
+
"size",
|
|
1980
|
+
"color",
|
|
1981
|
+
"fill",
|
|
1982
|
+
"spin",
|
|
1983
|
+
"rotate"
|
|
1984
|
+
]
|
|
1985
|
+
},
|
|
1986
|
+
{
|
|
1987
|
+
kind: "component",
|
|
1988
|
+
type: RtIconButtonComponent,
|
|
1989
|
+
selector: "rt-icon-button",
|
|
1990
|
+
inputs: [
|
|
1991
|
+
"icon",
|
|
1992
|
+
"glyph",
|
|
1993
|
+
"ariaLabel",
|
|
1994
|
+
"variant",
|
|
1995
|
+
"iconColor",
|
|
1996
|
+
"iconFill",
|
|
1997
|
+
"size",
|
|
1998
|
+
"iconSize",
|
|
1999
|
+
"type",
|
|
2000
|
+
"tooltip",
|
|
2001
|
+
"tooltipHideOnClick",
|
|
2002
|
+
"tabIndex",
|
|
2003
|
+
"loading",
|
|
2004
|
+
"disabled",
|
|
2005
|
+
"active",
|
|
2006
|
+
"expanded",
|
|
2007
|
+
"indicator"
|
|
2008
|
+
],
|
|
2009
|
+
outputs: ["clicked"]
|
|
2010
|
+
},
|
|
2011
|
+
{
|
|
2012
|
+
kind: "component",
|
|
2013
|
+
type: RtInputComponent,
|
|
2014
|
+
selector: "rt-input",
|
|
2015
|
+
inputs: [
|
|
2016
|
+
"appearance",
|
|
2017
|
+
"type",
|
|
2018
|
+
"placeholder",
|
|
2019
|
+
"iconLeft",
|
|
2020
|
+
"iconRight",
|
|
2021
|
+
"passwordToggle",
|
|
2022
|
+
"autocomplete"
|
|
2023
|
+
]
|
|
2024
|
+
},
|
|
2025
|
+
{
|
|
2026
|
+
kind: "component",
|
|
2027
|
+
type: RtScrollAreaComponent,
|
|
2028
|
+
selector: "rt-scroll-area",
|
|
2029
|
+
inputs: ["isScrollHintShown"]
|
|
2030
|
+
},
|
|
2031
|
+
{
|
|
2032
|
+
kind: "directive",
|
|
2033
|
+
type: RtScrollAreaContentDirective,
|
|
2034
|
+
selector: "[rtScrollAreaContent]"
|
|
2035
|
+
},
|
|
2036
|
+
{
|
|
2037
|
+
kind: "directive",
|
|
2038
|
+
type: RtScrollAreaFooterDirective,
|
|
2039
|
+
selector: "[rtScrollAreaFooter]"
|
|
2040
|
+
},
|
|
2041
|
+
{
|
|
2042
|
+
kind: "directive",
|
|
2043
|
+
type: RtScrollAreaHeaderDirective,
|
|
2044
|
+
selector: "[rtScrollAreaHeader]"
|
|
2045
|
+
},
|
|
2046
|
+
{
|
|
2047
|
+
kind: "directive",
|
|
2048
|
+
type: RtTooltipDirective,
|
|
2049
|
+
selector: "[rtTooltip]",
|
|
2050
|
+
inputs: [
|
|
2051
|
+
"rtTooltip",
|
|
2052
|
+
"rtTooltipPlacement",
|
|
2053
|
+
"rtTooltipWhenTruncated",
|
|
2054
|
+
"rtTooltipHideOnClick"
|
|
2055
|
+
],
|
|
2056
|
+
exportAs: ["rtTooltip"]
|
|
2057
|
+
},
|
|
2058
|
+
{
|
|
2059
|
+
kind: "component",
|
|
2060
|
+
type: RtSideMenuFavoritesComponent,
|
|
2061
|
+
selector: "rt-side-menu-favorites",
|
|
2062
|
+
outputs: ["clickSubMenuAction", "clickSubMenuAdditionalAction"]
|
|
2063
|
+
},
|
|
2064
|
+
{
|
|
2065
|
+
kind: "component",
|
|
2066
|
+
type: RtSideMenuSubItemComponent,
|
|
2067
|
+
selector: "rt-side-menu-sub-item",
|
|
2068
|
+
inputs: ["item", "inFavorites"],
|
|
2069
|
+
outputs: ["clickSubMenuAction", "clickSubMenuAdditionalAction"]
|
|
2070
|
+
},
|
|
2071
|
+
{
|
|
2072
|
+
kind: "pipe",
|
|
2073
|
+
type: RtSideMenuIconPipe,
|
|
2074
|
+
name: "rtSideMenuIcon"
|
|
2075
|
+
}
|
|
2076
|
+
],
|
|
2077
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush,
|
|
2078
|
+
encapsulation: i0.ViewEncapsulation.None
|
|
2079
|
+
});
|
|
2080
|
+
}
|
|
2081
|
+
};
|
|
2082
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
2083
|
+
minVersion: "12.0.0",
|
|
2084
|
+
version: "22.2.2",
|
|
2085
|
+
ngImport: i0,
|
|
2086
|
+
type: RtSideMenuComponent,
|
|
2087
|
+
decorators: [{
|
|
2088
|
+
type: Component,
|
|
2089
|
+
args: [{
|
|
2090
|
+
selector: "rt-side-menu",
|
|
2091
|
+
host: {
|
|
2092
|
+
class: BEM_BLOCK,
|
|
2093
|
+
"[class.rt-side-menu--pinned]": "isPinned()",
|
|
2094
|
+
"[style.--rt-side-menu-panel-dragged-width]": "panelWidthStyle()",
|
|
2095
|
+
"[class.rt-side-menu--favorite-actions-none]": "favoriteActionsReserve() === 'none'"
|
|
2096
|
+
},
|
|
2097
|
+
providers: [{
|
|
2098
|
+
provide: RT_SIDE_MENU,
|
|
2099
|
+
useExisting: RtSideMenuComponent
|
|
2100
|
+
}],
|
|
2101
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
2102
|
+
encapsulation: ViewEncapsulation.None,
|
|
2103
|
+
imports: [
|
|
2104
|
+
NgTemplateOutlet,
|
|
2105
|
+
ReactiveFormsModule,
|
|
2106
|
+
RouterLink,
|
|
2107
|
+
BlockDirective,
|
|
2108
|
+
ElemDirective,
|
|
2109
|
+
ModDirective,
|
|
2110
|
+
RtIconComponent,
|
|
2111
|
+
RtIconButtonComponent,
|
|
2112
|
+
RtInputComponent,
|
|
2113
|
+
RtScrollAreaComponent,
|
|
2114
|
+
RtScrollAreaContentDirective,
|
|
2115
|
+
RtScrollAreaFooterDirective,
|
|
2116
|
+
RtScrollAreaHeaderDirective,
|
|
2117
|
+
RtTooltipDirective,
|
|
2118
|
+
RtSideMenuFavoritesComponent,
|
|
2119
|
+
RtSideMenuIconPipe,
|
|
2120
|
+
RtSideMenuSubItemComponent
|
|
2121
|
+
],
|
|
2122
|
+
template: "<ng-container rtBlock=\"rt-side-menu\">\n @if (narrow()) {\n <!-- Узкий экран: один столбец — главные пункты или подменю выбранного раздела с кнопкой назад. -->\n <rt-scroll-area rtElem=\"mobile\" [isScrollHintShown]=\"true\">\n @if (headerTpl(); as header) {\n <ng-container *rtScrollAreaHeader>\n <ng-container [ngTemplateOutlet]=\"header\" />\n </ng-container>\n }\n\n <ng-container *rtScrollAreaContent>\n @if (selectedSubMenu()?.length) {\n <div rtElem=\"mobile-sub\">\n <button type=\"button\" rtElem=\"back\" qa-dataid=\"side-menu-back\" (click)=\"onBackToMainMenu()\">\n <rt-icon rtElem=\"back-icon\" size=\"sm\" name=\"arrow-left\" />\n <span rtElem=\"back-label\">{{ backLabel() }}</span>\n </button>\n\n <ng-container [ngTemplateOutlet]=\"subMenuTpl\" />\n </div>\n } @else {\n <nav rtElem=\"mobile-list\">\n @for (item of menuItems(); track item.id) {\n <ng-container [ngTemplateOutlet]=\"mobileItemTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n }\n </nav>\n }\n </ng-container>\n\n @if (footerTpl(); as footer) {\n <ng-container *rtScrollAreaFooter>\n <ng-container [ngTemplateOutlet]=\"footer\" />\n </ng-container>\n }\n </rt-scroll-area>\n } @else {\n <rt-scroll-area rtElem=\"rail\" [isScrollHintShown]=\"true\">\n @if (headerTpl(); as header) {\n <ng-container *rtScrollAreaHeader>\n <ng-container [ngTemplateOutlet]=\"header\" />\n </ng-container>\n }\n\n <ng-container *rtScrollAreaContent>\n <nav rtElem=\"rail-list\">\n @for (item of menuItems(); track item.id) {\n <ng-container [ngTemplateOutlet]=\"railItemTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n }\n </nav>\n </ng-container>\n\n @if (footerTpl(); as footer) {\n <ng-container *rtScrollAreaFooter>\n <ng-container [ngTemplateOutlet]=\"footer\" />\n </ng-container>\n }\n </rt-scroll-area>\n\n @if (subMenuOpened()) {\n @if (isSearchHeld()) {\n <!-- Подложка незакреплённой панели: подменю, взятое полем поиска, закрывает нажатие снаружи. -->\n <div\n rtElem=\"backdrop\"\n qa-dataid=\"side-menu-backdrop\"\n tabindex=\"-1\"\n (click)=\"closeSubMenu()\"\n (keydown.escape)=\"closeSubMenu()\"></div>\n }\n\n <div\n #panel\n rtElem=\"panel\"\n qa-dataid=\"side-menu-panel\"\n [rtMod]=\"{ pinned: isPinned(), held: isSearchHeld() }\"\n (mouseenter)=\"cancelSubMenuClose()\"\n (mouseleave)=\"toggleSubMenu()\">\n <div rtElem=\"panel-head\">\n <rt-input\n rtElem=\"search\"\n qa-dataid=\"side-menu-search\"\n iconLeft=\"search\"\n [size]=\"searchSize()\"\n [appearance]=\"searchAppearance()\"\n [placeholder]=\"searchLabel()\"\n [ariaLabel]=\"searchLabel()\"\n [formControl]=\"searchControl\"\n (focusin)=\"onSearchHold()\"\n (keydown)=\"onSearchKeydown($event)\" />\n\n @if (pinShown()) {\n <rt-icon-button\n rtElem=\"pin\"\n qa-dataid=\"side-menu-pin\"\n size=\"sm\"\n icon=\"pin\"\n [iconFill]=\"isPinned()\"\n [active]=\"isPinned()\"\n [ariaLabel]=\"isPinned() ? unpinLabel() : pinLabel()\"\n [tooltip]=\"isPinned() ? unpinLabel() : pinLabel()\"\n (clicked)=\"onSubMenuModeToggle()\" />\n }\n </div>\n\n <rt-scroll-area rtElem=\"panel-body\" [isScrollHintShown]=\"panelScrollHintShown()\">\n <ng-container *rtScrollAreaContent>\n <ng-container [ngTemplateOutlet]=\"subMenuTpl\" />\n </ng-container>\n </rt-scroll-area>\n </div>\n\n @if (isPinned()) {\n <!-- Ручка есть только у закреплённого подменю: незакреплённое уходит раньше, чем до края доедет рука. -->\n <div\n rtElem=\"resizer\"\n qa-dataid=\"side-menu-resize\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n tabindex=\"0\"\n [attr.aria-label]=\"resizeLabel()\"\n [attr.aria-valuenow]=\"resizeValueNow()\"\n [attr.aria-valuemin]=\"resizeValueNow() === null ? null : resizeValueMin\"\n [attr.aria-valuemax]=\"resizeValueNow() === null ? null : resizeValueMax\"\n (pointerdown)=\"onResizeStart($event)\"\n (keydown)=\"onResizeKeydown($event)\"></div>\n }\n }\n }\n <ng-template #subMenuTpl>\n @if (narrow()) {\n <rt-input\n rtElem=\"search\"\n qa-dataid=\"side-menu-search\"\n iconLeft=\"search\"\n [size]=\"searchSize()\"\n [appearance]=\"searchAppearance()\"\n [placeholder]=\"searchLabel()\"\n [ariaLabel]=\"searchLabel()\"\n [formControl]=\"searchControl\"\n (keydown)=\"onSearchKeydown($event)\" />\n }\n\n @if (isNothingFound()) {\n <div rtElem=\"empty\" qa-dataid=\"side-menu-empty\">{{ nothingFoundLabel() }}</div>\n }\n\n <div rtElem=\"sub-list\">\n <!-- Блок избранного раздела: сам решает, есть ли ему что показать, и без строк места не занимает. -->\n <rt-side-menu-favorites\n (clickSubMenuAction)=\"onClickSubMenu($event)\"\n (clickSubMenuAdditionalAction)=\"onClickSubMenuAdditional($event)\" />\n\n @for (item of visibleSubMenuItems(); track item.id) {\n <rt-side-menu-sub-item\n [item]=\"item\"\n (clickSubMenuAction)=\"onClickSubMenu($event)\"\n (clickSubMenuAdditionalAction)=\"onClickSubMenuAdditional($event)\" />\n }\n </div>\n </ng-template>\n\n <ng-template #railItemTpl let-item>\n @let isActive = activeRailIds().includes(item.id);\n <!-- Без подписей под значками имя пункта — в подсказке справа; выключенные подсказки гасят и её. -->\n @let railTip = railTitlesShown() || !subMenuTooltipsShown() ? '' : item.name;\n @if (item.link) {\n <a\n rtElem=\"rail-item\"\n qa-dataid=\"side-menu-item\"\n rtTooltipPlacement=\"right\"\n [routerLink]=\"item.link\"\n [rtMod]=\"{ active: isActive }\"\n [attr.aria-current]=\"isActive ? 'page' : null\"\n [attr.aria-label]=\"railTitlesShown() ? null : item.name\"\n [rtTooltip]=\"railTip\"\n (mouseenter)=\"toggleSubMenu(item)\"\n (click)=\"onClickMenu(item)\">\n <ng-container [ngTemplateOutlet]=\"railItemBodyTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n </a>\n } @else {\n <button\n type=\"button\"\n rtElem=\"rail-item\"\n qa-dataid=\"side-menu-item\"\n rtTooltipPlacement=\"right\"\n [rtMod]=\"{ active: isActive }\"\n [attr.aria-label]=\"railTitlesShown() ? null : item.name\"\n [rtTooltip]=\"railTip\"\n [attr.aria-expanded]=\"item.submenu?.length ? subMenuOpened() && selectedItem() === item : null\"\n (mouseenter)=\"toggleSubMenu(item)\"\n (click)=\"onClickMenu(item)\">\n <ng-container [ngTemplateOutlet]=\"railItemBodyTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n </button>\n }\n </ng-template>\n\n <ng-template #railItemBodyTpl let-item>\n @if (item.icon) {\n <!-- Имя Material первого кита рисуется своей парой; имя, которого кит не рисует, — своим шаблоном меню. -->\n @let kitIcon = item.icon | rtSideMenuIcon;\n <span rtElem=\"rail-icon\">\n @if (kitIcon) {\n <rt-icon [name]=\"kitIcon\" [fill]=\"railIconFill()\" />\n } @else if (ownIconTpl(); as own) {\n <span rtElem=\"own-icon\" qa-dataid=\"side-menu-own-icon\" aria-hidden=\"true\">\n <ng-container\n [ngTemplateOutlet]=\"own\"\n [ngTemplateOutletContext]=\"{ $implicit: item, icon: item.icon, slot: 'icon' }\" />\n </span>\n }\n </span>\n }\n\n @if (item.name && railTitlesShown()) {\n <span rtElem=\"rail-title\">{{ item.name }}</span>\n }\n </ng-template>\n\n <ng-template #mobileItemTpl let-item>\n @let isActive = activeRailIds().includes(item.id);\n @if (item.link && !item.submenu?.length) {\n <a\n rtElem=\"mobile-item\"\n qa-dataid=\"side-menu-item\"\n [routerLink]=\"item.link\"\n [rtMod]=\"{ active: isActive }\"\n [attr.aria-current]=\"isActive ? 'page' : null\"\n (click)=\"onClickMenu(item)\">\n <ng-container [ngTemplateOutlet]=\"mobileItemBodyTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n </a>\n } @else {\n <button\n type=\"button\"\n rtElem=\"mobile-item\"\n qa-dataid=\"side-menu-item\"\n [rtMod]=\"{ active: isActive }\"\n (click)=\"onClickMenu(item)\">\n <ng-container [ngTemplateOutlet]=\"mobileItemBodyTpl\" [ngTemplateOutletContext]=\"{ $implicit: item }\" />\n </button>\n }\n </ng-template>\n\n <ng-template #mobileItemBodyTpl let-item>\n @if (item.icon) {\n @let kitIcon = item.icon | rtSideMenuIcon;\n @if (kitIcon) {\n <rt-icon rtElem=\"mobile-icon\" [name]=\"kitIcon\" />\n } @else if (ownIconTpl(); as own) {\n <span rtElem=\"own-icon\" qa-dataid=\"side-menu-own-icon\" aria-hidden=\"true\">\n <ng-container [ngTemplateOutlet]=\"own\" [ngTemplateOutletContext]=\"{ $implicit: item, icon: item.icon, slot: 'icon' }\" />\n </span>\n }\n }\n\n <span rtElem=\"mobile-title\" [rtTooltip]=\"item.name\">{{ item.name }}</span>\n\n @if (item.submenu?.length) {\n <!-- Стрелка раздела, как у первого кита: нажатие уводит в подменю, а не раскрывает на месте. -->\n <rt-icon rtElem=\"mobile-chevron\" size=\"sm\" name=\"arrow-right\" />\n }\n </ng-template>\n</ng-container>\n",
|
|
2123
|
+
styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-side-menu,.rt-side-menu-favorites__row.cdk-drag-preview{--rt-side-menu-item-color: currentcolor;--rt-side-menu-item-bg-hover: var(--rt-color-bg-hover);--rt-side-menu-item-bg-active: var(--rt-color-action-primary-subtle);--rt-side-menu-item-color-active: var(--rt-color-action-primary-on-surface)}.rt-side-menu{--rt-side-menu-rail-width: 5.5rem;--rt-side-menu-panel-width: 15rem;--rt-side-menu-panel-held-width: 30rem;--rt-side-menu-mobile-width: 15rem;--rt-side-menu-panel-radius: var(--rt-radius-lg);--rt-side-menu-panel-shadow: var(--rt-shadow-nav-panel);--rt-side-menu-item-radius: var(--rt-radius-full);--rt-side-menu-resizer-border-width: var(--rt-border-width-thick);--rt-side-menu-panel-border-width: var(--rt-border-width-thin);--rt-side-menu-transition-duration: var(--rt-duration-fast);--rt-side-menu-rail-icon-size: var(--rt-icon-step-md);--rt-side-menu-rail-gap: var(--rt-space-md);--rt-side-menu-rail-bg: var(--rt-color-bg-surface);--rt-side-menu-rail-border-width: var(--rt-side-menu-panel-border-width);--rt-side-menu-panel-bg: var(--rt-color-bg-surface);--rt-side-menu-panel-head-padding: var(--rt-space-sm);--rt-side-menu-sub-list-padding-inline: var(--rt-space-2);--rt-side-menu-empty-padding: var(--rt-space-md);--rt-side-menu-panel-dragged-width: 0px;--rt-side-menu-panel-shown-width: max(var(--rt-side-menu-panel-width), var(--rt-side-menu-panel-dragged-width));position:relative;display:flex;height:100%;color:var(--rt-color-text-primary)}.rt-side-menu__rail{max-width:var(--rt-side-menu-rail-width);height:100%;box-sizing:border-box;flex:0 0 var(--rt-side-menu-rail-width);border-right:var(--rt-side-menu-rail-border-width) solid var(--rt-color-border-default);background:var(--rt-side-menu-rail-bg)}.rt-side-menu__rail .rt-scroll-area__body{padding-inline:var(--rt-space-1)}.rt-side-menu__rail-list{display:flex;flex-direction:column;align-items:center;gap:var(--rt-side-menu-rail-gap);padding-block:var(--rt-space-sm)}.rt-side-menu__rail-item{display:flex;width:100%;flex-direction:column;align-items:center;padding:0;border:0;background:transparent;color:var(--rt-side-menu-item-color);cursor:pointer;font:inherit;gap:var(--rt-space-1);text-decoration:none}.rt-side-menu__rail-item:focus-visible{outline:none}.rt-side-menu__rail-item:focus-visible .rt-side-menu__rail-icon{outline:var(--rt-focus-ring-width) solid var(--rt-focus-ring-color)}.rt-side-menu__rail-item:hover .rt-side-menu__rail-icon,.rt-side-menu__rail-item:active .rt-side-menu__rail-icon{background:var(--rt-side-menu-item-bg-hover)}.rt-side-menu__rail-item--active .rt-side-menu__rail-icon,.rt-side-menu__rail-item--active:hover .rt-side-menu__rail-icon{background:var(--rt-side-menu-item-bg-active);color:var(--rt-side-menu-item-color-active)}.rt-side-menu__rail-icon{--rt-icon-step-md: var(--rt-side-menu-rail-icon-size);display:flex;width:3.5rem;height:2rem;align-items:center;justify-content:center;border-radius:var(--rt-side-menu-item-radius);transition:background-color var(--rt-side-menu-transition-duration) ease}.rt-side-menu__rail-title{max-width:100%;font-size:var(--rt-text-xs);line-height:var(--rt-leading-snug);overflow-wrap:anywhere;text-align:center}.rt-side-menu__backdrop{position:fixed;z-index:var(--rt-z-dropdown);inset:0;inset-inline-start:var(--rt-side-menu-rail-width)}.rt-side-menu__panel{position:absolute;z-index:var(--rt-z-dropdown);top:0;left:var(--rt-side-menu-rail-width);display:flex;width:var(--rt-side-menu-panel-shown-width);height:100%;box-sizing:border-box;flex-direction:column;border-radius:0 var(--rt-side-menu-panel-radius) var(--rt-side-menu-panel-radius) 0;border-left:var(--rt-side-menu-panel-border-width) solid var(--rt-color-border-default);background:var(--rt-side-menu-panel-bg);box-shadow:var(--rt-side-menu-panel-shadow)}.rt-side-menu__panel--held{width:max(var(--rt-side-menu-panel-held-width),var(--rt-side-menu-panel-shown-width))}.rt-side-menu__panel--pinned{--rt-side-menu-panel-radius: 0;--rt-side-menu-panel-shadow: var(--rt-shadow-none);position:relative;left:0;flex-shrink:0}.rt-side-menu__panel-head{display:flex;align-items:center;padding:var(--rt-side-menu-panel-head-padding);gap:var(--rt-space-2)}.rt-side-menu__search{min-width:0;flex:1 1 auto}.rt-side-menu__pin{flex-shrink:0}.rt-side-menu__panel-body{min-height:0;flex:1 1 auto}.rt-side-menu__sub-list{display:flex;flex-direction:column;padding-block-end:var(--rt-space-sm);padding-inline:var(--rt-side-menu-sub-list-padding-inline)}.rt-side-menu__empty{padding:var(--rt-side-menu-empty-padding);color:var(--rt-color-text-muted);font-size:var(--rt-text-xs)}.rt-side-menu__resizer{position:absolute;z-index:var(--rt-z-dropdown);top:0;bottom:0;left:calc(var(--rt-side-menu-rail-width) + var(--rt-side-menu-panel-shown-width) - var(--rt-space-2));width:var(--rt-space-sm);cursor:col-resize}.rt-side-menu__resizer:before{position:absolute;top:0;bottom:0;left:50%;border-left:var(--rt-side-menu-resizer-border-width) solid transparent;content:\"\"}.rt-side-menu__resizer:hover:before,.rt-side-menu__resizer:focus-visible:before{border-left-color:var(--rt-color-border-strong)}.rt-side-menu__resizer:focus-visible{outline:none}.rt-side-menu__mobile{min-width:0;max-width:100%;height:100%;flex:0 0 var(--rt-side-menu-mobile-width);background:var(--rt-color-bg-surface)}.rt-side-menu__mobile .rt-scroll-area__body{padding-inline:0}.rt-side-menu__mobile-list,.rt-side-menu__mobile-sub{display:flex;flex-direction:column;padding:var(--rt-space-sm);gap:var(--rt-space-1)}.rt-side-menu__mobile-item,.rt-side-menu__back{display:flex;width:100%;min-height:var(--rt-control-height-lg);box-sizing:border-box;align-items:center;border:0;border-radius:var(--rt-side-menu-item-radius);background:transparent;color:var(--rt-side-menu-item-color);cursor:pointer;font:inherit;font-size:var(--rt-text-sm);gap:calc(var(--rt-space-sm) + var(--rt-space-xs));padding-inline:var(--rt-space-md);text-align:start;text-decoration:none}.rt-side-menu__mobile-item:hover,.rt-side-menu__back:hover{background:var(--rt-side-menu-item-bg-hover)}.rt-side-menu__mobile-item:focus-visible,.rt-side-menu__back:focus-visible{outline:var(--rt-focus-ring-width) solid var(--rt-focus-ring-color);outline-offset:calc(var(--rt-focus-ring-width) * -1)}.rt-side-menu__mobile-item--active,.rt-side-menu__back--active{background:var(--rt-side-menu-item-bg-active);color:var(--rt-side-menu-item-color-active)}.rt-side-menu__own-icon{--rt-side-menu-own-icon-size: var(--rt-size-5);display:inline-flex;width:var(--rt-side-menu-own-icon-size);height:var(--rt-side-menu-own-icon-size);flex-shrink:0;align-items:center;justify-content:center;color:inherit;line-height:1}.rt-side-menu__own-icon>*{max-width:100%;max-height:100%}.rt-side-menu__mobile-icon,.rt-side-menu__back-icon,.rt-side-menu__mobile-chevron{flex-shrink:0}.rt-side-menu__mobile-title,.rt-side-menu__back-label{overflow:hidden;min-width:0;flex:1 1 auto;text-overflow:ellipsis;white-space:nowrap}}\n"]
|
|
2124
|
+
}]
|
|
2125
|
+
}],
|
|
2126
|
+
ctorParameters: () => [],
|
|
2127
|
+
propDecorators: {
|
|
2128
|
+
panelRef: [{
|
|
2129
|
+
type: i0.ViewChild,
|
|
2130
|
+
args: ["panel", { isSignal: true }]
|
|
2131
|
+
}],
|
|
2132
|
+
headerTpl: [{
|
|
2133
|
+
type: i0.ContentChild,
|
|
2134
|
+
args: [i0.forwardRef(() => RtSideMenuHeaderDirective), {
|
|
2135
|
+
read: TemplateRef,
|
|
2136
|
+
isSignal: true
|
|
2137
|
+
}]
|
|
2138
|
+
}],
|
|
2139
|
+
footerTpl: [{
|
|
2140
|
+
type: i0.ContentChild,
|
|
2141
|
+
args: [i0.forwardRef(() => RtSideMenuFooterDirective), {
|
|
2142
|
+
read: TemplateRef,
|
|
2143
|
+
isSignal: true
|
|
2144
|
+
}]
|
|
2145
|
+
}],
|
|
2146
|
+
activeMenuIds: [{
|
|
2147
|
+
type: i0.Input,
|
|
2148
|
+
args: [{
|
|
2149
|
+
isSignal: true,
|
|
2150
|
+
alias: "activeMenuIds",
|
|
2151
|
+
required: true
|
|
2152
|
+
}]
|
|
2153
|
+
}],
|
|
2154
|
+
menuItems: [{
|
|
2155
|
+
type: i0.Input,
|
|
2156
|
+
args: [{
|
|
2157
|
+
isSignal: true,
|
|
2158
|
+
alias: "menuItems",
|
|
2159
|
+
required: false
|
|
2160
|
+
}]
|
|
2161
|
+
}],
|
|
2162
|
+
subMenuMode: [{
|
|
2163
|
+
type: i0.Input,
|
|
2164
|
+
args: [{
|
|
2165
|
+
isSignal: true,
|
|
2166
|
+
alias: "subMenuMode",
|
|
2167
|
+
required: false
|
|
2168
|
+
}]
|
|
2169
|
+
}],
|
|
2170
|
+
subMenuWidth: [{
|
|
2171
|
+
type: i0.Input,
|
|
2172
|
+
args: [{
|
|
2173
|
+
isSignal: true,
|
|
2174
|
+
alias: "subMenuWidth",
|
|
2175
|
+
required: false
|
|
2176
|
+
}]
|
|
2177
|
+
}],
|
|
2178
|
+
menuId: [{
|
|
2179
|
+
type: i0.Input,
|
|
2180
|
+
args: [{
|
|
2181
|
+
isSignal: true,
|
|
2182
|
+
alias: "menuId",
|
|
2183
|
+
required: false
|
|
2184
|
+
}]
|
|
2185
|
+
}],
|
|
2186
|
+
favoritesCount: [{
|
|
2187
|
+
type: i0.Input,
|
|
2188
|
+
args: [{
|
|
2189
|
+
isSignal: true,
|
|
2190
|
+
alias: "favoritesCount",
|
|
2191
|
+
required: false
|
|
2192
|
+
}]
|
|
2193
|
+
}],
|
|
2194
|
+
favoriteActionsReserve: [{
|
|
2195
|
+
type: i0.Input,
|
|
2196
|
+
args: [{
|
|
2197
|
+
isSignal: true,
|
|
2198
|
+
alias: "favoriteActionsReserve",
|
|
2199
|
+
required: false
|
|
2200
|
+
}]
|
|
2201
|
+
}],
|
|
2202
|
+
isFavoritesSearchShown: [{
|
|
2203
|
+
type: i0.Input,
|
|
2204
|
+
args: [{
|
|
2205
|
+
isSignal: true,
|
|
2206
|
+
alias: "isFavoritesSearchShown",
|
|
2207
|
+
required: false
|
|
2208
|
+
}]
|
|
2209
|
+
}],
|
|
2210
|
+
pinShown: [{
|
|
2211
|
+
type: i0.Input,
|
|
2212
|
+
args: [{
|
|
2213
|
+
isSignal: true,
|
|
2214
|
+
alias: "pinShown",
|
|
2215
|
+
required: false
|
|
2216
|
+
}]
|
|
2217
|
+
}],
|
|
2218
|
+
subMenuCloseDelay: [{
|
|
2219
|
+
type: i0.Input,
|
|
2220
|
+
args: [{
|
|
2221
|
+
isSignal: true,
|
|
2222
|
+
alias: "subMenuCloseDelay",
|
|
2223
|
+
required: false
|
|
2224
|
+
}]
|
|
2225
|
+
}],
|
|
2226
|
+
subMenuModeChange: [{
|
|
2227
|
+
type: i0.Output,
|
|
2228
|
+
args: ["subMenuModeChange"]
|
|
2229
|
+
}],
|
|
2230
|
+
subMenuWidthChange: [{
|
|
2231
|
+
type: i0.Output,
|
|
2232
|
+
args: ["subMenuWidthChange"]
|
|
2233
|
+
}],
|
|
2234
|
+
subMenuResizeStart: [{
|
|
2235
|
+
type: i0.Output,
|
|
2236
|
+
args: ["subMenuResizeStart"]
|
|
2237
|
+
}],
|
|
2238
|
+
subMenuResizeEnd: [{
|
|
2239
|
+
type: i0.Output,
|
|
2240
|
+
args: ["subMenuResizeEnd"]
|
|
2241
|
+
}],
|
|
2242
|
+
closeMobileMenuAction: [{
|
|
2243
|
+
type: i0.Output,
|
|
2244
|
+
args: ["closeMobileMenuAction"]
|
|
2245
|
+
}],
|
|
2246
|
+
clickSubMenuAction: [{
|
|
2247
|
+
type: i0.Output,
|
|
2248
|
+
args: ["clickSubMenuAction"]
|
|
2249
|
+
}],
|
|
2250
|
+
clickSubMenuAdditionalAction: [{
|
|
2251
|
+
type: i0.Output,
|
|
2252
|
+
args: ["clickSubMenuAdditionalAction"]
|
|
2253
|
+
}],
|
|
2254
|
+
ownIconTpl: [{
|
|
2255
|
+
type: i0.ContentChild,
|
|
2256
|
+
args: [i0.forwardRef(() => RtSideMenuIconDirective), {
|
|
2257
|
+
read: TemplateRef,
|
|
2258
|
+
isSignal: true
|
|
2259
|
+
}]
|
|
2260
|
+
}]
|
|
2261
|
+
}
|
|
2262
|
+
});
|
|
2263
|
+
export { RT_SIDE_MENU_DEFAULT_ID, RT_SIDE_MENU_SETTINGS_CONFIG, RT_SIDE_MENU_WIDTH_MAX, RT_SIDE_MENU_WIDTH_MIN, RT_SIDE_MENU_WIDTH_STEP, RtSideMenuComponent, RtSideMenuFooterDirective, RtSideMenuHeaderDirective, RtSideMenuIconDirective, RtSideMenuSettingsService, RtSideMenuSubItemComponent, clampSideMenuWidth, drawnSideMenuWidth, filterSideMenuItems, normalizeSideMenuId, normalizeSideMenuSettings, omitSideMenuSettings, parseSideMenuSettingsRecord, patchSideMenuSettings, pinnedSideMenuItems, provideRtSideMenuSettings, readSideMenuSettings, reportedSideMenuWidth, sideMenuIconName, sideMenuIdsToExpand, sideMenuPressOpensInBrowser, sideMenuWidthByKey, splitSideMenuTitle, splitTitleByWords, startSideMenuWidthDrag, stepSideMenuHighlight, unpairedSideMenuIcons, walkSideMenuItems, warnUnpairedSideMenuIcons };
|
|
1637
2264
|
|
|
1638
|
-
|
|
1639
|
-
//# sourceMappingURL=rt-tools-ui-kit-v2-side-menu.mjs.map
|
|
2265
|
+
//# sourceMappingURL=rt-tools-ui-kit-v2-side-menu.mjs.map
|