@rt-tools/ui-kit-v2 0.17.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -2
- package/fesm2022/rt-tools-ui-kit-v2-accordion.mjs +79 -0
- package/fesm2022/rt-tools-ui-kit-v2-accordion.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs +233 -0
- package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs +97 -0
- package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-aside-section.mjs +47 -0
- package/fesm2022/rt-tools-ui-kit-v2-aside-section.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-aside.mjs +709 -0
- package/fesm2022/rt-tools-ui-kit-v2-aside.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs +214 -0
- package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-bar-list.mjs +53 -0
- package/fesm2022/rt-tools-ui-kit-v2-bar-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-bottom-sheet.mjs +88 -0
- package/fesm2022/rt-tools-ui-kit-v2-bottom-sheet.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-button.mjs +365 -0
- package/fesm2022/rt-tools-ui-kit-v2-button.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs +152 -0
- package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-card.mjs +72 -0
- package/fesm2022/rt-tools-ui-kit-v2-card.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs +111 -0
- package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-collapsible-text.mjs +76 -0
- package/fesm2022/rt-tools-ui-kit-v2-collapsible-text.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-confirm-popover.mjs +255 -0
- package/fesm2022/rt-tools-ui-kit-v2-confirm-popover.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-container.mjs +1326 -0
- package/fesm2022/rt-tools-ui-kit-v2-container.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs +81 -0
- package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs +2688 -0
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-counter-row.mjs +45 -0
- package/fesm2022/rt-tools-ui-kit-v2-counter-row.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-counter.mjs +158 -0
- package/fesm2022/rt-tools-ui-kit-v2-counter.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs +894 -0
- package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs +1217 -0
- package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs +779 -0
- package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs +573 -0
- package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-delta-view.mjs +141 -0
- package/fesm2022/rt-tools-ui-kit-v2-delta-view.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-detail-list.mjs +68 -0
- package/fesm2022/rt-tools-ui-kit-v2-detail-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dialog.mjs +478 -0
- package/fesm2022/rt-tools-ui-kit-v2-dialog.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dot-field.mjs +183 -0
- package/fesm2022/rt-tools-ui-kit-v2-dot-field.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-download-link.mjs +44 -0
- package/fesm2022/rt-tools-ui-kit-v2-download-link.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs +260 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +1036 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-empty-state.mjs +56 -0
- package/fesm2022/rt-tools-ui-kit-v2-empty-state.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs +107 -0
- package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-field.mjs +183 -0
- package/fesm2022/rt-tools-ui-kit-v2-field.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs +219 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-drop.mjs +214 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-drop.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-input.mjs +117 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-input.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-list.mjs +32 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs +91 -0
- package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs +220 -0
- package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-header.mjs +72 -0
- package/fesm2022/rt-tools-ui-kit-v2-header.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs +163 -0
- package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-icon.mjs +711 -0
- package/fesm2022/rt-tools-ui-kit-v2-icon.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-image-cropper.mjs +540 -0
- package/fesm2022/rt-tools-ui-kit-v2-image-cropper.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs +227 -0
- package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-info-item.mjs +37 -0
- package/fesm2022/rt-tools-ui-kit-v2-info-item.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs +361 -0
- package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-input.mjs +143 -0
- package/fesm2022/rt-tools-ui-kit-v2-input.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-live-badge.mjs +49 -0
- package/fesm2022/rt-tools-ui-kit-v2-live-badge.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-logo.mjs +97 -0
- package/fesm2022/rt-tools-ui-kit-v2-logo.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-markdown-text.mjs +57 -0
- package/fesm2022/rt-tools-ui-kit-v2-markdown-text.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-menu.mjs +537 -0
- package/fesm2022/rt-tools-ui-kit-v2-menu.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-message.mjs +105 -0
- package/fesm2022/rt-tools-ui-kit-v2-message.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-money-list.mjs +71 -0
- package/fesm2022/rt-tools-ui-kit-v2-money-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs +315 -0
- package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-night-grid.mjs +51 -0
- package/fesm2022/rt-tools-ui-kit-v2-night-grid.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-note.mjs +44 -0
- package/fesm2022/rt-tools-ui-kit-v2-note.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-notifications-bell.mjs +54 -0
- package/fesm2022/rt-tools-ui-kit-v2-notifications-bell.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +339 -0
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs +187 -0
- package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-photo-viewer.mjs +170 -0
- package/fesm2022/rt-tools-ui-kit-v2-photo-viewer.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-popover.mjs +312 -0
- package/fesm2022/rt-tools-ui-kit-v2-popover.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-prompt-suggestion.mjs +46 -0
- package/fesm2022/rt-tools-ui-kit-v2-prompt-suggestion.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs +174 -0
- package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-radius.mjs +56 -0
- package/fesm2022/rt-tools-ui-kit-v2-radius.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +336 -12
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-ripple.mjs +118 -0
- package/fesm2022/rt-tools-ui-kit-v2-ripple.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs +290 -0
- package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs +37 -0
- package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-select.mjs +495 -0
- package/fesm2022/rt-tools-ui-kit-v2-select.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +1493 -0
- package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-skeleton-wrapper.mjs +49 -0
- package/fesm2022/rt-tools-ui-kit-v2-skeleton-wrapper.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-skeleton.mjs +123 -0
- package/fesm2022/rt-tools-ui-kit-v2-skeleton.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-spinner.mjs +70 -0
- package/fesm2022/rt-tools-ui-kit-v2-spinner.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs +92 -0
- package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs +147 -0
- package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs +117 -0
- package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-table.mjs +1636 -0
- package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs +350 -0
- package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-tag.mjs +122 -0
- package/fesm2022/rt-tools-ui-kit-v2-tag.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs +85 -0
- package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs +73 -0
- package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +222 -0
- package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-timeline.mjs +39 -0
- package/fesm2022/rt-tools-ui-kit-v2-timeline.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-toast.mjs +338 -0
- package/fesm2022/rt-tools-ui-kit-v2-toast.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs +132 -0
- package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs +162 -0
- package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs +135 -0
- package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs +214 -0
- package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-welcome-dialog.mjs +64 -0
- package/fesm2022/rt-tools-ui-kit-v2-welcome-dialog.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs +263 -0
- package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs +296 -0
- package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2.mjs +94 -23819
- package/fesm2022/rt-tools-ui-kit-v2.mjs.map +1 -1
- package/package.json +361 -1
- package/rt-tools-ui-kit-v2-0.19.0.tgz +0 -0
- package/src/assets/icons/sparkle.svg +9 -0
- package/src/assets/icons/thumb-down.svg +10 -0
- package/src/assets/icons/thumb-up.svg +9 -0
- package/src/assets/icons/trash-x.svg +7 -0
- package/src/assets/icons-material/sparkle.fill.svg +5 -0
- package/src/assets/icons-material/sparkle.svg +5 -0
- package/src/assets/icons-material/thumb-down.fill.svg +5 -0
- package/src/assets/icons-material/thumb-down.svg +5 -0
- package/src/assets/icons-material/thumb-up.fill.svg +5 -0
- package/src/assets/icons-material/thumb-up.svg +5 -0
- package/src/assets/icons-material/trash-x.fill.svg +5 -0
- package/src/assets/icons-material/trash-x.svg +5 -0
- package/src/lib/components/action-bar/CONTEXT.md +8 -2
- package/src/lib/components/action-bar/rt-action-bar-holder.component.scss +10 -7
- package/src/lib/components/action-bar/rt-action-bar.component.scss +82 -34
- package/src/lib/components/ai-run-status/CONTEXT.md +36 -0
- package/src/lib/components/ai-run-status/rt-ai-run-status.component.scss +119 -0
- package/src/lib/components/aside/CONTEXT.md +1 -0
- package/src/lib/components/aside/header/rt-aside-header.component.scss +27 -11
- package/src/lib/components/copy-value/CONTEXT.md +31 -0
- package/src/lib/components/copy-value/rt-copy-value.component.scss +39 -0
- package/src/lib/components/data-list/settings/rt-data-list-settings-aside.component.scss +5 -5
- package/src/lib/components/dot-field/CONTEXT.md +31 -0
- package/src/lib/components/dot-field/rt-dot-field.component.scss +20 -0
- package/src/lib/components/dot-field/stories/component/CONTEXT.md +14 -0
- package/src/lib/components/dot-field/stories/component/test-dot-field.component.scss +31 -0
- package/src/lib/components/dynamic-selector/CONTEXT.md +18 -0
- package/src/lib/components/dynamic-selector/list/rt-dynamic-selector-list.component.scss +29 -1
- package/src/lib/components/dynamic-selector/popup/rt-dynamic-selector-popup.component.scss +84 -25
- package/src/lib/components/empty-state/CONTEXT.md +2 -1
- package/src/lib/components/empty-state/rt-empty-state.component.scss +4 -2
- package/src/lib/components/field/CONTEXT.md +18 -2
- package/src/lib/components/icon/CONTEXT.md +16 -12
- package/src/lib/components/icon/rt-icon.component.scss +13 -3
- package/src/lib/components/prompt-suggestion/CONTEXT.md +29 -0
- package/src/lib/components/prompt-suggestion/rt-prompt-suggestion.component.scss +58 -0
- package/src/lib/components/select/rt-select.component.scss +4 -0
- package/src/lib/components/thread-list/CONTEXT.md +4 -0
- package/src/lib/components/thread-list/rt-thread-list.component.scss +29 -0
- package/src/lib/components/toolbar/CONTEXT.md +4 -0
- package/src/lib/components/toolbar/rt-toolbar.component.scss +7 -0
- package/src/rich-editor/lib/components/ai-chat/CONTEXT.md +58 -0
- package/src/rich-editor/lib/components/ai-chat/answer/rt-ai-chat-answer.component.scss +12 -0
- package/src/rich-editor/lib/components/ai-chat/rt-ai-chat.component.scss +222 -0
- package/src/rich-editor/lib/components/rich-editor/rt-rich-editor.component.scss +3 -0
- package/src/styles/_scrollbar.scss +9 -0
- package/src/styles/_semantic.scss +1 -1
- package/styles/tokens.css +11 -8
- package/types/rt-tools-ui-kit-v2-accordion.d.ts +30 -0
- package/types/rt-tools-ui-kit-v2-action-bar.d.ts +149 -0
- package/types/rt-tools-ui-kit-v2-ai-run-status.d.ts +49 -0
- package/types/rt-tools-ui-kit-v2-aside-section.d.ts +25 -0
- package/types/rt-tools-ui-kit-v2-aside.d.ts +444 -0
- package/types/rt-tools-ui-kit-v2-autocomplete.d.ts +78 -0
- package/types/rt-tools-ui-kit-v2-bar-list.d.ts +41 -0
- package/types/rt-tools-ui-kit-v2-bottom-sheet.d.ts +20 -0
- package/types/rt-tools-ui-kit-v2-button.d.ts +76 -0
- package/types/rt-tools-ui-kit-v2-calendar.d.ts +96 -0
- package/types/rt-tools-ui-kit-v2-card.d.ts +38 -0
- package/types/rt-tools-ui-kit-v2-checkbox.d.ts +46 -0
- package/types/rt-tools-ui-kit-v2-collapsible-text.d.ts +20 -0
- package/types/rt-tools-ui-kit-v2-confirm-popover.d.ts +85 -0
- package/types/rt-tools-ui-kit-v2-container.d.ts +425 -0
- package/types/rt-tools-ui-kit-v2-copy-value.d.ts +29 -0
- package/types/rt-tools-ui-kit-v2-core.d.ts +1262 -0
- package/types/rt-tools-ui-kit-v2-counter-row.d.ts +22 -0
- package/types/rt-tools-ui-kit-v2-counter.d.ts +70 -0
- package/types/rt-tools-ui-kit-v2-data-list.d.ts +334 -0
- package/types/rt-tools-ui-kit-v2-data-table.d.ts +494 -0
- package/types/rt-tools-ui-kit-v2-date-picker.d.ts +181 -0
- package/types/rt-tools-ui-kit-v2-date-range.d.ts +98 -0
- package/types/rt-tools-ui-kit-v2-delta-view.d.ts +20 -0
- package/types/rt-tools-ui-kit-v2-detail-list.d.ts +33 -0
- package/types/rt-tools-ui-kit-v2-dialog.d.ts +287 -0
- package/types/rt-tools-ui-kit-v2-dot-field.d.ts +17 -0
- package/types/rt-tools-ui-kit-v2-download-link.d.ts +17 -0
- package/types/rt-tools-ui-kit-v2-dynamic-list.d.ts +139 -0
- package/types/rt-tools-ui-kit-v2-dynamic-selector.d.ts +423 -0
- package/types/rt-tools-ui-kit-v2-empty-state.d.ts +29 -0
- package/types/rt-tools-ui-kit-v2-expansion-panel.d.ts +57 -0
- package/types/rt-tools-ui-kit-v2-field.d.ts +82 -0
- package/types/rt-tools-ui-kit-v2-file-card.d.ts +114 -0
- package/types/rt-tools-ui-kit-v2-file-drop.d.ts +75 -0
- package/types/rt-tools-ui-kit-v2-file-input.d.ts +48 -0
- package/types/rt-tools-ui-kit-v2-file-list.d.ts +13 -0
- package/types/rt-tools-ui-kit-v2-filter-control.d.ts +72 -0
- package/types/rt-tools-ui-kit-v2-form-control.d.ts +74 -0
- package/types/rt-tools-ui-kit-v2-header.d.ts +40 -0
- package/types/rt-tools-ui-kit-v2-icon-button.d.ts +113 -0
- package/types/rt-tools-ui-kit-v2-icon.d.ts +246 -0
- package/types/rt-tools-ui-kit-v2-image-cropper.d.ts +168 -0
- package/types/rt-tools-ui-kit-v2-image-upload.d.ts +102 -0
- package/types/rt-tools-ui-kit-v2-info-item.d.ts +13 -0
- package/types/rt-tools-ui-kit-v2-input-number.d.ts +67 -0
- package/types/rt-tools-ui-kit-v2-input.d.ts +54 -0
- package/types/rt-tools-ui-kit-v2-live-badge.d.ts +23 -0
- package/types/rt-tools-ui-kit-v2-logo.d.ts +58 -0
- package/types/rt-tools-ui-kit-v2-markdown-text.d.ts +30 -0
- package/types/rt-tools-ui-kit-v2-menu.d.ts +217 -0
- package/types/rt-tools-ui-kit-v2-message.d.ts +56 -0
- package/types/rt-tools-ui-kit-v2-money-list.d.ts +34 -0
- package/types/rt-tools-ui-kit-v2-multiselect.d.ts +93 -0
- package/types/rt-tools-ui-kit-v2-night-grid.d.ts +39 -0
- package/types/rt-tools-ui-kit-v2-note.d.ts +21 -0
- package/types/rt-tools-ui-kit-v2-notifications-bell.d.ts +23 -0
- package/types/rt-tools-ui-kit-v2-page-header.d.ts +173 -0
- package/types/rt-tools-ui-kit-v2-pagination.d.ts +64 -0
- package/types/rt-tools-ui-kit-v2-photo-viewer.d.ts +98 -0
- package/types/rt-tools-ui-kit-v2-popover.d.ts +79 -0
- package/types/rt-tools-ui-kit-v2-prompt-suggestion.d.ts +21 -0
- package/types/rt-tools-ui-kit-v2-radio-button.d.ts +61 -0
- package/types/rt-tools-ui-kit-v2-radius.d.ts +37 -0
- package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +186 -2
- package/types/rt-tools-ui-kit-v2-ripple.d.ts +39 -0
- package/types/rt-tools-ui-kit-v2-scroll-area.d.ts +91 -0
- package/types/rt-tools-ui-kit-v2-section-nav.d.ts +23 -0
- package/types/rt-tools-ui-kit-v2-select.d.ts +215 -0
- package/types/rt-tools-ui-kit-v2-side-menu.d.ts +483 -0
- package/types/rt-tools-ui-kit-v2-skeleton-wrapper.d.ts +32 -0
- package/types/rt-tools-ui-kit-v2-skeleton.d.ts +41 -0
- package/types/rt-tools-ui-kit-v2-spinner.d.ts +56 -0
- package/types/rt-tools-ui-kit-v2-split-button.d.ts +72 -0
- package/types/rt-tools-ui-kit-v2-stat-tile.d.ts +81 -0
- package/types/rt-tools-ui-kit-v2-stepper.d.ts +51 -0
- package/types/rt-tools-ui-kit-v2-table.d.ts +739 -0
- package/types/rt-tools-ui-kit-v2-tabs.d.ts +153 -0
- package/types/rt-tools-ui-kit-v2-tag.d.ts +70 -0
- package/types/rt-tools-ui-kit-v2-textarea.d.ts +36 -0
- package/types/rt-tools-ui-kit-v2-theme-toggle.d.ts +43 -0
- package/types/rt-tools-ui-kit-v2-thread-list.d.ts +124 -0
- package/types/rt-tools-ui-kit-v2-timeline.d.ts +35 -0
- package/types/rt-tools-ui-kit-v2-toast.d.ts +103 -0
- package/types/rt-tools-ui-kit-v2-toggle-button-group.d.ts +109 -0
- package/types/rt-tools-ui-kit-v2-toggle-switch.d.ts +85 -0
- package/types/rt-tools-ui-kit-v2-toolbar.d.ts +66 -0
- package/types/rt-tools-ui-kit-v2-tooltip.d.ts +74 -0
- package/types/rt-tools-ui-kit-v2-welcome-dialog.d.ts +33 -0
- package/types/rt-tools-ui-kit-v2-workspace-details.d.ts +128 -0
- package/types/rt-tools-ui-kit-v2-workspace.d.ts +84 -0
- package/types/rt-tools-ui-kit-v2.d.ts +90 -9599
- package/rt-tools-ui-kit-v2-0.17.0.tgz +0 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { viewChild, computed, input, booleanAttribute, forwardRef, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';
|
|
4
|
+
import { rtKitLabel } from '@rt-tools/ui-kit-v2/core';
|
|
5
|
+
import { RtButtonDirective } from '@rt-tools/ui-kit-v2/button';
|
|
6
|
+
import { RtFileCardComponent } from '@rt-tools/ui-kit-v2/file-card';
|
|
7
|
+
import { RtFileListComponent } from '@rt-tools/ui-kit-v2/file-list';
|
|
8
|
+
import { RtFormControlBase } from '@rt-tools/ui-kit-v2/form-control';
|
|
9
|
+
|
|
10
|
+
const BEM_BLOCK = 'rt-file-input';
|
|
11
|
+
/**
|
|
12
|
+
* Поле выбора файлов: кнопка «выбрать» + список выбранных файлов карточками
|
|
13
|
+
* `rt-file-card` (иконка типа, имя, размер, удаление). Скрывает нативный
|
|
14
|
+
* `<input type="file">`, value хранит как `File[]` (одиночный режим = максимум
|
|
15
|
+
* один файл). CVA через общий `RtFormControlBase`. Read-only представление —
|
|
16
|
+
* имена файлов через запятую.
|
|
17
|
+
*
|
|
18
|
+
* Без drag-drop (MVP). `accept` пробрасывается в нативный input, `multiple`
|
|
19
|
+
* включает множественный выбор.
|
|
20
|
+
*/
|
|
21
|
+
class RtFileInputComponent extends RtFormControlBase {
|
|
22
|
+
constructor() {
|
|
23
|
+
super(...arguments);
|
|
24
|
+
this.#t_uiChooseFile = rtKitLabel('uiChooseFile');
|
|
25
|
+
this.fileEl = viewChild('fileEl', /* @ts-ignore */
|
|
26
|
+
...(ngDevMode ? [{ debugName: "fileEl" }] : /* istanbul ignore next */ []));
|
|
27
|
+
this.buttonText = computed(() => this.buttonLabel() || this.#t_uiChooseFile(), /* @ts-ignore */
|
|
28
|
+
...(ngDevMode ? [{ debugName: "buttonText" }] : /* istanbul ignore next */ []));
|
|
29
|
+
this.hasValue = computed(() => this.value().length > 0, /* @ts-ignore */
|
|
30
|
+
...(ngDevMode ? [{ debugName: "hasValue" }] : /* istanbul ignore next */ []));
|
|
31
|
+
this.displayText = computed(() => this.value()
|
|
32
|
+
.map((f) => f.name)
|
|
33
|
+
.join(', '), /* @ts-ignore */
|
|
34
|
+
...(ngDevMode ? [{ debugName: "displayText" }] : /* istanbul ignore next */ []));
|
|
35
|
+
this.multiple = input(false, { ...(ngDevMode ? { debugName: "multiple" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
36
|
+
this.accept = input(null, /* @ts-ignore */
|
|
37
|
+
...(ngDevMode ? [{ debugName: "accept" }] : /* istanbul ignore next */ []));
|
|
38
|
+
/**
|
|
39
|
+
* Выбор каталога целиком вместо отдельных файлов. Браузер отдаёт
|
|
40
|
+
* относительные пути (`webkitRelativePath`), по ним вызывающая сторона
|
|
41
|
+
* восстанавливает структуру — иначе пользователю пришлось бы выбирать
|
|
42
|
+
* десятки файлов по одному.
|
|
43
|
+
*/
|
|
44
|
+
this.directory = input(false, { ...(ngDevMode ? { debugName: "directory" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
45
|
+
/** Пусто — берётся переведённая подпись по умолчанию */
|
|
46
|
+
this.buttonLabel = input('', /* @ts-ignore */
|
|
47
|
+
...(ngDevMode ? [{ debugName: "buttonLabel" }] : /* istanbul ignore next */ []));
|
|
48
|
+
}
|
|
49
|
+
#t_uiChooseFile;
|
|
50
|
+
getEmptyValue() {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
focusAfterClear() {
|
|
54
|
+
// Скрытый native input фокусировать бессмысленно — фокус остаётся на кнопке.
|
|
55
|
+
}
|
|
56
|
+
openPicker() {
|
|
57
|
+
if (this.isDisabled()) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
this.fileEl()?.nativeElement.click();
|
|
61
|
+
}
|
|
62
|
+
onFiles(event) {
|
|
63
|
+
const list = event.target.files;
|
|
64
|
+
const files = list ? Array.from(list) : [];
|
|
65
|
+
const next = this.multiple() ? files : files.slice(0, 1);
|
|
66
|
+
this.value.set(next);
|
|
67
|
+
this.emitChange(next);
|
|
68
|
+
this.markTouched();
|
|
69
|
+
}
|
|
70
|
+
removeFile(index) {
|
|
71
|
+
if (this.isDisabled()) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const next = this.value().filter((_, i) => i !== index);
|
|
75
|
+
this.value.set(next);
|
|
76
|
+
this.emitChange(next);
|
|
77
|
+
// Сбрасываем native input, иначе повторный выбор того же файла не сработает.
|
|
78
|
+
const el = this.fileEl()?.nativeElement;
|
|
79
|
+
if (el) {
|
|
80
|
+
el.value = '';
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtFileInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
84
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtFileInputComponent, isStandalone: true, selector: "rt-file-input", inputs: { multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, directory: { classPropertyName: "directory", publicName: "directory", isSignal: true, isRequired: false, transformFunction: null }, buttonLabel: { classPropertyName: "buttonLabel", publicName: "buttonLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.rt-file-input--disabled": "isDisabled()", "class.rt-file-input--invalid": "isInvalid()", "class.rt-file-input--readonly": "isReadonly()" }, classAttribute: "rt-file-input" }, providers: [
|
|
85
|
+
// Алиас базового токена — для contentChild(RtFormControlBase) в rt-field.
|
|
86
|
+
{ provide: RtFormControlBase, useExisting: forwardRef(() => RtFileInputComponent) },
|
|
87
|
+
], viewQueries: [{ propertyName: "fileEl", first: true, predicate: ["fileEl"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ng-container rtBlock=\"rt-file-input\">\n @if (isReadonly()) {\n <span rtElem=\"readonly\" qa-dataid=\"file-input-readonly\" [rtMod]=\"{ empty: !displayText() }\">{{ displayText() || '\u2014' }}</span>\n } @else {\n <input\n #fileEl\n qa-dataid=\"file-input-native\"\n type=\"file\"\n hidden\n [multiple]=\"multiple()\"\n [disabled]=\"isDisabled()\"\n [attr.id]=\"effectiveControlId()\"\n [attr.accept]=\"accept()\"\n [attr.webkitdirectory]=\"directory() ? '' : null\"\n (change)=\"onFiles($event)\" />\n\n <button\n rtElem=\"trigger\"\n qa-dataid=\"file-input-trigger\"\n type=\"button\"\n rtButton\n appearance=\"outlined\"\n icon=\"ico-upload\"\n [label]=\"buttonText()\"\n [attr.aria-label]=\"buttonText()\"\n [disabled]=\"isDisabled()\"\n (click)=\"openPicker()\"></button>\n\n @if (value().length > 0) {\n <rt-file-list rtElem=\"list\" qa-dataid=\"file-input-list\">\n @for (file of value(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"file-input-file\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"isDisabled()\"\n (removed)=\"removeFile($index)\" />\n }\n </rt-file-list>\n }\n }\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-file-input{display:flex;flex-direction:column;align-items:flex-start;gap:var(--rt-space-sm)}.rt-file-input--disabled{opacity:var(--rt-input-disabled-opacity)}.rt-file-input__list{width:100%}.rt-file-input__readonly{color:var(--rt-field-value-color);font-size:var(--rt-field-value-font-size)}.rt-file-input__readonly--empty{color:var(--rt-field-value-empty-color)}}\n"], dependencies: [{ kind: "directive", type:
|
|
88
|
+
// standalone components / directives
|
|
89
|
+
RtButtonDirective, selector: "button[rtButton], a[rtButton]", inputs: ["label", "icon", "iconPos", "theme", "appearance", "size", "loading", "loadingIcon", "loadingLabel", "pressed"] }, { kind: "component", type: RtFileCardComponent, selector: "rt-file-card", inputs: ["name", "sizeBytes", "size", "showDownload", "showRemove", "showRename", "disabled"], outputs: ["download", "removed", "rename"] }, { kind: "component", type: RtFileListComponent, selector: "rt-file-list" }, { kind: "directive", type: BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }, { kind: "directive", type: ModDirective, selector: "[rtMod]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
90
|
+
}
|
|
91
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtFileInputComponent, decorators: [{
|
|
92
|
+
type: Component,
|
|
93
|
+
args: [{ selector: 'rt-file-input', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
94
|
+
// standalone components / directives
|
|
95
|
+
RtButtonDirective,
|
|
96
|
+
RtFileCardComponent,
|
|
97
|
+
RtFileListComponent,
|
|
98
|
+
BlockDirective,
|
|
99
|
+
ElemDirective,
|
|
100
|
+
ModDirective,
|
|
101
|
+
], providers: [
|
|
102
|
+
// Алиас базового токена — для contentChild(RtFormControlBase) в rt-field.
|
|
103
|
+
{ provide: RtFormControlBase, useExisting: forwardRef(() => RtFileInputComponent) },
|
|
104
|
+
], host: {
|
|
105
|
+
class: BEM_BLOCK,
|
|
106
|
+
'[class.rt-file-input--disabled]': 'isDisabled()',
|
|
107
|
+
'[class.rt-file-input--invalid]': 'isInvalid()',
|
|
108
|
+
'[class.rt-file-input--readonly]': 'isReadonly()',
|
|
109
|
+
}, template: "<ng-container rtBlock=\"rt-file-input\">\n @if (isReadonly()) {\n <span rtElem=\"readonly\" qa-dataid=\"file-input-readonly\" [rtMod]=\"{ empty: !displayText() }\">{{ displayText() || '\u2014' }}</span>\n } @else {\n <input\n #fileEl\n qa-dataid=\"file-input-native\"\n type=\"file\"\n hidden\n [multiple]=\"multiple()\"\n [disabled]=\"isDisabled()\"\n [attr.id]=\"effectiveControlId()\"\n [attr.accept]=\"accept()\"\n [attr.webkitdirectory]=\"directory() ? '' : null\"\n (change)=\"onFiles($event)\" />\n\n <button\n rtElem=\"trigger\"\n qa-dataid=\"file-input-trigger\"\n type=\"button\"\n rtButton\n appearance=\"outlined\"\n icon=\"ico-upload\"\n [label]=\"buttonText()\"\n [attr.aria-label]=\"buttonText()\"\n [disabled]=\"isDisabled()\"\n (click)=\"openPicker()\"></button>\n\n @if (value().length > 0) {\n <rt-file-list rtElem=\"list\" qa-dataid=\"file-input-list\">\n @for (file of value(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"file-input-file\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"isDisabled()\"\n (removed)=\"removeFile($index)\" />\n }\n </rt-file-list>\n }\n }\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-file-input{display:flex;flex-direction:column;align-items:flex-start;gap:var(--rt-space-sm)}.rt-file-input--disabled{opacity:var(--rt-input-disabled-opacity)}.rt-file-input__list{width:100%}.rt-file-input__readonly{color:var(--rt-field-value-color);font-size:var(--rt-field-value-font-size)}.rt-file-input__readonly--empty{color:var(--rt-field-value-empty-color)}}\n"] }]
|
|
110
|
+
}], propDecorators: { fileEl: [{ type: i0.ViewChild, args: ['fileEl', { isSignal: true }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], directory: [{ type: i0.Input, args: [{ isSignal: true, alias: "directory", required: false }] }], buttonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonLabel", required: false }] }] } });
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Generated bundle index. Do not edit.
|
|
114
|
+
*/
|
|
115
|
+
|
|
116
|
+
export { RtFileInputComponent };
|
|
117
|
+
//# sourceMappingURL=rt-tools-ui-kit-v2-file-input.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-file-input.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/file-input/rt-file-input.component.ts","../../../projects/ui-kit-v2/src/lib/components/file-input/rt-file-input.component.html","../../../projects/ui-kit-v2/src/lib/components/file-input/rt-tools-ui-kit-v2-file-input.ts"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n forwardRef,\n input,\n InputSignal,\n InputSignalWithTransform,\n Signal,\n viewChild,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { RtButtonDirective } from '@rt-tools/ui-kit-v2/button';\nimport { RtFileCardComponent } from '@rt-tools/ui-kit-v2/file-card';\nimport { RtFileListComponent } from '@rt-tools/ui-kit-v2/file-list';\nimport { RtFormControlBase } from '@rt-tools/ui-kit-v2/form-control';\n\nconst BEM_BLOCK: string = 'rt-file-input';\n\n/**\n * Поле выбора файлов: кнопка «выбрать» + список выбранных файлов карточками\n * `rt-file-card` (иконка типа, имя, размер, удаление). Скрывает нативный\n * `<input type=\"file\">`, value хранит как `File[]` (одиночный режим = максимум\n * один файл). CVA через общий `RtFormControlBase`. Read-only представление —\n * имена файлов через запятую.\n *\n * Без drag-drop (MVP). `accept` пробрасывается в нативный input, `multiple`\n * включает множественный выбор.\n */\n@Component({\n selector: 'rt-file-input',\n templateUrl: './rt-file-input.component.html',\n styleUrls: ['./rt-file-input.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtButtonDirective,\n RtFileCardComponent,\n RtFileListComponent,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n providers: [\n // Алиас базового токена — для contentChild(RtFormControlBase) в rt-field.\n { provide: RtFormControlBase, useExisting: forwardRef(() => RtFileInputComponent) },\n ],\n host: {\n class: BEM_BLOCK,\n '[class.rt-file-input--disabled]': 'isDisabled()',\n '[class.rt-file-input--invalid]': 'isInvalid()',\n '[class.rt-file-input--readonly]': 'isReadonly()',\n },\n})\nexport class RtFileInputComponent extends RtFormControlBase<File[]> {\n readonly #t_uiChooseFile: Signal<string> = rtKitLabel('uiChooseFile');\n\n protected readonly fileEl: Signal<ElementRef<HTMLInputElement> | undefined> = viewChild<ElementRef<HTMLInputElement>>('fileEl');\n\n protected readonly buttonText: Signal<string> = computed((): string => this.buttonLabel() || this.#t_uiChooseFile());\n\n protected readonly hasValue: Signal<boolean> = computed((): boolean => this.value().length > 0);\n\n public readonly displayText: Signal<string> = computed((): string =>\n this.value()\n .map((f: File): string => f.name)\n .join(', ')\n );\n\n public readonly multiple: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n public readonly accept: InputSignal<string | null> = input<string | null>(null);\n\n /**\n * Выбор каталога целиком вместо отдельных файлов. Браузер отдаёт\n * относительные пути (`webkitRelativePath`), по ним вызывающая сторона\n * восстанавливает структуру — иначе пользователю пришлось бы выбирать\n * десятки файлов по одному.\n */\n public readonly directory: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n /** Пусто — берётся переведённая подпись по умолчанию */\n public readonly buttonLabel: InputSignal<string> = input<string>('');\n\n protected getEmptyValue(): File[] {\n return [];\n }\n\n protected focusAfterClear(): void {\n // Скрытый native input фокусировать бессмысленно — фокус остаётся на кнопке.\n }\n\n protected openPicker(): void {\n if (this.isDisabled()) {\n return;\n }\n this.fileEl()?.nativeElement.click();\n }\n\n protected onFiles(event: Event): void {\n const list: FileList | null = (event.target as HTMLInputElement).files;\n const files: File[] = list ? Array.from(list) : [];\n const next: File[] = this.multiple() ? files : files.slice(0, 1);\n this.value.set(next);\n this.emitChange(next);\n this.markTouched();\n }\n\n protected removeFile(index: number): void {\n if (this.isDisabled()) {\n return;\n }\n const next: File[] = this.value().filter((_: File, i: number): boolean => i !== index);\n this.value.set(next);\n this.emitChange(next);\n // Сбрасываем native input, иначе повторный выбор того же файла не сработает.\n const el: HTMLInputElement | undefined = this.fileEl()?.nativeElement;\n if (el) {\n el.value = '';\n }\n }\n}\n","<ng-container rtBlock=\"rt-file-input\">\n @if (isReadonly()) {\n <span rtElem=\"readonly\" qa-dataid=\"file-input-readonly\" [rtMod]=\"{ empty: !displayText() }\">{{ displayText() || '—' }}</span>\n } @else {\n <input\n #fileEl\n qa-dataid=\"file-input-native\"\n type=\"file\"\n hidden\n [multiple]=\"multiple()\"\n [disabled]=\"isDisabled()\"\n [attr.id]=\"effectiveControlId()\"\n [attr.accept]=\"accept()\"\n [attr.webkitdirectory]=\"directory() ? '' : null\"\n (change)=\"onFiles($event)\" />\n\n <button\n rtElem=\"trigger\"\n qa-dataid=\"file-input-trigger\"\n type=\"button\"\n rtButton\n appearance=\"outlined\"\n icon=\"ico-upload\"\n [label]=\"buttonText()\"\n [attr.aria-label]=\"buttonText()\"\n [disabled]=\"isDisabled()\"\n (click)=\"openPicker()\"></button>\n\n @if (value().length > 0) {\n <rt-file-list rtElem=\"list\" qa-dataid=\"file-input-list\">\n @for (file of value(); track $index) {\n <rt-file-card\n showRemove\n qa-dataid=\"file-input-file\"\n [name]=\"file.name\"\n [sizeBytes]=\"file.size\"\n [disabled]=\"isDisabled()\"\n (removed)=\"removeFile($index)\" />\n }\n </rt-file-list>\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,32 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { BlockDirective } from '@rt-tools/core';
|
|
4
|
+
|
|
5
|
+
const BEM_BLOCK = 'rt-file-list';
|
|
6
|
+
/**
|
|
7
|
+
* Вертикальный контейнер для карточек файлов (`rt-file-card`): задаёт отступы между
|
|
8
|
+
* карточками и растягивает их по ширине. Чисто презентационный — содержимое
|
|
9
|
+
* проецируется через `<ng-content />`, логику списка держит caller.
|
|
10
|
+
*/
|
|
11
|
+
class RtFileListComponent {
|
|
12
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtFileListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
13
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: RtFileListComponent, isStandalone: true, selector: "rt-file-list", host: { classAttribute: "rt-file-list" }, ngImport: i0, template: "<ng-container rtBlock=\"rt-file-list\">\n <ng-content />\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-file-list{display:flex;width:100%;flex-direction:column;gap:var(--rt-space-sm)}}\n"], dependencies: [{ kind: "directive", type:
|
|
14
|
+
// standalone components / directives
|
|
15
|
+
BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
16
|
+
}
|
|
17
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtFileListComponent, decorators: [{
|
|
18
|
+
type: Component,
|
|
19
|
+
args: [{ selector: 'rt-file-list', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
20
|
+
// standalone components / directives
|
|
21
|
+
BlockDirective,
|
|
22
|
+
], host: {
|
|
23
|
+
class: BEM_BLOCK,
|
|
24
|
+
}, template: "<ng-container rtBlock=\"rt-file-list\">\n <ng-content />\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-file-list{display:flex;width:100%;flex-direction:column;gap:var(--rt-space-sm)}}\n"] }]
|
|
25
|
+
}] });
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Generated bundle index. Do not edit.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
export { RtFileListComponent };
|
|
32
|
+
//# sourceMappingURL=rt-tools-ui-kit-v2-file-list.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-file-list.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/file-list/rt-file-list.component.ts","../../../projects/ui-kit-v2/src/lib/components/file-list/rt-file-list.component.html","../../../projects/ui-kit-v2/src/lib/components/file-list/rt-tools-ui-kit-v2-file-list.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, ViewEncapsulation } from '@angular/core';\n\nimport { BlockDirective } from '@rt-tools/core';\n\nconst BEM_BLOCK: string = 'rt-file-list';\n\n/**\n * Вертикальный контейнер для карточек файлов (`rt-file-card`): задаёт отступы между\n * карточками и растягивает их по ширине. Чисто презентационный — содержимое\n * проецируется через `<ng-content />`, логику списка держит caller.\n */\n@Component({\n selector: 'rt-file-list',\n templateUrl: './rt-file-list.component.html',\n styleUrls: ['./rt-file-list.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n BlockDirective,\n ],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtFileListComponent {}\n","<ng-container rtBlock=\"rt-file-list\">\n <ng-content />\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAIA,MAAM,SAAS,GAAW,cAAc;AAExC;;;;AAIG;MAeU,mBAAmB,CAAA;8GAAnB,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,kHCzBhC,gFAGA,EAAA,MAAA,EAAA,CAAA,oIAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA;;gBDgBQ,cAAc,EAAA,QAAA,EAAA,WAAA,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;;2FAMT,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAd/B,SAAS;+BACI,cAAc,EAAA,eAAA,EAGP,uBAAuB,CAAC,MAAM,iBAChC,iBAAiB,CAAC,IAAI,EAAA,OAAA,EAC5B;;wBAEL,cAAc;qBACjB,EAAA,IAAA,EACK;AACF,wBAAA,KAAK,EAAE,SAAS;AACnB,qBAAA,EAAA,QAAA,EAAA,gFAAA,EAAA,MAAA,EAAA,CAAA,oIAAA,CAAA,EAAA;;;AEvBL;;AAEG;;;;"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, computed, input, booleanAttribute, output, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import * as i1 from '@angular/forms';
|
|
4
|
+
import { FormsModule } from '@angular/forms';
|
|
5
|
+
import { BreakpointsService } from '@rt-tools/ui-kit-v2/core';
|
|
6
|
+
import { RtSelectComponent } from '@rt-tools/ui-kit-v2/select';
|
|
7
|
+
import { RtToggleButtonGroupComponent } from '@rt-tools/ui-kit-v2/toggle-button-group';
|
|
8
|
+
|
|
9
|
+
const BEM_BLOCK = 'rt-filter-control';
|
|
10
|
+
/**
|
|
11
|
+
* Адаптивный фильтр-контрол для тулбаров list-страниц.
|
|
12
|
+
*
|
|
13
|
+
* Один и тот же набор опций рендерится двумя способами по ширине вьюпорта:
|
|
14
|
+
* - десктоп (> 1080px) — развёрнутые сегменты `rt-toggle-button-group`;
|
|
15
|
+
* - узкий экран (≤ 1080px, `BreakpointsService.narrow`) — компактный
|
|
16
|
+
* `rt-select` с `clearable=false` (сброс — через явную опцию «Все»).
|
|
17
|
+
*
|
|
18
|
+
* API повторяет controlled-контракт rt-toggle-button-group (`[options]` /
|
|
19
|
+
* `[value]` / `(valueChange)`), поэтому миграция потребителя — смена селектора
|
|
20
|
+
* без правки хендлеров. Sentinel «нет фильтра» задаёт сам потребитель реальным
|
|
21
|
+
* значением опции («»/false), а не `null`/`undefined` — rt-select всегда
|
|
22
|
+
* показывает выбранную опцию.
|
|
23
|
+
*
|
|
24
|
+
* Generic `<T = string>` сохраняет типизацию по value (union'ы, enum'ы).
|
|
25
|
+
*/
|
|
26
|
+
class RtFilterControlComponent {
|
|
27
|
+
constructor() {
|
|
28
|
+
this.#breakpoints = inject(BreakpointsService);
|
|
29
|
+
this.isNarrow = this.#breakpoints.narrow;
|
|
30
|
+
/** Проекция опций фильтра в форму rt-select (icon/title отбрасываются). */
|
|
31
|
+
this.selectOptions = computed(() => this.options().map((option) => ({
|
|
32
|
+
label: option.label,
|
|
33
|
+
value: option.value,
|
|
34
|
+
})), /* @ts-ignore */
|
|
35
|
+
...(ngDevMode ? [{ debugName: "selectOptions" }] : /* istanbul ignore next */ []));
|
|
36
|
+
this.options = input.required(/* @ts-ignore */
|
|
37
|
+
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
38
|
+
this.value = input(undefined, /* @ts-ignore */
|
|
39
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
40
|
+
this.ariaLabel = input(null, /* @ts-ignore */
|
|
41
|
+
...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
42
|
+
this.placeholder = input('', /* @ts-ignore */
|
|
43
|
+
...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
44
|
+
/**
|
|
45
|
+
* Размер сегментов (десктоп). На узком экране select всегда рендерится в md,
|
|
46
|
+
* чтобы совпадать по высоте и ширине со строкой поиска list-страницы.
|
|
47
|
+
*/
|
|
48
|
+
this.size = input('sm', /* @ts-ignore */
|
|
49
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
50
|
+
this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
51
|
+
/** Растягивает сегменты на всю ширину контейнера (только десктоп-вариант). */
|
|
52
|
+
this.fullWidth = input(false, { ...(ngDevMode ? { debugName: "fullWidth" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
53
|
+
this.valueChange = output();
|
|
54
|
+
}
|
|
55
|
+
#breakpoints;
|
|
56
|
+
onValueChange(value) {
|
|
57
|
+
this.valueChange.emit(value);
|
|
58
|
+
}
|
|
59
|
+
onSelectionChange(value) {
|
|
60
|
+
// rt-select с clearable=false и явной опцией «Все» не эмитит null,
|
|
61
|
+
// но guard оставляем на случай программной очистки.
|
|
62
|
+
if (value !== null) {
|
|
63
|
+
this.valueChange.emit(value);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtFilterControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
67
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtFilterControlComponent, isStandalone: true, selector: "rt-filter-control", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, host: { classAttribute: "rt-filter-control" }, ngImport: i0, template: "@if (isNarrow()) {\n <rt-select\n qa-dataid=\"filter-control-select\"\n size=\"md\"\n [options]=\"selectOptions()\"\n [placeholder]=\"placeholder()\"\n [ariaLabel]=\"ariaLabel()\"\n [clearable]=\"false\"\n [disabled]=\"disabled()\"\n [ngModel]=\"value()\"\n (selectionChange)=\"onSelectionChange($event)\" />\n} @else {\n <rt-toggle-button-group\n qa-dataid=\"filter-control-group\"\n [options]=\"options()\"\n [value]=\"value()\"\n [ariaLabel]=\"ariaLabel()\"\n [size]=\"size()\"\n [disabled]=\"disabled()\"\n [fullWidth]=\"fullWidth()\"\n (valueChange)=\"onValueChange($event)\" />\n}\n", styles: ["@layer rt-kit.components{.rt-filter-control{display:inline-flex}@media(width<=1080px){.rt-filter-control{display:block}.rt-filter-control .rt-select{inline-size:100%;max-inline-size:var(--rt-input-max-width)}}@media(width<=768px){.rt-filter-control{inline-size:100%}}}\n"], dependencies: [{ kind: "ngmodule", type:
|
|
68
|
+
// Angular
|
|
69
|
+
FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type:
|
|
70
|
+
// standalone components / directives
|
|
71
|
+
RtSelectComponent, selector: "rt-select", inputs: ["appearance", "options", "placeholder", "iconLeft", "filter", "filterPlaceholder", "panelWidth", "panelMaxHeight"], outputs: ["selectionChange"] }, { kind: "component", type: RtToggleButtonGroupComponent, selector: "rt-toggle-button-group", inputs: ["options", "value", "multiple", "values", "ariaLabel", "size", "disabled", "fullWidth"], outputs: ["valueChange", "valuesChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
72
|
+
}
|
|
73
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtFilterControlComponent, decorators: [{
|
|
74
|
+
type: Component,
|
|
75
|
+
args: [{ selector: 'rt-filter-control', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
76
|
+
// Angular
|
|
77
|
+
FormsModule,
|
|
78
|
+
// standalone components / directives
|
|
79
|
+
RtSelectComponent,
|
|
80
|
+
RtToggleButtonGroupComponent,
|
|
81
|
+
], host: {
|
|
82
|
+
class: BEM_BLOCK,
|
|
83
|
+
}, template: "@if (isNarrow()) {\n <rt-select\n qa-dataid=\"filter-control-select\"\n size=\"md\"\n [options]=\"selectOptions()\"\n [placeholder]=\"placeholder()\"\n [ariaLabel]=\"ariaLabel()\"\n [clearable]=\"false\"\n [disabled]=\"disabled()\"\n [ngModel]=\"value()\"\n (selectionChange)=\"onSelectionChange($event)\" />\n} @else {\n <rt-toggle-button-group\n qa-dataid=\"filter-control-group\"\n [options]=\"options()\"\n [value]=\"value()\"\n [ariaLabel]=\"ariaLabel()\"\n [size]=\"size()\"\n [disabled]=\"disabled()\"\n [fullWidth]=\"fullWidth()\"\n (valueChange)=\"onValueChange($event)\" />\n}\n", styles: ["@layer rt-kit.components{.rt-filter-control{display:inline-flex}@media(width<=1080px){.rt-filter-control{display:block}.rt-filter-control .rt-select{inline-size:100%;max-inline-size:var(--rt-input-max-width)}}@media(width<=768px){.rt-filter-control{inline-size:100%}}}\n"] }]
|
|
84
|
+
}], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Generated bundle index. Do not edit.
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
export { RtFilterControlComponent };
|
|
91
|
+
//# sourceMappingURL=rt-tools-ui-kit-v2-filter-control.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-filter-control.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/filter-control/rt-filter-control.component.ts","../../../projects/ui-kit-v2/src/lib/components/filter-control/rt-filter-control.component.html","../../../projects/ui-kit-v2/src/lib/components/filter-control/rt-tools-ui-kit-v2-filter-control.ts"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n input,\n InputSignal,\n InputSignalWithTransform,\n output,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { BreakpointsService } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtSelectComponent } from '@rt-tools/ui-kit-v2/select';\nimport { IRtSelect } from '@rt-tools/ui-kit-v2/select';\nimport { RtToggleButtonGroupComponent } from '@rt-tools/ui-kit-v2/toggle-button-group';\nimport { IRtFilterControl } from './rt-filter-control.model';\n\nconst BEM_BLOCK: string = 'rt-filter-control';\n\n/**\n * Адаптивный фильтр-контрол для тулбаров list-страниц.\n *\n * Один и тот же набор опций рендерится двумя способами по ширине вьюпорта:\n * - десктоп (> 1080px) — развёрнутые сегменты `rt-toggle-button-group`;\n * - узкий экран (≤ 1080px, `BreakpointsService.narrow`) — компактный\n * `rt-select` с `clearable=false` (сброс — через явную опцию «Все»).\n *\n * API повторяет controlled-контракт rt-toggle-button-group (`[options]` /\n * `[value]` / `(valueChange)`), поэтому миграция потребителя — смена селектора\n * без правки хендлеров. Sentinel «нет фильтра» задаёт сам потребитель реальным\n * значением опции («»/false), а не `null`/`undefined` — rt-select всегда\n * показывает выбранную опцию.\n *\n * Generic `<T = string>` сохраняет типизацию по value (union'ы, enum'ы).\n */\n@Component({\n selector: 'rt-filter-control',\n templateUrl: './rt-filter-control.component.html',\n styleUrls: ['./rt-filter-control.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // Angular\n FormsModule,\n\n // standalone components / directives\n RtSelectComponent,\n RtToggleButtonGroupComponent,\n ],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtFilterControlComponent<T = string> {\n readonly #breakpoints: BreakpointsService = inject(BreakpointsService);\n\n protected readonly isNarrow: Signal<boolean> = this.#breakpoints.narrow;\n\n /** Проекция опций фильтра в форму rt-select (icon/title отбрасываются). */\n protected readonly selectOptions: Signal<ReadonlyArray<IRtSelect.Option<T>>> = computed((): ReadonlyArray<IRtSelect.Option<T>> =>\n this.options().map((option: IRtFilterControl.Option<T>): IRtSelect.Option<T> => ({\n label: option.label,\n value: option.value,\n }))\n );\n\n public readonly options: InputSignal<ReadonlyArray<IRtFilterControl.Option<T>>> =\n input.required<ReadonlyArray<IRtFilterControl.Option<T>>>();\n\n public readonly value: InputSignal<T | undefined> = input<T | undefined>(undefined);\n\n public readonly ariaLabel: InputSignal<string | null> = input<string | null>(null);\n\n public readonly placeholder: InputSignal<string> = input<string>('');\n\n /**\n * Размер сегментов (десктоп). На узком экране select всегда рендерится в md,\n * чтобы совпадать по высоте и ширине со строкой поиска list-страницы.\n */\n public readonly size: InputSignal<IRtFilterControl.Size> = input<IRtFilterControl.Size>('sm');\n\n public readonly disabled: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Растягивает сегменты на всю ширину контейнера (только десктоп-вариант). */\n public readonly fullWidth: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly valueChange: OutputEmitterRef<T> = output<T>();\n\n protected onValueChange(value: T): void {\n this.valueChange.emit(value);\n }\n\n protected onSelectionChange(value: T | null): void {\n // rt-select с clearable=false и явной опцией «Все» не эмитит null,\n // но guard оставляем на случай программной очистки.\n if (value !== null) {\n this.valueChange.emit(value);\n }\n }\n}\n","@if (isNarrow()) {\n <rt-select\n qa-dataid=\"filter-control-select\"\n size=\"md\"\n [options]=\"selectOptions()\"\n [placeholder]=\"placeholder()\"\n [ariaLabel]=\"ariaLabel()\"\n [clearable]=\"false\"\n [disabled]=\"disabled()\"\n [ngModel]=\"value()\"\n (selectionChange)=\"onSelectionChange($event)\" />\n} @else {\n <rt-toggle-button-group\n qa-dataid=\"filter-control-group\"\n [options]=\"options()\"\n [value]=\"value()\"\n [ariaLabel]=\"ariaLabel()\"\n [size]=\"size()\"\n [disabled]=\"disabled()\"\n [fullWidth]=\"fullWidth()\"\n (valueChange)=\"onValueChange($event)\" />\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, DestroyRef, signal, computed, input, booleanAttribute, Directive } from '@angular/core';
|
|
3
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
4
|
+
import { Validators, NgControl } from '@angular/forms';
|
|
5
|
+
|
|
6
|
+
/** Состояние поля, которому форма ещё ничего не сказала. */
|
|
7
|
+
const PRISTINE_STATE = { invalid: false, errors: null, required: false, interacted: false };
|
|
8
|
+
/** Рассылает ли контрол своё состояние. Переходник сигнальной формы — не рассылает. */
|
|
9
|
+
function emitsEvents(control) {
|
|
10
|
+
return typeof control.events?.pipe === 'function';
|
|
11
|
+
}
|
|
12
|
+
/** Состояние формы, снятое с контрола любого рода. */
|
|
13
|
+
function stateOf(control) {
|
|
14
|
+
return {
|
|
15
|
+
invalid: !!control.invalid && (control.touched || control.dirty),
|
|
16
|
+
errors: control.errors,
|
|
17
|
+
required: control.hasValidator(Validators.required),
|
|
18
|
+
interacted: control.touched || control.dirty,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
class RtFormControlBase {
|
|
22
|
+
#ngControl;
|
|
23
|
+
#destroyRef;
|
|
24
|
+
#onChange;
|
|
25
|
+
#onTouched;
|
|
26
|
+
// Состояние, которым управляет родительский rt-field (через публичные сеттеры):
|
|
27
|
+
// авто-id для связки label[for], read-only режим, зеркало ошибок/required.
|
|
28
|
+
#controlIdAssigned;
|
|
29
|
+
#readonlyAssigned;
|
|
30
|
+
/**
|
|
31
|
+
* Обязательность, объявленная полем. Шаблонная форма валидатора на контрол не кладёт, и без
|
|
32
|
+
* этого признака её обязательное поле не получало бы ни звёздочки, ни ошибки.
|
|
33
|
+
*/
|
|
34
|
+
#requiredAssigned;
|
|
35
|
+
/** Состояние, разосланное прежней привязкой: её контрол сигналами не читается. */
|
|
36
|
+
#pushedState;
|
|
37
|
+
/**
|
|
38
|
+
* Контрол сигнальной привязки. Его состояние не рассылается, а читается геттерами, и
|
|
39
|
+
* внутри геттеров стоят вызовы сигналов формы — то есть из `computed` оно реактивно.
|
|
40
|
+
*/
|
|
41
|
+
#signalControl;
|
|
42
|
+
/** Отключение, назначенное формой через CVA (`setDisabledState`). */
|
|
43
|
+
#disabledByForm;
|
|
44
|
+
/** Состояние формы: у сигнальной привязки читается, у прежней берётся разосланное. */
|
|
45
|
+
#state;
|
|
46
|
+
/**
|
|
47
|
+
* Пустое поле, обязательное по слову rt-field, которого уже коснулись. Валидатор формы здесь
|
|
48
|
+
* не нужен: его ошибку контрол и так получает от формы.
|
|
49
|
+
*/
|
|
50
|
+
#missingRequired;
|
|
51
|
+
constructor() {
|
|
52
|
+
this.#ngControl = inject(NgControl, { self: true, optional: true });
|
|
53
|
+
this.#destroyRef = inject(DestroyRef);
|
|
54
|
+
this.#onChange = () => undefined;
|
|
55
|
+
this.#onTouched = () => undefined;
|
|
56
|
+
// Состояние, которым управляет родительский rt-field (через публичные сеттеры):
|
|
57
|
+
// авто-id для связки label[for], read-only режим, зеркало ошибок/required.
|
|
58
|
+
this.#controlIdAssigned = signal(null, /* @ts-ignore */
|
|
59
|
+
...(ngDevMode ? [{ debugName: "#controlIdAssigned" }] : /* istanbul ignore next */ []));
|
|
60
|
+
this.#readonlyAssigned = signal(false, /* @ts-ignore */
|
|
61
|
+
...(ngDevMode ? [{ debugName: "#readonlyAssigned" }] : /* istanbul ignore next */ []));
|
|
62
|
+
/**
|
|
63
|
+
* Обязательность, объявленная полем. Шаблонная форма валидатора на контрол не кладёт, и без
|
|
64
|
+
* этого признака её обязательное поле не получало бы ни звёздочки, ни ошибки.
|
|
65
|
+
*/
|
|
66
|
+
this.#requiredAssigned = signal(false, /* @ts-ignore */
|
|
67
|
+
...(ngDevMode ? [{ debugName: "#requiredAssigned" }] : /* istanbul ignore next */ []));
|
|
68
|
+
/** Состояние, разосланное прежней привязкой: её контрол сигналами не читается. */
|
|
69
|
+
this.#pushedState = signal(PRISTINE_STATE, /* @ts-ignore */
|
|
70
|
+
...(ngDevMode ? [{ debugName: "#pushedState" }] : /* istanbul ignore next */ []));
|
|
71
|
+
/**
|
|
72
|
+
* Контрол сигнальной привязки. Его состояние не рассылается, а читается геттерами, и
|
|
73
|
+
* внутри геттеров стоят вызовы сигналов формы — то есть из `computed` оно реактивно.
|
|
74
|
+
*/
|
|
75
|
+
this.#signalControl = signal(null, /* @ts-ignore */
|
|
76
|
+
...(ngDevMode ? [{ debugName: "#signalControl" }] : /* istanbul ignore next */ []));
|
|
77
|
+
/** Отключение, назначенное формой через CVA (`setDisabledState`). */
|
|
78
|
+
this.#disabledByForm = signal(false, /* @ts-ignore */
|
|
79
|
+
...(ngDevMode ? [{ debugName: "#disabledByForm" }] : /* istanbul ignore next */ []));
|
|
80
|
+
/**
|
|
81
|
+
* Отключение: вход и форма — два независимых источника, поле отключено,
|
|
82
|
+
* если так сказал любой из них. Сводить их в один signal нельзя: форма
|
|
83
|
+
* зовёт `setDisabledState` при связывании контрола, то есть раньше, чем
|
|
84
|
+
* поле впервые обновит своё вью, и мирроринг входа затирал бы её слово —
|
|
85
|
+
* контрол, созданный отключённым, оказывался бы редактируемым.
|
|
86
|
+
*/
|
|
87
|
+
this.isDisabled = computed(() => this.disabled() || this.#disabledByForm(), /* @ts-ignore */
|
|
88
|
+
...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
89
|
+
/** Состояние формы: у сигнальной привязки читается, у прежней берётся разосланное. */
|
|
90
|
+
this.#state = computed(() => {
|
|
91
|
+
const control = this.#signalControl();
|
|
92
|
+
return control === null ? this.#pushedState() : stateOf(control);
|
|
93
|
+
}, /* @ts-ignore */
|
|
94
|
+
...(ngDevMode ? [{ debugName: "#state" }] : /* istanbul ignore next */ []));
|
|
95
|
+
/**
|
|
96
|
+
* Пустое поле, обязательное по слову rt-field, которого уже коснулись. Валидатор формы здесь
|
|
97
|
+
* не нужен: его ошибку контрол и так получает от формы.
|
|
98
|
+
*/
|
|
99
|
+
this.#missingRequired = computed(() => this.#requiredAssigned() && !this.#state().required && this.#state().interacted && !this.hasValue(), /* @ts-ignore */
|
|
100
|
+
...(ngDevMode ? [{ debugName: "#missingRequired" }] : /* istanbul ignore next */ []));
|
|
101
|
+
this.isInvalid = computed(() => this.#state().invalid || this.#missingRequired(), /* @ts-ignore */
|
|
102
|
+
...(ngDevMode ? [{ debugName: "isInvalid" }] : /* istanbul ignore next */ []));
|
|
103
|
+
/** Видимость кнопки очистки: включена, есть значение, поле активно. */
|
|
104
|
+
this.showClearButton = computed(() => this.clearable() && this.hasValue() && !this.isDisabled(), /* @ts-ignore */
|
|
105
|
+
...(ngDevMode ? [{ debugName: "showClearButton" }] : /* istanbul ignore next */ []));
|
|
106
|
+
this.size = input('md', /* @ts-ignore */
|
|
107
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
108
|
+
this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
109
|
+
this.controlId = input(null, /* @ts-ignore */
|
|
110
|
+
...(ngDevMode ? [{ debugName: "controlId" }] : /* istanbul ignore next */ []));
|
|
111
|
+
this.ariaLabel = input(null, /* @ts-ignore */
|
|
112
|
+
...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
113
|
+
this.clearable = input(true, { ...(ngDevMode ? { debugName: "clearable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
114
|
+
/**
|
|
115
|
+
* Видимая resting-рамка контрола. По умолчанию `true` — рамка видна на обеих
|
|
116
|
+
* темах. `false` снимает только resting-рамку; focus/invalid состояния свою
|
|
117
|
+
* рамку показывают всё равно, read-only остаётся плоским.
|
|
118
|
+
*/
|
|
119
|
+
this.bordered = input(true, { ...(ngDevMode ? { debugName: "bordered" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
120
|
+
/** Итоговый id поля: явный input важнее авто-id, назначенного rt-field. */
|
|
121
|
+
this.effectiveControlId = computed(() => this.controlId() ?? this.#controlIdAssigned(), /* @ts-ignore */
|
|
122
|
+
...(ngDevMode ? [{ debugName: "effectiveControlId" }] : /* istanbul ignore next */ []));
|
|
123
|
+
/** Read-only режим (плоский текст вместо контрола); включается rt-field'ом. */
|
|
124
|
+
this.isReadonly = this.#readonlyAssigned.asReadonly();
|
|
125
|
+
/** Публичный invalid для rt-field (touched/dirty учтён в состоянии). */
|
|
126
|
+
this.invalid = computed(() => this.isInvalid(), /* @ts-ignore */
|
|
127
|
+
...(ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []));
|
|
128
|
+
/** Текущие ошибки связанного контрола — источник текста ошибки в rt-field. */
|
|
129
|
+
this.errors = computed(() => this.#state().errors ?? (this.#missingRequired() ? { required: true } : null), /* @ts-ignore */
|
|
130
|
+
...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
|
|
131
|
+
/** Обязателен ли контрол — по валидатору формы или по слову rt-field. Для авто-«*». */
|
|
132
|
+
this.required = computed(() => this.#state().required || this.#requiredAssigned(), /* @ts-ignore */
|
|
133
|
+
...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
134
|
+
this.value = signal(this.getEmptyValue(), /* @ts-ignore */
|
|
135
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
136
|
+
// Self-inject NgControl + ручная привязка valueAccessor: доступ к
|
|
137
|
+
// control.invalid/touched без NG_VALUE_ACCESSOR provider'а (тот
|
|
138
|
+
// спровоцировал бы NG0200 cycle при self-reference).
|
|
139
|
+
if (this.#ngControl !== null) {
|
|
140
|
+
this.#ngControl.valueAccessor = this;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
ngOnInit() {
|
|
144
|
+
const control = this.#ngControl?.control ?? null;
|
|
145
|
+
if (control === null) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
// Контрол, который состояния не рассылает, — переходник сигнальной формы: событий у
|
|
149
|
+
// него нет вовсе, и подписка на них роняла поле из запуска вместе со всем поддеревом
|
|
150
|
+
// разметки. Состояние у него читается геттерами, поэтому берётся вычислением.
|
|
151
|
+
if (!emitsEvents(control)) {
|
|
152
|
+
this.#signalControl.set(control);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
// Авто-подсветка invalid + зеркало ошибок/required для rt-field.
|
|
156
|
+
this.#pushedState.set(stateOf(control));
|
|
157
|
+
control.events.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe(() => {
|
|
158
|
+
this.#pushedState.set(stateOf(control));
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
writeValue(value) {
|
|
162
|
+
this.value.set(value ?? this.getEmptyValue());
|
|
163
|
+
}
|
|
164
|
+
registerOnChange(fn) {
|
|
165
|
+
this.#onChange = fn;
|
|
166
|
+
}
|
|
167
|
+
registerOnTouched(fn) {
|
|
168
|
+
this.#onTouched = fn;
|
|
169
|
+
}
|
|
170
|
+
setDisabledState(isDisabled) {
|
|
171
|
+
this.#disabledByForm.set(isDisabled);
|
|
172
|
+
}
|
|
173
|
+
/** Назначить авто-id (rt-field), когда у контрола нет явного controlId. */
|
|
174
|
+
assignControlId(id) {
|
|
175
|
+
this.#controlIdAssigned.set(id);
|
|
176
|
+
}
|
|
177
|
+
/** Включить/выключить read-only режим — вызывает родительский rt-field. */
|
|
178
|
+
setReadonly(value) {
|
|
179
|
+
this.#readonlyAssigned.set(value);
|
|
180
|
+
}
|
|
181
|
+
/** Объявить контрол обязательным — вызывает родительский rt-field. */
|
|
182
|
+
setRequired(value) {
|
|
183
|
+
this.#requiredAssigned.set(value);
|
|
184
|
+
}
|
|
185
|
+
/** Очистка значения по кнопке-крестику + возврат фокуса в поле. */
|
|
186
|
+
clear(event) {
|
|
187
|
+
event?.stopPropagation();
|
|
188
|
+
if (this.isDisabled()) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
this.clearValue();
|
|
192
|
+
this.#onChange(this.value());
|
|
193
|
+
this.#onTouched();
|
|
194
|
+
this.focusAfterClear();
|
|
195
|
+
}
|
|
196
|
+
/** Сбрасывает значение к пустому. Поля с display-сигналом расширяют. */
|
|
197
|
+
clearValue() {
|
|
198
|
+
this.value.set(this.getEmptyValue());
|
|
199
|
+
}
|
|
200
|
+
/** Прокидывает change наружу — для обработчиков пользовательского ввода. */
|
|
201
|
+
emitChange(value) {
|
|
202
|
+
this.#onChange(value);
|
|
203
|
+
}
|
|
204
|
+
/** Помечает контрол touched — для blur/close-обработчиков. */
|
|
205
|
+
markTouched() {
|
|
206
|
+
this.#onTouched();
|
|
207
|
+
}
|
|
208
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtFormControlBase, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
209
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.6", type: RtFormControlBase, isStandalone: true, inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, controlId: { classPropertyName: "controlId", publicName: "controlId", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
|
|
210
|
+
}
|
|
211
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtFormControlBase, decorators: [{
|
|
212
|
+
type: Directive
|
|
213
|
+
}], ctorParameters: () => [], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], controlId: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlId", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], bordered: [{ type: i0.Input, args: [{ isSignal: true, alias: "bordered", required: false }] }] } });
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Generated bundle index. Do not edit.
|
|
217
|
+
*/
|
|
218
|
+
|
|
219
|
+
export { RtFormControlBase };
|
|
220
|
+
//# sourceMappingURL=rt-tools-ui-kit-v2-form-control.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-form-control.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/form-control/rt-form-control.base.ts","../../../projects/ui-kit-v2/src/lib/components/form-control/rt-tools-ui-kit-v2-form-control.ts"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n computed,\n DestroyRef,\n Directive,\n inject,\n input,\n InputSignal,\n InputSignalWithTransform,\n OnInit,\n Signal,\n signal,\n WritableSignal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { AbstractControl, ControlValueAccessor, NgControl, ValidationErrors, Validators } from '@angular/forms';\n\nimport { IRtInput } from '@rt-tools/ui-kit-v2/core';\n\n/**\n * Базовый класс input-семейства common/ui. Владеет единым CVA-ядром:\n * - self-injected `NgControl` + ручная привязка `valueAccessor` (без\n * `NG_VALUE_ACCESSOR` provider — иначе NG0200 cycle при self-reference),\n * что даёт доступ к `control.invalid/touched` для авто-подсветки ошибки;\n * - сигнал значения `value`, состояния `isDisabled`/`isInvalid` (отключение\n * складывается из входа `disabled` и слова формы — см. `isDisabled`);\n * - общие инпуты `size`/`disabled`/`controlId`/`ariaLabel`/`clearable`;\n * - оркестрацию очистки (`clear`) через абстрактные хуки конкретного поля.\n *\n * Конкретные поля реализуют `getEmptyValue`/`hasValue`/`focusAfterClear`. Поля\n * с отдельным display-состоянием (autocomplete, input-number) дополнительно\n * переопределяют `writeValue`/`clearValue`, синхронизируя свой display-сигнал.\n */\n/**\n * Состояние формы, каким его видит поле: негодность, ошибки и обязательность.\n *\n * Собрано одной записью затем, что источников у него два и говорят они по-разному. Прежняя\n * привязка рассылает состояние событиями контрола, сигнальная — не рассылает вовсе и отдаёт\n * его чтениями своего переходника. Порознь эти два пути дали бы полю два набора сигналов, и\n * обёртке пришлось бы знать, какой из них живой.\n */\ninterface IControlState {\n invalid: boolean;\n errors: ValidationErrors | null;\n required: boolean;\n /** Касались ли контрола или правили его: до этого пустое обязательное поле не краснеет. */\n interacted: boolean;\n}\n\n/** Состояние поля, которому форма ещё ничего не сказала. */\nconst PRISTINE_STATE: IControlState = { invalid: false, errors: null, required: false, interacted: false };\n\n/** Рассылает ли контрол своё состояние. Переходник сигнальной формы — не рассылает. */\nfunction emitsEvents(control: AbstractControl): boolean {\n return typeof (control.events as { pipe?: unknown } | undefined)?.pipe === 'function';\n}\n\n/** Состояние формы, снятое с контрола любого рода. */\nfunction stateOf(control: AbstractControl): IControlState {\n return {\n invalid: !!control.invalid && (control.touched || control.dirty),\n errors: control.errors,\n required: control.hasValidator(Validators.required),\n interacted: control.touched || control.dirty,\n };\n}\n\n@Directive()\nexport abstract class RtFormControlBase<TValue> implements ControlValueAccessor, OnInit {\n readonly #ngControl: NgControl | null = inject(NgControl, { self: true, optional: true });\n readonly #destroyRef: DestroyRef = inject(DestroyRef);\n\n #onChange: (value: TValue) => void = (): void => undefined;\n #onTouched: () => void = (): void => undefined;\n\n // Состояние, которым управляет родительский rt-field (через публичные сеттеры):\n // авто-id для связки label[for], read-only режим, зеркало ошибок/required.\n readonly #controlIdAssigned: WritableSignal<string | null> = signal<string | null>(null);\n readonly #readonlyAssigned: WritableSignal<boolean> = signal<boolean>(false);\n /**\n * Обязательность, объявленная полем. Шаблонная форма валидатора на контрол не кладёт, и без\n * этого признака её обязательное поле не получало бы ни звёздочки, ни ошибки.\n */\n readonly #requiredAssigned: WritableSignal<boolean> = signal<boolean>(false);\n /** Состояние, разосланное прежней привязкой: её контрол сигналами не читается. */\n readonly #pushedState: WritableSignal<IControlState> = signal<IControlState>(PRISTINE_STATE);\n /**\n * Контрол сигнальной привязки. Его состояние не рассылается, а читается геттерами, и\n * внутри геттеров стоят вызовы сигналов формы — то есть из `computed` оно реактивно.\n */\n readonly #signalControl: WritableSignal<AbstractControl | null> = signal<AbstractControl | null>(null);\n /** Отключение, назначенное формой через CVA (`setDisabledState`). */\n readonly #disabledByForm: WritableSignal<boolean> = signal<boolean>(false);\n\n protected readonly value: WritableSignal<TValue>;\n /**\n * Отключение: вход и форма — два независимых источника, поле отключено,\n * если так сказал любой из них. Сводить их в один signal нельзя: форма\n * зовёт `setDisabledState` при связывании контрола, то есть раньше, чем\n * поле впервые обновит своё вью, и мирроринг входа затирал бы её слово —\n * контрол, созданный отключённым, оказывался бы редактируемым.\n */\n protected readonly isDisabled: Signal<boolean> = computed((): boolean => this.disabled() || this.#disabledByForm());\n /** Состояние формы: у сигнальной привязки читается, у прежней берётся разосланное. */\n readonly #state: Signal<IControlState> = computed((): IControlState => {\n const control: AbstractControl | null = this.#signalControl();\n return control === null ? this.#pushedState() : stateOf(control);\n });\n\n /**\n * Пустое поле, обязательное по слову rt-field, которого уже коснулись. Валидатор формы здесь\n * не нужен: его ошибку контрол и так получает от формы.\n */\n readonly #missingRequired: Signal<boolean> = computed(\n (): boolean => this.#requiredAssigned() && !this.#state().required && this.#state().interacted && !this.hasValue()\n );\n\n protected readonly isInvalid: Signal<boolean> = computed((): boolean => this.#state().invalid || this.#missingRequired());\n\n /** Видимость кнопки очистки: включена, есть значение, поле активно. */\n protected readonly showClearButton: Signal<boolean> = computed(\n (): boolean => this.clearable() && this.hasValue() && !this.isDisabled()\n );\n\n /** Есть ли в поле значение — гейт видимости крестика. */\n protected abstract readonly hasValue: Signal<boolean>;\n\n public readonly size: InputSignal<IRtInput.Size> = input<IRtInput.Size>('md');\n public readonly disabled: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n public readonly controlId: InputSignal<string | null> = input<string | null>(null);\n public readonly ariaLabel: InputSignal<string | null> = input<string | null>(null);\n public readonly clearable: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(true, {\n transform: booleanAttribute,\n });\n\n /**\n * Видимая resting-рамка контрола. По умолчанию `true` — рамка видна на обеих\n * темах. `false` снимает только resting-рамку; focus/invalid состояния свою\n * рамку показывают всё равно, read-only остаётся плоским.\n */\n public readonly bordered: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(true, {\n transform: booleanAttribute,\n });\n\n /** Итоговый id поля: явный input важнее авто-id, назначенного rt-field. */\n public readonly effectiveControlId: Signal<string | null> = computed(\n (): string | null => this.controlId() ?? this.#controlIdAssigned()\n );\n\n /** Read-only режим (плоский текст вместо контрола); включается rt-field'ом. */\n public readonly isReadonly: Signal<boolean> = this.#readonlyAssigned.asReadonly();\n\n /** Публичный invalid для rt-field (touched/dirty учтён в состоянии). */\n public readonly invalid: Signal<boolean> = computed((): boolean => this.isInvalid());\n\n /** Текущие ошибки связанного контрола — источник текста ошибки в rt-field. */\n public readonly errors: Signal<ValidationErrors | null> = computed(\n (): ValidationErrors | null => this.#state().errors ?? (this.#missingRequired() ? { required: true } : null)\n );\n\n /** Обязателен ли контрол — по валидатору формы или по слову rt-field. Для авто-«*». */\n public readonly required: Signal<boolean> = computed((): boolean => this.#state().required || this.#requiredAssigned());\n\n /** Текст read-only представления. Реализуется конкретным контролом. */\n public abstract readonly displayText: Signal<string>;\n\n constructor() {\n this.value = signal<TValue>(this.getEmptyValue());\n // Self-inject NgControl + ручная привязка valueAccessor: доступ к\n // control.invalid/touched без NG_VALUE_ACCESSOR provider'а (тот\n // спровоцировал бы NG0200 cycle при self-reference).\n if (this.#ngControl !== null) {\n this.#ngControl.valueAccessor = this;\n }\n }\n\n public ngOnInit(): void {\n const control: AbstractControl | null = this.#ngControl?.control ?? null;\n if (control === null) {\n return;\n }\n // Контрол, который состояния не рассылает, — переходник сигнальной формы: событий у\n // него нет вовсе, и подписка на них роняла поле из запуска вместе со всем поддеревом\n // разметки. Состояние у него читается геттерами, поэтому берётся вычислением.\n if (!emitsEvents(control)) {\n this.#signalControl.set(control);\n return;\n }\n // Авто-подсветка invalid + зеркало ошибок/required для rt-field.\n this.#pushedState.set(stateOf(control));\n control.events.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe((): void => {\n this.#pushedState.set(stateOf(control));\n });\n }\n\n public writeValue(value: TValue | null): void {\n this.value.set(value ?? this.getEmptyValue());\n }\n\n public registerOnChange(fn: (value: TValue) => void): void {\n this.#onChange = fn;\n }\n\n public registerOnTouched(fn: () => void): void {\n this.#onTouched = fn;\n }\n\n public setDisabledState(isDisabled: boolean): void {\n this.#disabledByForm.set(isDisabled);\n }\n\n /** Назначить авто-id (rt-field), когда у контрола нет явного controlId. */\n public assignControlId(id: string): void {\n this.#controlIdAssigned.set(id);\n }\n\n /** Включить/выключить read-only режим — вызывает родительский rt-field. */\n public setReadonly(value: boolean): void {\n this.#readonlyAssigned.set(value);\n }\n\n /** Объявить контрол обязательным — вызывает родительский rt-field. */\n public setRequired(value: boolean): void {\n this.#requiredAssigned.set(value);\n }\n\n /** Очистка значения по кнопке-крестику + возврат фокуса в поле. */\n protected clear(event?: Event): void {\n event?.stopPropagation();\n if (this.isDisabled()) {\n return;\n }\n this.clearValue();\n this.#onChange(this.value());\n this.#onTouched();\n this.focusAfterClear();\n }\n\n /** Сбрасывает значение к пустому. Поля с display-сигналом расширяют. */\n protected clearValue(): void {\n this.value.set(this.getEmptyValue());\n }\n\n /** Прокидывает change наружу — для обработчиков пользовательского ввода. */\n protected emitChange(value: TValue): void {\n this.#onChange(value);\n }\n\n /** Помечает контрол touched — для blur/close-обработчиков. */\n protected markTouched(): void {\n this.#onTouched();\n }\n\n /** Пустое значение поля (тип-специфично: \"\", null, []). */\n protected abstract getEmptyValue(): TValue;\n\n /** Возврат фокуса после очистки (в input или на trigger-кнопку). */\n protected abstract focusAfterClear(): void;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|