@rt-tools/ui-kit-v2 0.16.0 → 0.18.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 +25 -0
- 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 +227 -0
- package/fesm2022/rt-tools-ui-kit-v2-action-bar.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 +702 -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-core.mjs +2590 -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 +937 -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 +674 -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-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 +96 -41
- 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 +196 -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 +91 -23164
- package/fesm2022/rt-tools-ui-kit-v2.mjs.map +1 -1
- package/package.json +349 -1
- package/rt-tools-ui-kit-v2-0.18.0.tgz +0 -0
- package/src/lib/components/action-bar/CONTEXT.md +5 -0
- package/src/lib/components/action-bar/rt-action-bar.component.scss +30 -16
- package/src/lib/components/aside/CONTEXT.md +9 -1
- package/src/lib/components/aside/footer/rt-aside-footer.component.scss +7 -8
- package/src/lib/components/aside/header/rt-aside-header.component.scss +16 -1
- package/src/lib/components/aside/rt-aside.component.scss +17 -1
- package/src/lib/components/button/CONTEXT.md +12 -11
- package/src/lib/components/button/rt-button.directive.scss +36 -0
- package/src/lib/components/data-list/settings/rt-data-list-settings-aside.component.scss +2 -2
- package/src/lib/components/data-table/cell/rt-data-table-cell.component.scss +1 -1
- package/src/lib/components/data-table/filter-cell/rt-data-table-filter-cell.component.scss +1 -1
- package/src/lib/components/data-table/rt-data-table.component.scss +1 -1
- package/src/lib/components/dialog/CONTEXT.md +9 -0
- package/src/lib/components/dialog/content/rt-dialog-content.component.scss +20 -0
- package/src/lib/components/dialog/footer/rt-dialog-footer.component.scss +18 -2
- package/src/lib/components/dialog/header/rt-dialog-header.component.scss +21 -3
- package/src/lib/components/dialog/rt-dialog.component.scss +9 -3
- 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 +6 -0
- package/src/lib/components/field/CONTEXT.md +18 -2
- package/src/lib/components/header/CONTEXT.md +2 -2
- package/src/lib/components/icon/CONTEXT.md +11 -7
- package/src/lib/components/icon/rt-icon.component.scss +47 -0
- package/src/lib/components/icon-button/CONTEXT.md +27 -20
- package/src/lib/components/icon-button/rt-icon-button.component.scss +51 -25
- package/src/lib/components/image-upload/CONTEXT.md +20 -15
- package/src/lib/components/image-upload/rt-image-upload.component.scss +14 -2
- package/src/lib/components/pagination/rt-pagination.component.scss +1 -1
- package/src/lib/components/scroll-area/CONTEXT.md +2 -0
- package/src/lib/components/scroll-area/rt-scroll-area.component.scss +20 -3
- package/src/lib/components/select/rt-select.component.scss +4 -0
- package/src/lib/components/side-menu/CONTEXT.md +7 -2
- package/src/lib/components/spinner/CONTEXT.md +15 -8
- package/src/lib/components/spinner/rt-spinner.component.scss +108 -9
- package/src/lib/components/tag/rt-tag.component.scss +43 -23
- package/src/lib/components/toast/CONTEXT.md +8 -0
- package/src/lib/components/toast/rt-toast.component.scss +74 -15
- package/src/lib/components/toast/rt-toaster.component.scss +5 -1
- package/src/lib/components/toggle-button-group/rt-toggle-button-group.component.scss +35 -37
- package/src/lib/components/toggle-switch/CONTEXT.md +11 -3
- package/src/lib/components/toggle-switch/rt-toggle-switch.component.scss +53 -14
- package/src/lib/components/toolbar/rt-toolbar.component.scss +15 -4
- package/src/lib/components/tooltip/CONTEXT.md +5 -5
- package/src/rich-editor/lib/components/chat/CONTEXT.md +7 -2
- package/src/rich-editor/lib/components/chat/rt-chat.component.scss +25 -0
- package/src/styles/_semantic.scss +1 -1
- package/styles/tokens.css +43 -8
- package/types/rt-tools-ui-kit-v2-accordion.d.ts +30 -0
- package/types/rt-tools-ui-kit-v2-action-bar.d.ts +140 -0
- package/types/rt-tools-ui-kit-v2-aside-section.d.ts +25 -0
- package/types/rt-tools-ui-kit-v2-aside.d.ts +436 -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-core.d.ts +1222 -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 +384 -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 +238 -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-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 +16 -20
- 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 +111 -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 +87 -9290
- package/rt-tools-ui-kit-v2-0.16.0.tgz +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-image-cropper.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/image-cropper/rt-image-cropper.logic.ts","../../../projects/ui-kit-v2/src/lib/components/image-cropper/rt-image-cropper.component.ts","../../../projects/ui-kit-v2/src/lib/components/image-cropper/rt-image-cropper.component.html","../../../projects/ui-kit-v2/src/lib/components/image-cropper/rt-tools-ui-kit-v2-image-cropper.ts"],"sourcesContent":["import { IRtImageCropper } from './rt-image-cropper.model';\n\n/**\n * Чистая логика обрезки: вписывание исходника в поле, рамка в пикселях\n * исходника, её движение и растяжение, перевод клавиш и выбор формата.\n * Компонент только переводит указатель в сдвиги и рисует то, что вернулось.\n */\n\n/** Все восемь ручек по часовой стрелке от левого верхнего угла */\nexport const RT_IMAGE_CROPPER_HANDLES: readonly IRtImageCropper.Handle[] = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'];\n\n/** Шаг клавиш в пикселях поля: стрелка и стрелка с Shift */\nexport const RT_IMAGE_CROPPER_KEY_STEP: number = 1;\nexport const RT_IMAGE_CROPPER_KEY_STEP_LARGE: number = 10;\n\n/** Качество по умолчанию — то же, что у загрузчика первого кита */\nexport const RT_IMAGE_CROPPER_QUALITY: number = 92;\n\nconst OWN_TYPES: readonly string[] = ['image/png', 'image/jpeg', 'image/webp'];\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n\n/**\n * Вписывает исходник в поле целиком, с его пропорциями, по центру. Ни одна часть\n * картинки не срезается полем, и ни одна не растянута.\n */\nexport function fitSource(source: IRtImageCropper.Size, field: IRtImageCropper.Size): IRtImageCropper.Fit {\n if (source.width <= 0 || source.height <= 0 || field.width <= 0 || field.height <= 0) {\n return { scale: 0, offsetX: 0, offsetY: 0, width: 0, height: 0 };\n }\n const scale: number = Math.min(field.width / source.width, field.height / source.height);\n const width: number = source.width * scale;\n const height: number = source.height * scale;\n return { offsetX: (field.width - width) / 2, offsetY: (field.height - height) / 2, scale, width, height };\n}\n\n/**\n * Пропорция, которую держит рамка. Круглый вид держит один к одному при любой\n * заданной; заданная не числом или не больше нуля значит свободную рамку.\n */\nexport function frameRatio(ratio: number | null | undefined, round: boolean): number | null {\n if (round) {\n return 1;\n }\n return typeof ratio === 'number' && Number.isFinite(ratio) && ratio > 0 ? ratio : null;\n}\n\n/**\n * Начальная рамка — наибольшая, какую позволяет пропорция, по центру исходника.\n * Свободная начинается как весь исходник.\n */\nexport function initialFrame(source: IRtImageCropper.Size, ratio: number | null): IRtImageCropper.Rect {\n if (ratio === null) {\n return { x: 0, y: 0, width: source.width, height: source.height };\n }\n const width: number = Math.min(source.width, source.height * ratio);\n const height: number = width / ratio;\n return { x: (source.width - width) / 2, y: (source.height - height) / 2, width, height };\n}\n\n/** Сдвиг рамки целиком: размер тот же, у края исходника рамка останавливается */\nexport function moveFrame(frame: IRtImageCropper.Rect, delta: IRtImageCropper.Delta, source: IRtImageCropper.Size): IRtImageCropper.Rect {\n return {\n x: clamp(frame.x + delta.dx, 0, Math.max(0, source.width - frame.width)),\n y: clamp(frame.y + delta.dy, 0, Math.max(0, source.height - frame.height)),\n width: frame.width,\n height: frame.height,\n };\n}\n\n/** Знак оси по ручке: к концу оси, к началу, или ось не тянется */\nfunction axisSign(handle: IRtImageCropper.Handle, forward: string, backward: string): number {\n if (handle.includes(forward)) {\n return 1;\n }\n return handle.includes(backward) ? -1 : 0;\n}\n\n/** По каким осям и в какую сторону тянет ручка */\nexport function handleDirection(handle: IRtImageCropper.Handle): IRtImageCropper.Direction {\n return { x: axisSign(handle, 'e', 'w'), y: axisSign(handle, 's', 'n') };\n}\n\n/**\n * Наибольший размер по оси: от неподвижной стороны до края исходника, а для оси,\n * которую ручка не тянет, — удвоенное расстояние от центра до ближнего края.\n */\nfunction axisRoom(start: number, size: number, limit: number, direction: number): number {\n if (direction > 0) {\n return limit - start;\n }\n if (direction < 0) {\n return start + size;\n }\n const centre: number = start + size / 2;\n return 2 * Math.min(centre, limit - centre);\n}\n\n/** Где рамка встаёт на оси: от неподвижной стороны, или вокруг центра для оси, которую ручка не тянет */\nfunction axisStart(start: number, size: number, next: number, direction: number): number {\n if (direction > 0) {\n return start;\n }\n if (direction < 0) {\n return start + size - next;\n }\n return start + size / 2 - next / 2;\n}\n\n/** Свободная рамка: каждая ось тянется сама, ось без ручки остаётся как была */\nfunction resizeFree(\n frame: IRtImageCropper.Rect,\n direction: IRtImageCropper.Direction,\n delta: IRtImageCropper.Delta,\n source: IRtImageCropper.Size,\n least: number\n): IRtImageCropper.Rect {\n let { x, y, width, height }: IRtImageCropper.Rect = frame;\n if (direction.x !== 0) {\n const room: number = axisRoom(frame.x, frame.width, source.width, direction.x);\n width = clamp(frame.width + direction.x * delta.dx, Math.min(least, room), room);\n x = axisStart(frame.x, frame.width, width, direction.x);\n }\n if (direction.y !== 0) {\n const room: number = axisRoom(frame.y, frame.height, source.height, direction.y);\n height = clamp(frame.height + direction.y * delta.dy, Math.min(least, room), room);\n y = axisStart(frame.y, frame.height, height, direction.y);\n }\n return { x, y, width, height };\n}\n\n/**\n * Ширина, которую просит сдвиг при заданной пропорции. Угол берёт ту ось, по\n * которой сдвиг больше; сторона — свою ось.\n */\nfunction wantedRatioWidth(\n frame: IRtImageCropper.Rect,\n direction: IRtImageCropper.Direction,\n delta: IRtImageCropper.Delta,\n ratio: number\n): number {\n const byWidth: number = frame.width + direction.x * delta.dx;\n const byHeight: number = (frame.height + direction.y * delta.dy) * ratio;\n if (direction.x === 0) {\n return byHeight;\n }\n if (direction.y === 0) {\n return byWidth;\n }\n return Math.abs(delta.dx) >= Math.abs(delta.dy * ratio) ? byWidth : byHeight;\n}\n\n/**\n * Растяжение рамки за ручку. Сторона или угол напротив ручки стоит на месте;\n * рамка не выходит за исходник и не становится меньше наименьшего размера; рамка\n * с пропорцией держит её, а боковая ручка тянет её вокруг центра второй оси.\n */\nexport function resizeFrame(\n frame: IRtImageCropper.Rect,\n handle: IRtImageCropper.Handle,\n delta: IRtImageCropper.Delta,\n source: IRtImageCropper.Size,\n ratio: number | null,\n minSize: number\n): IRtImageCropper.Rect {\n const direction: IRtImageCropper.Direction = handleDirection(handle);\n const least: number = Math.max(0, minSize);\n if (ratio === null) {\n return resizeFree(frame, direction, delta, source, least);\n }\n const roomWidth: number = Math.min(\n axisRoom(frame.x, frame.width, source.width, direction.x),\n axisRoom(frame.y, frame.height, source.height, direction.y) * ratio\n );\n const leastWidth: number = Math.min(Math.max(least, least * ratio), roomWidth);\n const width: number = clamp(wantedRatioWidth(frame, direction, delta, ratio), leastWidth, roomWidth);\n const height: number = width / ratio;\n return {\n x: axisStart(frame.x, frame.width, width, direction.x),\n y: axisStart(frame.y, frame.height, height, direction.y),\n width,\n height,\n };\n}\n\n/**\n * Сдвиг от стрелки клавиатуры в пикселях исходника. Одно нажатие — пиксель поля,\n * с Shift десять; не стрелка даёт `null`.\n */\nexport function keyDelta(key: string, isLarge: boolean, scale: number): IRtImageCropper.Delta | null {\n if (scale <= 0) {\n return null;\n }\n const step: number = (isLarge ? RT_IMAGE_CROPPER_KEY_STEP_LARGE : RT_IMAGE_CROPPER_KEY_STEP) / scale;\n switch (key) {\n case 'ArrowLeft':\n return { dx: -step, dy: 0 };\n case 'ArrowRight':\n return { dx: step, dy: 0 };\n case 'ArrowUp':\n return { dx: 0, dy: -step };\n case 'ArrowDown':\n return { dx: 0, dy: step };\n default:\n return null;\n }\n}\n\n/** Сдвиг указателя в пикселях поля переводится в пиксели исходника */\nexport function fieldDelta(dx: number, dy: number, scale: number): IRtImageCropper.Delta {\n return scale > 0 ? { dx: dx / scale, dy: dy / scale } : { dx: 0, dy: 0 };\n}\n\n/** Рамка в пикселях поля — для рисования поверх вписанной картинки */\nexport function frameInField(frame: IRtImageCropper.Rect, fit: IRtImageCropper.Fit): IRtImageCropper.Rect {\n return {\n x: fit.offsetX + frame.x * fit.scale,\n y: fit.offsetY + frame.y * fit.scale,\n width: frame.width * fit.scale,\n height: frame.height * fit.scale,\n };\n}\n\n/** Рамка в целых пикселях исходника — то, что вырезает холст; не меньше пикселя */\nexport function cropArea(frame: IRtImageCropper.Rect, source: IRtImageCropper.Size): IRtImageCropper.Rect {\n const x: number = clamp(Math.round(frame.x), 0, Math.max(0, source.width - 1));\n const y: number = clamp(Math.round(frame.y), 0, Math.max(0, source.height - 1));\n return {\n x,\n y,\n width: clamp(Math.round(frame.width), 1, Math.max(1, source.width - x)),\n height: clamp(Math.round(frame.height), 1, Math.max(1, source.height - y)),\n };\n}\n\n/**\n * Тип результата. Без выбранного формата берётся формат исходника, и png, когда\n * он не из трёх.\n */\nexport function resultType(format: IRtImageCropper.Format | null | undefined, sourceType: string): string {\n if (format) {\n return `image/${format}`;\n }\n return OWN_TYPES.includes(sourceType) ? sourceType : 'image/png';\n}\n\n/** Качество холста — доля единицы; вход берёт проценты */\nexport function resultQuality(quality: number): number {\n return Number.isFinite(quality) ? clamp(quality, 0, 100) / 100 : RT_IMAGE_CROPPER_QUALITY / 100;\n}\n\n/** Имя файла результата: основа имени исходника и расширение по типу результата */\nexport function resultFileName(sourceName: string, type: string): string {\n const extension: string = type === 'image/jpeg' ? 'jpg' : type.replace('image/', '');\n const dot: number = sourceName.lastIndexOf('.');\n let base: string = sourceName || 'image';\n if (dot > 0) {\n base = sourceName.slice(0, dot);\n }\n return `${base}.${extension}`;\n}\n","import { BooleanInput, NumberInput } from '@angular/cdk/coercion';\nimport { DOCUMENT } from '@angular/common';\nimport {\n afterNextRender,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n effect,\n ElementRef,\n inject,\n input,\n InputSignal,\n InputSignalWithTransform,\n numberAttribute,\n output,\n OutputEmitterRef,\n Signal,\n signal,\n untracked,\n viewChild,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective, PlatformService, WINDOW } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelKey, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { RtSpinnerComponent } from '@rt-tools/ui-kit-v2/spinner';\nimport {\n cropArea,\n fieldDelta,\n fitSource,\n frameInField,\n frameRatio,\n initialFrame,\n keyDelta,\n moveFrame,\n resizeFrame,\n resultFileName,\n resultQuality,\n resultType,\n RT_IMAGE_CROPPER_HANDLES,\n RT_IMAGE_CROPPER_QUALITY,\n} from './rt-image-cropper.logic';\nimport { IRtImageCropper } from './rt-image-cropper.model';\n\nconst BEM_BLOCK: string = 'rt-image-cropper';\n\n/** Наименьший размер рамки по умолчанию, в пикселях исходника */\nconst DEFAULT_MIN_SIZE: number = 16;\n\n/** Подпись каждой ручки — ключ словаря кита */\nconst HANDLE_LABELS: Readonly<Record<IRtImageCropper.Handle, TRtKitLabelKey>> = {\n n: 'uiImageCropperHandleN',\n s: 'uiImageCropperHandleS',\n e: 'uiImageCropperHandleE',\n w: 'uiImageCropperHandleW',\n ne: 'uiImageCropperHandleNe',\n nw: 'uiImageCropperHandleNw',\n se: 'uiImageCropperHandleSe',\n sw: 'uiImageCropperHandleSw',\n};\n\n/** Состояние поля: пусто, читается, не прочиталось, готово */\ntype TCropperState = 'empty' | 'loading' | 'refusal' | 'ready';\n\n/** Жест, который сейчас идёт: что тянут, откуда и какая рамка была на старте */\ninterface IDrag {\n readonly pointerId: number;\n readonly handle: IRtImageCropper.Handle | null;\n readonly startX: number;\n readonly startY: number;\n readonly startFrame: IRtImageCropper.Rect;\n}\n\nfunction sameRect(a: IRtImageCropper.Rect, b: IRtImageCropper.Rect): boolean {\n return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;\n}\n\nfunction optionalNumber(value: NumberInput): number | null {\n return value === null || value === undefined || value === '' ? null : numberAttribute(value, 0);\n}\n\n/**\n * Обрезка изображения: исходник вписан в поле целиком, поверх — рамка с восемью\n * ручками. Рамка живёт в пикселях исходника и двигается указателем, пальцем и\n * стрелками; после прочтения исходника и после каждого законченного изменения\n * компонент отдаёт файл, вырезанный рамкой, в выбранном формате и качестве.\n *\n * Поворот снимка по EXIF делает сам браузер: картинка и холст читают исходник с\n * `image-orientation: from-image`, и размеры, которые видит логика, уже\n * повёрнутые.\n */\n@Component({\n selector: 'rt-image-cropper',\n templateUrl: './rt-image-cropper.component.html',\n styleUrl: './rt-image-cropper.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n BlockDirective,\n ElemDirective,\n ModDirective,\n RtSpinnerComponent,\n ],\n host: {\n class: BEM_BLOCK,\n '[class.rt-image-cropper--round]': 'round()',\n '[class.rt-image-cropper--disabled]': 'disabled()',\n '[style.--rt-image-cropper-image-x]': \"image().x + 'px'\",\n '[style.--rt-image-cropper-image-y]': \"image().y + 'px'\",\n '[style.--rt-image-cropper-image-width]': \"image().width + 'px'\",\n '[style.--rt-image-cropper-image-height]': \"image().height + 'px'\",\n '[style.--rt-image-cropper-frame-x]': \"frameBox().x + 'px'\",\n '[style.--rt-image-cropper-frame-y]': \"frameBox().y + 'px'\",\n '[style.--rt-image-cropper-frame-width]': \"frameBox().width + 'px'\",\n '[style.--rt-image-cropper-frame-height]': \"frameBox().height + 'px'\",\n },\n})\nexport class RtImageCropperComponent {\n readonly #destroyRef: DestroyRef = inject(DestroyRef);\n\n readonly #window: Window & typeof globalThis = inject(WINDOW) as Window & typeof globalThis;\n\n readonly #document: Document = inject(DOCUMENT);\n\n readonly #platform: PlatformService = inject(PlatformService);\n\n readonly #fieldSize: WritableSignal<IRtImageCropper.Size> = signal({ width: 0, height: 0 });\n\n readonly #source: WritableSignal<IRtImageCropper.Size> = signal({ width: 0, height: 0 });\n\n readonly #frame: WritableSignal<IRtImageCropper.Rect> = signal({ x: 0, y: 0, width: 0, height: 0 });\n\n readonly #ratio: Signal<number | null> = computed((): number | null => frameRatio(this.ratio(), this.round()));\n\n readonly #fit: Signal<IRtImageCropper.Fit> = computed((): IRtImageCropper.Fit => fitSource(this.#source(), this.#fieldSize()));\n\n #image: HTMLImageElement | null = null;\n\n /** Картинка, которая сейчас читается: ответ прежней после смены исходника не принимается */\n #pending: HTMLImageElement | null = null;\n\n #sourceType: string = '';\n\n #sourceName: string = '';\n\n #drag: IDrag | null = null;\n\n /** Номер последнего запроса результата: поздний ответ холста по старой рамке отбрасывается */\n #resultTicket: number = 0;\n\n protected readonly field: Signal<ElementRef<HTMLElement>> = viewChild.required<ElementRef<HTMLElement>>('field');\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly handles: readonly IRtImageCropper.Handle[] = RT_IMAGE_CROPPER_HANDLES;\n\n protected readonly handleLabels: Readonly<Record<IRtImageCropper.Handle, TRtKitLabelKey>> = HANDLE_LABELS;\n\n protected readonly state: WritableSignal<TCropperState> = signal('empty');\n\n /** Текст пустого поля: свой, если задан, иначе подпись кита */\n protected readonly placeholderText: Signal<string> = computed((): string => this.placeholder() || this.t().uiImageCropperPlaceholder);\n\n /** Адрес исходника для картинки в поле */\n protected readonly url: WritableSignal<string | null> = signal(null);\n\n /** Где картинка лежит в поле, в пикселях поля */\n protected readonly image: Signal<IRtImageCropper.Rect> = computed((): IRtImageCropper.Rect => {\n const fit: IRtImageCropper.Fit = this.#fit();\n return { x: fit.offsetX, y: fit.offsetY, width: fit.width, height: fit.height };\n });\n\n /** Рамка в пикселях поля */\n protected readonly frameBox: Signal<IRtImageCropper.Rect> = computed((): IRtImageCropper.Rect =>\n frameInField(this.#frame(), this.#fit())\n );\n\n /** Подсказка пустого поля; пусто — подпись кита `uiImageCropperPlaceholder` */\n public readonly placeholder: InputSignal<string> = input<string>('');\n\n /** Исходник: файл, который надо обрезать; пусто — поле с подсказкой */\n public readonly file: InputSignal<Blob | null> = input<Blob | null>(null);\n\n /** Пропорция рамки, ширина к высоте; пусто — рамка свободная */\n public readonly ratio: InputSignalWithTransform<number | null, NumberInput> = input<number | null, NumberInput>(null, {\n transform: optionalNumber,\n });\n\n /** Круглый вид: маска на экране и пропорция один к одному; результат — квадрат */\n public readonly round: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Наименьший размер рамки в пикселях исходника */\n public readonly minSize: InputSignalWithTransform<number, NumberInput> = input<number, NumberInput>(DEFAULT_MIN_SIZE, {\n transform: (value: NumberInput): number => numberAttribute(value, DEFAULT_MIN_SIZE),\n });\n\n /** Формат результата; пусто — формат исходника, png, когда он не из трёх */\n public readonly format: InputSignal<IRtImageCropper.Format | null> = input<IRtImageCropper.Format | null>(null);\n\n /** Качество результата в процентах — для jpeg и webp */\n public readonly quality: InputSignalWithTransform<number, NumberInput> = input<number, NumberInput>(RT_IMAGE_CROPPER_QUALITY, {\n transform: (value: NumberInput): number => numberAttribute(value, RT_IMAGE_CROPPER_QUALITY),\n });\n\n /** Недоступна: рамка видна, но не меняется ни указателем, ни клавишами */\n public readonly disabled: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Файл, вырезанный рамкой: после прочтения исходника и после каждого законченного изменения */\n public readonly cropped: OutputEmitterRef<IRtImageCropper.Result> = output<IRtImageCropper.Result>();\n\n /** Исходник не прочитался */\n public readonly loadFailed: OutputEmitterRef<void> = output<void>();\n\n constructor() {\n effect((): void => {\n const file: Blob | null = this.file();\n untracked((): void => this.#load(file));\n });\n\n effect((): void => {\n const ratio: number | null = this.#ratio();\n untracked((): void => {\n if (this.state() === 'ready') {\n this.#frame.set(initialFrame(this.#source(), ratio));\n this.#emitResult();\n }\n });\n });\n\n afterNextRender((): void => this.#observe(this.field().nativeElement));\n\n this.#destroyRef.onDestroy((): void => this.#revoke());\n }\n\n protected onPointerDown(event: PointerEvent, handle: IRtImageCropper.Handle | null): void {\n if (this.disabled() || this.#drag !== null || (event.pointerType === 'mouse' && event.button !== 0)) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n const target: EventTarget | null = event.currentTarget;\n if (target instanceof this.#window.HTMLElement && typeof target.setPointerCapture === 'function') {\n target.setPointerCapture(event.pointerId);\n }\n this.#drag = { pointerId: event.pointerId, startX: event.clientX, startY: event.clientY, startFrame: this.#frame(), handle };\n }\n\n protected onPointerMove(event: PointerEvent): void {\n const drag: IDrag | null = this.#drag;\n if (drag === null || drag.pointerId !== event.pointerId) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n const delta: IRtImageCropper.Delta = fieldDelta(event.clientX - drag.startX, event.clientY - drag.startY, this.#fit().scale);\n this.#frame.set(this.#change(drag.startFrame, drag.handle, delta));\n }\n\n protected onPointerUp(event: PointerEvent): void {\n const drag: IDrag | null = this.#drag;\n if (drag === null || drag.pointerId !== event.pointerId) {\n return;\n }\n event.stopPropagation();\n this.#drag = null;\n const target: EventTarget | null = event.currentTarget;\n if (target instanceof this.#window.HTMLElement && typeof target.releasePointerCapture === 'function') {\n target.releasePointerCapture(event.pointerId);\n }\n if (!sameRect(drag.startFrame, this.#frame())) {\n this.#emitResult();\n }\n }\n\n protected onKeyDown(event: KeyboardEvent, handle: IRtImageCropper.Handle | null): void {\n if (this.disabled()) {\n return;\n }\n const delta: IRtImageCropper.Delta | null = keyDelta(event.key, event.shiftKey, this.#fit().scale);\n if (delta === null) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n const before: IRtImageCropper.Rect = this.#frame();\n const next: IRtImageCropper.Rect = this.#change(before, handle, delta);\n if (!sameRect(before, next)) {\n this.#frame.set(next);\n this.#emitResult();\n }\n }\n\n /** Одна точка для указателя и клавиш: внутри рамки — сдвиг, на ручке — растяжение */\n #change(frame: IRtImageCropper.Rect, handle: IRtImageCropper.Handle | null, delta: IRtImageCropper.Delta): IRtImageCropper.Rect {\n return handle === null\n ? moveFrame(frame, delta, this.#source())\n : resizeFrame(frame, handle, delta, this.#source(), this.#ratio(), this.minSize());\n }\n\n #load(file: Blob | null): void {\n this.#revoke();\n this.#image = null;\n this.#pending = null;\n this.#drag = null;\n this.#resultTicket++;\n if (file === null || !this.#platform.isPlatformBrowser) {\n this.state.set('empty');\n return;\n }\n this.#sourceType = file.type;\n this.#sourceName = file instanceof this.#window.File ? file.name : '';\n const url: string = this.#window.URL.createObjectURL(file);\n const image: HTMLImageElement = new this.#window.Image();\n this.#pending = image;\n this.url.set(url);\n this.state.set('loading');\n image.onload = (): void => {\n if (this.#pending === image) {\n this.#pending = null;\n this.#ready(image);\n }\n };\n image.onerror = (): void => {\n if (this.#pending === image) {\n this.#pending = null;\n this.#refuse();\n }\n };\n image.src = url;\n }\n\n #ready(image: HTMLImageElement): void {\n if (image.naturalWidth <= 0 || image.naturalHeight <= 0) {\n this.#refuse();\n return;\n }\n this.#image = image;\n this.#source.set({ width: image.naturalWidth, height: image.naturalHeight });\n this.#frame.set(initialFrame(this.#source(), this.#ratio()));\n this.state.set('ready');\n this.#emitResult();\n }\n\n #refuse(): void {\n this.state.set('refusal');\n this.loadFailed.emit();\n }\n\n #revoke(): void {\n const url: string | null = this.url();\n if (url !== null) {\n this.#window.URL.revokeObjectURL(url);\n this.url.set(null);\n }\n }\n\n #observe(field: HTMLElement): void {\n const measure: () => void = (): void => this.#fieldSize.set({ width: field.clientWidth, height: field.clientHeight });\n measure();\n if (typeof this.#window.ResizeObserver !== 'function') {\n return;\n }\n const observer: ResizeObserver = new this.#window.ResizeObserver(measure);\n observer.observe(field);\n this.#destroyRef.onDestroy((): void => observer.disconnect());\n }\n\n /** Вырезает рамку холстом и отдаёт файл; ответ по устаревшей рамке не выходит */\n #emitResult(): void {\n const image: HTMLImageElement | null = this.#image;\n if (image === null) {\n return;\n }\n this.#resultTicket++;\n const ticket: number = this.#resultTicket;\n const area: IRtImageCropper.Rect = cropArea(this.#frame(), this.#source());\n const canvas: HTMLCanvasElement = this.#document.createElement('canvas');\n canvas.width = area.width;\n canvas.height = area.height;\n const context: CanvasRenderingContext2D | null = canvas.getContext('2d');\n if (context === null) {\n return;\n }\n context.drawImage(image, area.x, area.y, area.width, area.height, 0, 0, area.width, area.height);\n const type: string = resultType(this.format(), this.#sourceType);\n canvas.toBlob(\n (blob: Blob | null): void => {\n if (blob === null || ticket !== this.#resultTicket) {\n return;\n }\n const file: File = new this.#window.File([blob], resultFileName(this.#sourceName, type), { type });\n this.cropped.emit({ file, frame: area });\n },\n type,\n resultQuality(this.quality())\n );\n }\n}\n","<ng-container rtBlock=\"rt-image-cropper\">\n <div #field rtElem=\"field\" qa-dataid=\"image-cropper-field\">\n @switch (state()) {\n @case ('empty') {\n <p rtElem=\"placeholder\" qa-dataid=\"image-cropper-placeholder\">{{ placeholderText() }}</p>\n }\n @case ('loading') {\n <rt-spinner rtElem=\"spinner\" qa-dataid=\"image-cropper-spinner\" />\n }\n @case ('refusal') {\n <p rtElem=\"refusal\" qa-dataid=\"image-cropper-refusal\">{{ t().uiImageCropperRefusal }}</p>\n }\n @case ('ready') {\n <img rtElem=\"image\" qa-dataid=\"image-cropper-image\" alt=\"\" draggable=\"false\" [src]=\"url()\" />\n <div\n rtElem=\"frame\"\n qa-dataid=\"image-cropper-frame\"\n role=\"group\"\n [attr.aria-label]=\"t().uiImageCropperFrame\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event, null)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n (pointercancel)=\"onPointerUp($event)\"\n (keydown)=\"onKeyDown($event, null)\">\n @for (handle of handles; track handle) {\n <span\n rtElem=\"handle\"\n role=\"button\"\n [attr.qa-dataid]=\"'image-cropper-handle-' + handle\"\n [rtMod]=\"{ side: handle }\"\n [attr.aria-label]=\"t()[handleLabels[handle]]\"\n [attr.aria-disabled]=\"disabled() || null\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n (pointerdown)=\"onPointerDown($event, handle)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n (pointercancel)=\"onPointerUp($event)\"\n (keydown)=\"onKeyDown($event, handle)\"></span>\n }\n </div>\n }\n }\n </div>\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,227 @@
|
|
|
1
|
+
import { DOCUMENT } from '@angular/common';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { inject, viewChild, signal, computed, linkedSignal, input, booleanAttribute, numberAttribute, output, DestroyRef, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
4
|
+
import { WINDOW, BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';
|
|
5
|
+
import { RT_KIT_LABELS } from '@rt-tools/ui-kit-v2/core';
|
|
6
|
+
import { RtButtonDirective } from '@rt-tools/ui-kit-v2/button';
|
|
7
|
+
import { RtEmptyStateComponent } from '@rt-tools/ui-kit-v2/empty-state';
|
|
8
|
+
import { RtFileDropComponent } from '@rt-tools/ui-kit-v2/file-drop';
|
|
9
|
+
import { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';
|
|
10
|
+
import { RT_IMAGE_CROPPER_QUALITY, RtImageCropperComponent } from '@rt-tools/ui-kit-v2/image-cropper';
|
|
11
|
+
import { RtSpinnerComponent } from '@rt-tools/ui-kit-v2/spinner';
|
|
12
|
+
import { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Какое состояние занимает место. Загрузка приложения важнее всего, выбранный исходник важнее
|
|
16
|
+
* картинки, картинка важнее зоны загрузки.
|
|
17
|
+
*/
|
|
18
|
+
function uploadState(loading, hasSource, image) {
|
|
19
|
+
if (loading) {
|
|
20
|
+
return 'loading';
|
|
21
|
+
}
|
|
22
|
+
if (hasSource) {
|
|
23
|
+
return 'cropping';
|
|
24
|
+
}
|
|
25
|
+
return image ? 'image' : 'empty';
|
|
26
|
+
}
|
|
27
|
+
/** Берётся только файл изображения: брошенный файл другого типа загрузчик пропускает */
|
|
28
|
+
function isImageFile(file) {
|
|
29
|
+
return !!file && file.type.startsWith('image/');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const BEM_BLOCK = 'rt-image-upload';
|
|
33
|
+
/**
|
|
34
|
+
* Загрузчик одного изображения: одно место, в котором по очереди стоят зона загрузки, обрезка и
|
|
35
|
+
* сама картинка. Файл выбирают кнопкой зоны или бросают на неё; выбранный открывает обрезку, а
|
|
36
|
+
* «Применить» ставит результат на место картинки и отдаёт файл приложению. Нажатие на картинку
|
|
37
|
+
* выбирает другой файл.
|
|
38
|
+
*
|
|
39
|
+
* Картинка — адрес: приложение даёт свой, а адрес применённого файла загрузчик делает сам и
|
|
40
|
+
* отпускает его, когда картинку сменили или компонент ушёл. Файл приложение получает в
|
|
41
|
+
* `imageChanged`.
|
|
42
|
+
*/
|
|
43
|
+
class RtImageUploadComponent {
|
|
44
|
+
#window;
|
|
45
|
+
#document;
|
|
46
|
+
/** Адрес, сделанный загрузчиком под применённый файл: его и только его он отпускает */
|
|
47
|
+
#ownUrl;
|
|
48
|
+
constructor() {
|
|
49
|
+
this.#window = inject(WINDOW);
|
|
50
|
+
this.#document = inject(DOCUMENT);
|
|
51
|
+
/** Адрес, сделанный загрузчиком под применённый файл: его и только его он отпускает */
|
|
52
|
+
this.#ownUrl = null;
|
|
53
|
+
this.picker = viewChild.required('picker', /* @ts-ignore */
|
|
54
|
+
...(ngDevMode ? [{ debugName: "picker" }] : /* istanbul ignore next */ []));
|
|
55
|
+
this.t = inject(RT_KIT_LABELS);
|
|
56
|
+
/** Выбранный файл, который сейчас режет обрезка */
|
|
57
|
+
this.source = signal(null, /* @ts-ignore */
|
|
58
|
+
...(ngDevMode ? [{ debugName: "source" }] : /* istanbul ignore next */ []));
|
|
59
|
+
/** Последний результат обрезки — его берёт «Применить» */
|
|
60
|
+
this.result = signal(null, /* @ts-ignore */
|
|
61
|
+
...(ngDevMode ? [{ debugName: "result" }] : /* istanbul ignore next */ []));
|
|
62
|
+
/** Что сейчас стоит в месте загрузчика */
|
|
63
|
+
this.state = computed(() => uploadState(this.loading(), this.source() !== null, this.image()), /* @ts-ignore */
|
|
64
|
+
...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
|
|
65
|
+
/** Подсказка над картинкой: своя приложения или подпись кита */
|
|
66
|
+
this.hint = computed(() => this.tooltip() || this.t().uiImageUploadChange, /* @ts-ignore */
|
|
67
|
+
...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
68
|
+
/** Круглая ли кнопка скачивания: подложка под размытием повторяет её скругление */
|
|
69
|
+
this.downloadRound = computed(() => this.downloadShape() === 'circle', /* @ts-ignore */
|
|
70
|
+
...(ngDevMode ? [{ debugName: "downloadRound" }] : /* istanbul ignore next */ []));
|
|
71
|
+
/** Шаг скругления кнопки скачивания: круг — полный шаг, квадрат — скругление кнопки по умолчанию */
|
|
72
|
+
this.downloadRadius = computed(() => (this.downloadRound() ? 'full' : null), /* @ts-ignore */
|
|
73
|
+
...(ngDevMode ? [{ debugName: "downloadRadius" }] : /* istanbul ignore next */ []));
|
|
74
|
+
/**
|
|
75
|
+
* Адрес текущей картинки: данный приложением или сделанный под применённый файл. Новый адрес от
|
|
76
|
+
* приложения снова берёт верх над применённым.
|
|
77
|
+
*/
|
|
78
|
+
this.image = linkedSignal(() => this.imageUrl(), /* @ts-ignore */
|
|
79
|
+
...(ngDevMode ? [{ debugName: "image" }] : /* istanbul ignore next */ []));
|
|
80
|
+
/** Адрес картинки от приложения */
|
|
81
|
+
this.imageUrl = input(null, /* @ts-ignore */
|
|
82
|
+
...(ngDevMode ? [{ debugName: "imageUrl" }] : /* istanbul ignore next */ []));
|
|
83
|
+
/** Имя файла, под которым картинку скачивают и отдают приложению */
|
|
84
|
+
this.fileName = input('image', /* @ts-ignore */
|
|
85
|
+
...(ngDevMode ? [{ debugName: "fileName" }] : /* istanbul ignore next */ []));
|
|
86
|
+
/** Подсказка над картинкой; пустая — подпись кита */
|
|
87
|
+
this.tooltip = input('', /* @ts-ignore */
|
|
88
|
+
...(ngDevMode ? [{ debugName: "tooltip" }] : /* istanbul ignore next */ []));
|
|
89
|
+
/** Кнопка скачивания рядом с картинкой */
|
|
90
|
+
this.downloadable = input(false, { ...(ngDevMode ? { debugName: "downloadable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
91
|
+
/** Форма кнопки скачивания; она заходит за правый верхний угол картинки при любой форме */
|
|
92
|
+
this.downloadShape = input('circle', /* @ts-ignore */
|
|
93
|
+
...(ngDevMode ? [{ debugName: "downloadShape" }] : /* istanbul ignore next */ []));
|
|
94
|
+
/** Размер значка кнопки скачивания; пусто — от размера кнопки */
|
|
95
|
+
this.downloadIconSize = input(null, /* @ts-ignore */
|
|
96
|
+
...(ngDevMode ? [{ debugName: "downloadIconSize" }] : /* istanbul ignore next */ []));
|
|
97
|
+
/** Вид кнопки выбора файла в пустом загрузчике */
|
|
98
|
+
this.chooseAppearance = input('outlined', /* @ts-ignore */
|
|
99
|
+
...(ngDevMode ? [{ debugName: "chooseAppearance" }] : /* istanbul ignore next */ []));
|
|
100
|
+
/** Значок кнопки выбора файла; пусто — кнопка без значка */
|
|
101
|
+
this.chooseIcon = input('ico-upload', /* @ts-ignore */
|
|
102
|
+
...(ngDevMode ? [{ debugName: "chooseIcon" }] : /* istanbul ignore next */ []));
|
|
103
|
+
/** Без кнопок «Отмена» и «Применить»: каждый результат обрезки применяется сразу */
|
|
104
|
+
this.autoApply = input(false, { ...(ngDevMode ? { debugName: "autoApply" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
105
|
+
/** Приложение загружает картинку: на месте стоит индикатор */
|
|
106
|
+
this.loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
107
|
+
/** Недоступный загрузчик не берёт файлов и не отзывается на нажатие картинки */
|
|
108
|
+
this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
109
|
+
/** Соотношение рамки обрезки; пусто — свободная рамка */
|
|
110
|
+
this.ratio = input(null, { ...(ngDevMode ? { debugName: "ratio" } : /* istanbul ignore next */ {}), transform: (value) => (value === null || value === '' ? null : numberAttribute(value, 0) || null) });
|
|
111
|
+
/** Круглая маска обрезки для аватара */
|
|
112
|
+
this.round = input(false, { ...(ngDevMode ? { debugName: "round" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
113
|
+
/** Формат результата; пусто — формат исходника */
|
|
114
|
+
this.format = input(null, /* @ts-ignore */
|
|
115
|
+
...(ngDevMode ? [{ debugName: "format" }] : /* istanbul ignore next */ []));
|
|
116
|
+
/** Качество результата, от 0 до 100 */
|
|
117
|
+
this.quality = input(RT_IMAGE_CROPPER_QUALITY, { ...(ngDevMode ? { debugName: "quality" } : /* istanbul ignore next */ {}), transform: (value) => numberAttribute(value, RT_IMAGE_CROPPER_QUALITY) });
|
|
118
|
+
/** Применённый файл — его приложение отправляет, куда ему надо */
|
|
119
|
+
this.imageChanged = output();
|
|
120
|
+
/** Картинку скачали */
|
|
121
|
+
this.downloaded = output();
|
|
122
|
+
inject(DestroyRef).onDestroy(() => this.#release());
|
|
123
|
+
}
|
|
124
|
+
/** Открывает выбор файла, если загрузчик доступен */
|
|
125
|
+
pick() {
|
|
126
|
+
if (!this.disabled()) {
|
|
127
|
+
this.picker().nativeElement.click();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/** Файл выбран кнопкой или брошен: изображение открывает обрезку, остальное пропускается */
|
|
131
|
+
choose(file) {
|
|
132
|
+
if (this.disabled() || !isImageFile(file)) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
this.result.set(null);
|
|
136
|
+
this.source.set(file);
|
|
137
|
+
}
|
|
138
|
+
onPicked(event) {
|
|
139
|
+
const input = event.target;
|
|
140
|
+
this.choose(input.files?.[0]);
|
|
141
|
+
// Тот же файл, выбранный второй раз, иначе не даёт события
|
|
142
|
+
input.value = '';
|
|
143
|
+
}
|
|
144
|
+
onSpace(event) {
|
|
145
|
+
event.preventDefault();
|
|
146
|
+
this.pick();
|
|
147
|
+
}
|
|
148
|
+
onCropped(result) {
|
|
149
|
+
this.result.set(result);
|
|
150
|
+
if (this.autoApply()) {
|
|
151
|
+
this.#applyResult(result, false);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
apply() {
|
|
155
|
+
const result = this.result();
|
|
156
|
+
if (result !== null) {
|
|
157
|
+
this.#applyResult(result, true);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
cancel() {
|
|
161
|
+
this.source.set(null);
|
|
162
|
+
this.result.set(null);
|
|
163
|
+
}
|
|
164
|
+
download() {
|
|
165
|
+
const url = this.image();
|
|
166
|
+
if (url === null) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const link = this.#document.createElement('a');
|
|
170
|
+
link.href = url;
|
|
171
|
+
link.download = this.fileName();
|
|
172
|
+
this.#document.body.appendChild(link);
|
|
173
|
+
link.click();
|
|
174
|
+
link.remove();
|
|
175
|
+
this.downloaded.emit();
|
|
176
|
+
}
|
|
177
|
+
/** Результат становится картинкой; `close` убирает обрезку — при автоприменении она остаётся */
|
|
178
|
+
#applyResult(result, close) {
|
|
179
|
+
const file = new File([result.file], this.fileName(), { type: result.file.type });
|
|
180
|
+
this.#release();
|
|
181
|
+
this.#ownUrl = this.#window.URL.createObjectURL(file);
|
|
182
|
+
this.image.set(this.#ownUrl);
|
|
183
|
+
this.imageChanged.emit(file);
|
|
184
|
+
if (close) {
|
|
185
|
+
this.cancel();
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
#release() {
|
|
189
|
+
if (this.#ownUrl !== null) {
|
|
190
|
+
this.#window.URL.revokeObjectURL(this.#ownUrl);
|
|
191
|
+
this.#ownUrl = null;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtImageUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
195
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtImageUploadComponent, isStandalone: true, selector: "rt-image-upload", inputs: { imageUrl: { classPropertyName: "imageUrl", publicName: "imageUrl", isSignal: true, isRequired: false, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null }, downloadable: { classPropertyName: "downloadable", publicName: "downloadable", isSignal: true, isRequired: false, transformFunction: null }, downloadShape: { classPropertyName: "downloadShape", publicName: "downloadShape", isSignal: true, isRequired: false, transformFunction: null }, downloadIconSize: { classPropertyName: "downloadIconSize", publicName: "downloadIconSize", isSignal: true, isRequired: false, transformFunction: null }, chooseAppearance: { classPropertyName: "chooseAppearance", publicName: "chooseAppearance", isSignal: true, isRequired: false, transformFunction: null }, chooseIcon: { classPropertyName: "chooseIcon", publicName: "chooseIcon", isSignal: true, isRequired: false, transformFunction: null }, autoApply: { classPropertyName: "autoApply", publicName: "autoApply", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ratio: { classPropertyName: "ratio", publicName: "ratio", isSignal: true, isRequired: false, transformFunction: null }, round: { classPropertyName: "round", publicName: "round", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, quality: { classPropertyName: "quality", publicName: "quality", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { imageChanged: "imageChanged", downloaded: "downloaded" }, host: { properties: { "class.rt-image-upload--disabled": "disabled()" }, classAttribute: "rt-image-upload" }, viewQueries: [{ propertyName: "picker", first: true, predicate: ["picker"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container rtBlock=\"rt-image-upload\">\n <input\n #picker\n hidden\n type=\"file\"\n accept=\"image/*\"\n qa-dataid=\"image-upload-native\"\n [disabled]=\"disabled()\"\n (change)=\"onPicked($event)\" />\n\n @switch (state()) {\n @case ('loading') {\n <div rtElem=\"loading\" qa-dataid=\"image-upload-loading\">\n <rt-spinner />\n </div>\n }\n @case ('cropping') {\n <rt-image-cropper\n qa-dataid=\"image-upload-cropper\"\n [file]=\"source()\"\n [ratio]=\"ratio()\"\n [round]=\"round()\"\n [format]=\"format()\"\n [quality]=\"quality()\"\n (cropped)=\"onCropped($event)\"\n (loadFailed)=\"cancel()\" />\n\n @if (!autoApply()) {\n <div rtElem=\"actions\">\n <button\n rtButton\n appearance=\"text\"\n type=\"button\"\n qa-dataid=\"image-upload-cancel\"\n [label]=\"t().uiImageUploadCancel\"\n [attr.aria-label]=\"t().uiImageUploadCancel\"\n (click)=\"cancel()\"></button>\n <button\n rtButton\n type=\"button\"\n qa-dataid=\"image-upload-apply\"\n [label]=\"t().uiImageUploadApply\"\n [attr.aria-label]=\"t().uiImageUploadApply\"\n [disabled]=\"!result()\"\n (click)=\"apply()\"></button>\n </div>\n }\n }\n @case ('image') {\n <rt-file-drop accept=\"image/*\" [disabled]=\"disabled()\" (filesDropped)=\"choose($event[0])\">\n <div rtElem=\"preview\">\n <img\n rtElem=\"image\"\n role=\"button\"\n qa-dataid=\"image-upload-image\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.alt]=\"t().uiImageUploadImage\"\n [rtTooltip]=\"disabled() ? '' : hint()\"\n [rtMod]=\"{ active: !disabled() }\"\n [src]=\"image()\"\n (click)=\"pick()\"\n (keydown.enter)=\"pick()\"\n (keydown.space)=\"onSpace($event)\" />\n\n @if (downloadable()) {\n <rt-icon-button\n rtElem=\"download\"\n icon=\"ico-download\"\n qa-dataid=\"image-upload-download\"\n [radius]=\"downloadRadius()\"\n [iconSize]=\"downloadIconSize()\"\n [rtMod]=\"{ round: downloadRound() }\"\n [ariaLabel]=\"t().uiDownload\"\n [tooltip]=\"t().uiDownload\"\n (click)=\"download()\" />\n }\n </div>\n </rt-file-drop>\n }\n @default {\n <rt-file-drop accept=\"image/*\" qa-dataid=\"image-upload-drop\" [disabled]=\"disabled()\" (filesDropped)=\"choose($event[0])\">\n <rt-empty-state framed icon=\"cloud-upload\" [title]=\"t().uiImageUploadDrop\">\n <button\n rtButton\n type=\"button\"\n qa-dataid=\"image-upload-choose\"\n [appearance]=\"chooseAppearance()\"\n [icon]=\"chooseIcon()\"\n [label]=\"t().uiImageUploadChoose\"\n [attr.aria-label]=\"t().uiImageUploadChoose\"\n [disabled]=\"disabled()\"\n (click)=\"pick()\"></button>\n </rt-empty-state>\n </rt-file-drop>\n }\n }\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-image-upload{--rt-image-upload-image-max-height: var(--rt-size-100);--rt-image-upload-image-radius: var(--rt-radius-md);--rt-image-upload-focus-shadow: var(--rt-shadow-focus-ring);--rt-image-upload-hover-opacity: .85;--rt-image-upload-download-overhang: var(--rt-space-sm);--rt-image-upload-download-bg: color-mix(in srgb, var(--rt-color-bg-surface) 75%, transparent);--rt-image-upload-download-radius: var(--rt-radius-md);--rt-image-upload-download-blur: 8px;--rt-image-upload-download-size: var(--rt-control-height-md);display:block;width:100%}.rt-image-upload__loading{display:flex;align-items:center;justify-content:center;padding:var(--rt-space-xl)}.rt-image-upload__actions{display:flex;justify-content:flex-end;margin-top:var(--rt-space-sm);gap:var(--rt-space-sm)}.rt-image-upload__preview{position:relative;display:inline-block;max-width:100%;box-sizing:border-box;padding:var(--rt-image-upload-download-overhang);vertical-align:top}.rt-image-upload__download{position:absolute;top:0;right:0;border-radius:var(--rt-image-upload-download-radius);-webkit-backdrop-filter:blur(var(--rt-image-upload-download-blur));backdrop-filter:blur(var(--rt-image-upload-download-blur));background:var(--rt-image-upload-download-bg)}.rt-image-upload__download--round{--rt-image-upload-download-radius: var(--rt-radius-full)}.rt-image-upload__download .rt-icon-button{--rt-icon-button-size-step: var(--rt-image-upload-download-size)}.rt-image-upload__image{display:block;max-width:100%;max-height:var(--rt-image-upload-image-max-height);border-radius:var(--rt-image-upload-image-radius);object-fit:contain}.rt-image-upload__image--active{cursor:pointer}.rt-image-upload__image--active:hover{opacity:var(--rt-image-upload-hover-opacity)}.rt-image-upload__image--active:focus-visible{box-shadow:var(--rt-image-upload-focus-shadow);outline:none}}\n"], dependencies: [{ kind: "directive", type:
|
|
196
|
+
// directives
|
|
197
|
+
BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }, { kind: "directive", type: ModDirective, selector: "[rtMod]" }, { kind: "directive", type: RtButtonDirective, selector: "button[rtButton], a[rtButton]", inputs: ["label", "icon", "iconPos", "theme", "appearance", "size", "loading", "loadingIcon", "loadingLabel", "pressed"] }, { kind: "directive", type: RtTooltipDirective, selector: "[rtTooltip]", inputs: ["rtTooltip", "rtTooltipPlacement", "rtTooltipWhenTruncated"], exportAs: ["rtTooltip"] }, { kind: "component", type:
|
|
198
|
+
// components
|
|
199
|
+
RtEmptyStateComponent, selector: "rt-empty-state", inputs: ["icon", "glyph", "title", "description", "framed"] }, { kind: "component", type: RtFileDropComponent, selector: "rt-file-drop", inputs: ["disabled", "overlayLabel", "zones", "accept"], outputs: ["filesDropped", "zoneFilesDropped", "draggingChange"] }, { 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: RtImageCropperComponent, selector: "rt-image-cropper", inputs: ["placeholder", "file", "ratio", "round", "minSize", "format", "quality", "disabled"], outputs: ["cropped", "loadFailed"] }, { kind: "component", type: RtSpinnerComponent, selector: "rt-spinner", inputs: ["diameter", "color", "appearance", "overlay", "backdrop", "plate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
200
|
+
}
|
|
201
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtImageUploadComponent, decorators: [{
|
|
202
|
+
type: Component,
|
|
203
|
+
args: [{ selector: 'rt-image-upload', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
204
|
+
// directives
|
|
205
|
+
BlockDirective,
|
|
206
|
+
ElemDirective,
|
|
207
|
+
ModDirective,
|
|
208
|
+
RtButtonDirective,
|
|
209
|
+
RtTooltipDirective,
|
|
210
|
+
// components
|
|
211
|
+
RtEmptyStateComponent,
|
|
212
|
+
RtFileDropComponent,
|
|
213
|
+
RtIconButtonComponent,
|
|
214
|
+
RtImageCropperComponent,
|
|
215
|
+
RtSpinnerComponent,
|
|
216
|
+
], host: {
|
|
217
|
+
class: BEM_BLOCK,
|
|
218
|
+
'[class.rt-image-upload--disabled]': 'disabled()',
|
|
219
|
+
}, template: "<ng-container rtBlock=\"rt-image-upload\">\n <input\n #picker\n hidden\n type=\"file\"\n accept=\"image/*\"\n qa-dataid=\"image-upload-native\"\n [disabled]=\"disabled()\"\n (change)=\"onPicked($event)\" />\n\n @switch (state()) {\n @case ('loading') {\n <div rtElem=\"loading\" qa-dataid=\"image-upload-loading\">\n <rt-spinner />\n </div>\n }\n @case ('cropping') {\n <rt-image-cropper\n qa-dataid=\"image-upload-cropper\"\n [file]=\"source()\"\n [ratio]=\"ratio()\"\n [round]=\"round()\"\n [format]=\"format()\"\n [quality]=\"quality()\"\n (cropped)=\"onCropped($event)\"\n (loadFailed)=\"cancel()\" />\n\n @if (!autoApply()) {\n <div rtElem=\"actions\">\n <button\n rtButton\n appearance=\"text\"\n type=\"button\"\n qa-dataid=\"image-upload-cancel\"\n [label]=\"t().uiImageUploadCancel\"\n [attr.aria-label]=\"t().uiImageUploadCancel\"\n (click)=\"cancel()\"></button>\n <button\n rtButton\n type=\"button\"\n qa-dataid=\"image-upload-apply\"\n [label]=\"t().uiImageUploadApply\"\n [attr.aria-label]=\"t().uiImageUploadApply\"\n [disabled]=\"!result()\"\n (click)=\"apply()\"></button>\n </div>\n }\n }\n @case ('image') {\n <rt-file-drop accept=\"image/*\" [disabled]=\"disabled()\" (filesDropped)=\"choose($event[0])\">\n <div rtElem=\"preview\">\n <img\n rtElem=\"image\"\n role=\"button\"\n qa-dataid=\"image-upload-image\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.alt]=\"t().uiImageUploadImage\"\n [rtTooltip]=\"disabled() ? '' : hint()\"\n [rtMod]=\"{ active: !disabled() }\"\n [src]=\"image()\"\n (click)=\"pick()\"\n (keydown.enter)=\"pick()\"\n (keydown.space)=\"onSpace($event)\" />\n\n @if (downloadable()) {\n <rt-icon-button\n rtElem=\"download\"\n icon=\"ico-download\"\n qa-dataid=\"image-upload-download\"\n [radius]=\"downloadRadius()\"\n [iconSize]=\"downloadIconSize()\"\n [rtMod]=\"{ round: downloadRound() }\"\n [ariaLabel]=\"t().uiDownload\"\n [tooltip]=\"t().uiDownload\"\n (click)=\"download()\" />\n }\n </div>\n </rt-file-drop>\n }\n @default {\n <rt-file-drop accept=\"image/*\" qa-dataid=\"image-upload-drop\" [disabled]=\"disabled()\" (filesDropped)=\"choose($event[0])\">\n <rt-empty-state framed icon=\"cloud-upload\" [title]=\"t().uiImageUploadDrop\">\n <button\n rtButton\n type=\"button\"\n qa-dataid=\"image-upload-choose\"\n [appearance]=\"chooseAppearance()\"\n [icon]=\"chooseIcon()\"\n [label]=\"t().uiImageUploadChoose\"\n [attr.aria-label]=\"t().uiImageUploadChoose\"\n [disabled]=\"disabled()\"\n (click)=\"pick()\"></button>\n </rt-empty-state>\n </rt-file-drop>\n }\n }\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-image-upload{--rt-image-upload-image-max-height: var(--rt-size-100);--rt-image-upload-image-radius: var(--rt-radius-md);--rt-image-upload-focus-shadow: var(--rt-shadow-focus-ring);--rt-image-upload-hover-opacity: .85;--rt-image-upload-download-overhang: var(--rt-space-sm);--rt-image-upload-download-bg: color-mix(in srgb, var(--rt-color-bg-surface) 75%, transparent);--rt-image-upload-download-radius: var(--rt-radius-md);--rt-image-upload-download-blur: 8px;--rt-image-upload-download-size: var(--rt-control-height-md);display:block;width:100%}.rt-image-upload__loading{display:flex;align-items:center;justify-content:center;padding:var(--rt-space-xl)}.rt-image-upload__actions{display:flex;justify-content:flex-end;margin-top:var(--rt-space-sm);gap:var(--rt-space-sm)}.rt-image-upload__preview{position:relative;display:inline-block;max-width:100%;box-sizing:border-box;padding:var(--rt-image-upload-download-overhang);vertical-align:top}.rt-image-upload__download{position:absolute;top:0;right:0;border-radius:var(--rt-image-upload-download-radius);-webkit-backdrop-filter:blur(var(--rt-image-upload-download-blur));backdrop-filter:blur(var(--rt-image-upload-download-blur));background:var(--rt-image-upload-download-bg)}.rt-image-upload__download--round{--rt-image-upload-download-radius: var(--rt-radius-full)}.rt-image-upload__download .rt-icon-button{--rt-icon-button-size-step: var(--rt-image-upload-download-size)}.rt-image-upload__image{display:block;max-width:100%;max-height:var(--rt-image-upload-image-max-height);border-radius:var(--rt-image-upload-image-radius);object-fit:contain}.rt-image-upload__image--active{cursor:pointer}.rt-image-upload__image--active:hover{opacity:var(--rt-image-upload-hover-opacity)}.rt-image-upload__image--active:focus-visible{box-shadow:var(--rt-image-upload-focus-shadow);outline:none}}\n"] }]
|
|
220
|
+
}], ctorParameters: () => [], propDecorators: { picker: [{ type: i0.ViewChild, args: ['picker', { isSignal: true }] }], imageUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageUrl", required: false }] }], fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], tooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltip", required: false }] }], downloadable: [{ type: i0.Input, args: [{ isSignal: true, alias: "downloadable", required: false }] }], downloadShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "downloadShape", required: false }] }], downloadIconSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "downloadIconSize", required: false }] }], chooseAppearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "chooseAppearance", required: false }] }], chooseIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "chooseIcon", required: false }] }], autoApply: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoApply", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ratio: [{ type: i0.Input, args: [{ isSignal: true, alias: "ratio", required: false }] }], round: [{ type: i0.Input, args: [{ isSignal: true, alias: "round", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], quality: [{ type: i0.Input, args: [{ isSignal: true, alias: "quality", required: false }] }], imageChanged: [{ type: i0.Output, args: ["imageChanged"] }], downloaded: [{ type: i0.Output, args: ["downloaded"] }] } });
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Generated bundle index. Do not edit.
|
|
224
|
+
*/
|
|
225
|
+
|
|
226
|
+
export { RtImageUploadComponent, isImageFile, uploadState };
|
|
227
|
+
//# sourceMappingURL=rt-tools-ui-kit-v2-image-upload.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-image-upload.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/image-upload/rt-image-upload.logic.ts","../../../projects/ui-kit-v2/src/lib/components/image-upload/rt-image-upload.component.ts","../../../projects/ui-kit-v2/src/lib/components/image-upload/rt-image-upload.component.html","../../../projects/ui-kit-v2/src/lib/components/image-upload/rt-tools-ui-kit-v2-image-upload.ts"],"sourcesContent":["import { IRtImageUpload } from './rt-image-upload.model';\n\n/**\n * Какое состояние занимает место. Загрузка приложения важнее всего, выбранный исходник важнее\n * картинки, картинка важнее зоны загрузки.\n */\nexport function uploadState(loading: boolean, hasSource: boolean, image: string | null): IRtImageUpload.State {\n if (loading) {\n return 'loading';\n }\n if (hasSource) {\n return 'cropping';\n }\n return image ? 'image' : 'empty';\n}\n\n/** Берётся только файл изображения: брошенный файл другого типа загрузчик пропускает */\nexport function isImageFile(file: File | null | undefined): file is File {\n return !!file && file.type.startsWith('image/');\n}\n","import { BooleanInput, NumberInput } from '@angular/cdk/coercion';\nimport { DOCUMENT } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n inject,\n input,\n InputSignal,\n InputSignalWithTransform,\n linkedSignal,\n numberAttribute,\n output,\n OutputEmitterRef,\n Signal,\n signal,\n viewChild,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective, WINDOW } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { IButton } from '@rt-tools/ui-kit-v2/core';\nimport { RtButtonDirective } from '@rt-tools/ui-kit-v2/button';\nimport { RtEmptyStateComponent } from '@rt-tools/ui-kit-v2/empty-state';\nimport { RtFileDropComponent } from '@rt-tools/ui-kit-v2/file-drop';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { IRtImageCropper, RT_IMAGE_CROPPER_QUALITY, RtImageCropperComponent } from '@rt-tools/ui-kit-v2/image-cropper';\nimport { TRtRadius } from '@rt-tools/ui-kit-v2/core';\nimport { RtSpinnerComponent } from '@rt-tools/ui-kit-v2/spinner';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { isImageFile, uploadState } from './rt-image-upload.logic';\nimport { IRtImageUpload } from './rt-image-upload.model';\n\nconst BEM_BLOCK: string = 'rt-image-upload';\n\n/**\n * Загрузчик одного изображения: одно место, в котором по очереди стоят зона загрузки, обрезка и\n * сама картинка. Файл выбирают кнопкой зоны или бросают на неё; выбранный открывает обрезку, а\n * «Применить» ставит результат на место картинки и отдаёт файл приложению. Нажатие на картинку\n * выбирает другой файл.\n *\n * Картинка — адрес: приложение даёт свой, а адрес применённого файла загрузчик делает сам и\n * отпускает его, когда картинку сменили или компонент ушёл. Файл приложение получает в\n * `imageChanged`.\n */\n@Component({\n selector: 'rt-image-upload',\n templateUrl: './rt-image-upload.component.html',\n styleUrl: './rt-image-upload.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // directives\n BlockDirective,\n ElemDirective,\n ModDirective,\n RtButtonDirective,\n RtTooltipDirective,\n\n // components\n RtEmptyStateComponent,\n RtFileDropComponent,\n RtIconButtonComponent,\n RtImageCropperComponent,\n RtSpinnerComponent,\n ],\n host: {\n class: BEM_BLOCK,\n '[class.rt-image-upload--disabled]': 'disabled()',\n },\n})\nexport class RtImageUploadComponent {\n readonly #window: Window & typeof globalThis = inject(WINDOW) as Window & typeof globalThis;\n\n readonly #document: Document = inject(DOCUMENT);\n\n /** Адрес, сделанный загрузчиком под применённый файл: его и только его он отпускает */\n #ownUrl: string | null = null;\n\n protected readonly picker: Signal<ElementRef<HTMLInputElement>> = viewChild.required<ElementRef<HTMLInputElement>>('picker');\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n /** Выбранный файл, который сейчас режет обрезка */\n protected readonly source: WritableSignal<File | null> = signal(null);\n\n /** Последний результат обрезки — его берёт «Применить» */\n protected readonly result: WritableSignal<IRtImageCropper.Result | null> = signal(null);\n\n /** Что сейчас стоит в месте загрузчика */\n protected readonly state: Signal<IRtImageUpload.State> = computed((): IRtImageUpload.State =>\n uploadState(this.loading(), this.source() !== null, this.image())\n );\n\n /** Подсказка над картинкой: своя приложения или подпись кита */\n protected readonly hint: Signal<string> = computed((): string => this.tooltip() || this.t().uiImageUploadChange);\n\n /** Круглая ли кнопка скачивания: подложка под размытием повторяет её скругление */\n protected readonly downloadRound: Signal<boolean> = computed((): boolean => this.downloadShape() === 'circle');\n\n /** Шаг скругления кнопки скачивания: круг — полный шаг, квадрат — скругление кнопки по умолчанию */\n protected readonly downloadRadius: Signal<TRtRadius | null> = computed((): TRtRadius | null => (this.downloadRound() ? 'full' : null));\n\n /**\n * Адрес текущей картинки: данный приложением или сделанный под применённый файл. Новый адрес от\n * приложения снова берёт верх над применённым.\n */\n protected readonly image: WritableSignal<string | null> = linkedSignal((): string | null => this.imageUrl());\n\n /** Адрес картинки от приложения */\n public readonly imageUrl: InputSignal<string | null> = input<string | null>(null);\n\n /** Имя файла, под которым картинку скачивают и отдают приложению */\n public readonly fileName: InputSignal<string> = input<string>('image');\n\n /** Подсказка над картинкой; пустая — подпись кита */\n public readonly tooltip: InputSignal<string> = input<string>('');\n\n /** Кнопка скачивания рядом с картинкой */\n public readonly downloadable: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Форма кнопки скачивания; она заходит за правый верхний угол картинки при любой форме */\n public readonly downloadShape: InputSignal<IRtImageUpload.DownloadShape> = input<IRtImageUpload.DownloadShape>('circle');\n\n /** Размер значка кнопки скачивания; пусто — от размера кнопки */\n public readonly downloadIconSize: InputSignal<IRtIcon.Size | null> = input<IRtIcon.Size | null>(null);\n\n /** Вид кнопки выбора файла в пустом загрузчике */\n public readonly chooseAppearance: InputSignal<IButton.Appearance> = input<IButton.Appearance>('outlined');\n\n /** Значок кнопки выбора файла; пусто — кнопка без значка */\n public readonly chooseIcon: InputSignal<string | null> = input<string | null>('ico-upload');\n\n /** Без кнопок «Отмена» и «Применить»: каждый результат обрезки применяется сразу */\n public readonly autoApply: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Приложение загружает картинку: на месте стоит индикатор */\n public readonly loading: 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 ratio: InputSignalWithTransform<number | null, NumberInput> = input<number | null, NumberInput>(null, {\n transform: (value: NumberInput): number | null => (value === null || value === '' ? null : numberAttribute(value, 0) || null),\n });\n\n /** Круглая маска обрезки для аватара */\n public readonly round: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Формат результата; пусто — формат исходника */\n public readonly format: InputSignal<IRtImageCropper.Format | null> = input<IRtImageCropper.Format | null>(null);\n\n /** Качество результата, от 0 до 100 */\n public readonly quality: InputSignalWithTransform<number, NumberInput> = input<number, NumberInput>(RT_IMAGE_CROPPER_QUALITY, {\n transform: (value: NumberInput): number => numberAttribute(value, RT_IMAGE_CROPPER_QUALITY),\n });\n\n /** Применённый файл — его приложение отправляет, куда ему надо */\n public readonly imageChanged: OutputEmitterRef<File> = output<File>();\n\n /** Картинку скачали */\n public readonly downloaded: OutputEmitterRef<void> = output<void>();\n\n constructor() {\n inject(DestroyRef).onDestroy((): void => this.#release());\n }\n\n /** Открывает выбор файла, если загрузчик доступен */\n public pick(): void {\n if (!this.disabled()) {\n this.picker().nativeElement.click();\n }\n }\n\n /** Файл выбран кнопкой или брошен: изображение открывает обрезку, остальное пропускается */\n public choose(file: File | null | undefined): void {\n if (this.disabled() || !isImageFile(file)) {\n return;\n }\n this.result.set(null);\n this.source.set(file);\n }\n\n protected onPicked(event: Event): void {\n const input: HTMLInputElement = event.target as HTMLInputElement;\n this.choose(input.files?.[0]);\n // Тот же файл, выбранный второй раз, иначе не даёт события\n input.value = '';\n }\n\n protected onSpace(event: Event): void {\n event.preventDefault();\n this.pick();\n }\n\n protected onCropped(result: IRtImageCropper.Result): void {\n this.result.set(result);\n if (this.autoApply()) {\n this.#applyResult(result, false);\n }\n }\n\n protected apply(): void {\n const result: IRtImageCropper.Result | null = this.result();\n if (result !== null) {\n this.#applyResult(result, true);\n }\n }\n\n protected cancel(): void {\n this.source.set(null);\n this.result.set(null);\n }\n\n protected download(): void {\n const url: string | null = this.image();\n if (url === null) {\n return;\n }\n const link: HTMLAnchorElement = this.#document.createElement('a');\n link.href = url;\n link.download = this.fileName();\n this.#document.body.appendChild(link);\n link.click();\n link.remove();\n this.downloaded.emit();\n }\n\n /** Результат становится картинкой; `close` убирает обрезку — при автоприменении она остаётся */\n #applyResult(result: IRtImageCropper.Result, close: boolean): void {\n const file: File = new File([result.file], this.fileName(), { type: result.file.type });\n this.#release();\n this.#ownUrl = this.#window.URL.createObjectURL(file);\n this.image.set(this.#ownUrl);\n this.imageChanged.emit(file);\n if (close) {\n this.cancel();\n }\n }\n\n #release(): void {\n if (this.#ownUrl !== null) {\n this.#window.URL.revokeObjectURL(this.#ownUrl);\n this.#ownUrl = null;\n }\n }\n}\n","<ng-container rtBlock=\"rt-image-upload\">\n <input\n #picker\n hidden\n type=\"file\"\n accept=\"image/*\"\n qa-dataid=\"image-upload-native\"\n [disabled]=\"disabled()\"\n (change)=\"onPicked($event)\" />\n\n @switch (state()) {\n @case ('loading') {\n <div rtElem=\"loading\" qa-dataid=\"image-upload-loading\">\n <rt-spinner />\n </div>\n }\n @case ('cropping') {\n <rt-image-cropper\n qa-dataid=\"image-upload-cropper\"\n [file]=\"source()\"\n [ratio]=\"ratio()\"\n [round]=\"round()\"\n [format]=\"format()\"\n [quality]=\"quality()\"\n (cropped)=\"onCropped($event)\"\n (loadFailed)=\"cancel()\" />\n\n @if (!autoApply()) {\n <div rtElem=\"actions\">\n <button\n rtButton\n appearance=\"text\"\n type=\"button\"\n qa-dataid=\"image-upload-cancel\"\n [label]=\"t().uiImageUploadCancel\"\n [attr.aria-label]=\"t().uiImageUploadCancel\"\n (click)=\"cancel()\"></button>\n <button\n rtButton\n type=\"button\"\n qa-dataid=\"image-upload-apply\"\n [label]=\"t().uiImageUploadApply\"\n [attr.aria-label]=\"t().uiImageUploadApply\"\n [disabled]=\"!result()\"\n (click)=\"apply()\"></button>\n </div>\n }\n }\n @case ('image') {\n <rt-file-drop accept=\"image/*\" [disabled]=\"disabled()\" (filesDropped)=\"choose($event[0])\">\n <div rtElem=\"preview\">\n <img\n rtElem=\"image\"\n role=\"button\"\n qa-dataid=\"image-upload-image\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.alt]=\"t().uiImageUploadImage\"\n [rtTooltip]=\"disabled() ? '' : hint()\"\n [rtMod]=\"{ active: !disabled() }\"\n [src]=\"image()\"\n (click)=\"pick()\"\n (keydown.enter)=\"pick()\"\n (keydown.space)=\"onSpace($event)\" />\n\n @if (downloadable()) {\n <rt-icon-button\n rtElem=\"download\"\n icon=\"ico-download\"\n qa-dataid=\"image-upload-download\"\n [radius]=\"downloadRadius()\"\n [iconSize]=\"downloadIconSize()\"\n [rtMod]=\"{ round: downloadRound() }\"\n [ariaLabel]=\"t().uiDownload\"\n [tooltip]=\"t().uiDownload\"\n (click)=\"download()\" />\n }\n </div>\n </rt-file-drop>\n }\n @default {\n <rt-file-drop accept=\"image/*\" qa-dataid=\"image-upload-drop\" [disabled]=\"disabled()\" (filesDropped)=\"choose($event[0])\">\n <rt-empty-state framed icon=\"cloud-upload\" [title]=\"t().uiImageUploadDrop\">\n <button\n rtButton\n type=\"button\"\n qa-dataid=\"image-upload-choose\"\n [appearance]=\"chooseAppearance()\"\n [icon]=\"chooseIcon()\"\n [label]=\"t().uiImageUploadChoose\"\n [attr.aria-label]=\"t().uiImageUploadChoose\"\n [disabled]=\"disabled()\"\n (click)=\"pick()\"></button>\n </rt-empty-state>\n </rt-file-drop>\n }\n }\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,37 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, booleanAttribute, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { BlockDirective, ElemDirective } from '@rt-tools/core';
|
|
4
|
+
import { RtSkeletonWrapperComponent } from '@rt-tools/ui-kit-v2/skeleton-wrapper';
|
|
5
|
+
|
|
6
|
+
const BEM_BLOCK = 'rt-info-item';
|
|
7
|
+
class RtInfoItemComponent {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.label = input.required(/* @ts-ignore */
|
|
10
|
+
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
11
|
+
this.loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
12
|
+
this.grow = input(false, { ...(ngDevMode ? { debugName: "grow" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
13
|
+
}
|
|
14
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtInfoItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
15
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtInfoItemComponent, isStandalone: true, selector: "rt-info-item", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, grow: { classPropertyName: "grow", publicName: "grow", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.rt-info-item--grow": "grow()" }, classAttribute: "rt-info-item" }, ngImport: i0, template: "<ng-container rtBlock=\"rt-info-item\">\n <span rtElem=\"label\" qa-dataid=\"info-item-label\">{{ label() }}</span>\n @if (loading()) {\n <rt-skeleton-wrapper rtElem=\"value-skeleton\" qa-dataid=\"info-item-skeleton\" width=\"80px\" [isLoading]=\"true\" />\n } @else {\n <span rtElem=\"value\" qa-dataid=\"info-item-value\"><ng-content /></span>\n }\n</ng-container>\n", styles: ["@layer rt-kit.components{.rt-info-item{padding:var(--rt-space-md);border-radius:var(--rt-radius-xl);background:var(--rt-color-bg-surface);box-shadow:var(--rt-shadow-card-soft);display:flex;min-width:0;flex-direction:column;margin:0;gap:var(--rt-space-0-5)}.rt-info-item--grow{flex:1 0 0}.rt-info-item__label{margin:0;color:var(--rt-color-text-primary);font-size:var(--rt-text-xs);font-weight:var(--rt-font-weight-regular);letter-spacing:var(--rt-letter-spacing-wide);line-height:var(--rt-leading-snug)}.rt-info-item__value{display:flex;flex-wrap:wrap;align-items:baseline;margin:0;color:var(--rt-color-text-primary);font-size:var(--rt-text-sm);font-weight:var(--rt-font-weight-bold);gap:var(--rt-space-0-5);letter-spacing:var(--rt-letter-spacing-wide);line-height:var(--rt-leading-snug);overflow-wrap:anywhere}.rt-info-item__value-skeleton{display:block}[data-theme=dark] .rt-info-item{background:var(--rt-color-bg-nav);box-shadow:var(--rt-shadow-card-soft)}}\n"], dependencies: [{ kind: "component", type:
|
|
16
|
+
// standalone components / directives
|
|
17
|
+
RtSkeletonWrapperComponent, selector: "rt-skeleton-wrapper", inputs: ["width", "height", "shape", "size", "radius", "animation", "isLoading"] }, { kind: "directive", type: BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
18
|
+
}
|
|
19
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtInfoItemComponent, decorators: [{
|
|
20
|
+
type: Component,
|
|
21
|
+
args: [{ selector: 'rt-info-item', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
22
|
+
// standalone components / directives
|
|
23
|
+
RtSkeletonWrapperComponent,
|
|
24
|
+
BlockDirective,
|
|
25
|
+
ElemDirective,
|
|
26
|
+
], host: {
|
|
27
|
+
class: BEM_BLOCK,
|
|
28
|
+
'[class.rt-info-item--grow]': 'grow()',
|
|
29
|
+
}, template: "<ng-container rtBlock=\"rt-info-item\">\n <span rtElem=\"label\" qa-dataid=\"info-item-label\">{{ label() }}</span>\n @if (loading()) {\n <rt-skeleton-wrapper rtElem=\"value-skeleton\" qa-dataid=\"info-item-skeleton\" width=\"80px\" [isLoading]=\"true\" />\n } @else {\n <span rtElem=\"value\" qa-dataid=\"info-item-value\"><ng-content /></span>\n }\n</ng-container>\n", styles: ["@layer rt-kit.components{.rt-info-item{padding:var(--rt-space-md);border-radius:var(--rt-radius-xl);background:var(--rt-color-bg-surface);box-shadow:var(--rt-shadow-card-soft);display:flex;min-width:0;flex-direction:column;margin:0;gap:var(--rt-space-0-5)}.rt-info-item--grow{flex:1 0 0}.rt-info-item__label{margin:0;color:var(--rt-color-text-primary);font-size:var(--rt-text-xs);font-weight:var(--rt-font-weight-regular);letter-spacing:var(--rt-letter-spacing-wide);line-height:var(--rt-leading-snug)}.rt-info-item__value{display:flex;flex-wrap:wrap;align-items:baseline;margin:0;color:var(--rt-color-text-primary);font-size:var(--rt-text-sm);font-weight:var(--rt-font-weight-bold);gap:var(--rt-space-0-5);letter-spacing:var(--rt-letter-spacing-wide);line-height:var(--rt-leading-snug);overflow-wrap:anywhere}.rt-info-item__value-skeleton{display:block}[data-theme=dark] .rt-info-item{background:var(--rt-color-bg-nav);box-shadow:var(--rt-shadow-card-soft)}}\n"] }]
|
|
30
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], grow: [{ type: i0.Input, args: [{ isSignal: true, alias: "grow", required: false }] }] } });
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Generated bundle index. Do not edit.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
export { RtInfoItemComponent };
|
|
37
|
+
//# sourceMappingURL=rt-tools-ui-kit-v2-info-item.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-info-item.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/info-item/rt-info-item.component.ts","../../../projects/ui-kit-v2/src/lib/components/info-item/rt-info-item.component.html","../../../projects/ui-kit-v2/src/lib/components/info-item/rt-tools-ui-kit-v2-info-item.ts"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n input,\n InputSignal,\n InputSignalWithTransform,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { RtSkeletonWrapperComponent } from '@rt-tools/ui-kit-v2/skeleton-wrapper';\n\nconst BEM_BLOCK: string = 'rt-info-item';\n\n@Component({\n selector: 'rt-info-item',\n templateUrl: './rt-info-item.component.html',\n styleUrl: './rt-info-item.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtSkeletonWrapperComponent,\n BlockDirective,\n ElemDirective,\n ],\n host: {\n class: BEM_BLOCK,\n '[class.rt-info-item--grow]': 'grow()',\n },\n})\nexport class RtInfoItemComponent {\n public readonly label: InputSignal<string> = input.required<string>();\n\n public readonly loading: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly grow: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n}\n","<ng-container rtBlock=\"rt-info-item\">\n <span rtElem=\"label\" qa-dataid=\"info-item-label\">{{ label() }}</span>\n @if (loading()) {\n <rt-skeleton-wrapper rtElem=\"value-skeleton\" qa-dataid=\"info-item-skeleton\" width=\"80px\" [isLoading]=\"true\" />\n } @else {\n <span rtElem=\"value\" qa-dataid=\"info-item-value\"><ng-content /></span>\n }\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AAeA,MAAM,SAAS,GAAW,cAAc;MAmB3B,mBAAmB,CAAA;AAjBhC,IAAA,WAAA,GAAA;QAkBoB,IAAA,CAAA,KAAK,GAAwB,KAAK,CAAC,QAAQ;kFAAU;QAErD,IAAA,CAAA,OAAO,GAAoD,KAAK,CAAwB,KAAK,+EACzG,SAAS,EAAE,gBAAgB,EAAA,CAC7B;QAEc,IAAA,CAAA,IAAI,GAAoD,KAAK,CAAwB,KAAK,4EACtG,SAAS,EAAE,gBAAgB,EAAA,CAC7B;AACL,IAAA;8GAVY,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAnB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,mBAAmB,8hBClChC,4YAQA,EAAA,MAAA,EAAA,CAAA,m8BAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA;;gBDiBQ,0BAA0B,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,OAAA,EAAA,MAAA,EAAA,QAAA,EAAA,WAAA,EAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAC1B,cAAc,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACd,aAAa,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA,CAAA;;2FAOR,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAjB/B,SAAS;+BACI,cAAc,EAAA,eAAA,EAGP,uBAAuB,CAAC,MAAM,iBAChC,iBAAiB,CAAC,IAAI,EAAA,OAAA,EAC5B;;wBAEL,0BAA0B;wBAC1B,cAAc;wBACd,aAAa;qBAChB,EAAA,IAAA,EACK;AACF,wBAAA,KAAK,EAAE,SAAS;AAChB,wBAAA,4BAA4B,EAAE,QAAQ;AACzC,qBAAA,EAAA,QAAA,EAAA,4YAAA,EAAA,MAAA,EAAA,CAAA,m8BAAA,CAAA,EAAA;;;AEhCL;;AAEG;;;;"}
|