@rt-tools/ui-kit-v2 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -0
- package/fesm2022/rt-tools-ui-kit-v2-accordion.mjs +79 -0
- package/fesm2022/rt-tools-ui-kit-v2-accordion.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs +227 -0
- package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-aside-section.mjs +47 -0
- package/fesm2022/rt-tools-ui-kit-v2-aside-section.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-aside.mjs +702 -0
- package/fesm2022/rt-tools-ui-kit-v2-aside.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs +214 -0
- package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-bar-list.mjs +53 -0
- package/fesm2022/rt-tools-ui-kit-v2-bar-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-bottom-sheet.mjs +88 -0
- package/fesm2022/rt-tools-ui-kit-v2-bottom-sheet.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-button.mjs +365 -0
- package/fesm2022/rt-tools-ui-kit-v2-button.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs +152 -0
- package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-card.mjs +72 -0
- package/fesm2022/rt-tools-ui-kit-v2-card.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs +111 -0
- package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-collapsible-text.mjs +76 -0
- package/fesm2022/rt-tools-ui-kit-v2-collapsible-text.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-confirm-popover.mjs +255 -0
- package/fesm2022/rt-tools-ui-kit-v2-confirm-popover.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-container.mjs +1326 -0
- package/fesm2022/rt-tools-ui-kit-v2-container.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs +2590 -0
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-counter-row.mjs +45 -0
- package/fesm2022/rt-tools-ui-kit-v2-counter-row.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-counter.mjs +158 -0
- package/fesm2022/rt-tools-ui-kit-v2-counter.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs +894 -0
- package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs +1217 -0
- package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs +779 -0
- package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs +573 -0
- package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-delta-view.mjs +141 -0
- package/fesm2022/rt-tools-ui-kit-v2-delta-view.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-detail-list.mjs +68 -0
- package/fesm2022/rt-tools-ui-kit-v2-detail-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dialog.mjs +478 -0
- package/fesm2022/rt-tools-ui-kit-v2-dialog.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dot-field.mjs +183 -0
- package/fesm2022/rt-tools-ui-kit-v2-dot-field.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-download-link.mjs +44 -0
- package/fesm2022/rt-tools-ui-kit-v2-download-link.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs +260 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +937 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-empty-state.mjs +56 -0
- package/fesm2022/rt-tools-ui-kit-v2-empty-state.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs +107 -0
- package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-field.mjs +183 -0
- package/fesm2022/rt-tools-ui-kit-v2-field.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs +219 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-drop.mjs +214 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-drop.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-input.mjs +117 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-input.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-list.mjs +32 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs +91 -0
- package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs +220 -0
- package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-header.mjs +72 -0
- package/fesm2022/rt-tools-ui-kit-v2-header.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs +163 -0
- package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-icon.mjs +674 -0
- package/fesm2022/rt-tools-ui-kit-v2-icon.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-image-cropper.mjs +540 -0
- package/fesm2022/rt-tools-ui-kit-v2-image-cropper.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs +227 -0
- package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-info-item.mjs +37 -0
- package/fesm2022/rt-tools-ui-kit-v2-info-item.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs +361 -0
- package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-input.mjs +143 -0
- package/fesm2022/rt-tools-ui-kit-v2-input.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-live-badge.mjs +49 -0
- package/fesm2022/rt-tools-ui-kit-v2-live-badge.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-logo.mjs +97 -0
- package/fesm2022/rt-tools-ui-kit-v2-logo.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-markdown-text.mjs +57 -0
- package/fesm2022/rt-tools-ui-kit-v2-markdown-text.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-menu.mjs +537 -0
- package/fesm2022/rt-tools-ui-kit-v2-menu.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-message.mjs +105 -0
- package/fesm2022/rt-tools-ui-kit-v2-message.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-money-list.mjs +71 -0
- package/fesm2022/rt-tools-ui-kit-v2-money-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs +315 -0
- package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-night-grid.mjs +51 -0
- package/fesm2022/rt-tools-ui-kit-v2-night-grid.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-note.mjs +44 -0
- package/fesm2022/rt-tools-ui-kit-v2-note.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-notifications-bell.mjs +54 -0
- package/fesm2022/rt-tools-ui-kit-v2-notifications-bell.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +339 -0
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs +187 -0
- package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-photo-viewer.mjs +170 -0
- package/fesm2022/rt-tools-ui-kit-v2-photo-viewer.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-popover.mjs +312 -0
- package/fesm2022/rt-tools-ui-kit-v2-popover.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs +174 -0
- package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-radius.mjs +56 -0
- package/fesm2022/rt-tools-ui-kit-v2-radius.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-ripple.mjs +118 -0
- package/fesm2022/rt-tools-ui-kit-v2-ripple.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs +290 -0
- package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs +37 -0
- package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-select.mjs +495 -0
- package/fesm2022/rt-tools-ui-kit-v2-select.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +1493 -0
- package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-skeleton-wrapper.mjs +49 -0
- package/fesm2022/rt-tools-ui-kit-v2-skeleton-wrapper.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-skeleton.mjs +123 -0
- package/fesm2022/rt-tools-ui-kit-v2-skeleton.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-spinner.mjs +70 -0
- package/fesm2022/rt-tools-ui-kit-v2-spinner.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs +92 -0
- package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs +147 -0
- package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs +117 -0
- package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-table.mjs +1636 -0
- package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs +350 -0
- package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-tag.mjs +122 -0
- package/fesm2022/rt-tools-ui-kit-v2-tag.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs +85 -0
- package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs +73 -0
- package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +196 -0
- package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-timeline.mjs +39 -0
- package/fesm2022/rt-tools-ui-kit-v2-timeline.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-toast.mjs +338 -0
- package/fesm2022/rt-tools-ui-kit-v2-toast.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs +132 -0
- package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs +162 -0
- package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs +135 -0
- package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs +214 -0
- package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-welcome-dialog.mjs +64 -0
- package/fesm2022/rt-tools-ui-kit-v2-welcome-dialog.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs +263 -0
- package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs +296 -0
- package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2.mjs +91 -23819
- package/fesm2022/rt-tools-ui-kit-v2.mjs.map +1 -1
- package/package.json +349 -1
- package/rt-tools-ui-kit-v2-0.18.0.tgz +0 -0
- package/src/lib/components/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/field/CONTEXT.md +18 -2
- package/src/lib/components/select/rt-select.component.scss +4 -0
- package/src/styles/_semantic.scss +1 -1
- package/styles/tokens.css +8 -8
- package/types/rt-tools-ui-kit-v2-accordion.d.ts +30 -0
- package/types/rt-tools-ui-kit-v2-action-bar.d.ts +140 -0
- package/types/rt-tools-ui-kit-v2-aside-section.d.ts +25 -0
- package/types/rt-tools-ui-kit-v2-aside.d.ts +436 -0
- package/types/rt-tools-ui-kit-v2-autocomplete.d.ts +78 -0
- package/types/rt-tools-ui-kit-v2-bar-list.d.ts +41 -0
- package/types/rt-tools-ui-kit-v2-bottom-sheet.d.ts +20 -0
- package/types/rt-tools-ui-kit-v2-button.d.ts +76 -0
- package/types/rt-tools-ui-kit-v2-calendar.d.ts +96 -0
- package/types/rt-tools-ui-kit-v2-card.d.ts +38 -0
- package/types/rt-tools-ui-kit-v2-checkbox.d.ts +46 -0
- package/types/rt-tools-ui-kit-v2-collapsible-text.d.ts +20 -0
- package/types/rt-tools-ui-kit-v2-confirm-popover.d.ts +85 -0
- package/types/rt-tools-ui-kit-v2-container.d.ts +425 -0
- package/types/rt-tools-ui-kit-v2-core.d.ts +1222 -0
- package/types/rt-tools-ui-kit-v2-counter-row.d.ts +22 -0
- package/types/rt-tools-ui-kit-v2-counter.d.ts +70 -0
- package/types/rt-tools-ui-kit-v2-data-list.d.ts +334 -0
- package/types/rt-tools-ui-kit-v2-data-table.d.ts +494 -0
- package/types/rt-tools-ui-kit-v2-date-picker.d.ts +181 -0
- package/types/rt-tools-ui-kit-v2-date-range.d.ts +98 -0
- package/types/rt-tools-ui-kit-v2-delta-view.d.ts +20 -0
- package/types/rt-tools-ui-kit-v2-detail-list.d.ts +33 -0
- package/types/rt-tools-ui-kit-v2-dialog.d.ts +287 -0
- package/types/rt-tools-ui-kit-v2-dot-field.d.ts +17 -0
- package/types/rt-tools-ui-kit-v2-download-link.d.ts +17 -0
- package/types/rt-tools-ui-kit-v2-dynamic-list.d.ts +139 -0
- package/types/rt-tools-ui-kit-v2-dynamic-selector.d.ts +384 -0
- package/types/rt-tools-ui-kit-v2-empty-state.d.ts +29 -0
- package/types/rt-tools-ui-kit-v2-expansion-panel.d.ts +57 -0
- package/types/rt-tools-ui-kit-v2-field.d.ts +82 -0
- package/types/rt-tools-ui-kit-v2-file-card.d.ts +114 -0
- package/types/rt-tools-ui-kit-v2-file-drop.d.ts +75 -0
- package/types/rt-tools-ui-kit-v2-file-input.d.ts +48 -0
- package/types/rt-tools-ui-kit-v2-file-list.d.ts +13 -0
- package/types/rt-tools-ui-kit-v2-filter-control.d.ts +72 -0
- package/types/rt-tools-ui-kit-v2-form-control.d.ts +74 -0
- package/types/rt-tools-ui-kit-v2-header.d.ts +40 -0
- package/types/rt-tools-ui-kit-v2-icon-button.d.ts +113 -0
- package/types/rt-tools-ui-kit-v2-icon.d.ts +238 -0
- package/types/rt-tools-ui-kit-v2-image-cropper.d.ts +168 -0
- package/types/rt-tools-ui-kit-v2-image-upload.d.ts +102 -0
- package/types/rt-tools-ui-kit-v2-info-item.d.ts +13 -0
- package/types/rt-tools-ui-kit-v2-input-number.d.ts +67 -0
- package/types/rt-tools-ui-kit-v2-input.d.ts +54 -0
- package/types/rt-tools-ui-kit-v2-live-badge.d.ts +23 -0
- package/types/rt-tools-ui-kit-v2-logo.d.ts +58 -0
- package/types/rt-tools-ui-kit-v2-markdown-text.d.ts +30 -0
- package/types/rt-tools-ui-kit-v2-menu.d.ts +217 -0
- package/types/rt-tools-ui-kit-v2-message.d.ts +56 -0
- package/types/rt-tools-ui-kit-v2-money-list.d.ts +34 -0
- package/types/rt-tools-ui-kit-v2-multiselect.d.ts +93 -0
- package/types/rt-tools-ui-kit-v2-night-grid.d.ts +39 -0
- package/types/rt-tools-ui-kit-v2-note.d.ts +21 -0
- package/types/rt-tools-ui-kit-v2-notifications-bell.d.ts +23 -0
- package/types/rt-tools-ui-kit-v2-page-header.d.ts +173 -0
- package/types/rt-tools-ui-kit-v2-pagination.d.ts +64 -0
- package/types/rt-tools-ui-kit-v2-photo-viewer.d.ts +98 -0
- package/types/rt-tools-ui-kit-v2-popover.d.ts +79 -0
- package/types/rt-tools-ui-kit-v2-radio-button.d.ts +61 -0
- package/types/rt-tools-ui-kit-v2-radius.d.ts +37 -0
- package/types/rt-tools-ui-kit-v2-ripple.d.ts +39 -0
- package/types/rt-tools-ui-kit-v2-scroll-area.d.ts +91 -0
- package/types/rt-tools-ui-kit-v2-section-nav.d.ts +23 -0
- package/types/rt-tools-ui-kit-v2-select.d.ts +215 -0
- package/types/rt-tools-ui-kit-v2-side-menu.d.ts +483 -0
- package/types/rt-tools-ui-kit-v2-skeleton-wrapper.d.ts +32 -0
- package/types/rt-tools-ui-kit-v2-skeleton.d.ts +41 -0
- package/types/rt-tools-ui-kit-v2-spinner.d.ts +56 -0
- package/types/rt-tools-ui-kit-v2-split-button.d.ts +72 -0
- package/types/rt-tools-ui-kit-v2-stat-tile.d.ts +81 -0
- package/types/rt-tools-ui-kit-v2-stepper.d.ts +51 -0
- package/types/rt-tools-ui-kit-v2-table.d.ts +739 -0
- package/types/rt-tools-ui-kit-v2-tabs.d.ts +153 -0
- package/types/rt-tools-ui-kit-v2-tag.d.ts +70 -0
- package/types/rt-tools-ui-kit-v2-textarea.d.ts +36 -0
- package/types/rt-tools-ui-kit-v2-theme-toggle.d.ts +43 -0
- package/types/rt-tools-ui-kit-v2-thread-list.d.ts +111 -0
- package/types/rt-tools-ui-kit-v2-timeline.d.ts +35 -0
- package/types/rt-tools-ui-kit-v2-toast.d.ts +103 -0
- package/types/rt-tools-ui-kit-v2-toggle-button-group.d.ts +109 -0
- package/types/rt-tools-ui-kit-v2-toggle-switch.d.ts +85 -0
- package/types/rt-tools-ui-kit-v2-toolbar.d.ts +66 -0
- package/types/rt-tools-ui-kit-v2-tooltip.d.ts +74 -0
- package/types/rt-tools-ui-kit-v2-welcome-dialog.d.ts +33 -0
- package/types/rt-tools-ui-kit-v2-workspace-details.d.ts +128 -0
- package/types/rt-tools-ui-kit-v2-workspace.d.ts +84 -0
- package/types/rt-tools-ui-kit-v2.d.ts +87 -9599
- package/rt-tools-ui-kit-v2-0.17.0.tgz +0 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, booleanAttribute, HostBinding, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import * as i1 from '@rt-tools/ui-kit-v2/radius';
|
|
4
|
+
import { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';
|
|
5
|
+
|
|
6
|
+
const BEM_BLOCK = 'rt-skeleton';
|
|
7
|
+
/**
|
|
8
|
+
* Visual primitive для loading-state'а: серая полоска с shimmer-анимацией.
|
|
9
|
+
*
|
|
10
|
+
* Не использовать напрямую — оборачивай реальный content в `<rt-skeleton-wrapper>`
|
|
11
|
+
* с input'ом `[isLoading]`. Wrapper решает что показать (skeleton или content),
|
|
12
|
+
* этот компонент только рисует placeholder.
|
|
13
|
+
*
|
|
14
|
+
* Скругление прямоугольника и квадрата — шаг общего входа `radius`; круг остаётся кругом.
|
|
15
|
+
*
|
|
16
|
+
* Shimmer через background-position keyframes; `@media (prefers-reduced-motion)`
|
|
17
|
+
* убирает анимацию для пользователей с reduced-motion preference.
|
|
18
|
+
*/
|
|
19
|
+
class RtSkeletonComponent {
|
|
20
|
+
constructor() {
|
|
21
|
+
this.#sizeMap = {
|
|
22
|
+
sm: '10px',
|
|
23
|
+
md: '15px',
|
|
24
|
+
lg: '20px',
|
|
25
|
+
};
|
|
26
|
+
this.shape = input('rectangle', /* @ts-ignore */
|
|
27
|
+
...(ngDevMode ? [{ debugName: "shape" }] : /* istanbul ignore next */ []));
|
|
28
|
+
this.size = input('md', /* @ts-ignore */
|
|
29
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
30
|
+
this.width = input('100%', /* @ts-ignore */
|
|
31
|
+
...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
|
|
32
|
+
this.height = input(this.#sizeMap.sm, /* @ts-ignore */
|
|
33
|
+
...(ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []));
|
|
34
|
+
this.animation = input(true, { ...(ngDevMode ? { debugName: "animation" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
35
|
+
}
|
|
36
|
+
#sizeMap;
|
|
37
|
+
get isRectangle() {
|
|
38
|
+
return this.shape() === 'rectangle';
|
|
39
|
+
}
|
|
40
|
+
get isCircle() {
|
|
41
|
+
return this.shape() === 'circle';
|
|
42
|
+
}
|
|
43
|
+
get isSquare() {
|
|
44
|
+
return this.shape() === 'square';
|
|
45
|
+
}
|
|
46
|
+
get isSizeSm() {
|
|
47
|
+
return this.size() === 'sm';
|
|
48
|
+
}
|
|
49
|
+
get isSizeMd() {
|
|
50
|
+
return this.size() === 'md';
|
|
51
|
+
}
|
|
52
|
+
get isSizeLg() {
|
|
53
|
+
return this.size() === 'lg';
|
|
54
|
+
}
|
|
55
|
+
get isAnimated() {
|
|
56
|
+
return this.animation();
|
|
57
|
+
}
|
|
58
|
+
get hostWidth() {
|
|
59
|
+
switch (this.shape()) {
|
|
60
|
+
case 'circle':
|
|
61
|
+
case 'square':
|
|
62
|
+
return this.#getSizeValue();
|
|
63
|
+
case 'rectangle':
|
|
64
|
+
default:
|
|
65
|
+
return this.width();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
get hostHeight() {
|
|
69
|
+
switch (this.shape()) {
|
|
70
|
+
case 'circle':
|
|
71
|
+
case 'square':
|
|
72
|
+
return this.#getSizeValue();
|
|
73
|
+
case 'rectangle':
|
|
74
|
+
default:
|
|
75
|
+
return this.height();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
#getSizeValue() {
|
|
79
|
+
return this.#sizeMap[this.size()];
|
|
80
|
+
}
|
|
81
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtSkeletonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
82
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: RtSkeletonComponent, isStandalone: true, selector: "rt-skeleton", inputs: { shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, animation: { classPropertyName: "animation", publicName: "animation", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.rt-skeleton--rectangle": "this.isRectangle", "class.rt-skeleton--circle": "this.isCircle", "class.rt-skeleton--square": "this.isSquare", "class.rt-skeleton--sm": "this.isSizeSm", "class.rt-skeleton--md": "this.isSizeMd", "class.rt-skeleton--lg": "this.isSizeLg", "class.rt-skeleton--animated": "this.isAnimated", "style.width": "this.hostWidth", "style.height": "this.hostHeight" }, classAttribute: "rt-skeleton" }, hostDirectives: [{ directive: i1.RtRadiusDirective, inputs: ["radius", "radius"] }], ngImport: i0, template: '', isInline: true, styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-skeleton{--rt-skeleton-wave-duration: 2.5s;--rt-skeleton-radius: var(--rt-radius-sm);--rt-skeleton-circle-radius: var(--rt-radius-full);position:relative;display:inline-block;overflow:hidden;background:linear-gradient(90deg,var(--rt-color-skeleton-base) 0%,var(--rt-color-skeleton-wave) 50%,var(--rt-color-skeleton-base) 100%);background-size:200% 100%}.rt-skeleton--rectangle{border-radius:var(--rt-skeleton-radius)}.rt-skeleton--circle{border-radius:var(--rt-skeleton-circle-radius)}.rt-skeleton--square{border-radius:var(--rt-skeleton-radius)}.rt-skeleton[data-rt-radius=none]{--rt-skeleton-radius: var(--rt-radius-none)}.rt-skeleton[data-rt-radius=xs]{--rt-skeleton-radius: var(--rt-radius-xs)}.rt-skeleton[data-rt-radius=sm]{--rt-skeleton-radius: var(--rt-radius-sm)}.rt-skeleton[data-rt-radius=ms]{--rt-skeleton-radius: var(--rt-radius-ms)}.rt-skeleton[data-rt-radius=md]{--rt-skeleton-radius: var(--rt-radius-md)}.rt-skeleton[data-rt-radius=lg]{--rt-skeleton-radius: var(--rt-radius-lg)}.rt-skeleton[data-rt-radius=xl]{--rt-skeleton-radius: var(--rt-radius-xl)}.rt-skeleton[data-rt-radius=\"2xl\"]{--rt-skeleton-radius: var(--rt-radius-2xl)}.rt-skeleton[data-rt-radius=full]{--rt-skeleton-radius: var(--rt-radius-full)}.rt-skeleton--sm{min-width:10px;min-height:10px}.rt-skeleton--md{min-width:15px;min-height:15px}.rt-skeleton--lg{min-width:20px;min-height:20px}.rt-skeleton--animated{animation:rt-skeleton-wave var(--rt-skeleton-wave-duration) ease-in-out infinite}@keyframes rt-skeleton-wave{0%{background-position:200% 0}to{background-position:-200% 0}}@media(prefers-reduced-motion:reduce){.rt-skeleton--animated{animation:none}}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
83
|
+
}
|
|
84
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtSkeletonComponent, decorators: [{
|
|
85
|
+
type: Component,
|
|
86
|
+
args: [{ selector: 'rt-skeleton', template: '', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }], host: {
|
|
87
|
+
class: BEM_BLOCK,
|
|
88
|
+
}, styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-skeleton{--rt-skeleton-wave-duration: 2.5s;--rt-skeleton-radius: var(--rt-radius-sm);--rt-skeleton-circle-radius: var(--rt-radius-full);position:relative;display:inline-block;overflow:hidden;background:linear-gradient(90deg,var(--rt-color-skeleton-base) 0%,var(--rt-color-skeleton-wave) 50%,var(--rt-color-skeleton-base) 100%);background-size:200% 100%}.rt-skeleton--rectangle{border-radius:var(--rt-skeleton-radius)}.rt-skeleton--circle{border-radius:var(--rt-skeleton-circle-radius)}.rt-skeleton--square{border-radius:var(--rt-skeleton-radius)}.rt-skeleton[data-rt-radius=none]{--rt-skeleton-radius: var(--rt-radius-none)}.rt-skeleton[data-rt-radius=xs]{--rt-skeleton-radius: var(--rt-radius-xs)}.rt-skeleton[data-rt-radius=sm]{--rt-skeleton-radius: var(--rt-radius-sm)}.rt-skeleton[data-rt-radius=ms]{--rt-skeleton-radius: var(--rt-radius-ms)}.rt-skeleton[data-rt-radius=md]{--rt-skeleton-radius: var(--rt-radius-md)}.rt-skeleton[data-rt-radius=lg]{--rt-skeleton-radius: var(--rt-radius-lg)}.rt-skeleton[data-rt-radius=xl]{--rt-skeleton-radius: var(--rt-radius-xl)}.rt-skeleton[data-rt-radius=\"2xl\"]{--rt-skeleton-radius: var(--rt-radius-2xl)}.rt-skeleton[data-rt-radius=full]{--rt-skeleton-radius: var(--rt-radius-full)}.rt-skeleton--sm{min-width:10px;min-height:10px}.rt-skeleton--md{min-width:15px;min-height:15px}.rt-skeleton--lg{min-width:20px;min-height:20px}.rt-skeleton--animated{animation:rt-skeleton-wave var(--rt-skeleton-wave-duration) ease-in-out infinite}@keyframes rt-skeleton-wave{0%{background-position:200% 0}to{background-position:-200% 0}}@media(prefers-reduced-motion:reduce){.rt-skeleton--animated{animation:none}}}\n"] }]
|
|
89
|
+
}], propDecorators: { shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], animation: [{ type: i0.Input, args: [{ isSignal: true, alias: "animation", required: false }] }], isRectangle: [{
|
|
90
|
+
type: HostBinding,
|
|
91
|
+
args: ['class.rt-skeleton--rectangle']
|
|
92
|
+
}], isCircle: [{
|
|
93
|
+
type: HostBinding,
|
|
94
|
+
args: ['class.rt-skeleton--circle']
|
|
95
|
+
}], isSquare: [{
|
|
96
|
+
type: HostBinding,
|
|
97
|
+
args: ['class.rt-skeleton--square']
|
|
98
|
+
}], isSizeSm: [{
|
|
99
|
+
type: HostBinding,
|
|
100
|
+
args: ['class.rt-skeleton--sm']
|
|
101
|
+
}], isSizeMd: [{
|
|
102
|
+
type: HostBinding,
|
|
103
|
+
args: ['class.rt-skeleton--md']
|
|
104
|
+
}], isSizeLg: [{
|
|
105
|
+
type: HostBinding,
|
|
106
|
+
args: ['class.rt-skeleton--lg']
|
|
107
|
+
}], isAnimated: [{
|
|
108
|
+
type: HostBinding,
|
|
109
|
+
args: ['class.rt-skeleton--animated']
|
|
110
|
+
}], hostWidth: [{
|
|
111
|
+
type: HostBinding,
|
|
112
|
+
args: ['style.width']
|
|
113
|
+
}], hostHeight: [{
|
|
114
|
+
type: HostBinding,
|
|
115
|
+
args: ['style.height']
|
|
116
|
+
}] } });
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Generated bundle index. Do not edit.
|
|
120
|
+
*/
|
|
121
|
+
|
|
122
|
+
export { RtSkeletonComponent };
|
|
123
|
+
//# sourceMappingURL=rt-tools-ui-kit-v2-skeleton.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-skeleton.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/skeleton/rt-skeleton.component.ts","../../../projects/ui-kit-v2/src/lib/components/skeleton/rt-tools-ui-kit-v2-skeleton.ts"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n HostBinding,\n input,\n InputSignal,\n InputSignalWithTransform,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\n\nexport type TRtSkeletonShape = 'rectangle' | 'circle' | 'square';\nexport type TRtSkeletonSize = 'sm' | 'md' | 'lg';\n\nconst BEM_BLOCK: string = 'rt-skeleton';\n\n/**\n * Visual primitive для loading-state'а: серая полоска с shimmer-анимацией.\n *\n * Не использовать напрямую — оборачивай реальный content в `<rt-skeleton-wrapper>`\n * с input'ом `[isLoading]`. Wrapper решает что показать (skeleton или content),\n * этот компонент только рисует placeholder.\n *\n * Скругление прямоугольника и квадрата — шаг общего входа `radius`; круг остаётся кругом.\n *\n * Shimmer через background-position keyframes; `@media (prefers-reduced-motion)`\n * убирает анимацию для пользователей с reduced-motion preference.\n */\n@Component({\n selector: 'rt-skeleton',\n template: '',\n styleUrls: ['./rt-skeleton.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtSkeletonComponent {\n readonly #sizeMap: Record<TRtSkeletonSize, string> = {\n sm: '10px',\n md: '15px',\n lg: '20px',\n };\n\n public readonly shape: InputSignal<TRtSkeletonShape> = input<TRtSkeletonShape>('rectangle');\n\n public readonly size: InputSignal<TRtSkeletonSize> = input<TRtSkeletonSize>('md');\n\n public readonly width: InputSignal<string> = input<string>('100%');\n\n public readonly height: InputSignal<string> = input<string>(this.#sizeMap.sm);\n\n public readonly animation: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(true, {\n transform: booleanAttribute,\n });\n\n @HostBinding('class.rt-skeleton--rectangle')\n protected get isRectangle(): boolean {\n return this.shape() === 'rectangle';\n }\n\n @HostBinding('class.rt-skeleton--circle')\n protected get isCircle(): boolean {\n return this.shape() === 'circle';\n }\n\n @HostBinding('class.rt-skeleton--square')\n protected get isSquare(): boolean {\n return this.shape() === 'square';\n }\n\n @HostBinding('class.rt-skeleton--sm')\n protected get isSizeSm(): boolean {\n return this.size() === 'sm';\n }\n\n @HostBinding('class.rt-skeleton--md')\n protected get isSizeMd(): boolean {\n return this.size() === 'md';\n }\n\n @HostBinding('class.rt-skeleton--lg')\n protected get isSizeLg(): boolean {\n return this.size() === 'lg';\n }\n\n @HostBinding('class.rt-skeleton--animated')\n protected get isAnimated(): boolean {\n return this.animation();\n }\n\n @HostBinding('style.width')\n protected get hostWidth(): string {\n switch (this.shape()) {\n case 'circle':\n case 'square':\n return this.#getSizeValue();\n\n case 'rectangle':\n default:\n return this.width();\n }\n }\n\n @HostBinding('style.height')\n protected get hostHeight(): string {\n switch (this.shape()) {\n case 'circle':\n case 'square':\n return this.#getSizeValue();\n\n case 'rectangle':\n default:\n return this.height();\n }\n }\n\n #getSizeValue(): string {\n return this.#sizeMap[this.size()];\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { NgTemplateOutlet } from '@angular/common';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { computed, input, numberAttribute, booleanAttribute, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
4
|
+
import { BlockDirective, ElemDirective } from '@rt-tools/core';
|
|
5
|
+
|
|
6
|
+
const BEM_BLOCK = 'rt-spinner';
|
|
7
|
+
/**
|
|
8
|
+
* Атомарный rotating-spinner для loading-индикаторов.
|
|
9
|
+
*
|
|
10
|
+
* Без новых режимов кольцо рисует сам host: border с одной цветной стороной и вращение, своей
|
|
11
|
+
* разметки нет. Так спиннер стоит у семи компонентов кита, и их разметка от режимов не меняется.
|
|
12
|
+
*
|
|
13
|
+
* Режимы `overlay`, `plate` и вид `arc` рисуют внутреннюю разметку, а host перестаёт быть кольцом:
|
|
14
|
+
* - `overlay` — спиннер занимает позиционированного родителя целиком и ставит кольцо в центр;
|
|
15
|
+
* слой — ступень `sticky`, ниже всего, что открывается поверх страницы;
|
|
16
|
+
* - `backdrop` — полупрозрачная подложка оверлея, без `overlay` не действует;
|
|
17
|
+
* - `plate` — круглая плашка с тенью под кольцом;
|
|
18
|
+
* - `appearance="arc"` — дуга без дорожки, как у Material.
|
|
19
|
+
*
|
|
20
|
+
* Анимация уважает `@media (prefers-reduced-motion)` — вращение замедляется.
|
|
21
|
+
*/
|
|
22
|
+
class RtSpinnerComponent {
|
|
23
|
+
constructor() {
|
|
24
|
+
/** Кольцо рисуется внутренней разметкой, а не самим host-ом. */
|
|
25
|
+
this.framed = computed(() => this.overlay() || this.plate() || this.appearance() === 'arc', /* @ts-ignore */
|
|
26
|
+
...(ngDevMode ? [{ debugName: "framed" }] : /* istanbul ignore next */ []));
|
|
27
|
+
this.modifiers = computed(() => ({
|
|
28
|
+
[`${BEM_BLOCK}--${this.color()}`]: true,
|
|
29
|
+
[`${BEM_BLOCK}--framed`]: this.framed(),
|
|
30
|
+
[`${BEM_BLOCK}--overlay`]: this.overlay(),
|
|
31
|
+
[`${BEM_BLOCK}--backdrop`]: this.overlay() && this.backdrop(),
|
|
32
|
+
}), /* @ts-ignore */
|
|
33
|
+
...(ngDevMode ? [{ debugName: "modifiers" }] : /* istanbul ignore next */ []));
|
|
34
|
+
this.cssDiameter = computed(() => `${this.diameter()}px`, /* @ts-ignore */
|
|
35
|
+
...(ngDevMode ? [{ debugName: "cssDiameter" }] : /* istanbul ignore next */ []));
|
|
36
|
+
/** Диаметр spinner'а в px. Default 32. */
|
|
37
|
+
this.diameter = input(32, { ...(ngDevMode ? { debugName: "diameter" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
38
|
+
/** Семантическая палитра. Default `primary`. */
|
|
39
|
+
this.color = input('primary', /* @ts-ignore */
|
|
40
|
+
...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
|
|
41
|
+
/** Вид кольца: `border` — с дорожкой, `arc` — дуга без дорожки. Default `border`. */
|
|
42
|
+
this.appearance = input('border', /* @ts-ignore */
|
|
43
|
+
...(ngDevMode ? [{ debugName: "appearance" }] : /* istanbul ignore next */ []));
|
|
44
|
+
/** Спиннер накрывает позиционированного родителя и стоит в его центре. Default `false`. */
|
|
45
|
+
this.overlay = input(false, { ...(ngDevMode ? { debugName: "overlay" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
46
|
+
/** Полупрозрачная подложка оверлея; без `overlay` не действует. Default `false`. */
|
|
47
|
+
this.backdrop = input(false, { ...(ngDevMode ? { debugName: "backdrop" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
48
|
+
/** Круглая плашка с тенью под кольцом. Default `false`. */
|
|
49
|
+
this.plate = input(false, { ...(ngDevMode ? { debugName: "plate" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
50
|
+
}
|
|
51
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtSpinnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
52
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtSpinnerComponent, isStandalone: true, selector: "rt-spinner", inputs: { diameter: { classPropertyName: "diameter", publicName: "diameter", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, overlay: { classPropertyName: "overlay", publicName: "overlay", isSignal: true, isRequired: false, transformFunction: null }, backdrop: { classPropertyName: "backdrop", publicName: "backdrop", isSignal: true, isRequired: false, transformFunction: null }, plate: { classPropertyName: "plate", publicName: "plate", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "status", "aria-live": "polite" }, properties: { "class": "modifiers()", "style.--rt-spinner-diameter": "cssDiameter()" }, classAttribute: "rt-spinner" }, ngImport: i0, template: "@if (framed()) {\n <ng-container rtBlock=\"rt-spinner\">\n @if (plate()) {\n <span rtElem=\"plate\">\n <ng-container [ngTemplateOutlet]=\"ring\" />\n </span>\n } @else {\n <ng-container [ngTemplateOutlet]=\"ring\" />\n }\n\n <ng-template #ring>\n @if (appearance() === 'arc') {\n <svg rtElem=\"arc\" viewBox=\"0 0 48 48\" focusable=\"false\" aria-hidden=\"true\">\n <circle rtElem=\"arc-circle\" cx=\"24\" cy=\"24\" r=\"20\" />\n </svg>\n } @else {\n <span rtElem=\"ring\"></span>\n }\n </ng-template>\n </ng-container>\n}\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-spinner{--rt-spinner-diameter: 32px;--rt-spinner-border-width: 3px;--rt-spinner-track-color: var(--rt-color-border-subtle);--rt-spinner-progress-color: var(--rt-color-action-primary);--rt-spinner-rotation-duration: 1s;--rt-spinner-rotation-duration-reduced: 4s;--rt-spinner-radius: var(--rt-radius-full);--rt-spinner-overlay-z: var(--rt-z-sticky);--rt-spinner-plate-size: calc(var(--rt-spinner-diameter) + 2 * var(--rt-space-2));--rt-spinner-plate-bg: var(--rt-color-bg-surface);--rt-spinner-plate-shadow: var(--rt-shadow-md);--rt-spinner-plate-radius: var(--rt-radius-full);--rt-spinner-backdrop-bg: color-mix(in srgb, var(--rt-color-bg-subtle) 85%, transparent);--rt-spinner-arc-duration: 1.4s;--rt-spinner-arc-duration-reduced: 5.6s}.rt-spinner,.rt-spinner__ring{display:inline-block;width:var(--rt-spinner-diameter);height:var(--rt-spinner-diameter);box-sizing:border-box;border:var(--rt-spinner-border-width) solid var(--rt-spinner-track-color);border-radius:var(--rt-spinner-radius);border-right-color:var(--rt-spinner-progress-color);animation:rt-spinner-rotate var(--rt-spinner-rotation-duration) linear infinite}.rt-spinner--primary{--rt-spinner-progress-color: var(--rt-color-action-primary)}.rt-spinner--neutral{--rt-spinner-progress-color: var(--rt-color-text-primary)}.rt-spinner--on-primary{--rt-spinner-track-color: var(--rt-overlay-white-25);--rt-spinner-progress-color: var(--rt-color-action-on-primary)}.rt-spinner--framed{display:inline-flex;width:auto;height:auto;align-items:center;justify-content:center;border:0;border-radius:0;animation:none}.rt-spinner--overlay{position:absolute;z-index:var(--rt-spinner-overlay-z);display:flex;inset:0}.rt-spinner--backdrop{background:var(--rt-spinner-backdrop-bg)}.rt-spinner__plate{display:inline-flex;width:var(--rt-spinner-plate-size);height:var(--rt-spinner-plate-size);align-items:center;justify-content:center;border-radius:var(--rt-spinner-plate-radius);background:var(--rt-spinner-plate-bg);box-shadow:var(--rt-spinner-plate-shadow)}.rt-spinner__arc{display:block;width:var(--rt-spinner-diameter);height:var(--rt-spinner-diameter);animation:rt-spinner-rotate var(--rt-spinner-arc-duration) linear infinite}.rt-spinner__arc-circle{animation:rt-spinner-arc-dash var(--rt-spinner-arc-duration) ease-in-out infinite;fill:none;stroke:var(--rt-spinner-progress-color);stroke-dasharray:89 200;stroke-dashoffset:-35;stroke-linecap:round;stroke-width:4}@keyframes rt-spinner-rotate{to{transform:rotate(1turn)}}@keyframes rt-spinner-arc-dash{0%{stroke-dasharray:89 200;stroke-dashoffset:-35}50%{stroke-dasharray:89 200;stroke-dashoffset:-124}50.01%{stroke-dasharray:1 200;stroke-dashoffset:0}to{stroke-dasharray:89 200;stroke-dashoffset:-35}}@media(prefers-reduced-motion:reduce){.rt-spinner,.rt-spinner__ring{animation-duration:var(--rt-spinner-rotation-duration-reduced)}.rt-spinner__arc,.rt-spinner__arc-circle{animation-duration:var(--rt-spinner-arc-duration-reduced)}}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
53
|
+
}
|
|
54
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtSpinnerComponent, decorators: [{
|
|
55
|
+
type: Component,
|
|
56
|
+
args: [{ selector: 'rt-spinner', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [NgTemplateOutlet, BlockDirective, ElemDirective], host: {
|
|
57
|
+
class: BEM_BLOCK,
|
|
58
|
+
role: 'status',
|
|
59
|
+
'aria-live': 'polite',
|
|
60
|
+
'[class]': 'modifiers()',
|
|
61
|
+
'[style.--rt-spinner-diameter]': 'cssDiameter()',
|
|
62
|
+
}, template: "@if (framed()) {\n <ng-container rtBlock=\"rt-spinner\">\n @if (plate()) {\n <span rtElem=\"plate\">\n <ng-container [ngTemplateOutlet]=\"ring\" />\n </span>\n } @else {\n <ng-container [ngTemplateOutlet]=\"ring\" />\n }\n\n <ng-template #ring>\n @if (appearance() === 'arc') {\n <svg rtElem=\"arc\" viewBox=\"0 0 48 48\" focusable=\"false\" aria-hidden=\"true\">\n <circle rtElem=\"arc-circle\" cx=\"24\" cy=\"24\" r=\"20\" />\n </svg>\n } @else {\n <span rtElem=\"ring\"></span>\n }\n </ng-template>\n </ng-container>\n}\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-spinner{--rt-spinner-diameter: 32px;--rt-spinner-border-width: 3px;--rt-spinner-track-color: var(--rt-color-border-subtle);--rt-spinner-progress-color: var(--rt-color-action-primary);--rt-spinner-rotation-duration: 1s;--rt-spinner-rotation-duration-reduced: 4s;--rt-spinner-radius: var(--rt-radius-full);--rt-spinner-overlay-z: var(--rt-z-sticky);--rt-spinner-plate-size: calc(var(--rt-spinner-diameter) + 2 * var(--rt-space-2));--rt-spinner-plate-bg: var(--rt-color-bg-surface);--rt-spinner-plate-shadow: var(--rt-shadow-md);--rt-spinner-plate-radius: var(--rt-radius-full);--rt-spinner-backdrop-bg: color-mix(in srgb, var(--rt-color-bg-subtle) 85%, transparent);--rt-spinner-arc-duration: 1.4s;--rt-spinner-arc-duration-reduced: 5.6s}.rt-spinner,.rt-spinner__ring{display:inline-block;width:var(--rt-spinner-diameter);height:var(--rt-spinner-diameter);box-sizing:border-box;border:var(--rt-spinner-border-width) solid var(--rt-spinner-track-color);border-radius:var(--rt-spinner-radius);border-right-color:var(--rt-spinner-progress-color);animation:rt-spinner-rotate var(--rt-spinner-rotation-duration) linear infinite}.rt-spinner--primary{--rt-spinner-progress-color: var(--rt-color-action-primary)}.rt-spinner--neutral{--rt-spinner-progress-color: var(--rt-color-text-primary)}.rt-spinner--on-primary{--rt-spinner-track-color: var(--rt-overlay-white-25);--rt-spinner-progress-color: var(--rt-color-action-on-primary)}.rt-spinner--framed{display:inline-flex;width:auto;height:auto;align-items:center;justify-content:center;border:0;border-radius:0;animation:none}.rt-spinner--overlay{position:absolute;z-index:var(--rt-spinner-overlay-z);display:flex;inset:0}.rt-spinner--backdrop{background:var(--rt-spinner-backdrop-bg)}.rt-spinner__plate{display:inline-flex;width:var(--rt-spinner-plate-size);height:var(--rt-spinner-plate-size);align-items:center;justify-content:center;border-radius:var(--rt-spinner-plate-radius);background:var(--rt-spinner-plate-bg);box-shadow:var(--rt-spinner-plate-shadow)}.rt-spinner__arc{display:block;width:var(--rt-spinner-diameter);height:var(--rt-spinner-diameter);animation:rt-spinner-rotate var(--rt-spinner-arc-duration) linear infinite}.rt-spinner__arc-circle{animation:rt-spinner-arc-dash var(--rt-spinner-arc-duration) ease-in-out infinite;fill:none;stroke:var(--rt-spinner-progress-color);stroke-dasharray:89 200;stroke-dashoffset:-35;stroke-linecap:round;stroke-width:4}@keyframes rt-spinner-rotate{to{transform:rotate(1turn)}}@keyframes rt-spinner-arc-dash{0%{stroke-dasharray:89 200;stroke-dashoffset:-35}50%{stroke-dasharray:89 200;stroke-dashoffset:-124}50.01%{stroke-dasharray:1 200;stroke-dashoffset:0}to{stroke-dasharray:89 200;stroke-dashoffset:-35}}@media(prefers-reduced-motion:reduce){.rt-spinner,.rt-spinner__ring{animation-duration:var(--rt-spinner-rotation-duration-reduced)}.rt-spinner__arc,.rt-spinner__arc-circle{animation-duration:var(--rt-spinner-arc-duration-reduced)}}}\n"] }]
|
|
63
|
+
}], propDecorators: { diameter: [{ type: i0.Input, args: [{ isSignal: true, alias: "diameter", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], overlay: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlay", required: false }] }], backdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "backdrop", required: false }] }], plate: [{ type: i0.Input, args: [{ isSignal: true, alias: "plate", required: false }] }] } });
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Generated bundle index. Do not edit.
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
export { RtSpinnerComponent };
|
|
70
|
+
//# sourceMappingURL=rt-tools-ui-kit-v2-spinner.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-spinner.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/spinner/rt-spinner.component.ts","../../../projects/ui-kit-v2/src/lib/components/spinner/rt-spinner.component.html","../../../projects/ui-kit-v2/src/lib/components/spinner/rt-tools-ui-kit-v2-spinner.ts"],"sourcesContent":["import { BooleanInput, NumberInput } from '@angular/cdk/coercion';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n input,\n InputSignal,\n InputSignalWithTransform,\n numberAttribute,\n Signal,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { IRtSpinner } from './rt-spinner.model';\n\nconst BEM_BLOCK: string = 'rt-spinner';\n\n/**\n * Атомарный rotating-spinner для loading-индикаторов.\n *\n * Без новых режимов кольцо рисует сам host: border с одной цветной стороной и вращение, своей\n * разметки нет. Так спиннер стоит у семи компонентов кита, и их разметка от режимов не меняется.\n *\n * Режимы `overlay`, `plate` и вид `arc` рисуют внутреннюю разметку, а host перестаёт быть кольцом:\n * - `overlay` — спиннер занимает позиционированного родителя целиком и ставит кольцо в центр;\n * слой — ступень `sticky`, ниже всего, что открывается поверх страницы;\n * - `backdrop` — полупрозрачная подложка оверлея, без `overlay` не действует;\n * - `plate` — круглая плашка с тенью под кольцом;\n * - `appearance=\"arc\"` — дуга без дорожки, как у Material.\n *\n * Анимация уважает `@media (prefers-reduced-motion)` — вращение замедляется.\n */\n@Component({\n selector: 'rt-spinner',\n templateUrl: './rt-spinner.component.html',\n styleUrls: ['./rt-spinner.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [NgTemplateOutlet, BlockDirective, ElemDirective],\n host: {\n class: BEM_BLOCK,\n role: 'status',\n 'aria-live': 'polite',\n '[class]': 'modifiers()',\n '[style.--rt-spinner-diameter]': 'cssDiameter()',\n },\n})\nexport class RtSpinnerComponent {\n /** Кольцо рисуется внутренней разметкой, а не самим host-ом. */\n protected readonly framed: Signal<boolean> = computed((): boolean => this.overlay() || this.plate() || this.appearance() === 'arc');\n\n protected readonly modifiers: Signal<Record<string, boolean>> = computed((): Record<string, boolean> => ({\n [`${BEM_BLOCK}--${this.color()}`]: true,\n [`${BEM_BLOCK}--framed`]: this.framed(),\n [`${BEM_BLOCK}--overlay`]: this.overlay(),\n [`${BEM_BLOCK}--backdrop`]: this.overlay() && this.backdrop(),\n }));\n\n protected readonly cssDiameter: Signal<string> = computed((): string => `${this.diameter()}px`);\n\n /** Диаметр spinner'а в px. Default 32. */\n public readonly diameter: InputSignalWithTransform<number, NumberInput> = input<number, NumberInput>(32, {\n transform: numberAttribute,\n });\n\n /** Семантическая палитра. Default `primary`. */\n public readonly color: InputSignal<IRtSpinner.Color> = input<IRtSpinner.Color>('primary');\n\n /** Вид кольца: `border` — с дорожкой, `arc` — дуга без дорожки. Default `border`. */\n public readonly appearance: InputSignal<IRtSpinner.Appearance> = input<IRtSpinner.Appearance>('border');\n\n /** Спиннер накрывает позиционированного родителя и стоит в его центре. Default `false`. */\n public readonly overlay: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Полупрозрачная подложка оверлея; без `overlay` не действует. Default `false`. */\n public readonly backdrop: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Круглая плашка с тенью под кольцом. Default `false`. */\n public readonly plate: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n}\n","@if (framed()) {\n <ng-container rtBlock=\"rt-spinner\">\n @if (plate()) {\n <span rtElem=\"plate\">\n <ng-container [ngTemplateOutlet]=\"ring\" />\n </span>\n } @else {\n <ng-container [ngTemplateOutlet]=\"ring\" />\n }\n\n <ng-template #ring>\n @if (appearance() === 'arc') {\n <svg rtElem=\"arc\" viewBox=\"0 0 48 48\" focusable=\"false\" aria-hidden=\"true\">\n <circle rtElem=\"arc-circle\" cx=\"24\" cy=\"24\" r=\"20\" />\n </svg>\n } @else {\n <span rtElem=\"ring\"></span>\n }\n </ng-template>\n </ng-container>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { viewChild, computed, input, booleanAttribute, output, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { BlockDirective, ElemDirective } 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 { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';
|
|
7
|
+
import * as i1 from '@rt-tools/ui-kit-v2/radius';
|
|
8
|
+
import { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';
|
|
9
|
+
|
|
10
|
+
const BEM_BLOCK = 'rt-split-button';
|
|
11
|
+
/**
|
|
12
|
+
* Кнопка с раздельным действием: основной CTA («лицо») + каретка, по клику на
|
|
13
|
+
* которую раскрывается меню второстепенных действий. Применяется, когда у
|
|
14
|
+
* сценария ДВА позитивных действия и нужно явно выделить главное, не пряча
|
|
15
|
+
* второстепенное (например, футер формы: лицо «Сохранить», в меню
|
|
16
|
+
* «Сохранить черновик»).
|
|
17
|
+
*
|
|
18
|
+
* Меню — поверх `[rtPopover]` (CDK Overlay): авто-flip у края, outside-click и
|
|
19
|
+
* Escape закрывают, не режется `overflow: hidden` предками (футер aside'а).
|
|
20
|
+
* Лицо и каретка — две `[rtButton]`, визуально сшитые в один контрол.
|
|
21
|
+
*
|
|
22
|
+
* `ViewEncapsulation.None` — стили префиксованы `.rt-split-button`.
|
|
23
|
+
*/
|
|
24
|
+
class RtSplitButtonComponent {
|
|
25
|
+
constructor() {
|
|
26
|
+
this.#t_uiMoreActions = rtKitLabel('uiMoreActions');
|
|
27
|
+
this.menu = viewChild(RtPopoverDirective, /* @ts-ignore */
|
|
28
|
+
...(ngDevMode ? [{ debugName: "menu" }] : /* istanbul ignore next */ []));
|
|
29
|
+
/** Своё имя каретки важнее умолчания: экран знает, что за действия в меню */
|
|
30
|
+
this.menuAriaText = computed(() => this.menuAriaLabel() || this.#t_uiMoreActions(), /* @ts-ignore */
|
|
31
|
+
...(ngDevMode ? [{ debugName: "menuAriaText" }] : /* istanbul ignore next */ []));
|
|
32
|
+
/** Подпись основного действия («лицо»). */
|
|
33
|
+
this.label = input.required(/* @ts-ignore */
|
|
34
|
+
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
35
|
+
/** Пункты выпадающего меню второстепенных действий. */
|
|
36
|
+
this.menuItems = input.required(/* @ts-ignore */
|
|
37
|
+
...(ngDevMode ? [{ debugName: "menuItems" }] : /* istanbul ignore next */ []));
|
|
38
|
+
/** Семантическая палитра лица и каретки. */
|
|
39
|
+
this.theme = input('primary', /* @ts-ignore */
|
|
40
|
+
...(ngDevMode ? [{ debugName: "theme" }] : /* istanbul ignore next */ []));
|
|
41
|
+
/** Размер контрола. */
|
|
42
|
+
this.size = input('md', /* @ts-ignore */
|
|
43
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
44
|
+
/** Доступное имя для каретки (icon-only кнопка открытия меню). */
|
|
45
|
+
this.menuAriaLabel = input('', /* @ts-ignore */
|
|
46
|
+
...(ngDevMode ? [{ debugName: "menuAriaLabel" }] : /* istanbul ignore next */ []));
|
|
47
|
+
/** Загрузка: спиннер на лице + блокировка обеих кнопок. */
|
|
48
|
+
this.loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
49
|
+
/** Нативное отключение обеих кнопок. */
|
|
50
|
+
this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
51
|
+
/** Клик по лицу (основное действие). */
|
|
52
|
+
this.faceClick = output();
|
|
53
|
+
/** Выбор пункта меню — эмитит `value` выбранного пункта. */
|
|
54
|
+
this.itemSelect = output();
|
|
55
|
+
}
|
|
56
|
+
#t_uiMoreActions;
|
|
57
|
+
onFace() {
|
|
58
|
+
if (this.disabled() || this.loading()) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
this.faceClick.emit();
|
|
62
|
+
}
|
|
63
|
+
onToggle() {
|
|
64
|
+
if (this.disabled() || this.loading()) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
this.menu()?.toggle();
|
|
68
|
+
}
|
|
69
|
+
onItem(item) {
|
|
70
|
+
if (item.disabled) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
this.menu()?.close();
|
|
74
|
+
this.itemSelect.emit(item.value);
|
|
75
|
+
}
|
|
76
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtSplitButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
77
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtSplitButtonComponent, isStandalone: true, selector: "rt-split-button", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, menuItems: { classPropertyName: "menuItems", publicName: "menuItems", isSignal: true, isRequired: true, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, menuAriaLabel: { classPropertyName: "menuAriaLabel", publicName: "menuAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { faceClick: "faceClick", itemSelect: "itemSelect" }, host: { properties: { "class.rt-split-button--open": "menu()?.isOpen()" }, classAttribute: "rt-split-button" }, viewQueries: [{ propertyName: "menu", first: true, predicate: RtPopoverDirective, descendants: true, isSignal: true }], hostDirectives: [{ directive: i1.RtRadiusDirective, inputs: ["radius", "radius"] }], ngImport: i0, template: "<ng-container rtBlock=\"rt-split-button\">\n <!-- Popover \u0432\u0438\u0441\u0438\u0442 \u043D\u0430 \u0432\u0441\u0451\u043C \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u0435 (\u0430 \u043D\u0435 \u043D\u0430 \u0443\u0437\u043A\u043E\u0439 \u043A\u0430\u0440\u0435\u0442\u043A\u0435): width=\"trigger\"\n \u0434\u0435\u043B\u0430\u0435\u0442 \u043C\u0435\u043D\u044E \u043F\u043E \u0448\u0438\u0440\u0438\u043D\u0435 \u043A\u043D\u043E\u043F\u043A\u0438, originX:start \u2014 \u0440\u043E\u0432\u043D\u043E \u043F\u043E\u0434 \u0435\u0451 \u043B\u0435\u0432\u044B\u043C \u043A\u0440\u0430\u0435\u043C,\n \u0431\u0435\u0437 \u0433\u043E\u0440\u0438\u0437\u043E\u043D\u0442\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u0432\u044B\u043B\u0435\u0442\u0430 \u0437\u0430 \u044D\u043A\u0440\u0430\u043D. \u0422\u0440\u0438\u0433\u0433\u0435\u0440 manual \u2014 \u043E\u0442\u043A\u0440\u044B\u0432\u0430\u0435\u0442 \u043A\u0430\u0440\u0435\u0442\u043A\u0430. -->\n <div\n rtElem=\"control\"\n rtPopoverTrigger=\"manual\"\n rtPopoverWidth=\"trigger\"\n rtPopoverPanelClass=\"rt-split-button-menu-panel\"\n [rtPopover]=\"menuTpl\"\n [rtPopoverOffsetY]=\"6\"\n [rtPopoverDisabled]=\"disabled() || loading()\">\n <button\n rtButton\n rtElem=\"face\"\n qa-dataid=\"split-button-face\"\n type=\"button\"\n [label]=\"label()\"\n [theme]=\"theme()\"\n [size]=\"size()\"\n [attr.aria-label]=\"label()\"\n [loading]=\"loading()\"\n [disabled]=\"disabled()\"\n (click)=\"onFace()\"></button>\n\n <button\n rtButton\n rtElem=\"toggle\"\n qa-dataid=\"split-button-toggle\"\n type=\"button\"\n icon=\"chevron-down\"\n [theme]=\"theme()\"\n [size]=\"size()\"\n [attr.aria-label]=\"menuAriaText()\"\n [disabled]=\"disabled() || loading()\"\n (click)=\"onToggle()\"></button>\n </div>\n\n <ng-template #menuTpl>\n <ul rtElem=\"menu\" qa-dataid=\"split-button-menu\" role=\"menu\">\n @for (item of menuItems(); track item.value) {\n <li role=\"none\">\n <button\n rtButton\n rtElem=\"menu-item\"\n qa-dataid=\"split-button-menu-item\"\n type=\"button\"\n theme=\"secondary\"\n appearance=\"text\"\n size=\"sm\"\n role=\"menuitem\"\n [attr.data-value]=\"item.value\"\n [label]=\"item.label\"\n [icon]=\"item.icon ?? null\"\n [attr.aria-label]=\"item.label\"\n [disabled]=\"item.disabled ?? false\"\n (click)=\"onItem(item)\"></button>\n </li>\n }\n </ul>\n </ng-template>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-split-button{--rt-split-button-divider-width: var(--rt-border-width-thin);--rt-split-button-caret-transition-duration: var(--rt-duration-fast);display:inline-flex}.rt-split-button[data-rt-radius=none]>.rt-split-button__control>.rt-button{--rt-btn-radius: var(--rt-radius-none)}.rt-split-button[data-rt-radius=xs]>.rt-split-button__control>.rt-button{--rt-btn-radius: var(--rt-radius-xs)}.rt-split-button[data-rt-radius=sm]>.rt-split-button__control>.rt-button{--rt-btn-radius: var(--rt-radius-sm)}.rt-split-button[data-rt-radius=ms]>.rt-split-button__control>.rt-button{--rt-btn-radius: var(--rt-radius-ms)}.rt-split-button[data-rt-radius=md]>.rt-split-button__control>.rt-button{--rt-btn-radius: var(--rt-radius-md)}.rt-split-button[data-rt-radius=lg]>.rt-split-button__control>.rt-button{--rt-btn-radius: var(--rt-radius-lg)}.rt-split-button[data-rt-radius=xl]>.rt-split-button__control>.rt-button{--rt-btn-radius: var(--rt-radius-xl)}.rt-split-button[data-rt-radius=\"2xl\"]>.rt-split-button__control>.rt-button{--rt-btn-radius: var(--rt-radius-2xl)}.rt-split-button[data-rt-radius=full]>.rt-split-button__control>.rt-button{--rt-btn-radius: var(--rt-radius-full)}.rt-split-button__control{display:inline-flex;width:100%;align-items:stretch}.rt-split-button__face.rt-button{border-end-end-radius:0;border-start-end-radius:0}.rt-split-button__toggle.rt-button{min-width:0;border-end-start-radius:0;border-inline-start:var(--rt-split-button-divider-width) solid color-mix(in srgb,var(--rt-color-text-inverse) 24%,transparent);border-start-start-radius:0;padding-inline:var(--rt-space-sm)}.rt-split-button__toggle.rt-button .rt-button__icon{fill:currentcolor;transition:transform var(--rt-split-button-caret-transition-duration) ease}.rt-split-button--open .rt-split-button__toggle.rt-button .rt-button__icon{transform:rotate(180deg)}.rt-split-button__menu{--rt-split-button-menu-radius: var(--rt-radius-md);--rt-split-button-menu-border-width: var(--rt-border-width-thin);--rt-split-button-menu-shadow: var(--rt-shadow-lg);display:flex;width:100%;box-sizing:border-box;flex-direction:column;padding:var(--rt-space-2xs);border:var(--rt-split-button-menu-border-width) solid var(--rt-color-border-subtle);border-radius:var(--rt-split-button-menu-radius);margin:0;background:var(--rt-color-bg-surface);box-shadow:var(--rt-split-button-menu-shadow);gap:var(--rt-space-2xs);list-style:none}.rt-split-button__menu-item.rt-button{overflow:hidden;width:100%;justify-content:flex-start}.rt-split-button__menu-item.rt-button .rt-button__label{display:block;overflow:hidden;min-width:0;text-overflow:ellipsis}}\n"], dependencies: [{ kind: "directive", type: RtButtonDirective, selector: "button[rtButton], a[rtButton]", inputs: ["label", "icon", "iconPos", "theme", "appearance", "size", "loading", "loadingIcon", "loadingLabel", "pressed"] }, { kind: "directive", type: RtPopoverDirective, selector: "[rtPopover]", inputs: ["rtPopover", "rtPopoverTrigger", "rtPopoverWidth", "rtPopoverAlign", "rtPopoverFitViewport", "rtPopoverContext", "rtPopoverPanelClass", "rtPopoverDisabled", "rtPopoverOffsetY", "rtPopoverOffsetX"], outputs: ["rtPopoverOpened", "rtPopoverClosed"], exportAs: ["rtPopover"] }, { kind: "directive", type: BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
78
|
+
}
|
|
79
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtSplitButtonComponent, decorators: [{
|
|
80
|
+
type: Component,
|
|
81
|
+
args: [{ selector: 'rt-split-button', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [RtButtonDirective, RtPopoverDirective, BlockDirective, ElemDirective], hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }], host: {
|
|
82
|
+
class: BEM_BLOCK,
|
|
83
|
+
'[class.rt-split-button--open]': 'menu()?.isOpen()',
|
|
84
|
+
}, template: "<ng-container rtBlock=\"rt-split-button\">\n <!-- Popover \u0432\u0438\u0441\u0438\u0442 \u043D\u0430 \u0432\u0441\u0451\u043C \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u0435 (\u0430 \u043D\u0435 \u043D\u0430 \u0443\u0437\u043A\u043E\u0439 \u043A\u0430\u0440\u0435\u0442\u043A\u0435): width=\"trigger\"\n \u0434\u0435\u043B\u0430\u0435\u0442 \u043C\u0435\u043D\u044E \u043F\u043E \u0448\u0438\u0440\u0438\u043D\u0435 \u043A\u043D\u043E\u043F\u043A\u0438, originX:start \u2014 \u0440\u043E\u0432\u043D\u043E \u043F\u043E\u0434 \u0435\u0451 \u043B\u0435\u0432\u044B\u043C \u043A\u0440\u0430\u0435\u043C,\n \u0431\u0435\u0437 \u0433\u043E\u0440\u0438\u0437\u043E\u043D\u0442\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u0432\u044B\u043B\u0435\u0442\u0430 \u0437\u0430 \u044D\u043A\u0440\u0430\u043D. \u0422\u0440\u0438\u0433\u0433\u0435\u0440 manual \u2014 \u043E\u0442\u043A\u0440\u044B\u0432\u0430\u0435\u0442 \u043A\u0430\u0440\u0435\u0442\u043A\u0430. -->\n <div\n rtElem=\"control\"\n rtPopoverTrigger=\"manual\"\n rtPopoverWidth=\"trigger\"\n rtPopoverPanelClass=\"rt-split-button-menu-panel\"\n [rtPopover]=\"menuTpl\"\n [rtPopoverOffsetY]=\"6\"\n [rtPopoverDisabled]=\"disabled() || loading()\">\n <button\n rtButton\n rtElem=\"face\"\n qa-dataid=\"split-button-face\"\n type=\"button\"\n [label]=\"label()\"\n [theme]=\"theme()\"\n [size]=\"size()\"\n [attr.aria-label]=\"label()\"\n [loading]=\"loading()\"\n [disabled]=\"disabled()\"\n (click)=\"onFace()\"></button>\n\n <button\n rtButton\n rtElem=\"toggle\"\n qa-dataid=\"split-button-toggle\"\n type=\"button\"\n icon=\"chevron-down\"\n [theme]=\"theme()\"\n [size]=\"size()\"\n [attr.aria-label]=\"menuAriaText()\"\n [disabled]=\"disabled() || loading()\"\n (click)=\"onToggle()\"></button>\n </div>\n\n <ng-template #menuTpl>\n <ul rtElem=\"menu\" qa-dataid=\"split-button-menu\" role=\"menu\">\n @for (item of menuItems(); track item.value) {\n <li role=\"none\">\n <button\n rtButton\n rtElem=\"menu-item\"\n qa-dataid=\"split-button-menu-item\"\n type=\"button\"\n theme=\"secondary\"\n appearance=\"text\"\n size=\"sm\"\n role=\"menuitem\"\n [attr.data-value]=\"item.value\"\n [label]=\"item.label\"\n [icon]=\"item.icon ?? null\"\n [attr.aria-label]=\"item.label\"\n [disabled]=\"item.disabled ?? false\"\n (click)=\"onItem(item)\"></button>\n </li>\n }\n </ul>\n </ng-template>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-split-button{--rt-split-button-divider-width: var(--rt-border-width-thin);--rt-split-button-caret-transition-duration: var(--rt-duration-fast);display:inline-flex}.rt-split-button[data-rt-radius=none]>.rt-split-button__control>.rt-button{--rt-btn-radius: var(--rt-radius-none)}.rt-split-button[data-rt-radius=xs]>.rt-split-button__control>.rt-button{--rt-btn-radius: var(--rt-radius-xs)}.rt-split-button[data-rt-radius=sm]>.rt-split-button__control>.rt-button{--rt-btn-radius: var(--rt-radius-sm)}.rt-split-button[data-rt-radius=ms]>.rt-split-button__control>.rt-button{--rt-btn-radius: var(--rt-radius-ms)}.rt-split-button[data-rt-radius=md]>.rt-split-button__control>.rt-button{--rt-btn-radius: var(--rt-radius-md)}.rt-split-button[data-rt-radius=lg]>.rt-split-button__control>.rt-button{--rt-btn-radius: var(--rt-radius-lg)}.rt-split-button[data-rt-radius=xl]>.rt-split-button__control>.rt-button{--rt-btn-radius: var(--rt-radius-xl)}.rt-split-button[data-rt-radius=\"2xl\"]>.rt-split-button__control>.rt-button{--rt-btn-radius: var(--rt-radius-2xl)}.rt-split-button[data-rt-radius=full]>.rt-split-button__control>.rt-button{--rt-btn-radius: var(--rt-radius-full)}.rt-split-button__control{display:inline-flex;width:100%;align-items:stretch}.rt-split-button__face.rt-button{border-end-end-radius:0;border-start-end-radius:0}.rt-split-button__toggle.rt-button{min-width:0;border-end-start-radius:0;border-inline-start:var(--rt-split-button-divider-width) solid color-mix(in srgb,var(--rt-color-text-inverse) 24%,transparent);border-start-start-radius:0;padding-inline:var(--rt-space-sm)}.rt-split-button__toggle.rt-button .rt-button__icon{fill:currentcolor;transition:transform var(--rt-split-button-caret-transition-duration) ease}.rt-split-button--open .rt-split-button__toggle.rt-button .rt-button__icon{transform:rotate(180deg)}.rt-split-button__menu{--rt-split-button-menu-radius: var(--rt-radius-md);--rt-split-button-menu-border-width: var(--rt-border-width-thin);--rt-split-button-menu-shadow: var(--rt-shadow-lg);display:flex;width:100%;box-sizing:border-box;flex-direction:column;padding:var(--rt-space-2xs);border:var(--rt-split-button-menu-border-width) solid var(--rt-color-border-subtle);border-radius:var(--rt-split-button-menu-radius);margin:0;background:var(--rt-color-bg-surface);box-shadow:var(--rt-split-button-menu-shadow);gap:var(--rt-space-2xs);list-style:none}.rt-split-button__menu-item.rt-button{overflow:hidden;width:100%;justify-content:flex-start}.rt-split-button__menu-item.rt-button .rt-button__label{display:block;overflow:hidden;min-width:0;text-overflow:ellipsis}}\n"] }]
|
|
85
|
+
}], propDecorators: { menu: [{ type: i0.ViewChild, args: [i0.forwardRef(() => RtPopoverDirective), { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], menuItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuItems", required: true }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], menuAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuAriaLabel", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], faceClick: [{ type: i0.Output, args: ["faceClick"] }], itemSelect: [{ type: i0.Output, args: ["itemSelect"] }] } });
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Generated bundle index. Do not edit.
|
|
89
|
+
*/
|
|
90
|
+
|
|
91
|
+
export { RtSplitButtonComponent };
|
|
92
|
+
//# sourceMappingURL=rt-tools-ui-kit-v2-split-button.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-split-button.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/split-button/rt-split-button.component.ts","../../../projects/ui-kit-v2/src/lib/components/split-button/rt-split-button.component.html","../../../projects/ui-kit-v2/src/lib/components/split-button/rt-tools-ui-kit-v2-split-button.ts"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n input,\n InputSignal,\n InputSignalWithTransform,\n output,\n OutputEmitterRef,\n Signal,\n viewChild,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { RtButtonDirective } from '@rt-tools/ui-kit-v2/button';\nimport { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { IRtSplitButton } from './rt-split-button.model';\n\nconst BEM_BLOCK: string = 'rt-split-button';\n\n/**\n * Кнопка с раздельным действием: основной CTA («лицо») + каретка, по клику на\n * которую раскрывается меню второстепенных действий. Применяется, когда у\n * сценария ДВА позитивных действия и нужно явно выделить главное, не пряча\n * второстепенное (например, футер формы: лицо «Сохранить», в меню\n * «Сохранить черновик»).\n *\n * Меню — поверх `[rtPopover]` (CDK Overlay): авто-flip у края, outside-click и\n * Escape закрывают, не режется `overflow: hidden` предками (футер aside'а).\n * Лицо и каретка — две `[rtButton]`, визуально сшитые в один контрол.\n *\n * `ViewEncapsulation.None` — стили префиксованы `.rt-split-button`.\n */\n@Component({\n selector: 'rt-split-button',\n templateUrl: './rt-split-button.component.html',\n styleUrl: './rt-split-button.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [RtButtonDirective, RtPopoverDirective, BlockDirective, ElemDirective],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n '[class.rt-split-button--open]': 'menu()?.isOpen()',\n },\n})\nexport class RtSplitButtonComponent {\n readonly #t_uiMoreActions: Signal<string> = rtKitLabel('uiMoreActions');\n\n protected readonly menu: Signal<RtPopoverDirective | undefined> = viewChild(RtPopoverDirective);\n\n /** Своё имя каретки важнее умолчания: экран знает, что за действия в меню */\n protected readonly menuAriaText: Signal<string> = computed((): string => this.menuAriaLabel() || this.#t_uiMoreActions());\n\n /** Подпись основного действия («лицо»). */\n public readonly label: InputSignal<string> = input.required<string>();\n\n /** Пункты выпадающего меню второстепенных действий. */\n public readonly menuItems: InputSignal<readonly IRtSplitButton.MenuItem[]> = input.required<readonly IRtSplitButton.MenuItem[]>();\n\n /** Семантическая палитра лица и каретки. */\n public readonly theme: InputSignal<IRtSplitButton.Theme> = input<IRtSplitButton.Theme>('primary');\n\n /** Размер контрола. */\n public readonly size: InputSignal<IRtSplitButton.Size> = input<IRtSplitButton.Size>('md');\n\n /** Доступное имя для каретки (icon-only кнопка открытия меню). */\n public readonly menuAriaLabel: InputSignal<string> = input<string>('');\n\n /** Загрузка: спиннер на лице + блокировка обеих кнопок. */\n public readonly loading: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Нативное отключение обеих кнопок. */\n public readonly disabled: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Клик по лицу (основное действие). */\n public readonly faceClick: OutputEmitterRef<void> = output<void>();\n\n /** Выбор пункта меню — эмитит `value` выбранного пункта. */\n public readonly itemSelect: OutputEmitterRef<string> = output<string>();\n\n protected onFace(): void {\n if (this.disabled() || this.loading()) {\n return;\n }\n this.faceClick.emit();\n }\n\n protected onToggle(): void {\n if (this.disabled() || this.loading()) {\n return;\n }\n this.menu()?.toggle();\n }\n\n protected onItem(item: IRtSplitButton.MenuItem): void {\n if (item.disabled) {\n return;\n }\n this.menu()?.close();\n this.itemSelect.emit(item.value);\n }\n}\n","<ng-container rtBlock=\"rt-split-button\">\n <!-- Popover висит на всём контроле (а не на узкой каретке): width=\"trigger\"\n делает меню по ширине кнопки, originX:start — ровно под её левым краем,\n без горизонтального вылета за экран. Триггер manual — открывает каретка. -->\n <div\n rtElem=\"control\"\n rtPopoverTrigger=\"manual\"\n rtPopoverWidth=\"trigger\"\n rtPopoverPanelClass=\"rt-split-button-menu-panel\"\n [rtPopover]=\"menuTpl\"\n [rtPopoverOffsetY]=\"6\"\n [rtPopoverDisabled]=\"disabled() || loading()\">\n <button\n rtButton\n rtElem=\"face\"\n qa-dataid=\"split-button-face\"\n type=\"button\"\n [label]=\"label()\"\n [theme]=\"theme()\"\n [size]=\"size()\"\n [attr.aria-label]=\"label()\"\n [loading]=\"loading()\"\n [disabled]=\"disabled()\"\n (click)=\"onFace()\"></button>\n\n <button\n rtButton\n rtElem=\"toggle\"\n qa-dataid=\"split-button-toggle\"\n type=\"button\"\n icon=\"chevron-down\"\n [theme]=\"theme()\"\n [size]=\"size()\"\n [attr.aria-label]=\"menuAriaText()\"\n [disabled]=\"disabled() || loading()\"\n (click)=\"onToggle()\"></button>\n </div>\n\n <ng-template #menuTpl>\n <ul rtElem=\"menu\" qa-dataid=\"split-button-menu\" role=\"menu\">\n @for (item of menuItems(); track item.value) {\n <li role=\"none\">\n <button\n rtButton\n rtElem=\"menu-item\"\n qa-dataid=\"split-button-menu-item\"\n type=\"button\"\n theme=\"secondary\"\n appearance=\"text\"\n size=\"sm\"\n role=\"menuitem\"\n [attr.data-value]=\"item.value\"\n [label]=\"item.label\"\n [icon]=\"item.icon ?? null\"\n [attr.aria-label]=\"item.label\"\n [disabled]=\"item.disabled ?? false\"\n (click)=\"onItem(item)\"></button>\n </li>\n }\n </ul>\n </ng-template>\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,147 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { computed, inject, input, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';
|
|
4
|
+
import { rtKitLabel, RT_KIT_LABELS } from '@rt-tools/ui-kit-v2/core';
|
|
5
|
+
import { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';
|
|
6
|
+
|
|
7
|
+
const BEM_BLOCK = 'rt-stat-tile';
|
|
8
|
+
const DIRECTION_ICONS = Object.freeze({
|
|
9
|
+
up: 'arrow-up',
|
|
10
|
+
down: 'arrow-down',
|
|
11
|
+
flat: 'minus',
|
|
12
|
+
unknown: 'minus',
|
|
13
|
+
});
|
|
14
|
+
function directionOf(percent) {
|
|
15
|
+
if (percent === null) {
|
|
16
|
+
return 'unknown';
|
|
17
|
+
}
|
|
18
|
+
if (percent > 0) {
|
|
19
|
+
return 'up';
|
|
20
|
+
}
|
|
21
|
+
return percent < 0 ? 'down' : 'flat';
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Нулевая база — «—»: «+100 %» от нуля вводит в заблуждение, «∞» нечитаемо.
|
|
25
|
+
* Дробная часть — через запятую, как и остальные проценты в интерфейсе: кит
|
|
26
|
+
* форматирует сам, потому что не может зависеть от логики приложений.
|
|
27
|
+
*/
|
|
28
|
+
function percentText(percent) {
|
|
29
|
+
if (percent === null) {
|
|
30
|
+
return '—';
|
|
31
|
+
}
|
|
32
|
+
const sign = percent > 0 ? '+' : '';
|
|
33
|
+
return `${sign}${String(percent).replace('.', ',')} %`;
|
|
34
|
+
}
|
|
35
|
+
function deltaRow(key, delta) {
|
|
36
|
+
if (!delta) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const direction = directionOf(delta.percent);
|
|
40
|
+
return {
|
|
41
|
+
key,
|
|
42
|
+
direction,
|
|
43
|
+
label: delta.label,
|
|
44
|
+
text: percentText(delta.percent),
|
|
45
|
+
baseline: delta.baseline ?? '',
|
|
46
|
+
icon: DIRECTION_ICONS[direction],
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* KPI-плитка: крупное значение, необязательная вторичная строка и до двух строк
|
|
51
|
+
* сравнения (к предыдущему периоду и к прошлому году).
|
|
52
|
+
*
|
|
53
|
+
* Компонент ничего не считает и не форматирует: `value` и `baseline` приходят
|
|
54
|
+
* готовыми строками, `percent` — посчитанным числом. Так плитка не знает ни про
|
|
55
|
+
* валюты, ни про методику метрик и остаётся общей для любого домена.
|
|
56
|
+
*
|
|
57
|
+
* Нулевая база показывается как «—»: «+100 %» от нуля вводит в заблуждение, а
|
|
58
|
+
* «∞» нечитаемо.
|
|
59
|
+
*/
|
|
60
|
+
class RtStatTileComponent {
|
|
61
|
+
constructor() {
|
|
62
|
+
/**
|
|
63
|
+
* Значение базы уходит параметром перевода, а не подставляется в готовую
|
|
64
|
+
* строку: Transloco интерполирует `{{value}}` в момент перевода, и к
|
|
65
|
+
* возвращённой строке подставлять уже нечего — от подписи оставалась одна
|
|
66
|
+
* приставка («было», «was»), а само число пропадало.
|
|
67
|
+
*/
|
|
68
|
+
this.#baselineParams = computed(() => ({
|
|
69
|
+
value: this.deltaPrimary()?.baseline ?? '',
|
|
70
|
+
}), /* @ts-ignore */
|
|
71
|
+
...(ngDevMode ? [{ debugName: "#baselineParams" }] : /* istanbul ignore next */ []));
|
|
72
|
+
this.#baselineLine = rtKitLabel('uiBaseline', this.#baselineParams);
|
|
73
|
+
/**
|
|
74
|
+
* Дельта к предыдущему периоду — рядом со значением. Пустая база (`percent`
|
|
75
|
+
* = null) не рисуется вовсе: «—» рядом с цифрой читается как поломка, а не
|
|
76
|
+
* как «сравнивать не с чем».
|
|
77
|
+
*/
|
|
78
|
+
this.t = inject(RT_KIT_LABELS);
|
|
79
|
+
this.primaryDelta = computed(() => this.#visibleDelta(this.deltaPrimary()), /* @ts-ignore */
|
|
80
|
+
...(ngDevMode ? [{ debugName: "primaryDelta" }] : /* istanbul ignore next */ []));
|
|
81
|
+
/** Годовое сравнение — отдельным компактным чипом, без слов в строке. */
|
|
82
|
+
this.yearDelta = computed(() => this.#visibleDelta(this.deltaSecondary()), /* @ts-ignore */
|
|
83
|
+
...(ngDevMode ? [{ debugName: "yearDelta" }] : /* istanbul ignore next */ []));
|
|
84
|
+
/**
|
|
85
|
+
* База сравнения — короткой строкой «было X» и ничем больше: всё остальное
|
|
86
|
+
* (занятость, состав воронки) живёт во вторичной строке, иначе одна плитка
|
|
87
|
+
* растягивает ряд под самую длинную подпись.
|
|
88
|
+
*/
|
|
89
|
+
this.baselineText = computed(() => (this.deltaPrimary()?.baseline ? this.#baselineLine() : ''), /* @ts-ignore */
|
|
90
|
+
...(ngDevMode ? [{ debugName: "baselineText" }] : /* istanbul ignore next */ []));
|
|
91
|
+
/** Подпись метрики. */
|
|
92
|
+
this.label = input.required(/* @ts-ignore */
|
|
93
|
+
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
94
|
+
/** Уже отформатированное значение — плитка его не преобразует. */
|
|
95
|
+
this.value = input.required(/* @ts-ignore */
|
|
96
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
97
|
+
/** Вторичная строка под значением (занятость, доля оценки и т.п.). */
|
|
98
|
+
this.secondary = input(null, /* @ts-ignore */
|
|
99
|
+
...(ngDevMode ? [{ debugName: "secondary" }] : /* istanbul ignore next */ []));
|
|
100
|
+
/** Сравнение с предыдущим равным периодом. */
|
|
101
|
+
this.deltaPrimary = input(null, /* @ts-ignore */
|
|
102
|
+
...(ngDevMode ? [{ debugName: "deltaPrimary" }] : /* istanbul ignore next */ []));
|
|
103
|
+
/** Сравнение с тем же периодом год назад. */
|
|
104
|
+
this.deltaSecondary = input(null, /* @ts-ignore */
|
|
105
|
+
...(ngDevMode ? [{ debugName: "deltaSecondary" }] : /* istanbul ignore next */ []));
|
|
106
|
+
/** Пояснение методики — нативный title на иконке подсказки. */
|
|
107
|
+
this.hint = input(null, /* @ts-ignore */
|
|
108
|
+
...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Значение базы уходит параметром перевода, а не подставляется в готовую
|
|
112
|
+
* строку: Transloco интерполирует `{{value}}` в момент перевода, и к
|
|
113
|
+
* возвращённой строке подставлять уже нечего — от подписи оставалась одна
|
|
114
|
+
* приставка («было», «was»), а само число пропадало.
|
|
115
|
+
*/
|
|
116
|
+
#baselineParams;
|
|
117
|
+
#baselineLine;
|
|
118
|
+
#visibleDelta(delta) {
|
|
119
|
+
if (!delta || delta.percent === null) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
return deltaRow('primary', delta);
|
|
123
|
+
}
|
|
124
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtStatTileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
125
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtStatTileComponent, isStandalone: true, selector: "rt-stat-tile", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, secondary: { classPropertyName: "secondary", publicName: "secondary", isSignal: true, isRequired: false, transformFunction: null }, deltaPrimary: { classPropertyName: "deltaPrimary", publicName: "deltaPrimary", isSignal: true, isRequired: false, transformFunction: null }, deltaSecondary: { classPropertyName: "deltaSecondary", publicName: "deltaSecondary", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "rt-stat-tile" }, ngImport: i0, template: "<article rtBlock=\"rt-stat-tile\" qa-dataid=\"stat-tile\">\n <header rtElem=\"head\">\n <span rtElem=\"label\" qa-dataid=\"stat-tile-label\">{{ label() }}</span>\n @if (hint(); as hintText) {\n <rt-icon rtElem=\"hint\" qa-dataid=\"stat-tile-hint\" name=\"info-circle\" size=\"xs\" [attr.title]=\"hintText\" />\n }\n </header>\n\n <div rtElem=\"value-row\">\n <p rtElem=\"value\" qa-dataid=\"stat-tile-value\">{{ value() }}</p>\n\n @if (primaryDelta(); as row) {\n <span\n rtElem=\"delta\"\n qa-dataid=\"stat-tile-delta\"\n [attr.data-direction]=\"row.direction\"\n [rtMod]=\"{ direction: row.direction }\"\n [attr.title]=\"row.label\">\n <rt-icon qa-dataid=\"stat-tile-delta-icon\" size=\"xs\" [name]=\"row.icon\" />\n <span qa-dataid=\"stat-tile-delta-percent\">{{ row.text }}</span>\n </span>\n }\n\n @if (yearDelta(); as row) {\n <span\n rtElem=\"year\"\n qa-dataid=\"stat-tile-year\"\n [attr.data-direction]=\"row.direction\"\n [rtMod]=\"{ direction: row.direction }\"\n [attr.title]=\"row.label\">\n {{ t().uiYearOverYear }} {{ row.text }}\n </span>\n }\n </div>\n\n @if (baselineText(); as text) {\n <p rtElem=\"baseline\" qa-dataid=\"stat-tile-baseline\">{{ text }}</p>\n }\n\n @if (secondary(); as text) {\n <p rtElem=\"secondary\" qa-dataid=\"stat-tile-secondary\">{{ text }}</p>\n }\n</article>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{rt-stat-tile{display:block}rt-stat-tile .rt-stat-tile{--rt-stat-tile-year-radius: var(--rt-radius-sm);display:flex;height:100%;flex-direction:column;gap:var(--rt-space-2)}rt-stat-tile .rt-stat-tile__head{display:flex;align-items:center;gap:var(--rt-space-1)}rt-stat-tile .rt-stat-tile__label{color:var(--rt-color-text-primary);font-size:var(--rt-text-sm);font-weight:var(--rt-font-weight-semibold)}rt-stat-tile .rt-stat-tile__hint{color:var(--rt-color-text-muted);cursor:help}rt-stat-tile .rt-stat-tile__value-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--rt-space-4)}rt-stat-tile .rt-stat-tile__value{margin:0;color:var(--rt-color-text-primary);font-size:var(--rt-text-3xl);font-weight:var(--rt-font-weight-bold);line-height:var(--rt-leading-none)}rt-stat-tile .rt-stat-tile__delta{display:inline-flex;align-items:center;color:var(--rt-color-text-muted);font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-bold);gap:var(--rt-space-1);line-height:var(--rt-leading-none)}rt-stat-tile .rt-stat-tile__delta--direction--up{color:var(--rt-color-state-success)}rt-stat-tile .rt-stat-tile__delta--direction--down{color:var(--rt-color-state-danger)}rt-stat-tile .rt-stat-tile__year{flex:0 0 auto;padding:var(--rt-space-0-5) var(--rt-space-2);border-radius:var(--rt-stat-tile-year-radius);background:var(--rt-color-bg-surface-subtle);color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);font-weight:var(--rt-font-weight-semibold);line-height:var(--rt-leading-none);white-space:nowrap}rt-stat-tile .rt-stat-tile__year--direction--up{background:var(--rt-color-state-success-bg);color:var(--rt-color-state-success)}rt-stat-tile .rt-stat-tile__year--direction--down{background:var(--rt-color-state-danger-bg);color:var(--rt-color-state-danger)}rt-stat-tile .rt-stat-tile__baseline{overflow:hidden;margin:0;color:var(--rt-color-text-muted);font-size:var(--rt-text-sm);text-overflow:ellipsis;white-space:nowrap}rt-stat-tile .rt-stat-tile__secondary{overflow:hidden;margin:auto 0 0;color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);text-overflow:ellipsis;white-space:nowrap}}\n"], dependencies: [{ kind: "component", type:
|
|
126
|
+
// standalone components / directives
|
|
127
|
+
RtIconComponent, selector: "rt-icon", inputs: ["name", "glyph", "size", "color", "fill", "spin", "rotate"] }, { 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 }); }
|
|
128
|
+
}
|
|
129
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtStatTileComponent, decorators: [{
|
|
130
|
+
type: Component,
|
|
131
|
+
args: [{ selector: 'rt-stat-tile', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
132
|
+
// standalone components / directives
|
|
133
|
+
RtIconComponent,
|
|
134
|
+
BlockDirective,
|
|
135
|
+
ElemDirective,
|
|
136
|
+
ModDirective,
|
|
137
|
+
], host: {
|
|
138
|
+
class: BEM_BLOCK,
|
|
139
|
+
}, template: "<article rtBlock=\"rt-stat-tile\" qa-dataid=\"stat-tile\">\n <header rtElem=\"head\">\n <span rtElem=\"label\" qa-dataid=\"stat-tile-label\">{{ label() }}</span>\n @if (hint(); as hintText) {\n <rt-icon rtElem=\"hint\" qa-dataid=\"stat-tile-hint\" name=\"info-circle\" size=\"xs\" [attr.title]=\"hintText\" />\n }\n </header>\n\n <div rtElem=\"value-row\">\n <p rtElem=\"value\" qa-dataid=\"stat-tile-value\">{{ value() }}</p>\n\n @if (primaryDelta(); as row) {\n <span\n rtElem=\"delta\"\n qa-dataid=\"stat-tile-delta\"\n [attr.data-direction]=\"row.direction\"\n [rtMod]=\"{ direction: row.direction }\"\n [attr.title]=\"row.label\">\n <rt-icon qa-dataid=\"stat-tile-delta-icon\" size=\"xs\" [name]=\"row.icon\" />\n <span qa-dataid=\"stat-tile-delta-percent\">{{ row.text }}</span>\n </span>\n }\n\n @if (yearDelta(); as row) {\n <span\n rtElem=\"year\"\n qa-dataid=\"stat-tile-year\"\n [attr.data-direction]=\"row.direction\"\n [rtMod]=\"{ direction: row.direction }\"\n [attr.title]=\"row.label\">\n {{ t().uiYearOverYear }} {{ row.text }}\n </span>\n }\n </div>\n\n @if (baselineText(); as text) {\n <p rtElem=\"baseline\" qa-dataid=\"stat-tile-baseline\">{{ text }}</p>\n }\n\n @if (secondary(); as text) {\n <p rtElem=\"secondary\" qa-dataid=\"stat-tile-secondary\">{{ text }}</p>\n }\n</article>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{rt-stat-tile{display:block}rt-stat-tile .rt-stat-tile{--rt-stat-tile-year-radius: var(--rt-radius-sm);display:flex;height:100%;flex-direction:column;gap:var(--rt-space-2)}rt-stat-tile .rt-stat-tile__head{display:flex;align-items:center;gap:var(--rt-space-1)}rt-stat-tile .rt-stat-tile__label{color:var(--rt-color-text-primary);font-size:var(--rt-text-sm);font-weight:var(--rt-font-weight-semibold)}rt-stat-tile .rt-stat-tile__hint{color:var(--rt-color-text-muted);cursor:help}rt-stat-tile .rt-stat-tile__value-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--rt-space-4)}rt-stat-tile .rt-stat-tile__value{margin:0;color:var(--rt-color-text-primary);font-size:var(--rt-text-3xl);font-weight:var(--rt-font-weight-bold);line-height:var(--rt-leading-none)}rt-stat-tile .rt-stat-tile__delta{display:inline-flex;align-items:center;color:var(--rt-color-text-muted);font-size:var(--rt-text-md);font-weight:var(--rt-font-weight-bold);gap:var(--rt-space-1);line-height:var(--rt-leading-none)}rt-stat-tile .rt-stat-tile__delta--direction--up{color:var(--rt-color-state-success)}rt-stat-tile .rt-stat-tile__delta--direction--down{color:var(--rt-color-state-danger)}rt-stat-tile .rt-stat-tile__year{flex:0 0 auto;padding:var(--rt-space-0-5) var(--rt-space-2);border-radius:var(--rt-stat-tile-year-radius);background:var(--rt-color-bg-surface-subtle);color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);font-weight:var(--rt-font-weight-semibold);line-height:var(--rt-leading-none);white-space:nowrap}rt-stat-tile .rt-stat-tile__year--direction--up{background:var(--rt-color-state-success-bg);color:var(--rt-color-state-success)}rt-stat-tile .rt-stat-tile__year--direction--down{background:var(--rt-color-state-danger-bg);color:var(--rt-color-state-danger)}rt-stat-tile .rt-stat-tile__baseline{overflow:hidden;margin:0;color:var(--rt-color-text-muted);font-size:var(--rt-text-sm);text-overflow:ellipsis;white-space:nowrap}rt-stat-tile .rt-stat-tile__secondary{overflow:hidden;margin:auto 0 0;color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);text-overflow:ellipsis;white-space:nowrap}}\n"] }]
|
|
140
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], secondary: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondary", required: false }] }], deltaPrimary: [{ type: i0.Input, args: [{ isSignal: true, alias: "deltaPrimary", required: false }] }], deltaSecondary: [{ type: i0.Input, args: [{ isSignal: true, alias: "deltaSecondary", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }] } });
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Generated bundle index. Do not edit.
|
|
144
|
+
*/
|
|
145
|
+
|
|
146
|
+
export { RtStatTileComponent };
|
|
147
|
+
//# sourceMappingURL=rt-tools-ui-kit-v2-stat-tile.mjs.map
|