@rt-tools/ui-kit-v2 0.17.0 → 0.19.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/README.md +21 -2
- package/fesm2022/rt-tools-ui-kit-v2-accordion.mjs +79 -0
- package/fesm2022/rt-tools-ui-kit-v2-accordion.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs +233 -0
- package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs +97 -0
- package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-aside-section.mjs +47 -0
- package/fesm2022/rt-tools-ui-kit-v2-aside-section.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-aside.mjs +709 -0
- package/fesm2022/rt-tools-ui-kit-v2-aside.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs +214 -0
- package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-bar-list.mjs +53 -0
- package/fesm2022/rt-tools-ui-kit-v2-bar-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-bottom-sheet.mjs +88 -0
- package/fesm2022/rt-tools-ui-kit-v2-bottom-sheet.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-button.mjs +365 -0
- package/fesm2022/rt-tools-ui-kit-v2-button.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs +152 -0
- package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-card.mjs +72 -0
- package/fesm2022/rt-tools-ui-kit-v2-card.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs +111 -0
- package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-collapsible-text.mjs +76 -0
- package/fesm2022/rt-tools-ui-kit-v2-collapsible-text.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-confirm-popover.mjs +255 -0
- package/fesm2022/rt-tools-ui-kit-v2-confirm-popover.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-container.mjs +1326 -0
- package/fesm2022/rt-tools-ui-kit-v2-container.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs +81 -0
- package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs +2688 -0
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-counter-row.mjs +45 -0
- package/fesm2022/rt-tools-ui-kit-v2-counter-row.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-counter.mjs +158 -0
- package/fesm2022/rt-tools-ui-kit-v2-counter.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs +894 -0
- package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs +1217 -0
- package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs +779 -0
- package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs +573 -0
- package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-delta-view.mjs +141 -0
- package/fesm2022/rt-tools-ui-kit-v2-delta-view.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-detail-list.mjs +68 -0
- package/fesm2022/rt-tools-ui-kit-v2-detail-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dialog.mjs +478 -0
- package/fesm2022/rt-tools-ui-kit-v2-dialog.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dot-field.mjs +183 -0
- package/fesm2022/rt-tools-ui-kit-v2-dot-field.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-download-link.mjs +44 -0
- package/fesm2022/rt-tools-ui-kit-v2-download-link.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs +260 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +1036 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-empty-state.mjs +56 -0
- package/fesm2022/rt-tools-ui-kit-v2-empty-state.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs +107 -0
- package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-field.mjs +183 -0
- package/fesm2022/rt-tools-ui-kit-v2-field.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs +219 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-drop.mjs +214 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-drop.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-input.mjs +117 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-input.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-list.mjs +32 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs +91 -0
- package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs +220 -0
- package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-header.mjs +72 -0
- package/fesm2022/rt-tools-ui-kit-v2-header.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs +163 -0
- package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-icon.mjs +711 -0
- package/fesm2022/rt-tools-ui-kit-v2-icon.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-image-cropper.mjs +540 -0
- package/fesm2022/rt-tools-ui-kit-v2-image-cropper.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs +227 -0
- package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-info-item.mjs +37 -0
- package/fesm2022/rt-tools-ui-kit-v2-info-item.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs +361 -0
- package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-input.mjs +143 -0
- package/fesm2022/rt-tools-ui-kit-v2-input.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-live-badge.mjs +49 -0
- package/fesm2022/rt-tools-ui-kit-v2-live-badge.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-logo.mjs +97 -0
- package/fesm2022/rt-tools-ui-kit-v2-logo.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-markdown-text.mjs +57 -0
- package/fesm2022/rt-tools-ui-kit-v2-markdown-text.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-menu.mjs +537 -0
- package/fesm2022/rt-tools-ui-kit-v2-menu.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-message.mjs +105 -0
- package/fesm2022/rt-tools-ui-kit-v2-message.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-money-list.mjs +71 -0
- package/fesm2022/rt-tools-ui-kit-v2-money-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs +315 -0
- package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-night-grid.mjs +51 -0
- package/fesm2022/rt-tools-ui-kit-v2-night-grid.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-note.mjs +44 -0
- package/fesm2022/rt-tools-ui-kit-v2-note.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-notifications-bell.mjs +54 -0
- package/fesm2022/rt-tools-ui-kit-v2-notifications-bell.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +339 -0
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs +187 -0
- package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-photo-viewer.mjs +170 -0
- package/fesm2022/rt-tools-ui-kit-v2-photo-viewer.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-popover.mjs +312 -0
- package/fesm2022/rt-tools-ui-kit-v2-popover.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-prompt-suggestion.mjs +46 -0
- package/fesm2022/rt-tools-ui-kit-v2-prompt-suggestion.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs +174 -0
- package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-radius.mjs +56 -0
- package/fesm2022/rt-tools-ui-kit-v2-radius.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +336 -12
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-ripple.mjs +118 -0
- package/fesm2022/rt-tools-ui-kit-v2-ripple.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs +290 -0
- package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs +37 -0
- package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-select.mjs +495 -0
- package/fesm2022/rt-tools-ui-kit-v2-select.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +1493 -0
- package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-skeleton-wrapper.mjs +49 -0
- package/fesm2022/rt-tools-ui-kit-v2-skeleton-wrapper.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-skeleton.mjs +123 -0
- package/fesm2022/rt-tools-ui-kit-v2-skeleton.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-spinner.mjs +70 -0
- package/fesm2022/rt-tools-ui-kit-v2-spinner.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs +92 -0
- package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs +147 -0
- package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs +117 -0
- package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-table.mjs +1636 -0
- package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs +350 -0
- package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-tag.mjs +122 -0
- package/fesm2022/rt-tools-ui-kit-v2-tag.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs +85 -0
- package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs +73 -0
- package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +222 -0
- package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-timeline.mjs +39 -0
- package/fesm2022/rt-tools-ui-kit-v2-timeline.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-toast.mjs +338 -0
- package/fesm2022/rt-tools-ui-kit-v2-toast.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs +132 -0
- package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs +162 -0
- package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs +135 -0
- package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs +214 -0
- package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-welcome-dialog.mjs +64 -0
- package/fesm2022/rt-tools-ui-kit-v2-welcome-dialog.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs +263 -0
- package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs +296 -0
- package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2.mjs +94 -23819
- package/fesm2022/rt-tools-ui-kit-v2.mjs.map +1 -1
- package/package.json +361 -1
- package/rt-tools-ui-kit-v2-0.19.0.tgz +0 -0
- package/src/assets/icons/sparkle.svg +9 -0
- package/src/assets/icons/thumb-down.svg +10 -0
- package/src/assets/icons/thumb-up.svg +9 -0
- package/src/assets/icons/trash-x.svg +7 -0
- package/src/assets/icons-material/sparkle.fill.svg +5 -0
- package/src/assets/icons-material/sparkle.svg +5 -0
- package/src/assets/icons-material/thumb-down.fill.svg +5 -0
- package/src/assets/icons-material/thumb-down.svg +5 -0
- package/src/assets/icons-material/thumb-up.fill.svg +5 -0
- package/src/assets/icons-material/thumb-up.svg +5 -0
- package/src/assets/icons-material/trash-x.fill.svg +5 -0
- package/src/assets/icons-material/trash-x.svg +5 -0
- package/src/lib/components/action-bar/CONTEXT.md +8 -2
- package/src/lib/components/action-bar/rt-action-bar-holder.component.scss +10 -7
- package/src/lib/components/action-bar/rt-action-bar.component.scss +82 -34
- package/src/lib/components/ai-run-status/CONTEXT.md +36 -0
- package/src/lib/components/ai-run-status/rt-ai-run-status.component.scss +119 -0
- package/src/lib/components/aside/CONTEXT.md +1 -0
- package/src/lib/components/aside/header/rt-aside-header.component.scss +27 -11
- package/src/lib/components/copy-value/CONTEXT.md +31 -0
- package/src/lib/components/copy-value/rt-copy-value.component.scss +39 -0
- package/src/lib/components/data-list/settings/rt-data-list-settings-aside.component.scss +5 -5
- package/src/lib/components/dot-field/CONTEXT.md +31 -0
- package/src/lib/components/dot-field/rt-dot-field.component.scss +20 -0
- package/src/lib/components/dot-field/stories/component/CONTEXT.md +14 -0
- package/src/lib/components/dot-field/stories/component/test-dot-field.component.scss +31 -0
- package/src/lib/components/dynamic-selector/CONTEXT.md +18 -0
- package/src/lib/components/dynamic-selector/list/rt-dynamic-selector-list.component.scss +29 -1
- package/src/lib/components/dynamic-selector/popup/rt-dynamic-selector-popup.component.scss +84 -25
- package/src/lib/components/empty-state/CONTEXT.md +2 -1
- package/src/lib/components/empty-state/rt-empty-state.component.scss +4 -2
- package/src/lib/components/field/CONTEXT.md +18 -2
- package/src/lib/components/icon/CONTEXT.md +16 -12
- package/src/lib/components/icon/rt-icon.component.scss +13 -3
- package/src/lib/components/prompt-suggestion/CONTEXT.md +29 -0
- package/src/lib/components/prompt-suggestion/rt-prompt-suggestion.component.scss +58 -0
- package/src/lib/components/select/rt-select.component.scss +4 -0
- package/src/lib/components/thread-list/CONTEXT.md +4 -0
- package/src/lib/components/thread-list/rt-thread-list.component.scss +29 -0
- package/src/lib/components/toolbar/CONTEXT.md +4 -0
- package/src/lib/components/toolbar/rt-toolbar.component.scss +7 -0
- package/src/rich-editor/lib/components/ai-chat/CONTEXT.md +58 -0
- package/src/rich-editor/lib/components/ai-chat/answer/rt-ai-chat-answer.component.scss +12 -0
- package/src/rich-editor/lib/components/ai-chat/rt-ai-chat.component.scss +222 -0
- package/src/rich-editor/lib/components/rich-editor/rt-rich-editor.component.scss +3 -0
- package/src/styles/_scrollbar.scss +9 -0
- package/src/styles/_semantic.scss +1 -1
- package/styles/tokens.css +11 -8
- package/types/rt-tools-ui-kit-v2-accordion.d.ts +30 -0
- package/types/rt-tools-ui-kit-v2-action-bar.d.ts +149 -0
- package/types/rt-tools-ui-kit-v2-ai-run-status.d.ts +49 -0
- package/types/rt-tools-ui-kit-v2-aside-section.d.ts +25 -0
- package/types/rt-tools-ui-kit-v2-aside.d.ts +444 -0
- package/types/rt-tools-ui-kit-v2-autocomplete.d.ts +78 -0
- package/types/rt-tools-ui-kit-v2-bar-list.d.ts +41 -0
- package/types/rt-tools-ui-kit-v2-bottom-sheet.d.ts +20 -0
- package/types/rt-tools-ui-kit-v2-button.d.ts +76 -0
- package/types/rt-tools-ui-kit-v2-calendar.d.ts +96 -0
- package/types/rt-tools-ui-kit-v2-card.d.ts +38 -0
- package/types/rt-tools-ui-kit-v2-checkbox.d.ts +46 -0
- package/types/rt-tools-ui-kit-v2-collapsible-text.d.ts +20 -0
- package/types/rt-tools-ui-kit-v2-confirm-popover.d.ts +85 -0
- package/types/rt-tools-ui-kit-v2-container.d.ts +425 -0
- package/types/rt-tools-ui-kit-v2-copy-value.d.ts +29 -0
- package/types/rt-tools-ui-kit-v2-core.d.ts +1262 -0
- package/types/rt-tools-ui-kit-v2-counter-row.d.ts +22 -0
- package/types/rt-tools-ui-kit-v2-counter.d.ts +70 -0
- package/types/rt-tools-ui-kit-v2-data-list.d.ts +334 -0
- package/types/rt-tools-ui-kit-v2-data-table.d.ts +494 -0
- package/types/rt-tools-ui-kit-v2-date-picker.d.ts +181 -0
- package/types/rt-tools-ui-kit-v2-date-range.d.ts +98 -0
- package/types/rt-tools-ui-kit-v2-delta-view.d.ts +20 -0
- package/types/rt-tools-ui-kit-v2-detail-list.d.ts +33 -0
- package/types/rt-tools-ui-kit-v2-dialog.d.ts +287 -0
- package/types/rt-tools-ui-kit-v2-dot-field.d.ts +17 -0
- package/types/rt-tools-ui-kit-v2-download-link.d.ts +17 -0
- package/types/rt-tools-ui-kit-v2-dynamic-list.d.ts +139 -0
- package/types/rt-tools-ui-kit-v2-dynamic-selector.d.ts +423 -0
- package/types/rt-tools-ui-kit-v2-empty-state.d.ts +29 -0
- package/types/rt-tools-ui-kit-v2-expansion-panel.d.ts +57 -0
- package/types/rt-tools-ui-kit-v2-field.d.ts +82 -0
- package/types/rt-tools-ui-kit-v2-file-card.d.ts +114 -0
- package/types/rt-tools-ui-kit-v2-file-drop.d.ts +75 -0
- package/types/rt-tools-ui-kit-v2-file-input.d.ts +48 -0
- package/types/rt-tools-ui-kit-v2-file-list.d.ts +13 -0
- package/types/rt-tools-ui-kit-v2-filter-control.d.ts +72 -0
- package/types/rt-tools-ui-kit-v2-form-control.d.ts +74 -0
- package/types/rt-tools-ui-kit-v2-header.d.ts +40 -0
- package/types/rt-tools-ui-kit-v2-icon-button.d.ts +113 -0
- package/types/rt-tools-ui-kit-v2-icon.d.ts +246 -0
- package/types/rt-tools-ui-kit-v2-image-cropper.d.ts +168 -0
- package/types/rt-tools-ui-kit-v2-image-upload.d.ts +102 -0
- package/types/rt-tools-ui-kit-v2-info-item.d.ts +13 -0
- package/types/rt-tools-ui-kit-v2-input-number.d.ts +67 -0
- package/types/rt-tools-ui-kit-v2-input.d.ts +54 -0
- package/types/rt-tools-ui-kit-v2-live-badge.d.ts +23 -0
- package/types/rt-tools-ui-kit-v2-logo.d.ts +58 -0
- package/types/rt-tools-ui-kit-v2-markdown-text.d.ts +30 -0
- package/types/rt-tools-ui-kit-v2-menu.d.ts +217 -0
- package/types/rt-tools-ui-kit-v2-message.d.ts +56 -0
- package/types/rt-tools-ui-kit-v2-money-list.d.ts +34 -0
- package/types/rt-tools-ui-kit-v2-multiselect.d.ts +93 -0
- package/types/rt-tools-ui-kit-v2-night-grid.d.ts +39 -0
- package/types/rt-tools-ui-kit-v2-note.d.ts +21 -0
- package/types/rt-tools-ui-kit-v2-notifications-bell.d.ts +23 -0
- package/types/rt-tools-ui-kit-v2-page-header.d.ts +173 -0
- package/types/rt-tools-ui-kit-v2-pagination.d.ts +64 -0
- package/types/rt-tools-ui-kit-v2-photo-viewer.d.ts +98 -0
- package/types/rt-tools-ui-kit-v2-popover.d.ts +79 -0
- package/types/rt-tools-ui-kit-v2-prompt-suggestion.d.ts +21 -0
- package/types/rt-tools-ui-kit-v2-radio-button.d.ts +61 -0
- package/types/rt-tools-ui-kit-v2-radius.d.ts +37 -0
- package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +186 -2
- package/types/rt-tools-ui-kit-v2-ripple.d.ts +39 -0
- package/types/rt-tools-ui-kit-v2-scroll-area.d.ts +91 -0
- package/types/rt-tools-ui-kit-v2-section-nav.d.ts +23 -0
- package/types/rt-tools-ui-kit-v2-select.d.ts +215 -0
- package/types/rt-tools-ui-kit-v2-side-menu.d.ts +483 -0
- package/types/rt-tools-ui-kit-v2-skeleton-wrapper.d.ts +32 -0
- package/types/rt-tools-ui-kit-v2-skeleton.d.ts +41 -0
- package/types/rt-tools-ui-kit-v2-spinner.d.ts +56 -0
- package/types/rt-tools-ui-kit-v2-split-button.d.ts +72 -0
- package/types/rt-tools-ui-kit-v2-stat-tile.d.ts +81 -0
- package/types/rt-tools-ui-kit-v2-stepper.d.ts +51 -0
- package/types/rt-tools-ui-kit-v2-table.d.ts +739 -0
- package/types/rt-tools-ui-kit-v2-tabs.d.ts +153 -0
- package/types/rt-tools-ui-kit-v2-tag.d.ts +70 -0
- package/types/rt-tools-ui-kit-v2-textarea.d.ts +36 -0
- package/types/rt-tools-ui-kit-v2-theme-toggle.d.ts +43 -0
- package/types/rt-tools-ui-kit-v2-thread-list.d.ts +124 -0
- package/types/rt-tools-ui-kit-v2-timeline.d.ts +35 -0
- package/types/rt-tools-ui-kit-v2-toast.d.ts +103 -0
- package/types/rt-tools-ui-kit-v2-toggle-button-group.d.ts +109 -0
- package/types/rt-tools-ui-kit-v2-toggle-switch.d.ts +85 -0
- package/types/rt-tools-ui-kit-v2-toolbar.d.ts +66 -0
- package/types/rt-tools-ui-kit-v2-tooltip.d.ts +74 -0
- package/types/rt-tools-ui-kit-v2-welcome-dialog.d.ts +33 -0
- package/types/rt-tools-ui-kit-v2-workspace-details.d.ts +128 -0
- package/types/rt-tools-ui-kit-v2-workspace.d.ts +84 -0
- package/types/rt-tools-ui-kit-v2.d.ts +90 -9599
- package/rt-tools-ui-kit-v2-0.17.0.tgz +0 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Pipe, inject, computed, input, booleanAttribute, output, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { BlockDirective, ElemDirective } from '@rt-tools/core';
|
|
4
|
+
import { RT_KIT_LABELS, formatFileSize } from '@rt-tools/ui-kit-v2/core';
|
|
5
|
+
import { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';
|
|
6
|
+
import { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';
|
|
7
|
+
import * as i1 from '@rt-tools/ui-kit-v2/radius';
|
|
8
|
+
import { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';
|
|
9
|
+
import { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';
|
|
10
|
+
|
|
11
|
+
/** Иконка Word-семейства (несколько расширений делят один глиф). */
|
|
12
|
+
const ICON_WORD = 'attach-docx-doc';
|
|
13
|
+
/** Иконка растровых изображений. */
|
|
14
|
+
const ICON_IMAGE = 'attach-jpg-png';
|
|
15
|
+
/** Иконка презентаций. */
|
|
16
|
+
const ICON_PRESENTATION = 'attach-ppt-pptx';
|
|
17
|
+
/** Иконка таблиц Excel-семейства. */
|
|
18
|
+
const ICON_SPREADSHEET = 'attach-xlsx-xls';
|
|
19
|
+
/** Иконка архивов. */
|
|
20
|
+
const ICON_ARCHIVE = 'attach-zip-rar';
|
|
21
|
+
/** Иконка web-форматов изображений/видео. */
|
|
22
|
+
const ICON_WEB_MEDIA = 'attach-webp';
|
|
23
|
+
/**
|
|
24
|
+
* Маппинг расширения файла → имя цветной иконки типа (`attach-*` в rt-icon-реестре).
|
|
25
|
+
*/
|
|
26
|
+
const FILE_TYPE_ICON = {
|
|
27
|
+
doc: ICON_WORD,
|
|
28
|
+
docx: ICON_WORD,
|
|
29
|
+
odt: ICON_WORD,
|
|
30
|
+
gif: ICON_IMAGE,
|
|
31
|
+
jpg: ICON_IMAGE,
|
|
32
|
+
jpeg: ICON_IMAGE,
|
|
33
|
+
png: ICON_IMAGE,
|
|
34
|
+
pdf: 'attach-pdf',
|
|
35
|
+
ppt: ICON_PRESENTATION,
|
|
36
|
+
pptx: ICON_PRESENTATION,
|
|
37
|
+
txt: 'attach-txt',
|
|
38
|
+
webp: ICON_WEB_MEDIA,
|
|
39
|
+
webm: ICON_WEB_MEDIA,
|
|
40
|
+
xls: ICON_SPREADSHEET,
|
|
41
|
+
xlsx: ICON_SPREADSHEET,
|
|
42
|
+
zip: ICON_ARCHIVE,
|
|
43
|
+
rar: ICON_ARCHIVE,
|
|
44
|
+
msg: 'attach-msg',
|
|
45
|
+
eml: 'attach-eml',
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Возвращает имя иконки типа файла по его имени (берётся расширение после
|
|
49
|
+
* последней точки). Неизвестное/отсутствующее расширение → нейтральный `attach-other`.
|
|
50
|
+
*/
|
|
51
|
+
function getFileTypeIcon(fileName) {
|
|
52
|
+
const ext = fileName.split('.').pop()?.toLowerCase() ?? '';
|
|
53
|
+
return FILE_TYPE_ICON[ext] ?? 'attach-other';
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Выводит читаемый заголовок из имени файла: отбрасывает расширение и заменяет
|
|
57
|
+
* разделители `_`/`-` на пробелы (CamelCase намеренно НЕ разбивается — это давало
|
|
58
|
+
* бы непредсказуемый результат на произвольных именах). Если после очистки строка
|
|
59
|
+
* пустая (например имя было `.pdf`) — возвращается исходное имя.
|
|
60
|
+
*/
|
|
61
|
+
function deriveFileTitle(fileName) {
|
|
62
|
+
const withoutExt = fileName.replace(/\.[^./\\]+$/, '');
|
|
63
|
+
const cleaned = withoutExt.replace(/[_-]+/g, ' ').replace(/\s+/g, ' ').trim();
|
|
64
|
+
return cleaned || fileName;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Многоточие, вставляемое в середину строки при усечении. */
|
|
68
|
+
const ELLIPSIS = '...';
|
|
69
|
+
/** Длина строки по умолчанию, при которой включается усечение. */
|
|
70
|
+
const DEFAULT_MAX_LENGTH = 32;
|
|
71
|
+
/**
|
|
72
|
+
* Усекает длинное имя файла по середине, сохраняя расширение видимым:
|
|
73
|
+
* `10588-1_EvaluationSearchReport.pdf` → `10588-1_EvaluationSearchRe...pdf`.
|
|
74
|
+
*
|
|
75
|
+
* Обычный CSS `text-overflow: ellipsis` режет хвост и теряет расширение —
|
|
76
|
+
* поэтому усечение по середине делается здесь, а не в стилях. Усечение
|
|
77
|
+
* посимвольное (не по ширине контейнера): предсказуемо и без измерений DOM.
|
|
78
|
+
*
|
|
79
|
+
* Pure-pipe: пересчитывается только при смене входа.
|
|
80
|
+
*/
|
|
81
|
+
class RtTruncateMiddlePipe {
|
|
82
|
+
transform(value, maxLength = DEFAULT_MAX_LENGTH) {
|
|
83
|
+
if (!value) {
|
|
84
|
+
return '';
|
|
85
|
+
}
|
|
86
|
+
if (value.length <= maxLength) {
|
|
87
|
+
return value;
|
|
88
|
+
}
|
|
89
|
+
const lastDot = value.lastIndexOf('.');
|
|
90
|
+
const hasExt = lastDot > 0 && lastDot < value.length - 1;
|
|
91
|
+
const ext = hasExt ? value.slice(lastDot + 1) : '';
|
|
92
|
+
const base = hasExt ? value.slice(0, lastDot) : value;
|
|
93
|
+
const headLength = maxLength - ext.length - ELLIPSIS.length;
|
|
94
|
+
if (headLength <= 0) {
|
|
95
|
+
// Расширение длиннее лимита — деградируем до простого усечения хвоста.
|
|
96
|
+
return value.slice(0, Math.max(0, maxLength - ELLIPSIS.length)) + ELLIPSIS;
|
|
97
|
+
}
|
|
98
|
+
return base.slice(0, headLength) + ELLIPSIS + ext;
|
|
99
|
+
}
|
|
100
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtTruncateMiddlePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
101
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.6", ngImport: i0, type: RtTruncateMiddlePipe, isStandalone: true, name: "rtTruncateMiddle" }); }
|
|
102
|
+
}
|
|
103
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtTruncateMiddlePipe, decorators: [{
|
|
104
|
+
type: Pipe,
|
|
105
|
+
args: [{ name: 'rtTruncateMiddle' }]
|
|
106
|
+
}] });
|
|
107
|
+
|
|
108
|
+
const BEM_BLOCK = 'rt-file-card';
|
|
109
|
+
/** Иконка типа файла крупнее прочего: по ней карточку находят взглядом. */
|
|
110
|
+
const ICON_SIZES = {
|
|
111
|
+
sm: 'sm',
|
|
112
|
+
md: 'xl',
|
|
113
|
+
lg: 'xl',
|
|
114
|
+
};
|
|
115
|
+
/** Кнопки действий: в компактной карточке они не должны задавать её высоту. */
|
|
116
|
+
const ACTION_SIZES = {
|
|
117
|
+
sm: 'sm',
|
|
118
|
+
md: 'sm',
|
|
119
|
+
lg: 'md',
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Карточка загруженного файла: цветная иконка типа, заголовок (выведенный из имени),
|
|
123
|
+
* усечённое по середине имя файла, бейдж размера и опциональные действия справа
|
|
124
|
+
* (скачать / переименовать / удалить).
|
|
125
|
+
*
|
|
126
|
+
* Презентационный компонент: сам ничего не решает, только эмиттит события действий.
|
|
127
|
+
* Кнопки включаются точечно через `showDownload`/`showRemove`/`showRename` — в режиме
|
|
128
|
+
* загрузки обычно нужен только remove, при показе сохранённых файлов — download.
|
|
129
|
+
*
|
|
130
|
+
* `showRename` по умолчанию выключен и сейчас нигде не включается: бэкенд не
|
|
131
|
+
* поддерживает переименование (`original_name` неизменяем после создания). Вход
|
|
132
|
+
* оставлен, чтобы кнопку можно было включить без правки компонента, когда появится API.
|
|
133
|
+
*/
|
|
134
|
+
class RtFileCardComponent {
|
|
135
|
+
constructor() {
|
|
136
|
+
/** Имя цветной иконки типа файла по расширению. */
|
|
137
|
+
this.t = inject(RT_KIT_LABELS);
|
|
138
|
+
this.iconName = computed(() => getFileTypeIcon(this.name()), /* @ts-ignore */
|
|
139
|
+
...(ngDevMode ? [{ debugName: "iconName" }] : /* istanbul ignore next */ []));
|
|
140
|
+
/** Заголовок карточки, выведенный из имени файла (без расширения, разделители → пробелы). */
|
|
141
|
+
this.title = computed(() => deriveFileTitle(this.name()), /* @ts-ignore */
|
|
142
|
+
...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
143
|
+
/** Отформатированный размер; пустая строка → размер неизвестен. */
|
|
144
|
+
this.sizeLabel = computed(() => formatFileSize(this.sizeBytes()), /* @ts-ignore */
|
|
145
|
+
...(ngDevMode ? [{ debugName: "sizeLabel" }] : /* istanbul ignore next */ []));
|
|
146
|
+
/** Показывать ли бейдж размера. */
|
|
147
|
+
this.hasSize = computed(() => this.sizeLabel() !== '', /* @ts-ignore */
|
|
148
|
+
...(ngDevMode ? [{ debugName: "hasSize" }] : /* istanbul ignore next */ []));
|
|
149
|
+
/** Размер иконки типа файла — маппится от размера карточки. */
|
|
150
|
+
this.iconSize = computed(() => ICON_SIZES[this.size()], /* @ts-ignore */
|
|
151
|
+
...(ngDevMode ? [{ debugName: "iconSize" }] : /* istanbul ignore next */ []));
|
|
152
|
+
/** Размер кнопок действий — маппится от размера карточки. */
|
|
153
|
+
this.actionSize = computed(() => ACTION_SIZES[this.size()], /* @ts-ignore */
|
|
154
|
+
...(ngDevMode ? [{ debugName: "actionSize" }] : /* istanbul ignore next */ []));
|
|
155
|
+
/** Имя файла с расширением — обязательно. */
|
|
156
|
+
this.name = input.required(/* @ts-ignore */
|
|
157
|
+
...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
158
|
+
/** Размер в байтах. `null` → бейдж размера скрыт. */
|
|
159
|
+
this.sizeBytes = input(null, /* @ts-ignore */
|
|
160
|
+
...(ngDevMode ? [{ debugName: "sizeBytes" }] : /* istanbul ignore next */ []));
|
|
161
|
+
/** Плотность карточки: `sm` для тесных мест вроде композера, `lg` — для страниц. */
|
|
162
|
+
this.size = input('md', /* @ts-ignore */
|
|
163
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
164
|
+
/** Показывать кнопку скачивания. */
|
|
165
|
+
this.showDownload = input(false, { ...(ngDevMode ? { debugName: "showDownload" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
166
|
+
/** Показывать кнопку удаления. */
|
|
167
|
+
this.showRemove = input(false, { ...(ngDevMode ? { debugName: "showRemove" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
168
|
+
/** Показывать кнопку переименования (отключена до появления API на бэке). */
|
|
169
|
+
this.showRename = input(false, { ...(ngDevMode ? { debugName: "showRename" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
170
|
+
/** Блокирует кнопки действий (например, во время сабмита формы). */
|
|
171
|
+
this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
172
|
+
/** Запрошено скачивание файла. */
|
|
173
|
+
this.download = output();
|
|
174
|
+
/** Запрошено удаление файла. */
|
|
175
|
+
this.removed = output();
|
|
176
|
+
/** Запрошено переименование файла. */
|
|
177
|
+
this.rename = output();
|
|
178
|
+
}
|
|
179
|
+
onDownload() {
|
|
180
|
+
this.download.emit();
|
|
181
|
+
}
|
|
182
|
+
onRemove() {
|
|
183
|
+
this.removed.emit();
|
|
184
|
+
}
|
|
185
|
+
onRename() {
|
|
186
|
+
this.rename.emit();
|
|
187
|
+
}
|
|
188
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtFileCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
189
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtFileCardComponent, isStandalone: true, selector: "rt-file-card", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, sizeBytes: { classPropertyName: "sizeBytes", publicName: "sizeBytes", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, showDownload: { classPropertyName: "showDownload", publicName: "showDownload", isSignal: true, isRequired: false, transformFunction: null }, showRemove: { classPropertyName: "showRemove", publicName: "showRemove", isSignal: true, isRequired: false, transformFunction: null }, showRename: { classPropertyName: "showRename", publicName: "showRename", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { download: "download", removed: "removed", rename: "rename" }, host: { properties: { "class.rt-file-card--sm": "size() === 'sm'", "class.rt-file-card--md": "size() === 'md'", "class.rt-file-card--lg": "size() === 'lg'" }, classAttribute: "rt-file-card" }, hostDirectives: [{ directive: i1.RtRadiusDirective, inputs: ["radius", "radius"] }], ngImport: i0, template: "<ng-container rtBlock=\"rt-file-card\">\n <rt-icon rtElem=\"icon\" [size]=\"iconSize()\" [name]=\"iconName()\" />\n\n <span rtElem=\"text\">\n <span rtElem=\"title\" qa-dataid=\"file-card-title\" [rtTooltip]=\"title()\">{{ title() }}</span>\n <span rtElem=\"name\" qa-dataid=\"file-card-name\" [rtTooltip]=\"name()\">{{ name() | rtTruncateMiddle }}</span>\n </span>\n\n <span rtElem=\"meta\">\n @if (hasSize()) {\n <span rtElem=\"size\" qa-dataid=\"file-card-size\">{{ sizeLabel() }}</span>\n }\n\n @if (showDownload()) {\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"file-card-download\"\n icon=\"ico-download\"\n variant=\"ghost\"\n [ariaLabel]=\"t().uiDownload\"\n [tooltip]=\"t().uiDownload\"\n [size]=\"actionSize()\"\n [disabled]=\"disabled()\"\n (clicked)=\"onDownload()\" />\n }\n\n @if (showRename()) {\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"file-card-rename\"\n icon=\"ico-edit\"\n variant=\"ghost\"\n [ariaLabel]=\"t().uiRename\"\n [tooltip]=\"t().uiRename\"\n [size]=\"actionSize()\"\n [disabled]=\"disabled()\"\n (clicked)=\"onRename()\" />\n }\n\n @if (showRemove()) {\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"file-card-remove\"\n icon=\"ico-trash\"\n variant=\"ghost\"\n [ariaLabel]=\"t().uiRemove\"\n [tooltip]=\"t().uiRemove\"\n [size]=\"actionSize()\"\n [disabled]=\"disabled()\"\n (clicked)=\"onRemove()\" />\n }\n </span>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-file-card{--rt-file-card-radius: var(--rt-radius-lg);--rt-file-card-border-width: var(--rt-border-width-thin);--rt-file-card-badge-radius: var(--rt-radius-full);--rt-file-card-padding-block: var(--rt-space-sm);--rt-file-card-padding-inline: var(--rt-space-md);--rt-file-card-gap: var(--rt-space-sm);--rt-file-card-title-size: var(--rt-text-md);--rt-file-card-name-size: var(--rt-text-sm);--rt-file-card-badge-size: var(--rt-text-xs);display:flex;align-items:center;padding:var(--rt-file-card-padding-block) var(--rt-file-card-padding-inline);border:var(--rt-file-card-border-width) solid var(--rt-color-border-subtle);border-radius:var(--rt-file-card-radius);background-color:var(--rt-color-bg-surface);gap:var(--rt-file-card-gap);max-inline-size:100%;min-inline-size:0}.rt-file-card--sm{--rt-file-card-padding-block: var(--rt-space-xs);--rt-file-card-padding-inline: var(--rt-space-sm);--rt-file-card-gap: var(--rt-space-xs);--rt-file-card-title-size: var(--rt-text-xs);--rt-file-card-name-size: var(--rt-text-2xs);--rt-file-card-badge-size: var(--rt-text-2xs)}.rt-file-card--md{--rt-file-card-padding-block: var(--rt-space-sm);--rt-file-card-padding-inline: var(--rt-space-md);--rt-file-card-gap: var(--rt-space-sm);--rt-file-card-title-size: var(--rt-text-md);--rt-file-card-name-size: var(--rt-text-sm);--rt-file-card-badge-size: var(--rt-text-xs)}.rt-file-card--lg{--rt-file-card-padding-block: var(--rt-space-md);--rt-file-card-padding-inline: var(--rt-space-lg);--rt-file-card-gap: var(--rt-space-md);--rt-file-card-title-size: var(--rt-text-lg);--rt-file-card-name-size: var(--rt-text-md);--rt-file-card-badge-size: var(--rt-text-sm)}.rt-file-card__icon{flex-shrink:0}.rt-file-card__text{display:flex;min-width:0;flex:1 1 auto;flex-direction:column;gap:var(--rt-space-2xs)}.rt-file-card__title{overflow:hidden;color:var(--rt-color-text-primary);font-size:var(--rt-file-card-title-size);font-weight:var(--rt-font-weight-semibold);text-overflow:ellipsis;white-space:nowrap}.rt-file-card__name{overflow:hidden;color:var(--rt-color-text-muted);font-size:var(--rt-file-card-name-size);text-overflow:ellipsis;white-space:nowrap}.rt-file-card__meta{display:flex;flex-shrink:0;align-items:center;gap:var(--rt-space-xs)}.rt-file-card__size{padding:var(--rt-space-2xs) var(--rt-space-sm);border:var(--rt-file-card-border-width) solid var(--rt-color-border-subtle);border-radius:var(--rt-file-card-badge-radius);color:var(--rt-color-text-muted);font-size:var(--rt-file-card-badge-size);white-space:nowrap}.rt-file-card__action{flex-shrink:0}.rt-file-card[data-rt-radius=none]{--rt-file-card-radius: var(--rt-radius-none)}.rt-file-card[data-rt-radius=xs]{--rt-file-card-radius: var(--rt-radius-xs)}.rt-file-card[data-rt-radius=sm]{--rt-file-card-radius: var(--rt-radius-sm)}.rt-file-card[data-rt-radius=ms]{--rt-file-card-radius: var(--rt-radius-ms)}.rt-file-card[data-rt-radius=md]{--rt-file-card-radius: var(--rt-radius-md)}.rt-file-card[data-rt-radius=lg]{--rt-file-card-radius: var(--rt-radius-lg)}.rt-file-card[data-rt-radius=xl]{--rt-file-card-radius: var(--rt-radius-xl)}.rt-file-card[data-rt-radius=\"2xl\"]{--rt-file-card-radius: var(--rt-radius-2xl)}.rt-file-card[data-rt-radius=full]{--rt-file-card-radius: var(--rt-radius-full)}}\n"], dependencies: [{ kind: "component", type:
|
|
190
|
+
// standalone components / directives
|
|
191
|
+
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: "directive", type: BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }, { kind: "pipe", type:
|
|
192
|
+
// pipes
|
|
193
|
+
RtTruncateMiddlePipe, name: "rtTruncateMiddle" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
194
|
+
}
|
|
195
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtFileCardComponent, decorators: [{
|
|
196
|
+
type: Component,
|
|
197
|
+
args: [{ selector: 'rt-file-card', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
198
|
+
// standalone components / directives
|
|
199
|
+
RtIconComponent,
|
|
200
|
+
RtIconButtonComponent,
|
|
201
|
+
RtTooltipDirective,
|
|
202
|
+
BlockDirective,
|
|
203
|
+
ElemDirective,
|
|
204
|
+
// pipes
|
|
205
|
+
RtTruncateMiddlePipe,
|
|
206
|
+
], hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }], host: {
|
|
207
|
+
class: BEM_BLOCK,
|
|
208
|
+
'[class.rt-file-card--sm]': "size() === 'sm'",
|
|
209
|
+
'[class.rt-file-card--md]': "size() === 'md'",
|
|
210
|
+
'[class.rt-file-card--lg]': "size() === 'lg'",
|
|
211
|
+
}, template: "<ng-container rtBlock=\"rt-file-card\">\n <rt-icon rtElem=\"icon\" [size]=\"iconSize()\" [name]=\"iconName()\" />\n\n <span rtElem=\"text\">\n <span rtElem=\"title\" qa-dataid=\"file-card-title\" [rtTooltip]=\"title()\">{{ title() }}</span>\n <span rtElem=\"name\" qa-dataid=\"file-card-name\" [rtTooltip]=\"name()\">{{ name() | rtTruncateMiddle }}</span>\n </span>\n\n <span rtElem=\"meta\">\n @if (hasSize()) {\n <span rtElem=\"size\" qa-dataid=\"file-card-size\">{{ sizeLabel() }}</span>\n }\n\n @if (showDownload()) {\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"file-card-download\"\n icon=\"ico-download\"\n variant=\"ghost\"\n [ariaLabel]=\"t().uiDownload\"\n [tooltip]=\"t().uiDownload\"\n [size]=\"actionSize()\"\n [disabled]=\"disabled()\"\n (clicked)=\"onDownload()\" />\n }\n\n @if (showRename()) {\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"file-card-rename\"\n icon=\"ico-edit\"\n variant=\"ghost\"\n [ariaLabel]=\"t().uiRename\"\n [tooltip]=\"t().uiRename\"\n [size]=\"actionSize()\"\n [disabled]=\"disabled()\"\n (clicked)=\"onRename()\" />\n }\n\n @if (showRemove()) {\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"file-card-remove\"\n icon=\"ico-trash\"\n variant=\"ghost\"\n [ariaLabel]=\"t().uiRemove\"\n [tooltip]=\"t().uiRemove\"\n [size]=\"actionSize()\"\n [disabled]=\"disabled()\"\n (clicked)=\"onRemove()\" />\n }\n </span>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-file-card{--rt-file-card-radius: var(--rt-radius-lg);--rt-file-card-border-width: var(--rt-border-width-thin);--rt-file-card-badge-radius: var(--rt-radius-full);--rt-file-card-padding-block: var(--rt-space-sm);--rt-file-card-padding-inline: var(--rt-space-md);--rt-file-card-gap: var(--rt-space-sm);--rt-file-card-title-size: var(--rt-text-md);--rt-file-card-name-size: var(--rt-text-sm);--rt-file-card-badge-size: var(--rt-text-xs);display:flex;align-items:center;padding:var(--rt-file-card-padding-block) var(--rt-file-card-padding-inline);border:var(--rt-file-card-border-width) solid var(--rt-color-border-subtle);border-radius:var(--rt-file-card-radius);background-color:var(--rt-color-bg-surface);gap:var(--rt-file-card-gap);max-inline-size:100%;min-inline-size:0}.rt-file-card--sm{--rt-file-card-padding-block: var(--rt-space-xs);--rt-file-card-padding-inline: var(--rt-space-sm);--rt-file-card-gap: var(--rt-space-xs);--rt-file-card-title-size: var(--rt-text-xs);--rt-file-card-name-size: var(--rt-text-2xs);--rt-file-card-badge-size: var(--rt-text-2xs)}.rt-file-card--md{--rt-file-card-padding-block: var(--rt-space-sm);--rt-file-card-padding-inline: var(--rt-space-md);--rt-file-card-gap: var(--rt-space-sm);--rt-file-card-title-size: var(--rt-text-md);--rt-file-card-name-size: var(--rt-text-sm);--rt-file-card-badge-size: var(--rt-text-xs)}.rt-file-card--lg{--rt-file-card-padding-block: var(--rt-space-md);--rt-file-card-padding-inline: var(--rt-space-lg);--rt-file-card-gap: var(--rt-space-md);--rt-file-card-title-size: var(--rt-text-lg);--rt-file-card-name-size: var(--rt-text-md);--rt-file-card-badge-size: var(--rt-text-sm)}.rt-file-card__icon{flex-shrink:0}.rt-file-card__text{display:flex;min-width:0;flex:1 1 auto;flex-direction:column;gap:var(--rt-space-2xs)}.rt-file-card__title{overflow:hidden;color:var(--rt-color-text-primary);font-size:var(--rt-file-card-title-size);font-weight:var(--rt-font-weight-semibold);text-overflow:ellipsis;white-space:nowrap}.rt-file-card__name{overflow:hidden;color:var(--rt-color-text-muted);font-size:var(--rt-file-card-name-size);text-overflow:ellipsis;white-space:nowrap}.rt-file-card__meta{display:flex;flex-shrink:0;align-items:center;gap:var(--rt-space-xs)}.rt-file-card__size{padding:var(--rt-space-2xs) var(--rt-space-sm);border:var(--rt-file-card-border-width) solid var(--rt-color-border-subtle);border-radius:var(--rt-file-card-badge-radius);color:var(--rt-color-text-muted);font-size:var(--rt-file-card-badge-size);white-space:nowrap}.rt-file-card__action{flex-shrink:0}.rt-file-card[data-rt-radius=none]{--rt-file-card-radius: var(--rt-radius-none)}.rt-file-card[data-rt-radius=xs]{--rt-file-card-radius: var(--rt-radius-xs)}.rt-file-card[data-rt-radius=sm]{--rt-file-card-radius: var(--rt-radius-sm)}.rt-file-card[data-rt-radius=ms]{--rt-file-card-radius: var(--rt-radius-ms)}.rt-file-card[data-rt-radius=md]{--rt-file-card-radius: var(--rt-radius-md)}.rt-file-card[data-rt-radius=lg]{--rt-file-card-radius: var(--rt-radius-lg)}.rt-file-card[data-rt-radius=xl]{--rt-file-card-radius: var(--rt-radius-xl)}.rt-file-card[data-rt-radius=\"2xl\"]{--rt-file-card-radius: var(--rt-radius-2xl)}.rt-file-card[data-rt-radius=full]{--rt-file-card-radius: var(--rt-radius-full)}}\n"] }]
|
|
212
|
+
}], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], sizeBytes: [{ type: i0.Input, args: [{ isSignal: true, alias: "sizeBytes", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], showDownload: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDownload", required: false }] }], showRemove: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRemove", required: false }] }], showRename: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRename", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], download: [{ type: i0.Output, args: ["download"] }], removed: [{ type: i0.Output, args: ["removed"] }], rename: [{ type: i0.Output, args: ["rename"] }] } });
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Generated bundle index. Do not edit.
|
|
216
|
+
*/
|
|
217
|
+
|
|
218
|
+
export { RtFileCardComponent, RtTruncateMiddlePipe, deriveFileTitle, getFileTypeIcon };
|
|
219
|
+
//# sourceMappingURL=rt-tools-ui-kit-v2-file-card.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-file-card.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/file-card/file-card.helper.ts","../../../projects/ui-kit-v2/src/lib/components/file-card/rt-truncate-middle.pipe.ts","../../../projects/ui-kit-v2/src/lib/components/file-card/rt-file-card.component.ts","../../../projects/ui-kit-v2/src/lib/components/file-card/rt-file-card.component.html","../../../projects/ui-kit-v2/src/lib/components/file-card/rt-tools-ui-kit-v2-file-card.ts"],"sourcesContent":["import { IRtIcon } from '@rt-tools/ui-kit-v2/core';\n\n/** Иконка Word-семейства (несколько расширений делят один глиф). */\nconst ICON_WORD: IRtIcon.Name = 'attach-docx-doc';\n\n/** Иконка растровых изображений. */\nconst ICON_IMAGE: IRtIcon.Name = 'attach-jpg-png';\n\n/** Иконка презентаций. */\nconst ICON_PRESENTATION: IRtIcon.Name = 'attach-ppt-pptx';\n\n/** Иконка таблиц Excel-семейства. */\nconst ICON_SPREADSHEET: IRtIcon.Name = 'attach-xlsx-xls';\n\n/** Иконка архивов. */\nconst ICON_ARCHIVE: IRtIcon.Name = 'attach-zip-rar';\n\n/** Иконка web-форматов изображений/видео. */\nconst ICON_WEB_MEDIA: IRtIcon.Name = 'attach-webp';\n\n/**\n * Маппинг расширения файла → имя цветной иконки типа (`attach-*` в rt-icon-реестре).\n */\nconst FILE_TYPE_ICON: Readonly<Record<string, IRtIcon.Name>> = {\n doc: ICON_WORD,\n docx: ICON_WORD,\n odt: ICON_WORD,\n gif: ICON_IMAGE,\n jpg: ICON_IMAGE,\n jpeg: ICON_IMAGE,\n png: ICON_IMAGE,\n pdf: 'attach-pdf',\n ppt: ICON_PRESENTATION,\n pptx: ICON_PRESENTATION,\n txt: 'attach-txt',\n webp: ICON_WEB_MEDIA,\n webm: ICON_WEB_MEDIA,\n xls: ICON_SPREADSHEET,\n xlsx: ICON_SPREADSHEET,\n zip: ICON_ARCHIVE,\n rar: ICON_ARCHIVE,\n msg: 'attach-msg',\n eml: 'attach-eml',\n};\n\n/**\n * Возвращает имя иконки типа файла по его имени (берётся расширение после\n * последней точки). Неизвестное/отсутствующее расширение → нейтральный `attach-other`.\n */\nexport function getFileTypeIcon(fileName: string): IRtIcon.Name {\n const ext: string = fileName.split('.').pop()?.toLowerCase() ?? '';\n return FILE_TYPE_ICON[ext] ?? 'attach-other';\n}\n\n/**\n * Выводит читаемый заголовок из имени файла: отбрасывает расширение и заменяет\n * разделители `_`/`-` на пробелы (CamelCase намеренно НЕ разбивается — это давало\n * бы непредсказуемый результат на произвольных именах). Если после очистки строка\n * пустая (например имя было `.pdf`) — возвращается исходное имя.\n */\nexport function deriveFileTitle(fileName: string): string {\n const withoutExt: string = fileName.replace(/\\.[^./\\\\]+$/, '');\n const cleaned: string = withoutExt.replace(/[_-]+/g, ' ').replace(/\\s+/g, ' ').trim();\n return cleaned || fileName;\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n/** Многоточие, вставляемое в середину строки при усечении. */\nconst ELLIPSIS: string = '...';\n\n/** Длина строки по умолчанию, при которой включается усечение. */\nconst DEFAULT_MAX_LENGTH: number = 32;\n\n/**\n * Усекает длинное имя файла по середине, сохраняя расширение видимым:\n * `10588-1_EvaluationSearchReport.pdf` → `10588-1_EvaluationSearchRe...pdf`.\n *\n * Обычный CSS `text-overflow: ellipsis` режет хвост и теряет расширение —\n * поэтому усечение по середине делается здесь, а не в стилях. Усечение\n * посимвольное (не по ширине контейнера): предсказуемо и без измерений DOM.\n *\n * Pure-pipe: пересчитывается только при смене входа.\n */\n@Pipe({ name: 'rtTruncateMiddle' })\nexport class RtTruncateMiddlePipe implements PipeTransform {\n public transform(value: string | null | undefined, maxLength: number = DEFAULT_MAX_LENGTH): string {\n if (!value) {\n return '';\n }\n if (value.length <= maxLength) {\n return value;\n }\n\n const lastDot: number = value.lastIndexOf('.');\n const hasExt: boolean = lastDot > 0 && lastDot < value.length - 1;\n const ext: string = hasExt ? value.slice(lastDot + 1) : '';\n const base: string = hasExt ? value.slice(0, lastDot) : value;\n\n const headLength: number = maxLength - ext.length - ELLIPSIS.length;\n if (headLength <= 0) {\n // Расширение длиннее лимита — деградируем до простого усечения хвоста.\n return value.slice(0, Math.max(0, maxLength - ELLIPSIS.length)) + ELLIPSIS;\n }\n\n return base.slice(0, headLength) + ELLIPSIS + ext;\n }\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n ChangeDetectionStrategy,\n Component,\n InputSignal,\n InputSignalWithTransform,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { formatFileSize } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { IRtIconButton } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { deriveFileTitle, getFileTypeIcon } from './file-card.helper';\nimport { IRtFileCard } from './rt-file-card.model';\nimport { RtTruncateMiddlePipe } from './rt-truncate-middle.pipe';\n\nconst BEM_BLOCK: string = 'rt-file-card';\n\n/** Иконка типа файла крупнее прочего: по ней карточку находят взглядом. */\nconst ICON_SIZES: Readonly<Record<IRtFileCard.Size, IRtIcon.Size>> = {\n sm: 'sm',\n md: 'xl',\n lg: 'xl',\n};\n\n/** Кнопки действий: в компактной карточке они не должны задавать её высоту. */\nconst ACTION_SIZES: Readonly<Record<IRtFileCard.Size, IRtIconButton.Size>> = {\n sm: 'sm',\n md: 'sm',\n lg: 'md',\n};\n\n/**\n * Карточка загруженного файла: цветная иконка типа, заголовок (выведенный из имени),\n * усечённое по середине имя файла, бейдж размера и опциональные действия справа\n * (скачать / переименовать / удалить).\n *\n * Презентационный компонент: сам ничего не решает, только эмиттит события действий.\n * Кнопки включаются точечно через `showDownload`/`showRemove`/`showRename` — в режиме\n * загрузки обычно нужен только remove, при показе сохранённых файлов — download.\n *\n * `showRename` по умолчанию выключен и сейчас нигде не включается: бэкенд не\n * поддерживает переименование (`original_name` неизменяем после создания). Вход\n * оставлен, чтобы кнопку можно было включить без правки компонента, когда появится API.\n */\n@Component({\n selector: 'rt-file-card',\n templateUrl: './rt-file-card.component.html',\n styleUrls: ['./rt-file-card.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtIconComponent,\n RtIconButtonComponent,\n RtTooltipDirective,\n BlockDirective,\n ElemDirective,\n\n // pipes\n RtTruncateMiddlePipe,\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n '[class.rt-file-card--sm]': \"size() === 'sm'\",\n '[class.rt-file-card--md]': \"size() === 'md'\",\n '[class.rt-file-card--lg]': \"size() === 'lg'\",\n },\n})\nexport class RtFileCardComponent {\n /** Имя цветной иконки типа файла по расширению. */\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly iconName: Signal<IRtIcon.Name> = computed((): IRtIcon.Name => getFileTypeIcon(this.name()));\n\n /** Заголовок карточки, выведенный из имени файла (без расширения, разделители → пробелы). */\n protected readonly title: Signal<string> = computed((): string => deriveFileTitle(this.name()));\n\n /** Отформатированный размер; пустая строка → размер неизвестен. */\n protected readonly sizeLabel: Signal<string> = computed((): string => formatFileSize(this.sizeBytes()));\n\n /** Показывать ли бейдж размера. */\n protected readonly hasSize: Signal<boolean> = computed((): boolean => this.sizeLabel() !== '');\n\n /** Размер иконки типа файла — маппится от размера карточки. */\n protected readonly iconSize: Signal<IRtIcon.Size> = computed((): IRtIcon.Size => ICON_SIZES[this.size()]);\n\n /** Размер кнопок действий — маппится от размера карточки. */\n protected readonly actionSize: Signal<IRtIconButton.Size> = computed((): IRtIconButton.Size => ACTION_SIZES[this.size()]);\n\n /** Имя файла с расширением — обязательно. */\n public readonly name: InputSignal<string> = input.required<string>();\n\n /** Размер в байтах. `null` → бейдж размера скрыт. */\n public readonly sizeBytes: InputSignal<number | null> = input<number | null>(null);\n\n /** Плотность карточки: `sm` для тесных мест вроде композера, `lg` — для страниц. */\n public readonly size: InputSignal<IRtFileCard.Size> = input<IRtFileCard.Size>('md');\n\n /** Показывать кнопку скачивания. */\n public readonly showDownload: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Показывать кнопку удаления. */\n public readonly showRemove: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Показывать кнопку переименования (отключена до появления API на бэке). */\n public readonly showRename: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Блокирует кнопки действий (например, во время сабмита формы). */\n public readonly disabled: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Запрошено скачивание файла. */\n public readonly download: OutputEmitterRef<void> = output<void>();\n\n /** Запрошено удаление файла. */\n public readonly removed: OutputEmitterRef<void> = output<void>();\n\n /** Запрошено переименование файла. */\n public readonly rename: OutputEmitterRef<void> = output<void>();\n\n protected onDownload(): void {\n this.download.emit();\n }\n\n protected onRemove(): void {\n this.removed.emit();\n }\n\n protected onRename(): void {\n this.rename.emit();\n }\n}\n","<ng-container rtBlock=\"rt-file-card\">\n <rt-icon rtElem=\"icon\" [size]=\"iconSize()\" [name]=\"iconName()\" />\n\n <span rtElem=\"text\">\n <span rtElem=\"title\" qa-dataid=\"file-card-title\" [rtTooltip]=\"title()\">{{ title() }}</span>\n <span rtElem=\"name\" qa-dataid=\"file-card-name\" [rtTooltip]=\"name()\">{{ name() | rtTruncateMiddle }}</span>\n </span>\n\n <span rtElem=\"meta\">\n @if (hasSize()) {\n <span rtElem=\"size\" qa-dataid=\"file-card-size\">{{ sizeLabel() }}</span>\n }\n\n @if (showDownload()) {\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"file-card-download\"\n icon=\"ico-download\"\n variant=\"ghost\"\n [ariaLabel]=\"t().uiDownload\"\n [tooltip]=\"t().uiDownload\"\n [size]=\"actionSize()\"\n [disabled]=\"disabled()\"\n (clicked)=\"onDownload()\" />\n }\n\n @if (showRename()) {\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"file-card-rename\"\n icon=\"ico-edit\"\n variant=\"ghost\"\n [ariaLabel]=\"t().uiRename\"\n [tooltip]=\"t().uiRename\"\n [size]=\"actionSize()\"\n [disabled]=\"disabled()\"\n (clicked)=\"onRename()\" />\n }\n\n @if (showRemove()) {\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"file-card-remove\"\n icon=\"ico-trash\"\n variant=\"ghost\"\n [ariaLabel]=\"t().uiRemove\"\n [tooltip]=\"t().uiRemove\"\n [size]=\"actionSize()\"\n [disabled]=\"disabled()\"\n (clicked)=\"onRemove()\" />\n }\n </span>\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, DestroyRef, ElementRef, signal, computed, input, booleanAttribute, output, HostListener, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';
|
|
4
|
+
import { rtKitLabel } from '@rt-tools/ui-kit-v2/core';
|
|
5
|
+
import * as i1 from '@rt-tools/ui-kit-v2/radius';
|
|
6
|
+
import { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';
|
|
7
|
+
|
|
8
|
+
const BEM_BLOCK = 'rt-file-drop';
|
|
9
|
+
/** Задержка скрытия оверлея: dragleave стреляет при переходе между дочерними
|
|
10
|
+
элементами, без debounce рамка мерцает. */
|
|
11
|
+
const DRAG_LEAVE_DEBOUNCE_MS = 80;
|
|
12
|
+
/**
|
|
13
|
+
* Зона перетаскивания файлов: оборачивает произвольный контент через
|
|
14
|
+
* content-projection и превращает его в drop-зону. При перетаскивании файла над
|
|
15
|
+
* областью рисует приглушающий оверлей-приглашение поверх контента, на drop —
|
|
16
|
+
* эмитит выброшенные файлы через `(filesDropped)`.
|
|
17
|
+
*
|
|
18
|
+
* Мультизонный режим: при непустом `zones` оверлей делится на вертикальную стопку
|
|
19
|
+
* равных зон с подписями; зона под курсором подсвечивается, drop эмитится через
|
|
20
|
+
* `(zoneFilesDropped)` с id зоны (а `(filesDropped)` в этом режиме НЕ эмитится).
|
|
21
|
+
* Зона курсора вычисляется по Y-координате против host-rect — оверлей остаётся
|
|
22
|
+
* pointer-events:none, drag-события продолжают идти в host-listener'ы.
|
|
23
|
+
*
|
|
24
|
+
* `accept` (формат как у нативного input[accept]) отфильтровывает неподходящие
|
|
25
|
+
* файлы до эмита — drop в обход файл-пикера не проносит запрещённые расширения;
|
|
26
|
+
* отбрасывание молчаливое, как у самого пикера.
|
|
27
|
+
*
|
|
28
|
+
* Слушает drag-события на собственном host'е (всплывают со всего спроецированного
|
|
29
|
+
* контента), гасит браузерный навигейт по файлу и принимает только перетаскивание
|
|
30
|
+
* файлов (а не внутренний drag элементов формы). Потребитель управляет приёмом
|
|
31
|
+
* через `[disabled]` (например «активна вкладка файлов и форма редактируема») и
|
|
32
|
+
* сам решает, что делать с файлами — компонент состояние файлов не хранит.
|
|
33
|
+
*
|
|
34
|
+
* Оверлей `pointer-events: none` — не перехватывает drag/drop, события доходят до
|
|
35
|
+
* host-listener'ов.
|
|
36
|
+
*/
|
|
37
|
+
class RtFileDropComponent {
|
|
38
|
+
#destroyRef;
|
|
39
|
+
#host;
|
|
40
|
+
#t_uiFileDropOverlay;
|
|
41
|
+
#dragLeaveTimer;
|
|
42
|
+
constructor() {
|
|
43
|
+
this.#destroyRef = inject(DestroyRef);
|
|
44
|
+
this.#host = inject(ElementRef);
|
|
45
|
+
this.#t_uiFileDropOverlay = rtKitLabel('uiFileDropOverlay');
|
|
46
|
+
this.#dragLeaveTimer = null;
|
|
47
|
+
/** Активна ли подсветка drop-зоны (файл тащат над областью). */
|
|
48
|
+
this.isDragging = signal(false, /* @ts-ignore */
|
|
49
|
+
...(ngDevMode ? [{ debugName: "isDragging" }] : /* istanbul ignore next */ []));
|
|
50
|
+
/** Зона под курсором в мультизонном режиме (id из `zones`). */
|
|
51
|
+
this.activeZoneId = signal(null, /* @ts-ignore */
|
|
52
|
+
...(ngDevMode ? [{ debugName: "activeZoneId" }] : /* istanbul ignore next */ []));
|
|
53
|
+
this.hasZones = computed(() => this.zones().length > 0, /* @ts-ignore */
|
|
54
|
+
...(ngDevMode ? [{ debugName: "hasZones" }] : /* istanbul ignore next */ []));
|
|
55
|
+
this.overlayText = computed(() => this.overlayLabel() || this.#t_uiFileDropOverlay(), /* @ts-ignore */
|
|
56
|
+
...(ngDevMode ? [{ debugName: "overlayText" }] : /* istanbul ignore next */ []));
|
|
57
|
+
/** Приём drop'а выключен (потребитель решает по своему контексту). */
|
|
58
|
+
this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
59
|
+
/** Пусто — берётся переведённая подпись по умолчанию */
|
|
60
|
+
this.overlayLabel = input('', /* @ts-ignore */
|
|
61
|
+
...(ngDevMode ? [{ debugName: "overlayLabel" }] : /* istanbul ignore next */ []));
|
|
62
|
+
/** Мультизонный режим: непустой список зон делит оверлей на стопку целей. */
|
|
63
|
+
this.zones = input([], /* @ts-ignore */
|
|
64
|
+
...(ngDevMode ? [{ debugName: "zones" }] : /* istanbul ignore next */ []));
|
|
65
|
+
/** Фильтр расширений/MIME (формат нативного input[accept]); пусто — без фильтра. */
|
|
66
|
+
this.accept = input('', /* @ts-ignore */
|
|
67
|
+
...(ngDevMode ? [{ debugName: "accept" }] : /* istanbul ignore next */ []));
|
|
68
|
+
this.filesDropped = output();
|
|
69
|
+
/** Drop в мультизонном режиме: файлы + id зоны, куда их бросили. */
|
|
70
|
+
this.zoneFilesDropped = output();
|
|
71
|
+
this.draggingChange = output();
|
|
72
|
+
this.#destroyRef.onDestroy(() => this.#clearLeaveTimer());
|
|
73
|
+
}
|
|
74
|
+
onDragOver(event) {
|
|
75
|
+
if (this.disabled() || !this.#isFileDrag(event)) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
event.preventDefault();
|
|
79
|
+
event.stopPropagation();
|
|
80
|
+
if (event.dataTransfer) {
|
|
81
|
+
event.dataTransfer.dropEffect = 'copy';
|
|
82
|
+
}
|
|
83
|
+
this.#clearLeaveTimer();
|
|
84
|
+
this.#setDragging(true);
|
|
85
|
+
if (this.hasZones()) {
|
|
86
|
+
this.activeZoneId.set(this.#zoneIdAt(event.clientY));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
onDragLeave(event) {
|
|
90
|
+
if (!this.isDragging()) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
event.preventDefault();
|
|
94
|
+
this.#clearLeaveTimer();
|
|
95
|
+
this.#dragLeaveTimer = setTimeout(() => {
|
|
96
|
+
this.#dragLeaveTimer = null;
|
|
97
|
+
this.#setDragging(false);
|
|
98
|
+
}, DRAG_LEAVE_DEBOUNCE_MS);
|
|
99
|
+
}
|
|
100
|
+
onDrop(event) {
|
|
101
|
+
if (this.disabled() || !this.#isFileDrag(event)) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
event.preventDefault();
|
|
105
|
+
event.stopPropagation();
|
|
106
|
+
this.#clearLeaveTimer();
|
|
107
|
+
this.#setDragging(false);
|
|
108
|
+
const files = Array.from(event.dataTransfer?.files ?? []).filter((file) => this.#matchesAccept(file));
|
|
109
|
+
if (files.length === 0) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (!this.hasZones()) {
|
|
113
|
+
this.filesDropped.emit(files);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const zoneId = this.#zoneIdAt(event.clientY);
|
|
117
|
+
if (zoneId === null) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
this.zoneFilesDropped.emit({ zoneId, files });
|
|
121
|
+
}
|
|
122
|
+
/** Меняет dragging-флаг и эмитит изменение только при реальном переходе. */
|
|
123
|
+
#setDragging(value) {
|
|
124
|
+
if (this.isDragging() === value) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
this.isDragging.set(value);
|
|
128
|
+
this.draggingChange.emit(value);
|
|
129
|
+
if (!value) {
|
|
130
|
+
this.activeZoneId.set(null);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/** Зона по Y-координате курсора: стопка равных по высоте полос host-rect. */
|
|
134
|
+
#zoneIdAt(clientY) {
|
|
135
|
+
const zones = this.zones();
|
|
136
|
+
if (zones.length === 0) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
const rect = this.#host.nativeElement.getBoundingClientRect();
|
|
140
|
+
if (rect.height <= 0) {
|
|
141
|
+
return zones[0].id;
|
|
142
|
+
}
|
|
143
|
+
const ratio = (clientY - rect.top) / rect.height;
|
|
144
|
+
const index = Math.min(zones.length - 1, Math.max(0, Math.floor(ratio * zones.length)));
|
|
145
|
+
return zones[index].id;
|
|
146
|
+
}
|
|
147
|
+
/** Файл проходит accept-фильтр (расширение `.pdf` / MIME `image/png` / `image/*`). */
|
|
148
|
+
#matchesAccept(file) {
|
|
149
|
+
const accept = this.accept().trim();
|
|
150
|
+
if (accept === '') {
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
const name = file.name.toLowerCase();
|
|
154
|
+
const mime = file.type.toLowerCase();
|
|
155
|
+
return accept.split(',').some((raw) => {
|
|
156
|
+
const token = raw.trim().toLowerCase();
|
|
157
|
+
if (token === '') {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
if (token.startsWith('.')) {
|
|
161
|
+
return name.endsWith(token);
|
|
162
|
+
}
|
|
163
|
+
if (token.endsWith('/*')) {
|
|
164
|
+
return mime.startsWith(token.slice(0, -1));
|
|
165
|
+
}
|
|
166
|
+
return mime === token;
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
/** Перетаскивают именно файлы (а не внутренний drag элементов формы). */
|
|
170
|
+
#isFileDrag(event) {
|
|
171
|
+
const types = event.dataTransfer?.types;
|
|
172
|
+
return types?.includes('Files') ?? false;
|
|
173
|
+
}
|
|
174
|
+
#clearLeaveTimer() {
|
|
175
|
+
if (this.#dragLeaveTimer !== null) {
|
|
176
|
+
clearTimeout(this.#dragLeaveTimer);
|
|
177
|
+
this.#dragLeaveTimer = null;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtFileDropComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
181
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtFileDropComponent, isStandalone: true, selector: "rt-file-drop", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, overlayLabel: { classPropertyName: "overlayLabel", publicName: "overlayLabel", isSignal: true, isRequired: false, transformFunction: null }, zones: { classPropertyName: "zones", publicName: "zones", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filesDropped: "filesDropped", zoneFilesDropped: "zoneFilesDropped", draggingChange: "draggingChange" }, host: { listeners: { "dragenter": "onDragOver($event)", "dragover": "onDragOver($event)", "dragleave": "onDragLeave($event)", "drop": "onDrop($event)" }, classAttribute: "rt-file-drop" }, hostDirectives: [{ directive: i1.RtRadiusDirective, inputs: ["radius", "radius"] }], ngImport: i0, template: "<ng-container rtBlock=\"rt-file-drop\">\n <ng-content />\n\n @if (isDragging()) {\n <div rtElem=\"overlay\" qa-dataid=\"file-drop-overlay\" aria-hidden=\"true\" [rtMod]=\"{ zoned: hasZones() }\">\n @if (hasZones()) {\n @for (zone of zones(); track zone.id) {\n <div\n rtElem=\"zone\"\n qa-dataid=\"file-drop-zone\"\n [attr.data-zone]=\"zone.id\"\n [attr.data-active]=\"activeZoneId() === zone.id\"\n [rtMod]=\"{ active: activeZoneId() === zone.id }\">\n <span rtElem=\"label\" qa-dataid=\"file-drop-zone-label\">{{ zone.label }}</span>\n @if (zone.sublabel) {\n <span rtElem=\"sublabel\" qa-dataid=\"file-drop-zone-sublabel\">{{ zone.sublabel }}</span>\n }\n </div>\n }\n } @else {\n <div rtElem=\"frame\" qa-dataid=\"file-drop-frame\">\n <span rtElem=\"label\" qa-dataid=\"file-drop-label\">{{ overlayText() }}</span>\n </div>\n }\n </div>\n }\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-file-drop{--rt-file-drop-radius: var(--rt-radius-lg);--rt-file-drop-border-width: var(--rt-border-width-thin);--rt-file-drop-transition-duration: var(--rt-duration-fast);--rt-file-drop-frame-inset: var(--rt-space-lg);--rt-file-drop-frame-padding: var(--rt-space-md);--rt-file-drop-label-size: var(--rt-text-lg);position:relative;display:block;height:100%}.rt-file-drop__overlay{position:absolute;z-index:50;display:flex;overflow:hidden;align-items:center;justify-content:center;border-radius:var(--rt-file-drop-radius);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);background:#00000073;container-type:size;inset:var(--rt-space-sm);pointer-events:none}.rt-file-drop__overlay--zoned{flex-direction:column;align-items:stretch;padding:var(--rt-space-md);gap:var(--rt-space-sm)}.rt-file-drop__frame{position:absolute;display:flex;box-sizing:border-box;align-items:center;justify-content:center;padding:var(--rt-file-drop-frame-padding);border:var(--rt-file-drop-border-width) dashed var(--rt-color-action-on-primary);border-radius:var(--rt-file-drop-radius);gap:var(--rt-space-sm);inset:var(--rt-file-drop-frame-inset);text-align:center}.rt-file-drop__zone{display:flex;min-height:0;box-sizing:border-box;flex:1 1 0;flex-direction:column;align-items:center;justify-content:center;padding:var(--rt-space-md);border:var(--rt-file-drop-border-width) dashed var(--rt-color-action-on-primary);border-radius:var(--rt-file-drop-radius);gap:var(--rt-space-2xs);text-align:center;transition:border-color var(--rt-file-drop-transition-duration) ease,background-color var(--rt-file-drop-transition-duration) ease}.rt-file-drop__zone--active{border-style:solid;border-color:var(--rt-color-action-primary);background:#ffffff1a}.rt-file-drop__label{color:var(--rt-color-action-on-primary);font-size:var(--rt-file-drop-label-size);font-weight:var(--rt-font-weight-semibold)}.rt-file-drop__sublabel{color:var(--rt-color-action-on-primary);font-size:var(--rt-text-sm);opacity:.8}.rt-file-drop[data-rt-radius=none]{--rt-file-drop-radius: var(--rt-radius-none)}.rt-file-drop[data-rt-radius=xs]{--rt-file-drop-radius: var(--rt-radius-xs)}.rt-file-drop[data-rt-radius=sm]{--rt-file-drop-radius: var(--rt-radius-sm)}.rt-file-drop[data-rt-radius=ms]{--rt-file-drop-radius: var(--rt-radius-ms)}.rt-file-drop[data-rt-radius=md]{--rt-file-drop-radius: var(--rt-radius-md)}.rt-file-drop[data-rt-radius=lg]{--rt-file-drop-radius: var(--rt-radius-lg)}.rt-file-drop[data-rt-radius=xl]{--rt-file-drop-radius: var(--rt-radius-xl)}.rt-file-drop[data-rt-radius=\"2xl\"]{--rt-file-drop-radius: var(--rt-radius-2xl)}.rt-file-drop[data-rt-radius=full]{--rt-file-drop-radius: var(--rt-radius-full)}@container (max-height: 6rem){.rt-file-drop__frame{--rt-file-drop-frame-inset: var(--rt-space-2xs);--rt-file-drop-frame-padding: var(--rt-space-2xs);--rt-file-drop-label-size: var(--rt-text-xs)}}}\n"], dependencies: [{ kind: "directive", type:
|
|
182
|
+
// standalone components / directives
|
|
183
|
+
BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }, { kind: "directive", type: ModDirective, selector: "[rtMod]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
184
|
+
}
|
|
185
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtFileDropComponent, decorators: [{
|
|
186
|
+
type: Component,
|
|
187
|
+
args: [{ selector: 'rt-file-drop', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
188
|
+
// standalone components / directives
|
|
189
|
+
BlockDirective,
|
|
190
|
+
ElemDirective,
|
|
191
|
+
ModDirective,
|
|
192
|
+
], hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }], host: {
|
|
193
|
+
class: BEM_BLOCK,
|
|
194
|
+
}, template: "<ng-container rtBlock=\"rt-file-drop\">\n <ng-content />\n\n @if (isDragging()) {\n <div rtElem=\"overlay\" qa-dataid=\"file-drop-overlay\" aria-hidden=\"true\" [rtMod]=\"{ zoned: hasZones() }\">\n @if (hasZones()) {\n @for (zone of zones(); track zone.id) {\n <div\n rtElem=\"zone\"\n qa-dataid=\"file-drop-zone\"\n [attr.data-zone]=\"zone.id\"\n [attr.data-active]=\"activeZoneId() === zone.id\"\n [rtMod]=\"{ active: activeZoneId() === zone.id }\">\n <span rtElem=\"label\" qa-dataid=\"file-drop-zone-label\">{{ zone.label }}</span>\n @if (zone.sublabel) {\n <span rtElem=\"sublabel\" qa-dataid=\"file-drop-zone-sublabel\">{{ zone.sublabel }}</span>\n }\n </div>\n }\n } @else {\n <div rtElem=\"frame\" qa-dataid=\"file-drop-frame\">\n <span rtElem=\"label\" qa-dataid=\"file-drop-label\">{{ overlayText() }}</span>\n </div>\n }\n </div>\n }\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-file-drop{--rt-file-drop-radius: var(--rt-radius-lg);--rt-file-drop-border-width: var(--rt-border-width-thin);--rt-file-drop-transition-duration: var(--rt-duration-fast);--rt-file-drop-frame-inset: var(--rt-space-lg);--rt-file-drop-frame-padding: var(--rt-space-md);--rt-file-drop-label-size: var(--rt-text-lg);position:relative;display:block;height:100%}.rt-file-drop__overlay{position:absolute;z-index:50;display:flex;overflow:hidden;align-items:center;justify-content:center;border-radius:var(--rt-file-drop-radius);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);background:#00000073;container-type:size;inset:var(--rt-space-sm);pointer-events:none}.rt-file-drop__overlay--zoned{flex-direction:column;align-items:stretch;padding:var(--rt-space-md);gap:var(--rt-space-sm)}.rt-file-drop__frame{position:absolute;display:flex;box-sizing:border-box;align-items:center;justify-content:center;padding:var(--rt-file-drop-frame-padding);border:var(--rt-file-drop-border-width) dashed var(--rt-color-action-on-primary);border-radius:var(--rt-file-drop-radius);gap:var(--rt-space-sm);inset:var(--rt-file-drop-frame-inset);text-align:center}.rt-file-drop__zone{display:flex;min-height:0;box-sizing:border-box;flex:1 1 0;flex-direction:column;align-items:center;justify-content:center;padding:var(--rt-space-md);border:var(--rt-file-drop-border-width) dashed var(--rt-color-action-on-primary);border-radius:var(--rt-file-drop-radius);gap:var(--rt-space-2xs);text-align:center;transition:border-color var(--rt-file-drop-transition-duration) ease,background-color var(--rt-file-drop-transition-duration) ease}.rt-file-drop__zone--active{border-style:solid;border-color:var(--rt-color-action-primary);background:#ffffff1a}.rt-file-drop__label{color:var(--rt-color-action-on-primary);font-size:var(--rt-file-drop-label-size);font-weight:var(--rt-font-weight-semibold)}.rt-file-drop__sublabel{color:var(--rt-color-action-on-primary);font-size:var(--rt-text-sm);opacity:.8}.rt-file-drop[data-rt-radius=none]{--rt-file-drop-radius: var(--rt-radius-none)}.rt-file-drop[data-rt-radius=xs]{--rt-file-drop-radius: var(--rt-radius-xs)}.rt-file-drop[data-rt-radius=sm]{--rt-file-drop-radius: var(--rt-radius-sm)}.rt-file-drop[data-rt-radius=ms]{--rt-file-drop-radius: var(--rt-radius-ms)}.rt-file-drop[data-rt-radius=md]{--rt-file-drop-radius: var(--rt-radius-md)}.rt-file-drop[data-rt-radius=lg]{--rt-file-drop-radius: var(--rt-radius-lg)}.rt-file-drop[data-rt-radius=xl]{--rt-file-drop-radius: var(--rt-radius-xl)}.rt-file-drop[data-rt-radius=\"2xl\"]{--rt-file-drop-radius: var(--rt-radius-2xl)}.rt-file-drop[data-rt-radius=full]{--rt-file-drop-radius: var(--rt-radius-full)}@container (max-height: 6rem){.rt-file-drop__frame{--rt-file-drop-frame-inset: var(--rt-space-2xs);--rt-file-drop-frame-padding: var(--rt-space-2xs);--rt-file-drop-label-size: var(--rt-text-xs)}}}\n"] }]
|
|
195
|
+
}], ctorParameters: () => [], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], overlayLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlayLabel", required: false }] }], zones: [{ type: i0.Input, args: [{ isSignal: true, alias: "zones", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], filesDropped: [{ type: i0.Output, args: ["filesDropped"] }], zoneFilesDropped: [{ type: i0.Output, args: ["zoneFilesDropped"] }], draggingChange: [{ type: i0.Output, args: ["draggingChange"] }], onDragOver: [{
|
|
196
|
+
type: HostListener,
|
|
197
|
+
args: ['dragenter', ['$event']]
|
|
198
|
+
}, {
|
|
199
|
+
type: HostListener,
|
|
200
|
+
args: ['dragover', ['$event']]
|
|
201
|
+
}], onDragLeave: [{
|
|
202
|
+
type: HostListener,
|
|
203
|
+
args: ['dragleave', ['$event']]
|
|
204
|
+
}], onDrop: [{
|
|
205
|
+
type: HostListener,
|
|
206
|
+
args: ['drop', ['$event']]
|
|
207
|
+
}] } });
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Generated bundle index. Do not edit.
|
|
211
|
+
*/
|
|
212
|
+
|
|
213
|
+
export { RtFileDropComponent };
|
|
214
|
+
//# sourceMappingURL=rt-tools-ui-kit-v2-file-drop.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-file-drop.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/file-drop/rt-file-drop.component.ts","../../../projects/ui-kit-v2/src/lib/components/file-drop/rt-file-drop.component.html","../../../projects/ui-kit-v2/src/lib/components/file-drop/rt-tools-ui-kit-v2-file-drop.ts"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n HostListener,\n inject,\n input,\n InputSignal,\n InputSignalWithTransform,\n output,\n OutputEmitterRef,\n Signal,\n signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { IRtFileDrop } from './rt-file-drop.model';\n\nconst BEM_BLOCK: string = 'rt-file-drop';\n\n/** Задержка скрытия оверлея: dragleave стреляет при переходе между дочерними\n элементами, без debounce рамка мерцает. */\nconst DRAG_LEAVE_DEBOUNCE_MS: number = 80;\n\n/**\n * Зона перетаскивания файлов: оборачивает произвольный контент через\n * content-projection и превращает его в drop-зону. При перетаскивании файла над\n * областью рисует приглушающий оверлей-приглашение поверх контента, на drop —\n * эмитит выброшенные файлы через `(filesDropped)`.\n *\n * Мультизонный режим: при непустом `zones` оверлей делится на вертикальную стопку\n * равных зон с подписями; зона под курсором подсвечивается, drop эмитится через\n * `(zoneFilesDropped)` с id зоны (а `(filesDropped)` в этом режиме НЕ эмитится).\n * Зона курсора вычисляется по Y-координате против host-rect — оверлей остаётся\n * pointer-events:none, drag-события продолжают идти в host-listener'ы.\n *\n * `accept` (формат как у нативного input[accept]) отфильтровывает неподходящие\n * файлы до эмита — drop в обход файл-пикера не проносит запрещённые расширения;\n * отбрасывание молчаливое, как у самого пикера.\n *\n * Слушает drag-события на собственном host'е (всплывают со всего спроецированного\n * контента), гасит браузерный навигейт по файлу и принимает только перетаскивание\n * файлов (а не внутренний drag элементов формы). Потребитель управляет приёмом\n * через `[disabled]` (например «активна вкладка файлов и форма редактируема») и\n * сам решает, что делать с файлами — компонент состояние файлов не хранит.\n *\n * Оверлей `pointer-events: none` — не перехватывает drag/drop, события доходят до\n * host-listener'ов.\n */\n@Component({\n selector: 'rt-file-drop',\n templateUrl: './rt-file-drop.component.html',\n styleUrl: './rt-file-drop.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtFileDropComponent {\n readonly #destroyRef: DestroyRef = inject(DestroyRef);\n\n readonly #host: ElementRef<HTMLElement> = inject(ElementRef);\n\n readonly #t_uiFileDropOverlay: Signal<string> = rtKitLabel('uiFileDropOverlay');\n\n #dragLeaveTimer: ReturnType<typeof setTimeout> | null = null;\n\n /** Активна ли подсветка drop-зоны (файл тащат над областью). */\n protected readonly isDragging: WritableSignal<boolean> = signal(false);\n\n /** Зона под курсором в мультизонном режиме (id из `zones`). */\n protected readonly activeZoneId: WritableSignal<string | null> = signal(null);\n\n protected readonly hasZones: Signal<boolean> = computed((): boolean => this.zones().length > 0);\n\n protected readonly overlayText: Signal<string> = computed((): string => this.overlayLabel() || this.#t_uiFileDropOverlay());\n\n /** Приём drop'а выключен (потребитель решает по своему контексту). */\n public readonly disabled: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Пусто — берётся переведённая подпись по умолчанию */\n public readonly overlayLabel: InputSignal<string> = input<string>('');\n\n /** Мультизонный режим: непустой список зон делит оверлей на стопку целей. */\n public readonly zones: InputSignal<readonly IRtFileDrop.Zone[]> = input<readonly IRtFileDrop.Zone[]>([]);\n\n /** Фильтр расширений/MIME (формат нативного input[accept]); пусто — без фильтра. */\n public readonly accept: InputSignal<string> = input<string>('');\n\n public readonly filesDropped: OutputEmitterRef<File[]> = output<File[]>();\n\n /** Drop в мультизонном режиме: файлы + id зоны, куда их бросили. */\n public readonly zoneFilesDropped: OutputEmitterRef<IRtFileDrop.ZoneDrop> = output<IRtFileDrop.ZoneDrop>();\n\n public readonly draggingChange: OutputEmitterRef<boolean> = output<boolean>();\n\n constructor() {\n this.#destroyRef.onDestroy((): void => this.#clearLeaveTimer());\n }\n\n @HostListener('dragenter', ['$event'])\n @HostListener('dragover', ['$event'])\n protected onDragOver(event: DragEvent): void {\n if (this.disabled() || !this.#isFileDrag(event)) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'copy';\n }\n this.#clearLeaveTimer();\n this.#setDragging(true);\n if (this.hasZones()) {\n this.activeZoneId.set(this.#zoneIdAt(event.clientY));\n }\n }\n\n @HostListener('dragleave', ['$event'])\n protected onDragLeave(event: DragEvent): void {\n if (!this.isDragging()) {\n return;\n }\n event.preventDefault();\n this.#clearLeaveTimer();\n this.#dragLeaveTimer = setTimeout((): void => {\n this.#dragLeaveTimer = null;\n this.#setDragging(false);\n }, DRAG_LEAVE_DEBOUNCE_MS);\n }\n\n @HostListener('drop', ['$event'])\n protected onDrop(event: DragEvent): void {\n if (this.disabled() || !this.#isFileDrag(event)) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n this.#clearLeaveTimer();\n this.#setDragging(false);\n\n const files: File[] = Array.from(event.dataTransfer?.files ?? []).filter((file: File): boolean => this.#matchesAccept(file));\n if (files.length === 0) {\n return;\n }\n if (!this.hasZones()) {\n this.filesDropped.emit(files);\n return;\n }\n const zoneId: string | null = this.#zoneIdAt(event.clientY);\n if (zoneId === null) {\n return;\n }\n this.zoneFilesDropped.emit({ zoneId, files });\n }\n\n /** Меняет dragging-флаг и эмитит изменение только при реальном переходе. */\n #setDragging(value: boolean): void {\n if (this.isDragging() === value) {\n return;\n }\n this.isDragging.set(value);\n this.draggingChange.emit(value);\n if (!value) {\n this.activeZoneId.set(null);\n }\n }\n\n /** Зона по Y-координате курсора: стопка равных по высоте полос host-rect. */\n #zoneIdAt(clientY: number): string | null {\n const zones: readonly IRtFileDrop.Zone[] = this.zones();\n if (zones.length === 0) {\n return null;\n }\n const rect: DOMRect = this.#host.nativeElement.getBoundingClientRect();\n if (rect.height <= 0) {\n return zones[0].id;\n }\n const ratio: number = (clientY - rect.top) / rect.height;\n const index: number = Math.min(zones.length - 1, Math.max(0, Math.floor(ratio * zones.length)));\n return zones[index].id;\n }\n\n /** Файл проходит accept-фильтр (расширение `.pdf` / MIME `image/png` / `image/*`). */\n #matchesAccept(file: File): boolean {\n const accept: string = this.accept().trim();\n if (accept === '') {\n return true;\n }\n const name: string = file.name.toLowerCase();\n const mime: string = file.type.toLowerCase();\n return accept.split(',').some((raw: string): boolean => {\n const token: string = raw.trim().toLowerCase();\n if (token === '') {\n return false;\n }\n if (token.startsWith('.')) {\n return name.endsWith(token);\n }\n if (token.endsWith('/*')) {\n return mime.startsWith(token.slice(0, -1));\n }\n return mime === token;\n });\n }\n\n /** Перетаскивают именно файлы (а не внутренний drag элементов формы). */\n #isFileDrag(event: DragEvent): boolean {\n const types: readonly string[] | undefined = event.dataTransfer?.types;\n return types?.includes('Files') ?? false;\n }\n\n #clearLeaveTimer(): void {\n if (this.#dragLeaveTimer !== null) {\n clearTimeout(this.#dragLeaveTimer);\n this.#dragLeaveTimer = null;\n }\n }\n}\n","<ng-container rtBlock=\"rt-file-drop\">\n <ng-content />\n\n @if (isDragging()) {\n <div rtElem=\"overlay\" qa-dataid=\"file-drop-overlay\" aria-hidden=\"true\" [rtMod]=\"{ zoned: hasZones() }\">\n @if (hasZones()) {\n @for (zone of zones(); track zone.id) {\n <div\n rtElem=\"zone\"\n qa-dataid=\"file-drop-zone\"\n [attr.data-zone]=\"zone.id\"\n [attr.data-active]=\"activeZoneId() === zone.id\"\n [rtMod]=\"{ active: activeZoneId() === zone.id }\">\n <span rtElem=\"label\" qa-dataid=\"file-drop-zone-label\">{{ zone.label }}</span>\n @if (zone.sublabel) {\n <span rtElem=\"sublabel\" qa-dataid=\"file-drop-zone-sublabel\">{{ zone.sublabel }}</span>\n }\n </div>\n }\n } @else {\n <div rtElem=\"frame\" qa-dataid=\"file-drop-frame\">\n <span rtElem=\"label\" qa-dataid=\"file-drop-label\">{{ overlayText() }}</span>\n </div>\n }\n </div>\n }\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|