@rt-tools/ui-kit-v2 0.23.3 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/rt-tools-ui-kit-v2-accordion.mjs +142 -71
- package/fesm2022/rt-tools-ui-kit-v2-accordion.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs +467 -231
- package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs +260 -91
- package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-aside-section.mjs +80 -46
- package/fesm2022/rt-tools-ui-kit-v2-aside-section.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-aside.mjs +984 -697
- package/fesm2022/rt-tools-ui-kit-v2-aside.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs +452 -210
- package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-bar-list.mjs +143 -52
- package/fesm2022/rt-tools-ui-kit-v2-bar-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-bottom-sheet.mjs +158 -83
- package/fesm2022/rt-tools-ui-kit-v2-bottom-sheet.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-breadcrumbs.mjs +335 -0
- package/fesm2022/rt-tools-ui-kit-v2-breadcrumbs.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-button.mjs +437 -363
- package/fesm2022/rt-tools-ui-kit-v2-button.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs +430 -149
- package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-card.mjs +155 -71
- package/fesm2022/rt-tools-ui-kit-v2-card.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-carousel.mjs +155 -0
- package/fesm2022/rt-tools-ui-kit-v2-carousel.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs +215 -110
- package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-collapsible-text.mjs +158 -75
- package/fesm2022/rt-tools-ui-kit-v2-collapsible-text.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-color-palette.mjs +769 -0
- package/fesm2022/rt-tools-ui-kit-v2-color-palette.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-confirm-popover.mjs +462 -253
- package/fesm2022/rt-tools-ui-kit-v2-confirm-popover.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-container.mjs +1276 -1316
- package/fesm2022/rt-tools-ui-kit-v2-container.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs +185 -80
- package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs +2321 -2619
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-counter-row.mjs +100 -44
- package/fesm2022/rt-tools-ui-kit-v2-counter-row.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-counter.mjs +290 -155
- package/fesm2022/rt-tools-ui-kit-v2-counter.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs +2097 -858
- package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs +2247 -1176
- package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs +1043 -705
- package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs +810 -525
- package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-delta-view.mjs +158 -138
- package/fesm2022/rt-tools-ui-kit-v2-delta-view.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-detail-list.mjs +177 -67
- package/fesm2022/rt-tools-ui-kit-v2-detail-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-dialog.mjs +550 -477
- package/fesm2022/rt-tools-ui-kit-v2-dialog.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-dot-field.mjs +185 -168
- package/fesm2022/rt-tools-ui-kit-v2-dot-field.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-download-link.mjs +116 -43
- package/fesm2022/rt-tools-ui-kit-v2-download-link.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs +585 -0
- package/fesm2022/rt-tools-ui-kit-v2-draggable-tree.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs +755 -259
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +3266 -1115
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-empty-state.mjs +190 -55
- package/fesm2022/rt-tools-ui-kit-v2-empty-state.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs +283 -103
- package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-field.mjs +393 -177
- package/fesm2022/rt-tools-ui-kit-v2-field.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs +399 -207
- package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-file-drop.mjs +288 -212
- package/fesm2022/rt-tools-ui-kit-v2-file-drop.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-file-input.mjs +262 -116
- package/fesm2022/rt-tools-ui-kit-v2-file-input.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-file-list.mjs +57 -31
- package/fesm2022/rt-tools-ui-kit-v2-file-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs +258 -90
- package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs +249 -215
- package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-header.mjs +199 -71
- package/fesm2022/rt-tools-ui-kit-v2-header.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree-selector.mjs +231 -0
- package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree-selector.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs +336 -0
- package/fesm2022/rt-tools-ui-kit-v2-hybrid-tree.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs +451 -162
- package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-icon.mjs +931 -686
- package/fesm2022/rt-tools-ui-kit-v2-icon.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-image-cropper.mjs +664 -491
- package/fesm2022/rt-tools-ui-kit-v2-image-cropper.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs +574 -222
- package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-info-item.mjs +150 -36
- package/fesm2022/rt-tools-ui-kit-v2-info-item.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-inline-edit.mjs +606 -0
- package/fesm2022/rt-tools-ui-kit-v2-inline-edit.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs +461 -355
- package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-input.mjs +338 -143
- package/fesm2022/rt-tools-ui-kit-v2-input.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-live-badge.mjs +135 -48
- package/fesm2022/rt-tools-ui-kit-v2-live-badge.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-logo.mjs +166 -92
- package/fesm2022/rt-tools-ui-kit-v2-logo.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-markdown-text.mjs +118 -56
- package/fesm2022/rt-tools-ui-kit-v2-markdown-text.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-menu.mjs +1054 -527
- package/fesm2022/rt-tools-ui-kit-v2-menu.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-message.mjs +230 -104
- package/fesm2022/rt-tools-ui-kit-v2-message.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-money-list.mjs +210 -70
- package/fesm2022/rt-tools-ui-kit-v2-money-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs +532 -311
- package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-night-grid.mjs +125 -50
- package/fesm2022/rt-tools-ui-kit-v2-night-grid.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-note.mjs +73 -43
- package/fesm2022/rt-tools-ui-kit-v2-note.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-notifications-bell.mjs +161 -53
- package/fesm2022/rt-tools-ui-kit-v2-notifications-bell.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +491 -310
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs +374 -174
- package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-photo-viewer.mjs +202 -159
- package/fesm2022/rt-tools-ui-kit-v2-photo-viewer.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-popover.mjs +438 -309
- package/fesm2022/rt-tools-ui-kit-v2-popover.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-profile-menu.mjs +295 -0
- package/fesm2022/rt-tools-ui-kit-v2-profile-menu.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-prompt-suggestion.mjs +135 -45
- package/fesm2022/rt-tools-ui-kit-v2-prompt-suggestion.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs +293 -171
- package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-radius.mjs +62 -55
- package/fesm2022/rt-tools-ui-kit-v2-radius.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +3379 -1466
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-ripple.mjs +114 -116
- package/fesm2022/rt-tools-ui-kit-v2-ripple.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs +406 -299
- package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs +137 -36
- package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-select.mjs +687 -468
- package/fesm2022/rt-tools-ui-kit-v2-select.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +2195 -1569
- package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-skeleton-wrapper.mjs +187 -48
- package/fesm2022/rt-tools-ui-kit-v2-skeleton-wrapper.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-skeleton.mjs +242 -122
- package/fesm2022/rt-tools-ui-kit-v2-skeleton.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs +439 -0
- package/fesm2022/rt-tools-ui-kit-v2-speed-menu.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-spinner.mjs +218 -69
- package/fesm2022/rt-tools-ui-kit-v2-spinner.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs +292 -91
- package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs +225 -138
- package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs +150 -116
- package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-table.mjs +2462 -1583
- package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs +647 -346
- package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tag.mjs +335 -121
- package/fesm2022/rt-tools-ui-kit-v2-tag.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs +217 -84
- package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs +151 -72
- package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +697 -226
- package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-timeline.mjs +92 -38
- package/fesm2022/rt-tools-ui-kit-v2-timeline.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-toast.mjs +752 -338
- package/fesm2022/rt-tools-ui-kit-v2-toast.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs +310 -129
- package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs +286 -158
- package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs +270 -134
- package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs +322 -202
- package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs +908 -0
- package/fesm2022/rt-tools-ui-kit-v2-tree-selector.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-tree.mjs +785 -0
- package/fesm2022/rt-tools-ui-kit-v2-tree.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-welcome-dialog.mjs +118 -63
- package/fesm2022/rt-tools-ui-kit-v2-welcome-dialog.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs +783 -262
- package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs +633 -294
- package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2.mjs +100 -103
- package/package.json +45 -1
- package/src/assets/icons/collapse-all.svg +9 -0
- package/src/assets/icons/expand-all.svg +9 -0
- package/src/assets/icons-material/collapse-all.fill.svg +5 -0
- package/src/assets/icons-material/collapse-all.svg +5 -0
- package/src/assets/icons-material/expand-all.fill.svg +5 -0
- package/src/assets/icons-material/expand-all.svg +5 -0
- package/src/assets/icons-material/undo.fill.svg +5 -0
- package/src/assets/icons-material/undo.svg +5 -0
- package/src/lib/components/bottom-sheet/CONTEXT.md +20 -2
- package/src/lib/components/bottom-sheet/rt-bottom-sheet.component.scss +36 -1
- package/src/lib/components/breadcrumbs/CONTEXT.md +37 -0
- package/src/lib/components/breadcrumbs/rt-breadcrumbs.component.scss +205 -0
- package/src/lib/components/carousel/CONTEXT.md +42 -0
- package/src/lib/components/carousel/rt-carousel.component.scss +117 -0
- package/src/lib/components/checkbox/CONTEXT.md +3 -0
- package/src/lib/components/checkbox/rt-checkbox.component.scss +9 -3
- package/src/lib/components/color-palette/CONTEXT.md +49 -0
- package/src/lib/components/color-palette/picker/rt-color-picker.component.scss +161 -0
- package/src/lib/components/color-palette/rt-color-palette.component.scss +132 -0
- package/src/lib/components/draggable-tree/CONTEXT.md +54 -0
- package/src/lib/components/draggable-tree/rt-draggable-tree.component.scss +219 -0
- package/src/lib/components/hybrid-tree/CONTEXT.md +31 -0
- package/src/lib/components/hybrid-tree-selector/CONTEXT.md +25 -0
- package/src/lib/components/icon-button/CONTEXT.md +3 -0
- package/src/lib/components/inline-edit/CONTEXT.md +41 -0
- package/src/lib/components/inline-edit/rt-inline-edit.component.scss +274 -0
- package/src/lib/components/popover/CONTEXT.md +3 -0
- package/src/lib/components/profile-menu/CONTEXT.md +32 -0
- package/src/lib/components/profile-menu/rt-profile-menu.component.scss +104 -0
- package/src/lib/components/speed-menu/CONTEXT.md +34 -0
- package/src/lib/components/speed-menu/rt-speed-menu.component.scss +118 -0
- package/src/lib/components/tag/rt-tag.component.scss +12 -0
- package/src/lib/components/thread-list/CONTEXT.md +1 -0
- package/src/lib/components/thread-list/rt-thread-list.component.scss +2 -1
- package/src/lib/components/toolbar/CONTEXT.md +9 -4
- package/src/lib/components/toolbar/rt-toolbar.component.scss +10 -2
- package/src/lib/components/tooltip/CONTEXT.md +8 -1
- package/src/lib/components/tree/CONTEXT.md +66 -0
- package/src/lib/components/tree/rt-tree.component.scss +313 -0
- package/src/lib/components/tree-selector/CONTEXT.md +47 -0
- package/src/lib/components/tree-selector/rt-tree-selector.component.scss +121 -0
- package/src/styles/_primitives.scss +4 -0
- package/src/styles/_semantic.scss +5 -0
- package/styles/tokens.css +43 -0
- package/types/rt-tools-ui-kit-v2-accordion.d.ts +31 -24
- package/types/rt-tools-ui-kit-v2-action-bar.d.ts +112 -91
- package/types/rt-tools-ui-kit-v2-ai-run-status.d.ts +64 -40
- package/types/rt-tools-ui-kit-v2-aside-section.d.ts +13 -10
- package/types/rt-tools-ui-kit-v2-aside.d.ts +268 -206
- package/types/rt-tools-ui-kit-v2-autocomplete.d.ts +102 -61
- package/types/rt-tools-ui-kit-v2-bar-list.d.ts +39 -27
- package/types/rt-tools-ui-kit-v2-bottom-sheet.d.ts +31 -20
- package/types/rt-tools-ui-kit-v2-breadcrumbs.d.ts +89 -0
- package/types/rt-tools-ui-kit-v2-button.d.ts +119 -59
- package/types/rt-tools-ui-kit-v2-calendar.d.ts +151 -86
- package/types/rt-tools-ui-kit-v2-card.d.ts +42 -21
- package/types/rt-tools-ui-kit-v2-carousel.d.ts +76 -0
- package/types/rt-tools-ui-kit-v2-checkbox.d.ts +48 -24
- package/types/rt-tools-ui-kit-v2-collapsible-text.d.ts +28 -20
- package/types/rt-tools-ui-kit-v2-color-palette.d.ts +208 -0
- package/types/rt-tools-ui-kit-v2-confirm-popover.d.ts +104 -47
- package/types/rt-tools-ui-kit-v2-container.d.ts +278 -221
- package/types/rt-tools-ui-kit-v2-copy-value.d.ts +39 -24
- package/types/rt-tools-ui-kit-v2-core.d.ts +862 -865
- package/types/rt-tools-ui-kit-v2-counter-row.d.ts +20 -12
- package/types/rt-tools-ui-kit-v2-counter.d.ts +70 -38
- package/types/rt-tools-ui-kit-v2-data-list.d.ts +429 -264
- package/types/rt-tools-ui-kit-v2-data-table.d.ts +500 -351
- package/types/rt-tools-ui-kit-v2-date-picker.d.ts +164 -138
- package/types/rt-tools-ui-kit-v2-date-range.d.ts +102 -84
- package/types/rt-tools-ui-kit-v2-delta-view.d.ts +16 -13
- package/types/rt-tools-ui-kit-v2-detail-list.d.ts +23 -16
- package/types/rt-tools-ui-kit-v2-dialog.d.ts +130 -101
- package/types/rt-tools-ui-kit-v2-dot-field.d.ts +10 -13
- package/types/rt-tools-ui-kit-v2-download-link.d.ts +22 -17
- package/types/rt-tools-ui-kit-v2-draggable-tree.d.ts +132 -0
- package/types/rt-tools-ui-kit-v2-dynamic-list.d.ts +185 -96
- package/types/rt-tools-ui-kit-v2-dynamic-selector.d.ts +904 -404
- package/types/rt-tools-ui-kit-v2-empty-state.d.ts +48 -19
- package/types/rt-tools-ui-kit-v2-expansion-panel.d.ts +67 -39
- package/types/rt-tools-ui-kit-v2-field.d.ts +90 -49
- package/types/rt-tools-ui-kit-v2-file-card.d.ts +115 -75
- package/types/rt-tools-ui-kit-v2-file-drop.d.ts +75 -48
- package/types/rt-tools-ui-kit-v2-file-input.d.ts +53 -36
- package/types/rt-tools-ui-kit-v2-file-list.d.ts +5 -8
- package/types/rt-tools-ui-kit-v2-filter-control.d.ts +83 -49
- package/types/rt-tools-ui-kit-v2-form-control.d.ts +102 -74
- package/types/rt-tools-ui-kit-v2-header.d.ts +40 -22
- package/types/rt-tools-ui-kit-v2-hybrid-tree-selector.d.ts +14 -0
- package/types/rt-tools-ui-kit-v2-hybrid-tree.d.ts +72 -0
- package/types/rt-tools-ui-kit-v2-icon-button.d.ts +190 -90
- package/types/rt-tools-ui-kit-v2-icon.d.ts +160 -129
- package/types/rt-tools-ui-kit-v2-image-cropper.d.ts +151 -111
- package/types/rt-tools-ui-kit-v2-image-upload.d.ts +159 -85
- package/types/rt-tools-ui-kit-v2-info-item.d.ts +26 -13
- package/types/rt-tools-ui-kit-v2-inline-edit.d.ts +194 -0
- package/types/rt-tools-ui-kit-v2-input-number.d.ts +102 -53
- package/types/rt-tools-ui-kit-v2-input.d.ts +82 -43
- package/types/rt-tools-ui-kit-v2-live-badge.d.ts +30 -17
- package/types/rt-tools-ui-kit-v2-logo.d.ts +49 -32
- package/types/rt-tools-ui-kit-v2-markdown-text.d.ts +26 -17
- package/types/rt-tools-ui-kit-v2-menu.d.ts +272 -155
- package/types/rt-tools-ui-kit-v2-message.d.ts +59 -33
- package/types/rt-tools-ui-kit-v2-money-list.d.ts +36 -18
- package/types/rt-tools-ui-kit-v2-multiselect.d.ts +114 -80
- package/types/rt-tools-ui-kit-v2-night-grid.d.ts +34 -25
- package/types/rt-tools-ui-kit-v2-note.d.ts +12 -9
- package/types/rt-tools-ui-kit-v2-notifications-bell.d.ts +37 -16
- package/types/rt-tools-ui-kit-v2-page-header.d.ts +218 -150
- package/types/rt-tools-ui-kit-v2-pagination.d.ts +99 -63
- package/types/rt-tools-ui-kit-v2-photo-viewer.d.ts +61 -66
- package/types/rt-tools-ui-kit-v2-popover.d.ts +116 -55
- package/types/rt-tools-ui-kit-v2-profile-menu.d.ts +103 -0
- package/types/rt-tools-ui-kit-v2-prompt-suggestion.d.ts +26 -16
- package/types/rt-tools-ui-kit-v2-radio-button.d.ts +85 -43
- package/types/rt-tools-ui-kit-v2-radius.d.ts +18 -15
- package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +931 -590
- package/types/rt-tools-ui-kit-v2-ripple.d.ts +28 -25
- package/types/rt-tools-ui-kit-v2-scroll-area.d.ts +60 -58
- package/types/rt-tools-ui-kit-v2-section-nav.d.ts +32 -22
- package/types/rt-tools-ui-kit-v2-select.d.ts +182 -139
- package/types/rt-tools-ui-kit-v2-side-menu.d.ts +452 -349
- package/types/rt-tools-ui-kit-v2-skeleton-wrapper.d.ts +53 -20
- package/types/rt-tools-ui-kit-v2-skeleton.d.ts +55 -26
- package/types/rt-tools-ui-kit-v2-speed-menu.d.ts +131 -0
- package/types/rt-tools-ui-kit-v2-spinner.d.ts +56 -28
- package/types/rt-tools-ui-kit-v2-split-button.d.ts +96 -55
- package/types/rt-tools-ui-kit-v2-stat-tile.d.ts +88 -60
- package/types/rt-tools-ui-kit-v2-stepper.d.ts +50 -37
- package/types/rt-tools-ui-kit-v2-table.d.ts +631 -480
- package/types/rt-tools-ui-kit-v2-tabs.d.ts +198 -113
- package/types/rt-tools-ui-kit-v2-tag.d.ts +106 -53
- package/types/rt-tools-ui-kit-v2-textarea.d.ts +48 -25
- package/types/rt-tools-ui-kit-v2-theme-toggle.d.ts +28 -26
- package/types/rt-tools-ui-kit-v2-thread-list.d.ts +154 -94
- package/types/rt-tools-ui-kit-v2-timeline.d.ts +30 -28
- package/types/rt-tools-ui-kit-v2-toast.d.ts +174 -98
- package/types/rt-tools-ui-kit-v2-toggle-button-group.d.ts +132 -86
- package/types/rt-tools-ui-kit-v2-toggle-switch.d.ts +88 -50
- package/types/rt-tools-ui-kit-v2-toolbar.d.ts +30 -27
- package/types/rt-tools-ui-kit-v2-tooltip.d.ts +65 -41
- package/types/rt-tools-ui-kit-v2-tree-selector.d.ts +257 -0
- package/types/rt-tools-ui-kit-v2-tree.d.ts +282 -0
- package/types/rt-tools-ui-kit-v2-welcome-dialog.d.ts +21 -24
- package/types/rt-tools-ui-kit-v2-workspace-details.d.ts +195 -124
- package/types/rt-tools-ui-kit-v2-workspace.d.ts +122 -79
- package/types/rt-tools-ui-kit-v2.d.ts +100 -90
- package/fesm2022/rt-tools-ui-kit-v2.mjs.map +0 -1
|
@@ -1 +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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"}
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-image-cropper.mjs","names":[],"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"],"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"],"mappings":"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"}
|