@rt-tools/ui-kit-v2 0.16.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -0
- package/fesm2022/rt-tools-ui-kit-v2-accordion.mjs +79 -0
- package/fesm2022/rt-tools-ui-kit-v2-accordion.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs +227 -0
- package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-aside-section.mjs +47 -0
- package/fesm2022/rt-tools-ui-kit-v2-aside-section.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-aside.mjs +702 -0
- package/fesm2022/rt-tools-ui-kit-v2-aside.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs +214 -0
- package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-bar-list.mjs +53 -0
- package/fesm2022/rt-tools-ui-kit-v2-bar-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-bottom-sheet.mjs +88 -0
- package/fesm2022/rt-tools-ui-kit-v2-bottom-sheet.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-button.mjs +365 -0
- package/fesm2022/rt-tools-ui-kit-v2-button.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs +152 -0
- package/fesm2022/rt-tools-ui-kit-v2-calendar.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-card.mjs +72 -0
- package/fesm2022/rt-tools-ui-kit-v2-card.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs +111 -0
- package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-collapsible-text.mjs +76 -0
- package/fesm2022/rt-tools-ui-kit-v2-collapsible-text.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-confirm-popover.mjs +255 -0
- package/fesm2022/rt-tools-ui-kit-v2-confirm-popover.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-container.mjs +1326 -0
- package/fesm2022/rt-tools-ui-kit-v2-container.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs +2590 -0
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-counter-row.mjs +45 -0
- package/fesm2022/rt-tools-ui-kit-v2-counter-row.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-counter.mjs +158 -0
- package/fesm2022/rt-tools-ui-kit-v2-counter.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs +894 -0
- package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs +1217 -0
- package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs +779 -0
- package/fesm2022/rt-tools-ui-kit-v2-date-picker.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs +573 -0
- package/fesm2022/rt-tools-ui-kit-v2-date-range.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-delta-view.mjs +141 -0
- package/fesm2022/rt-tools-ui-kit-v2-delta-view.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-detail-list.mjs +68 -0
- package/fesm2022/rt-tools-ui-kit-v2-detail-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dialog.mjs +478 -0
- package/fesm2022/rt-tools-ui-kit-v2-dialog.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dot-field.mjs +183 -0
- package/fesm2022/rt-tools-ui-kit-v2-dot-field.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-download-link.mjs +44 -0
- package/fesm2022/rt-tools-ui-kit-v2-download-link.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs +260 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +937 -0
- package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-empty-state.mjs +56 -0
- package/fesm2022/rt-tools-ui-kit-v2-empty-state.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs +107 -0
- package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-field.mjs +183 -0
- package/fesm2022/rt-tools-ui-kit-v2-field.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs +219 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-drop.mjs +214 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-drop.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-input.mjs +117 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-input.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-list.mjs +32 -0
- package/fesm2022/rt-tools-ui-kit-v2-file-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs +91 -0
- package/fesm2022/rt-tools-ui-kit-v2-filter-control.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs +220 -0
- package/fesm2022/rt-tools-ui-kit-v2-form-control.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-header.mjs +72 -0
- package/fesm2022/rt-tools-ui-kit-v2-header.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs +163 -0
- package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-icon.mjs +674 -0
- package/fesm2022/rt-tools-ui-kit-v2-icon.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-image-cropper.mjs +540 -0
- package/fesm2022/rt-tools-ui-kit-v2-image-cropper.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs +227 -0
- package/fesm2022/rt-tools-ui-kit-v2-image-upload.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-info-item.mjs +37 -0
- package/fesm2022/rt-tools-ui-kit-v2-info-item.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs +361 -0
- package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-input.mjs +143 -0
- package/fesm2022/rt-tools-ui-kit-v2-input.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-live-badge.mjs +49 -0
- package/fesm2022/rt-tools-ui-kit-v2-live-badge.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-logo.mjs +97 -0
- package/fesm2022/rt-tools-ui-kit-v2-logo.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-markdown-text.mjs +57 -0
- package/fesm2022/rt-tools-ui-kit-v2-markdown-text.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-menu.mjs +537 -0
- package/fesm2022/rt-tools-ui-kit-v2-menu.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-message.mjs +105 -0
- package/fesm2022/rt-tools-ui-kit-v2-message.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-money-list.mjs +71 -0
- package/fesm2022/rt-tools-ui-kit-v2-money-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs +315 -0
- package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-night-grid.mjs +51 -0
- package/fesm2022/rt-tools-ui-kit-v2-night-grid.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-note.mjs +44 -0
- package/fesm2022/rt-tools-ui-kit-v2-note.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-notifications-bell.mjs +54 -0
- package/fesm2022/rt-tools-ui-kit-v2-notifications-bell.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +339 -0
- package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs +187 -0
- package/fesm2022/rt-tools-ui-kit-v2-pagination.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-photo-viewer.mjs +170 -0
- package/fesm2022/rt-tools-ui-kit-v2-photo-viewer.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-popover.mjs +312 -0
- package/fesm2022/rt-tools-ui-kit-v2-popover.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs +174 -0
- package/fesm2022/rt-tools-ui-kit-v2-radio-button.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-radius.mjs +56 -0
- package/fesm2022/rt-tools-ui-kit-v2-radius.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +96 -41
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-ripple.mjs +118 -0
- package/fesm2022/rt-tools-ui-kit-v2-ripple.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs +290 -0
- package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs +37 -0
- package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-select.mjs +495 -0
- package/fesm2022/rt-tools-ui-kit-v2-select.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +1493 -0
- package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-skeleton-wrapper.mjs +49 -0
- package/fesm2022/rt-tools-ui-kit-v2-skeleton-wrapper.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-skeleton.mjs +123 -0
- package/fesm2022/rt-tools-ui-kit-v2-skeleton.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-spinner.mjs +70 -0
- package/fesm2022/rt-tools-ui-kit-v2-spinner.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs +92 -0
- package/fesm2022/rt-tools-ui-kit-v2-split-button.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs +147 -0
- package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs +117 -0
- package/fesm2022/rt-tools-ui-kit-v2-stepper.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-table.mjs +1636 -0
- package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs +350 -0
- package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-tag.mjs +122 -0
- package/fesm2022/rt-tools-ui-kit-v2-tag.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs +85 -0
- package/fesm2022/rt-tools-ui-kit-v2-textarea.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs +73 -0
- package/fesm2022/rt-tools-ui-kit-v2-theme-toggle.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +196 -0
- package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-timeline.mjs +39 -0
- package/fesm2022/rt-tools-ui-kit-v2-timeline.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-toast.mjs +338 -0
- package/fesm2022/rt-tools-ui-kit-v2-toast.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs +132 -0
- package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs +162 -0
- package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs +135 -0
- package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs +214 -0
- package/fesm2022/rt-tools-ui-kit-v2-tooltip.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-welcome-dialog.mjs +64 -0
- package/fesm2022/rt-tools-ui-kit-v2-welcome-dialog.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs +263 -0
- package/fesm2022/rt-tools-ui-kit-v2-workspace-details.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs +296 -0
- package/fesm2022/rt-tools-ui-kit-v2-workspace.mjs.map +1 -0
- package/fesm2022/rt-tools-ui-kit-v2.mjs +91 -23164
- package/fesm2022/rt-tools-ui-kit-v2.mjs.map +1 -1
- package/package.json +349 -1
- package/rt-tools-ui-kit-v2-0.18.0.tgz +0 -0
- package/src/lib/components/action-bar/CONTEXT.md +5 -0
- package/src/lib/components/action-bar/rt-action-bar.component.scss +30 -16
- package/src/lib/components/aside/CONTEXT.md +9 -1
- package/src/lib/components/aside/footer/rt-aside-footer.component.scss +7 -8
- package/src/lib/components/aside/header/rt-aside-header.component.scss +16 -1
- package/src/lib/components/aside/rt-aside.component.scss +17 -1
- package/src/lib/components/button/CONTEXT.md +12 -11
- package/src/lib/components/button/rt-button.directive.scss +36 -0
- package/src/lib/components/data-list/settings/rt-data-list-settings-aside.component.scss +2 -2
- package/src/lib/components/data-table/cell/rt-data-table-cell.component.scss +1 -1
- package/src/lib/components/data-table/filter-cell/rt-data-table-filter-cell.component.scss +1 -1
- package/src/lib/components/data-table/rt-data-table.component.scss +1 -1
- package/src/lib/components/dialog/CONTEXT.md +9 -0
- package/src/lib/components/dialog/content/rt-dialog-content.component.scss +20 -0
- package/src/lib/components/dialog/footer/rt-dialog-footer.component.scss +18 -2
- package/src/lib/components/dialog/header/rt-dialog-header.component.scss +21 -3
- package/src/lib/components/dialog/rt-dialog.component.scss +9 -3
- package/src/lib/components/dot-field/CONTEXT.md +31 -0
- package/src/lib/components/dot-field/rt-dot-field.component.scss +20 -0
- package/src/lib/components/dot-field/stories/component/CONTEXT.md +14 -0
- package/src/lib/components/dot-field/stories/component/test-dot-field.component.scss +31 -0
- package/src/lib/components/dynamic-selector/CONTEXT.md +6 -0
- package/src/lib/components/field/CONTEXT.md +18 -2
- package/src/lib/components/header/CONTEXT.md +2 -2
- package/src/lib/components/icon/CONTEXT.md +11 -7
- package/src/lib/components/icon/rt-icon.component.scss +47 -0
- package/src/lib/components/icon-button/CONTEXT.md +27 -20
- package/src/lib/components/icon-button/rt-icon-button.component.scss +51 -25
- package/src/lib/components/image-upload/CONTEXT.md +20 -15
- package/src/lib/components/image-upload/rt-image-upload.component.scss +14 -2
- package/src/lib/components/pagination/rt-pagination.component.scss +1 -1
- package/src/lib/components/scroll-area/CONTEXT.md +2 -0
- package/src/lib/components/scroll-area/rt-scroll-area.component.scss +20 -3
- package/src/lib/components/select/rt-select.component.scss +4 -0
- package/src/lib/components/side-menu/CONTEXT.md +7 -2
- package/src/lib/components/spinner/CONTEXT.md +15 -8
- package/src/lib/components/spinner/rt-spinner.component.scss +108 -9
- package/src/lib/components/tag/rt-tag.component.scss +43 -23
- package/src/lib/components/toast/CONTEXT.md +8 -0
- package/src/lib/components/toast/rt-toast.component.scss +74 -15
- package/src/lib/components/toast/rt-toaster.component.scss +5 -1
- package/src/lib/components/toggle-button-group/rt-toggle-button-group.component.scss +35 -37
- package/src/lib/components/toggle-switch/CONTEXT.md +11 -3
- package/src/lib/components/toggle-switch/rt-toggle-switch.component.scss +53 -14
- package/src/lib/components/toolbar/rt-toolbar.component.scss +15 -4
- package/src/lib/components/tooltip/CONTEXT.md +5 -5
- package/src/rich-editor/lib/components/chat/CONTEXT.md +7 -2
- package/src/rich-editor/lib/components/chat/rt-chat.component.scss +25 -0
- package/src/styles/_semantic.scss +1 -1
- package/styles/tokens.css +43 -8
- package/types/rt-tools-ui-kit-v2-accordion.d.ts +30 -0
- package/types/rt-tools-ui-kit-v2-action-bar.d.ts +140 -0
- package/types/rt-tools-ui-kit-v2-aside-section.d.ts +25 -0
- package/types/rt-tools-ui-kit-v2-aside.d.ts +436 -0
- package/types/rt-tools-ui-kit-v2-autocomplete.d.ts +78 -0
- package/types/rt-tools-ui-kit-v2-bar-list.d.ts +41 -0
- package/types/rt-tools-ui-kit-v2-bottom-sheet.d.ts +20 -0
- package/types/rt-tools-ui-kit-v2-button.d.ts +76 -0
- package/types/rt-tools-ui-kit-v2-calendar.d.ts +96 -0
- package/types/rt-tools-ui-kit-v2-card.d.ts +38 -0
- package/types/rt-tools-ui-kit-v2-checkbox.d.ts +46 -0
- package/types/rt-tools-ui-kit-v2-collapsible-text.d.ts +20 -0
- package/types/rt-tools-ui-kit-v2-confirm-popover.d.ts +85 -0
- package/types/rt-tools-ui-kit-v2-container.d.ts +425 -0
- package/types/rt-tools-ui-kit-v2-core.d.ts +1222 -0
- package/types/rt-tools-ui-kit-v2-counter-row.d.ts +22 -0
- package/types/rt-tools-ui-kit-v2-counter.d.ts +70 -0
- package/types/rt-tools-ui-kit-v2-data-list.d.ts +334 -0
- package/types/rt-tools-ui-kit-v2-data-table.d.ts +494 -0
- package/types/rt-tools-ui-kit-v2-date-picker.d.ts +181 -0
- package/types/rt-tools-ui-kit-v2-date-range.d.ts +98 -0
- package/types/rt-tools-ui-kit-v2-delta-view.d.ts +20 -0
- package/types/rt-tools-ui-kit-v2-detail-list.d.ts +33 -0
- package/types/rt-tools-ui-kit-v2-dialog.d.ts +287 -0
- package/types/rt-tools-ui-kit-v2-dot-field.d.ts +17 -0
- package/types/rt-tools-ui-kit-v2-download-link.d.ts +17 -0
- package/types/rt-tools-ui-kit-v2-dynamic-list.d.ts +139 -0
- package/types/rt-tools-ui-kit-v2-dynamic-selector.d.ts +384 -0
- package/types/rt-tools-ui-kit-v2-empty-state.d.ts +29 -0
- package/types/rt-tools-ui-kit-v2-expansion-panel.d.ts +57 -0
- package/types/rt-tools-ui-kit-v2-field.d.ts +82 -0
- package/types/rt-tools-ui-kit-v2-file-card.d.ts +114 -0
- package/types/rt-tools-ui-kit-v2-file-drop.d.ts +75 -0
- package/types/rt-tools-ui-kit-v2-file-input.d.ts +48 -0
- package/types/rt-tools-ui-kit-v2-file-list.d.ts +13 -0
- package/types/rt-tools-ui-kit-v2-filter-control.d.ts +72 -0
- package/types/rt-tools-ui-kit-v2-form-control.d.ts +74 -0
- package/types/rt-tools-ui-kit-v2-header.d.ts +40 -0
- package/types/rt-tools-ui-kit-v2-icon-button.d.ts +113 -0
- package/types/rt-tools-ui-kit-v2-icon.d.ts +238 -0
- package/types/rt-tools-ui-kit-v2-image-cropper.d.ts +168 -0
- package/types/rt-tools-ui-kit-v2-image-upload.d.ts +102 -0
- package/types/rt-tools-ui-kit-v2-info-item.d.ts +13 -0
- package/types/rt-tools-ui-kit-v2-input-number.d.ts +67 -0
- package/types/rt-tools-ui-kit-v2-input.d.ts +54 -0
- package/types/rt-tools-ui-kit-v2-live-badge.d.ts +23 -0
- package/types/rt-tools-ui-kit-v2-logo.d.ts +58 -0
- package/types/rt-tools-ui-kit-v2-markdown-text.d.ts +30 -0
- package/types/rt-tools-ui-kit-v2-menu.d.ts +217 -0
- package/types/rt-tools-ui-kit-v2-message.d.ts +56 -0
- package/types/rt-tools-ui-kit-v2-money-list.d.ts +34 -0
- package/types/rt-tools-ui-kit-v2-multiselect.d.ts +93 -0
- package/types/rt-tools-ui-kit-v2-night-grid.d.ts +39 -0
- package/types/rt-tools-ui-kit-v2-note.d.ts +21 -0
- package/types/rt-tools-ui-kit-v2-notifications-bell.d.ts +23 -0
- package/types/rt-tools-ui-kit-v2-page-header.d.ts +173 -0
- package/types/rt-tools-ui-kit-v2-pagination.d.ts +64 -0
- package/types/rt-tools-ui-kit-v2-photo-viewer.d.ts +98 -0
- package/types/rt-tools-ui-kit-v2-popover.d.ts +79 -0
- package/types/rt-tools-ui-kit-v2-radio-button.d.ts +61 -0
- package/types/rt-tools-ui-kit-v2-radius.d.ts +37 -0
- package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +16 -20
- package/types/rt-tools-ui-kit-v2-ripple.d.ts +39 -0
- package/types/rt-tools-ui-kit-v2-scroll-area.d.ts +91 -0
- package/types/rt-tools-ui-kit-v2-section-nav.d.ts +23 -0
- package/types/rt-tools-ui-kit-v2-select.d.ts +215 -0
- package/types/rt-tools-ui-kit-v2-side-menu.d.ts +483 -0
- package/types/rt-tools-ui-kit-v2-skeleton-wrapper.d.ts +32 -0
- package/types/rt-tools-ui-kit-v2-skeleton.d.ts +41 -0
- package/types/rt-tools-ui-kit-v2-spinner.d.ts +56 -0
- package/types/rt-tools-ui-kit-v2-split-button.d.ts +72 -0
- package/types/rt-tools-ui-kit-v2-stat-tile.d.ts +81 -0
- package/types/rt-tools-ui-kit-v2-stepper.d.ts +51 -0
- package/types/rt-tools-ui-kit-v2-table.d.ts +739 -0
- package/types/rt-tools-ui-kit-v2-tabs.d.ts +153 -0
- package/types/rt-tools-ui-kit-v2-tag.d.ts +70 -0
- package/types/rt-tools-ui-kit-v2-textarea.d.ts +36 -0
- package/types/rt-tools-ui-kit-v2-theme-toggle.d.ts +43 -0
- package/types/rt-tools-ui-kit-v2-thread-list.d.ts +111 -0
- package/types/rt-tools-ui-kit-v2-timeline.d.ts +35 -0
- package/types/rt-tools-ui-kit-v2-toast.d.ts +103 -0
- package/types/rt-tools-ui-kit-v2-toggle-button-group.d.ts +109 -0
- package/types/rt-tools-ui-kit-v2-toggle-switch.d.ts +85 -0
- package/types/rt-tools-ui-kit-v2-toolbar.d.ts +66 -0
- package/types/rt-tools-ui-kit-v2-tooltip.d.ts +74 -0
- package/types/rt-tools-ui-kit-v2-welcome-dialog.d.ts +33 -0
- package/types/rt-tools-ui-kit-v2-workspace-details.d.ts +128 -0
- package/types/rt-tools-ui-kit-v2-workspace.d.ts +84 -0
- package/types/rt-tools-ui-kit-v2.d.ts +87 -9290
- package/rt-tools-ui-kit-v2-0.16.0.tgz +0 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { NgTemplateOutlet } from '@angular/common';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { signal, viewChildren, computed, input, booleanAttribute, output, afterRenderEffect, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
4
|
+
import { BlockDirective, ElemDirective } from '@rt-tools/core';
|
|
5
|
+
import { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';
|
|
6
|
+
import * as i1 from '@rt-tools/ui-kit-v2/radius';
|
|
7
|
+
import { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';
|
|
8
|
+
import { RtSkeletonComponent } from '@rt-tools/ui-kit-v2/skeleton';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Контракты `rt-calendar` — презентационный месячный грид с range-выбором.
|
|
12
|
+
*
|
|
13
|
+
* Компонент домен-агностичен: состояния/цены/доступность дней вычисляет
|
|
14
|
+
* consumer и передаёт готовые view-модели месяцев. Клики по дням и навигация
|
|
15
|
+
* по месяцам эмитятся наружу; никакой доменной логики внутри нет.
|
|
16
|
+
*/
|
|
17
|
+
/** Состояние ячейки дня — модификатор `data-state` на кнопке дня. */
|
|
18
|
+
var ERtCalendarDayState;
|
|
19
|
+
(function (ERtCalendarDayState) {
|
|
20
|
+
ERtCalendarDayState["Free"] = "free";
|
|
21
|
+
ERtCalendarDayState["Busy"] = "busy";
|
|
22
|
+
ERtCalendarDayState["Past"] = "past";
|
|
23
|
+
ERtCalendarDayState["Blocked"] = "blocked";
|
|
24
|
+
ERtCalendarDayState["Start"] = "start";
|
|
25
|
+
ERtCalendarDayState["End"] = "end";
|
|
26
|
+
ERtCalendarDayState["InRange"] = "in-range";
|
|
27
|
+
/** Выбранный день одиночного выбора — залит. */
|
|
28
|
+
ERtCalendarDayState["Chosen"] = "chosen";
|
|
29
|
+
})(ERtCalendarDayState || (ERtCalendarDayState = {}));
|
|
30
|
+
|
|
31
|
+
const BEM_BLOCK = 'rt-calendar';
|
|
32
|
+
/** Клавиши, что календарь в режиме сетки отдаёт наружу вместо прокрутки страницы. */
|
|
33
|
+
const GRID_KEYS = new Set(['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'PageUp', 'PageDown', 'Home', 'End']);
|
|
34
|
+
class RtCalendarComponent {
|
|
35
|
+
/** Фокус двигала клавиша: только тогда календарь переводит фокус на `activeKey`. */
|
|
36
|
+
#keyed;
|
|
37
|
+
constructor() {
|
|
38
|
+
/** Фокус двигала клавиша: только тогда календарь переводит фокус на `activeKey`. */
|
|
39
|
+
this.#keyed = signal(false, /* @ts-ignore */
|
|
40
|
+
...(ngDevMode ? [{ debugName: "#keyed" }] : /* istanbul ignore next */ []));
|
|
41
|
+
this.sublabelSkeletonHeight = '12px';
|
|
42
|
+
this.chosenState = ERtCalendarDayState.Chosen;
|
|
43
|
+
this.dayButtons = viewChildren('dayButton', /* @ts-ignore */
|
|
44
|
+
...(ngDevMode ? [{ debugName: "dayButtons" }] : /* istanbul ignore next */ []));
|
|
45
|
+
/**
|
|
46
|
+
* День, что стоит в порядке обхода Tab в режиме сетки: `activeKey`, иначе выбранный, иначе
|
|
47
|
+
* сегодняшний, иначе первый доступный. Вне режима сетки — `null`, и каждый день обходится Tab.
|
|
48
|
+
*/
|
|
49
|
+
this.rovingKey = computed(() => {
|
|
50
|
+
if (!this.grid()) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const days = this.months().flatMap((month) => [...month.days]);
|
|
54
|
+
const active = this.activeKey();
|
|
55
|
+
const pick = days.find((day) => day.key === active) ??
|
|
56
|
+
days.find((day) => day.state === ERtCalendarDayState.Chosen) ??
|
|
57
|
+
days.find((day) => day.today === true) ??
|
|
58
|
+
days.find((day) => !day.disabled);
|
|
59
|
+
return pick?.key ?? null;
|
|
60
|
+
}, /* @ts-ignore */
|
|
61
|
+
...(ngDevMode ? [{ debugName: "rovingKey" }] : /* istanbul ignore next */ []));
|
|
62
|
+
this.months = input.required(/* @ts-ignore */
|
|
63
|
+
...(ngDevMode ? [{ debugName: "months" }] : /* istanbul ignore next */ []));
|
|
64
|
+
this.weekdayLabels = input.required(/* @ts-ignore */
|
|
65
|
+
...(ngDevMode ? [{ debugName: "weekdayLabels" }] : /* istanbul ignore next */ []));
|
|
66
|
+
this.canPrev = input(false, { ...(ngDevMode ? { debugName: "canPrev" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
67
|
+
this.canNext = input(false, { ...(ngDevMode ? { debugName: "canNext" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
68
|
+
/** Локализованные aria-подписи кнопок навигации — задаёт consumer. */
|
|
69
|
+
this.prevAriaLabel = input('', /* @ts-ignore */
|
|
70
|
+
...(ngDevMode ? [{ debugName: "prevAriaLabel" }] : /* istanbul ignore next */ []));
|
|
71
|
+
this.nextAriaLabel = input('', /* @ts-ignore */
|
|
72
|
+
...(ngDevMode ? [{ debugName: "nextAriaLabel" }] : /* istanbul ignore next */ []));
|
|
73
|
+
this.sublabelsLoading = input(false, { ...(ngDevMode ? { debugName: "sublabelsLoading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
74
|
+
/**
|
|
75
|
+
* Режим сетки: один день в обходе Tab, клавиши стрелок, PageUp/PageDown, Home и End уходят
|
|
76
|
+
* наружу событием `gridKey`, а фокус встаёт на `activeKey`. Выключен — поведение прежнее.
|
|
77
|
+
*/
|
|
78
|
+
this.grid = input(false, { ...(ngDevMode ? { debugName: "grid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
79
|
+
/** День с фокусом в режиме сетки, ключ `YYYY-MM-DD`; его ставит consumer по `gridKey`. */
|
|
80
|
+
this.activeKey = input(null, /* @ts-ignore */
|
|
81
|
+
...(ngDevMode ? [{ debugName: "activeKey" }] : /* istanbul ignore next */ []));
|
|
82
|
+
/** Заголовок месяца — кнопка, что шлёт `titleClick`: так consumer открывает выбор месяца. */
|
|
83
|
+
this.titleAction = input(false, { ...(ngDevMode ? { debugName: "titleAction" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
84
|
+
/** Заголовок первого месяца стоит в шапке между стрелками, а не над сеткой. */
|
|
85
|
+
this.headerTitle = input(false, { ...(ngDevMode ? { debugName: "headerTitle" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
86
|
+
this.prevMonth = output();
|
|
87
|
+
this.nextMonth = output();
|
|
88
|
+
this.dayClick = output();
|
|
89
|
+
/** Клавиша сетки на дне: куда перевести фокус, решает consumer. */
|
|
90
|
+
this.gridKey = output();
|
|
91
|
+
this.titleClick = output();
|
|
92
|
+
/** День под указателем или с фокусом; `null` — указатель ушёл с месяцев. По нему рисуется будущий диапазон. */
|
|
93
|
+
this.dayHover = output();
|
|
94
|
+
afterRenderEffect(() => {
|
|
95
|
+
const key = this.rovingKey();
|
|
96
|
+
if (!this.#keyed() || key === null) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
this.dayButtons()
|
|
100
|
+
.find((button) => button.nativeElement.dataset['iso'] === key)
|
|
101
|
+
?.nativeElement.focus();
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
onDayKey(event, day) {
|
|
105
|
+
if (!this.grid() || !GRID_KEYS.has(event.key)) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
event.preventDefault();
|
|
109
|
+
this.#keyed.set(true);
|
|
110
|
+
this.gridKey.emit({ key: event.key, day });
|
|
111
|
+
}
|
|
112
|
+
onDayHover(day) {
|
|
113
|
+
if (!day.disabled) {
|
|
114
|
+
this.dayHover.emit(day);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
onDayClick(day) {
|
|
118
|
+
if (!day.disabled) {
|
|
119
|
+
this.dayClick.emit(day);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtCalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
123
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtCalendarComponent, isStandalone: true, selector: "rt-calendar", inputs: { months: { classPropertyName: "months", publicName: "months", isSignal: true, isRequired: true, transformFunction: null }, weekdayLabels: { classPropertyName: "weekdayLabels", publicName: "weekdayLabels", isSignal: true, isRequired: true, transformFunction: null }, canPrev: { classPropertyName: "canPrev", publicName: "canPrev", isSignal: true, isRequired: false, transformFunction: null }, canNext: { classPropertyName: "canNext", publicName: "canNext", isSignal: true, isRequired: false, transformFunction: null }, prevAriaLabel: { classPropertyName: "prevAriaLabel", publicName: "prevAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, nextAriaLabel: { classPropertyName: "nextAriaLabel", publicName: "nextAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, sublabelsLoading: { classPropertyName: "sublabelsLoading", publicName: "sublabelsLoading", isSignal: true, isRequired: false, transformFunction: null }, grid: { classPropertyName: "grid", publicName: "grid", isSignal: true, isRequired: false, transformFunction: null }, activeKey: { classPropertyName: "activeKey", publicName: "activeKey", isSignal: true, isRequired: false, transformFunction: null }, titleAction: { classPropertyName: "titleAction", publicName: "titleAction", isSignal: true, isRequired: false, transformFunction: null }, headerTitle: { classPropertyName: "headerTitle", publicName: "headerTitle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { prevMonth: "prevMonth", nextMonth: "nextMonth", dayClick: "dayClick", gridKey: "gridKey", titleClick: "titleClick", dayHover: "dayHover" }, host: { classAttribute: "rt-calendar" }, viewQueries: [{ propertyName: "dayButtons", predicate: ["dayButton"], descendants: true, isSignal: true }], hostDirectives: [{ directive: i1.RtRadiusDirective, inputs: ["radius", "radius"] }], ngImport: i0, template: "<ng-container rtBlock=\"rt-calendar\">\n <div rtElem=\"header\">\n <rt-icon-button\n rtElem=\"nav\"\n qa-dataid=\"calendar-prev-month\"\n icon=\"chevron-left\"\n variant=\"secondary\"\n radius=\"full\"\n [ariaLabel]=\"prevAriaLabel()\"\n [disabled]=\"!canPrev()\"\n (clicked)=\"prevMonth.emit()\" />\n @if (headerTitle() && months()[0]; as first) {\n <ng-container *ngTemplateOutlet=\"titleTpl; context: { $implicit: first }\" />\n }\n <ng-content select=\"[calendarHint]\" />\n <rt-icon-button\n rtElem=\"nav\"\n qa-dataid=\"calendar-next-month\"\n icon=\"chevron-right\"\n variant=\"secondary\"\n radius=\"full\"\n [ariaLabel]=\"nextAriaLabel()\"\n [disabled]=\"!canNext()\"\n (clicked)=\"nextMonth.emit()\" />\n </div>\n\n <div rtElem=\"months\" qa-dataid=\"calendar-months\" (mouseleave)=\"dayHover.emit(null)\">\n @for (month of months(); track month.key) {\n <div rtElem=\"month\" qa-dataid=\"calendar-month\">\n @if (!headerTitle()) {\n <ng-container *ngTemplateOutlet=\"titleTpl; context: { $implicit: month }\" />\n }\n <div rtElem=\"grid\" qa-dataid=\"calendar-grid\">\n @for (weekday of weekdayLabels(); track $index) {\n <span rtElem=\"weekday\" qa-dataid=\"calendar-weekday\">{{ weekday }}</span>\n }\n @for (blank of month.leadingBlanks; track blank) {\n <!-- \u041F\u0443\u0441\u0442\u0430\u044F \u044F\u0447\u0435\u0439\u043A\u0430 \u0441\u0435\u0442\u043A\u0438 \u0434\u043E \u043F\u0435\u0440\u0432\u043E\u0433\u043E \u0434\u043D\u044F \u043C\u0435\u0441\u044F\u0446\u0430: \u0437\u0430\u043D\u0438\u043C\u0430\u0435\u0442 \u043C\u0435\u0441\u0442\u043E \u0438 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043A\u0440\u0430\u0441\u0438\u0442. -->\n <span qa-dataid=\"calendar-blank\" aria-hidden=\"true\"></span>\n }\n @for (day of month.days; track day.key) {\n <button\n #dayButton\n rtElem=\"day\"\n qa-dataid=\"calendar-day\"\n type=\"button\"\n [attr.data-iso]=\"day.key\"\n [attr.data-state]=\"day.state\"\n [attr.data-today]=\"day.today ? '' : null\"\n [attr.aria-current]=\"day.today ? 'date' : null\"\n [attr.aria-pressed]=\"day.state === chosenState ? true : null\"\n [attr.tabindex]=\"rovingKey() === null ? null : day.key === rovingKey() ? 0 : -1\"\n [disabled]=\"day.disabled\"\n (keydown)=\"onDayKey($event, day)\"\n (mouseenter)=\"onDayHover(day)\"\n (focus)=\"onDayHover(day)\"\n (click)=\"onDayClick(day)\">\n <span rtElem=\"day-num\" qa-dataid=\"calendar-day-num\">{{ day.dayOfMonth }}</span>\n @if (sublabelsLoading()) {\n <rt-skeleton\n rtElem=\"day-sublabel\"\n qa-dataid=\"calendar-day-price-skeleton\"\n width=\"80%\"\n radius=\"sm\"\n [height]=\"sublabelSkeletonHeight\" />\n } @else if (day.sublabel) {\n <span rtElem=\"day-sublabel\" qa-dataid=\"calendar-day-price\">{{ day.sublabel }}</span>\n }\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <ng-content />\n\n <ng-template #titleTpl let-month>\n @if (titleAction()) {\n <button rtElem=\"month-title\" qa-dataid=\"calendar-month-title\" type=\"button\" (click)=\"titleClick.emit(month)\">\n {{ month.label }}\n </button>\n } @else {\n <p rtElem=\"month-title\" qa-dataid=\"calendar-month-title\">{{ month.label }}</p>\n }\n </ng-template>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-calendar{--rt-calendar-day-radius: var(--rt-radius-md);--rt-calendar-day-size: auto;--rt-calendar-day-justify: flex-start;--rt-calendar-month-count: 2;--rt-calendar-column-gap: var(--rt-space-0-5);--rt-calendar-range-inner-radius: var(--rt-calendar-day-radius);--rt-calendar-today-ring: inset 0 0 0 var(--rt-border-width-thin) var(--rt-color-action-primary);display:block}.rt-calendar__header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--rt-space-4);gap:var(--rt-space-4)}.rt-calendar__nav{flex:0 0 auto}.rt-calendar__header .rt-calendar__month-title{width:auto;padding:var(--rt-space-1) var(--rt-space-2);margin:0}.rt-calendar__months{display:grid;gap:var(--rt-space-6);grid-template-columns:repeat(var(--rt-calendar-month-count),1fr)}.rt-calendar__month-title{display:block;width:100%;padding:0;border:none;margin:0 0 var(--rt-space-2);background:none;color:var(--rt-color-text-primary);font:inherit;font-weight:var(--rt-font-weight-semibold);text-align:center}.rt-calendar__month-title:first-letter{text-transform:uppercase}.rt-calendar__month-title:is(button){border-radius:var(--rt-calendar-day-radius);cursor:pointer}.rt-calendar__month-title:is(button):hover{color:var(--rt-color-text-link)}.rt-calendar__month-title:is(button):focus-visible{outline:var(--rt-focus-ring-width) solid var(--rt-focus-ring-color);outline-offset:var(--rt-focus-ring-offset)}.rt-calendar__grid{display:grid;gap:var(--rt-space-0-5) var(--rt-calendar-column-gap);grid-template-columns:repeat(7,1fr)}.rt-calendar__weekday{padding:var(--rt-space-1) 0;color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);text-align:center}.rt-calendar__day{display:flex;flex-direction:column;align-items:center;justify-content:var(--rt-calendar-day-justify);padding:var(--rt-space-2) var(--rt-space-0-5);border:none;border-radius:var(--rt-calendar-day-radius);background:none;color:var(--rt-color-text-primary);cursor:pointer;font:inherit;gap:var(--rt-space-0-5);min-block-size:var(--rt-calendar-day-size)}.rt-calendar__day:hover:not(:disabled,[data-state=start],[data-state=end],[data-state=in-range],[data-state=chosen]){background:var(--rt-color-bg-subtle)}.rt-calendar__day:disabled{color:var(--rt-color-text-muted);cursor:not-allowed;opacity:.45}.rt-calendar__day[data-state=past],.rt-calendar__day[data-state=blocked]{color:var(--rt-color-text-muted);opacity:.45}.rt-calendar__day[data-state=busy]{color:var(--rt-color-text-muted);opacity:.45;text-decoration:line-through}.rt-calendar__day[data-today]{box-shadow:var(--rt-calendar-today-ring)}.rt-calendar__day:focus-visible{outline:var(--rt-focus-ring-width) solid var(--rt-focus-ring-color);outline-offset:var(--rt-focus-ring-offset)}.rt-calendar__day[data-state=start],.rt-calendar__day[data-state=end],.rt-calendar__day[data-state=chosen]{background:var(--rt-color-action-primary);color:var(--rt-color-action-on-primary)}.rt-calendar__day[data-state=start]{border-end-end-radius:var(--rt-calendar-range-inner-radius);border-start-end-radius:var(--rt-calendar-range-inner-radius)}.rt-calendar__day[data-state=end]{border-end-start-radius:var(--rt-calendar-range-inner-radius);border-start-start-radius:var(--rt-calendar-range-inner-radius)}.rt-calendar__day[data-state=in-range]{border-radius:var(--rt-calendar-range-inner-radius);background:var(--rt-color-action-primary-soft);color:var(--rt-color-text-link);font-weight:var(--rt-font-weight-semibold)}.rt-calendar__day-num{font-size:var(--rt-text-sm);font-weight:var(--rt-font-weight-medium)}.rt-calendar__day-sublabel{font-size:var(--rt-text-2xs);opacity:.75}@media(width<=640px){.rt-calendar__months{grid-template-columns:1fr}.rt-calendar__month:last-child{display:none}}@media(width<=374px){.rt-calendar__day{padding-inline:0}.rt-calendar__day-sublabel{font-size:var(--rt-text-3xs)}}.rt-calendar[data-rt-radius=none]{--rt-calendar-day-radius: var(--rt-radius-none)}.rt-calendar[data-rt-radius=xs]{--rt-calendar-day-radius: var(--rt-radius-xs)}.rt-calendar[data-rt-radius=sm]{--rt-calendar-day-radius: var(--rt-radius-sm)}.rt-calendar[data-rt-radius=ms]{--rt-calendar-day-radius: var(--rt-radius-ms)}.rt-calendar[data-rt-radius=md]{--rt-calendar-day-radius: var(--rt-radius-md)}.rt-calendar[data-rt-radius=lg]{--rt-calendar-day-radius: var(--rt-radius-lg)}.rt-calendar[data-rt-radius=xl]{--rt-calendar-day-radius: var(--rt-radius-xl)}.rt-calendar[data-rt-radius=\"2xl\"]{--rt-calendar-day-radius: var(--rt-radius-2xl)}.rt-calendar[data-rt-radius=full]{--rt-calendar-day-radius: var(--rt-radius-full)}}\n"], dependencies: [{ kind: "directive", type:
|
|
124
|
+
// angular
|
|
125
|
+
NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type:
|
|
126
|
+
// rt-tools
|
|
127
|
+
BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }, { kind: "component", type:
|
|
128
|
+
// components
|
|
129
|
+
RtIconButtonComponent, selector: "rt-icon-button", inputs: ["icon", "glyph", "ariaLabel", "variant", "iconColor", "iconFill", "size", "iconSize", "type", "tooltip", "tabIndex", "loading", "disabled", "active", "indicator"], outputs: ["clicked"] }, { kind: "component", type: RtSkeletonComponent, selector: "rt-skeleton", inputs: ["shape", "size", "width", "height", "animation"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
130
|
+
}
|
|
131
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtCalendarComponent, decorators: [{
|
|
132
|
+
type: Component,
|
|
133
|
+
args: [{ selector: 'rt-calendar', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
134
|
+
// angular
|
|
135
|
+
NgTemplateOutlet,
|
|
136
|
+
// rt-tools
|
|
137
|
+
BlockDirective,
|
|
138
|
+
ElemDirective,
|
|
139
|
+
// components
|
|
140
|
+
RtIconButtonComponent,
|
|
141
|
+
RtSkeletonComponent,
|
|
142
|
+
], hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }], host: {
|
|
143
|
+
class: BEM_BLOCK,
|
|
144
|
+
}, template: "<ng-container rtBlock=\"rt-calendar\">\n <div rtElem=\"header\">\n <rt-icon-button\n rtElem=\"nav\"\n qa-dataid=\"calendar-prev-month\"\n icon=\"chevron-left\"\n variant=\"secondary\"\n radius=\"full\"\n [ariaLabel]=\"prevAriaLabel()\"\n [disabled]=\"!canPrev()\"\n (clicked)=\"prevMonth.emit()\" />\n @if (headerTitle() && months()[0]; as first) {\n <ng-container *ngTemplateOutlet=\"titleTpl; context: { $implicit: first }\" />\n }\n <ng-content select=\"[calendarHint]\" />\n <rt-icon-button\n rtElem=\"nav\"\n qa-dataid=\"calendar-next-month\"\n icon=\"chevron-right\"\n variant=\"secondary\"\n radius=\"full\"\n [ariaLabel]=\"nextAriaLabel()\"\n [disabled]=\"!canNext()\"\n (clicked)=\"nextMonth.emit()\" />\n </div>\n\n <div rtElem=\"months\" qa-dataid=\"calendar-months\" (mouseleave)=\"dayHover.emit(null)\">\n @for (month of months(); track month.key) {\n <div rtElem=\"month\" qa-dataid=\"calendar-month\">\n @if (!headerTitle()) {\n <ng-container *ngTemplateOutlet=\"titleTpl; context: { $implicit: month }\" />\n }\n <div rtElem=\"grid\" qa-dataid=\"calendar-grid\">\n @for (weekday of weekdayLabels(); track $index) {\n <span rtElem=\"weekday\" qa-dataid=\"calendar-weekday\">{{ weekday }}</span>\n }\n @for (blank of month.leadingBlanks; track blank) {\n <!-- \u041F\u0443\u0441\u0442\u0430\u044F \u044F\u0447\u0435\u0439\u043A\u0430 \u0441\u0435\u0442\u043A\u0438 \u0434\u043E \u043F\u0435\u0440\u0432\u043E\u0433\u043E \u0434\u043D\u044F \u043C\u0435\u0441\u044F\u0446\u0430: \u0437\u0430\u043D\u0438\u043C\u0430\u0435\u0442 \u043C\u0435\u0441\u0442\u043E \u0438 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043A\u0440\u0430\u0441\u0438\u0442. -->\n <span qa-dataid=\"calendar-blank\" aria-hidden=\"true\"></span>\n }\n @for (day of month.days; track day.key) {\n <button\n #dayButton\n rtElem=\"day\"\n qa-dataid=\"calendar-day\"\n type=\"button\"\n [attr.data-iso]=\"day.key\"\n [attr.data-state]=\"day.state\"\n [attr.data-today]=\"day.today ? '' : null\"\n [attr.aria-current]=\"day.today ? 'date' : null\"\n [attr.aria-pressed]=\"day.state === chosenState ? true : null\"\n [attr.tabindex]=\"rovingKey() === null ? null : day.key === rovingKey() ? 0 : -1\"\n [disabled]=\"day.disabled\"\n (keydown)=\"onDayKey($event, day)\"\n (mouseenter)=\"onDayHover(day)\"\n (focus)=\"onDayHover(day)\"\n (click)=\"onDayClick(day)\">\n <span rtElem=\"day-num\" qa-dataid=\"calendar-day-num\">{{ day.dayOfMonth }}</span>\n @if (sublabelsLoading()) {\n <rt-skeleton\n rtElem=\"day-sublabel\"\n qa-dataid=\"calendar-day-price-skeleton\"\n width=\"80%\"\n radius=\"sm\"\n [height]=\"sublabelSkeletonHeight\" />\n } @else if (day.sublabel) {\n <span rtElem=\"day-sublabel\" qa-dataid=\"calendar-day-price\">{{ day.sublabel }}</span>\n }\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <ng-content />\n\n <ng-template #titleTpl let-month>\n @if (titleAction()) {\n <button rtElem=\"month-title\" qa-dataid=\"calendar-month-title\" type=\"button\" (click)=\"titleClick.emit(month)\">\n {{ month.label }}\n </button>\n } @else {\n <p rtElem=\"month-title\" qa-dataid=\"calendar-month-title\">{{ month.label }}</p>\n }\n </ng-template>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-calendar{--rt-calendar-day-radius: var(--rt-radius-md);--rt-calendar-day-size: auto;--rt-calendar-day-justify: flex-start;--rt-calendar-month-count: 2;--rt-calendar-column-gap: var(--rt-space-0-5);--rt-calendar-range-inner-radius: var(--rt-calendar-day-radius);--rt-calendar-today-ring: inset 0 0 0 var(--rt-border-width-thin) var(--rt-color-action-primary);display:block}.rt-calendar__header{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--rt-space-4);gap:var(--rt-space-4)}.rt-calendar__nav{flex:0 0 auto}.rt-calendar__header .rt-calendar__month-title{width:auto;padding:var(--rt-space-1) var(--rt-space-2);margin:0}.rt-calendar__months{display:grid;gap:var(--rt-space-6);grid-template-columns:repeat(var(--rt-calendar-month-count),1fr)}.rt-calendar__month-title{display:block;width:100%;padding:0;border:none;margin:0 0 var(--rt-space-2);background:none;color:var(--rt-color-text-primary);font:inherit;font-weight:var(--rt-font-weight-semibold);text-align:center}.rt-calendar__month-title:first-letter{text-transform:uppercase}.rt-calendar__month-title:is(button){border-radius:var(--rt-calendar-day-radius);cursor:pointer}.rt-calendar__month-title:is(button):hover{color:var(--rt-color-text-link)}.rt-calendar__month-title:is(button):focus-visible{outline:var(--rt-focus-ring-width) solid var(--rt-focus-ring-color);outline-offset:var(--rt-focus-ring-offset)}.rt-calendar__grid{display:grid;gap:var(--rt-space-0-5) var(--rt-calendar-column-gap);grid-template-columns:repeat(7,1fr)}.rt-calendar__weekday{padding:var(--rt-space-1) 0;color:var(--rt-color-text-muted);font-size:var(--rt-text-xs);text-align:center}.rt-calendar__day{display:flex;flex-direction:column;align-items:center;justify-content:var(--rt-calendar-day-justify);padding:var(--rt-space-2) var(--rt-space-0-5);border:none;border-radius:var(--rt-calendar-day-radius);background:none;color:var(--rt-color-text-primary);cursor:pointer;font:inherit;gap:var(--rt-space-0-5);min-block-size:var(--rt-calendar-day-size)}.rt-calendar__day:hover:not(:disabled,[data-state=start],[data-state=end],[data-state=in-range],[data-state=chosen]){background:var(--rt-color-bg-subtle)}.rt-calendar__day:disabled{color:var(--rt-color-text-muted);cursor:not-allowed;opacity:.45}.rt-calendar__day[data-state=past],.rt-calendar__day[data-state=blocked]{color:var(--rt-color-text-muted);opacity:.45}.rt-calendar__day[data-state=busy]{color:var(--rt-color-text-muted);opacity:.45;text-decoration:line-through}.rt-calendar__day[data-today]{box-shadow:var(--rt-calendar-today-ring)}.rt-calendar__day:focus-visible{outline:var(--rt-focus-ring-width) solid var(--rt-focus-ring-color);outline-offset:var(--rt-focus-ring-offset)}.rt-calendar__day[data-state=start],.rt-calendar__day[data-state=end],.rt-calendar__day[data-state=chosen]{background:var(--rt-color-action-primary);color:var(--rt-color-action-on-primary)}.rt-calendar__day[data-state=start]{border-end-end-radius:var(--rt-calendar-range-inner-radius);border-start-end-radius:var(--rt-calendar-range-inner-radius)}.rt-calendar__day[data-state=end]{border-end-start-radius:var(--rt-calendar-range-inner-radius);border-start-start-radius:var(--rt-calendar-range-inner-radius)}.rt-calendar__day[data-state=in-range]{border-radius:var(--rt-calendar-range-inner-radius);background:var(--rt-color-action-primary-soft);color:var(--rt-color-text-link);font-weight:var(--rt-font-weight-semibold)}.rt-calendar__day-num{font-size:var(--rt-text-sm);font-weight:var(--rt-font-weight-medium)}.rt-calendar__day-sublabel{font-size:var(--rt-text-2xs);opacity:.75}@media(width<=640px){.rt-calendar__months{grid-template-columns:1fr}.rt-calendar__month:last-child{display:none}}@media(width<=374px){.rt-calendar__day{padding-inline:0}.rt-calendar__day-sublabel{font-size:var(--rt-text-3xs)}}.rt-calendar[data-rt-radius=none]{--rt-calendar-day-radius: var(--rt-radius-none)}.rt-calendar[data-rt-radius=xs]{--rt-calendar-day-radius: var(--rt-radius-xs)}.rt-calendar[data-rt-radius=sm]{--rt-calendar-day-radius: var(--rt-radius-sm)}.rt-calendar[data-rt-radius=ms]{--rt-calendar-day-radius: var(--rt-radius-ms)}.rt-calendar[data-rt-radius=md]{--rt-calendar-day-radius: var(--rt-radius-md)}.rt-calendar[data-rt-radius=lg]{--rt-calendar-day-radius: var(--rt-radius-lg)}.rt-calendar[data-rt-radius=xl]{--rt-calendar-day-radius: var(--rt-radius-xl)}.rt-calendar[data-rt-radius=\"2xl\"]{--rt-calendar-day-radius: var(--rt-radius-2xl)}.rt-calendar[data-rt-radius=full]{--rt-calendar-day-radius: var(--rt-radius-full)}}\n"] }]
|
|
145
|
+
}], ctorParameters: () => [], propDecorators: { dayButtons: [{ type: i0.ViewChildren, args: ['dayButton', { isSignal: true }] }], months: [{ type: i0.Input, args: [{ isSignal: true, alias: "months", required: true }] }], weekdayLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "weekdayLabels", required: true }] }], canPrev: [{ type: i0.Input, args: [{ isSignal: true, alias: "canPrev", required: false }] }], canNext: [{ type: i0.Input, args: [{ isSignal: true, alias: "canNext", required: false }] }], prevAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "prevAriaLabel", required: false }] }], nextAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextAriaLabel", required: false }] }], sublabelsLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "sublabelsLoading", required: false }] }], grid: [{ type: i0.Input, args: [{ isSignal: true, alias: "grid", required: false }] }], activeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeKey", required: false }] }], titleAction: [{ type: i0.Input, args: [{ isSignal: true, alias: "titleAction", required: false }] }], headerTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerTitle", required: false }] }], prevMonth: [{ type: i0.Output, args: ["prevMonth"] }], nextMonth: [{ type: i0.Output, args: ["nextMonth"] }], dayClick: [{ type: i0.Output, args: ["dayClick"] }], gridKey: [{ type: i0.Output, args: ["gridKey"] }], titleClick: [{ type: i0.Output, args: ["titleClick"] }], dayHover: [{ type: i0.Output, args: ["dayHover"] }] } });
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Generated bundle index. Do not edit.
|
|
149
|
+
*/
|
|
150
|
+
|
|
151
|
+
export { ERtCalendarDayState, RtCalendarComponent };
|
|
152
|
+
//# sourceMappingURL=rt-tools-ui-kit-v2-calendar.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-calendar.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/calendar/rt-calendar.model.ts","../../../projects/ui-kit-v2/src/lib/components/calendar/rt-calendar.component.ts","../../../projects/ui-kit-v2/src/lib/components/calendar/rt-calendar.component.html","../../../projects/ui-kit-v2/src/lib/components/calendar/rt-tools-ui-kit-v2-calendar.ts"],"sourcesContent":["/**\n * Контракты `rt-calendar` — презентационный месячный грид с range-выбором.\n *\n * Компонент домен-агностичен: состояния/цены/доступность дней вычисляет\n * consumer и передаёт готовые view-модели месяцев. Клики по дням и навигация\n * по месяцам эмитятся наружу; никакой доменной логики внутри нет.\n */\n\n/** Состояние ячейки дня — модификатор `data-state` на кнопке дня. */\nexport enum ERtCalendarDayState {\n Free = 'free',\n Busy = 'busy',\n Past = 'past',\n Blocked = 'blocked',\n Start = 'start',\n End = 'end',\n InRange = 'in-range',\n /** Выбранный день одиночного выбора — залит. */\n Chosen = 'chosen',\n}\n\nexport namespace IRtCalendar {\n /** View-модель дня. `key` — стабильный ключ (ISO-дата). */\n export interface Day {\n key: string;\n dayOfMonth: number;\n /** Подпись под числом (цена за ночь и т.п.); пустая строка не рендерится. */\n sublabel: string;\n state: ERtCalendarDayState;\n disabled: boolean;\n /** Сегодняшний день — обведён рамкой поверх любого состояния. */\n today?: boolean;\n }\n\n /** Клавиша сетки, нажатая на дне. */\n export interface GridKey {\n key: string;\n day: Day;\n }\n\n /** View-модель месяца: подпись, пустые ячейки до первого дня, дни. */\n export interface Month {\n key: string;\n label: string;\n leadingBlanks: readonly number[];\n days: readonly Day[];\n }\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n afterRenderEffect,\n booleanAttribute,\n computed,\n signal,\n viewChildren,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n input,\n InputSignal,\n InputSignalWithTransform,\n output,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\n\n// rt-tools\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { RtSkeletonComponent } from '@rt-tools/ui-kit-v2/skeleton';\nimport { ERtCalendarDayState, IRtCalendar } from './rt-calendar.model';\n\nconst BEM_BLOCK: string = 'rt-calendar';\n\n/** Клавиши, что календарь в режиме сетки отдаёт наружу вместо прокрутки страницы. */\nconst GRID_KEYS: ReadonlySet<string> = new Set(['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'PageUp', 'PageDown', 'Home', 'End']);\n\n@Component({\n selector: 'rt-calendar',\n templateUrl: './rt-calendar.component.html',\n styleUrl: './rt-calendar.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // angular\n NgTemplateOutlet,\n\n // rt-tools\n BlockDirective,\n ElemDirective,\n\n // components\n RtIconButtonComponent,\n RtSkeletonComponent,\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtCalendarComponent {\n /** Фокус двигала клавиша: только тогда календарь переводит фокус на `activeKey`. */\n readonly #keyed: WritableSignal<boolean> = signal(false);\n\n protected readonly sublabelSkeletonHeight: string = '12px';\n protected readonly chosenState: ERtCalendarDayState = ERtCalendarDayState.Chosen;\n\n protected readonly dayButtons: Signal<readonly ElementRef<HTMLButtonElement>[]> =\n viewChildren<ElementRef<HTMLButtonElement>>('dayButton');\n\n /**\n * День, что стоит в порядке обхода Tab в режиме сетки: `activeKey`, иначе выбранный, иначе\n * сегодняшний, иначе первый доступный. Вне режима сетки — `null`, и каждый день обходится Tab.\n */\n protected readonly rovingKey: Signal<string | null> = computed((): string | null => {\n if (!this.grid()) {\n return null;\n }\n const days: IRtCalendar.Day[] = this.months().flatMap((month: IRtCalendar.Month): IRtCalendar.Day[] => [...month.days]);\n const active: string | null = this.activeKey();\n const pick: IRtCalendar.Day | undefined =\n days.find((day: IRtCalendar.Day): boolean => day.key === active) ??\n days.find((day: IRtCalendar.Day): boolean => day.state === ERtCalendarDayState.Chosen) ??\n days.find((day: IRtCalendar.Day): boolean => day.today === true) ??\n days.find((day: IRtCalendar.Day): boolean => !day.disabled);\n return pick?.key ?? null;\n });\n\n public readonly months: InputSignal<readonly IRtCalendar.Month[]> = input.required<readonly IRtCalendar.Month[]>();\n public readonly weekdayLabels: InputSignal<readonly string[]> = input.required<readonly string[]>();\n public readonly canPrev: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n public readonly canNext: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n /** Локализованные aria-подписи кнопок навигации — задаёт consumer. */\n public readonly prevAriaLabel: InputSignal<string> = input<string>('');\n public readonly nextAriaLabel: InputSignal<string> = input<string>('');\n public readonly sublabelsLoading: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /**\n * Режим сетки: один день в обходе Tab, клавиши стрелок, PageUp/PageDown, Home и End уходят\n * наружу событием `gridKey`, а фокус встаёт на `activeKey`. Выключен — поведение прежнее.\n */\n public readonly grid: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n /** День с фокусом в режиме сетки, ключ `YYYY-MM-DD`; его ставит consumer по `gridKey`. */\n public readonly activeKey: InputSignal<string | null> = input<string | null>(null);\n /** Заголовок месяца — кнопка, что шлёт `titleClick`: так consumer открывает выбор месяца. */\n public readonly titleAction: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n /** Заголовок первого месяца стоит в шапке между стрелками, а не над сеткой. */\n public readonly headerTitle: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly prevMonth: OutputEmitterRef<void> = output<void>();\n public readonly nextMonth: OutputEmitterRef<void> = output<void>();\n public readonly dayClick: OutputEmitterRef<IRtCalendar.Day> = output<IRtCalendar.Day>();\n /** Клавиша сетки на дне: куда перевести фокус, решает consumer. */\n public readonly gridKey: OutputEmitterRef<IRtCalendar.GridKey> = output<IRtCalendar.GridKey>();\n public readonly titleClick: OutputEmitterRef<IRtCalendar.Month> = output<IRtCalendar.Month>();\n /** День под указателем или с фокусом; `null` — указатель ушёл с месяцев. По нему рисуется будущий диапазон. */\n public readonly dayHover: OutputEmitterRef<IRtCalendar.Day | null> = output<IRtCalendar.Day | null>();\n\n constructor() {\n afterRenderEffect((): void => {\n const key: string | null = this.rovingKey();\n if (!this.#keyed() || key === null) {\n return;\n }\n this.dayButtons()\n .find((button: ElementRef<HTMLButtonElement>): boolean => button.nativeElement.dataset['iso'] === key)\n ?.nativeElement.focus();\n });\n }\n\n protected onDayKey(event: KeyboardEvent, day: IRtCalendar.Day): void {\n if (!this.grid() || !GRID_KEYS.has(event.key)) {\n return;\n }\n event.preventDefault();\n this.#keyed.set(true);\n this.gridKey.emit({ key: event.key, day });\n }\n\n protected onDayHover(day: IRtCalendar.Day): void {\n if (!day.disabled) {\n this.dayHover.emit(day);\n }\n }\n\n protected onDayClick(day: IRtCalendar.Day): void {\n if (!day.disabled) {\n this.dayClick.emit(day);\n }\n }\n}\n","<ng-container rtBlock=\"rt-calendar\">\n <div rtElem=\"header\">\n <rt-icon-button\n rtElem=\"nav\"\n qa-dataid=\"calendar-prev-month\"\n icon=\"chevron-left\"\n variant=\"secondary\"\n radius=\"full\"\n [ariaLabel]=\"prevAriaLabel()\"\n [disabled]=\"!canPrev()\"\n (clicked)=\"prevMonth.emit()\" />\n @if (headerTitle() && months()[0]; as first) {\n <ng-container *ngTemplateOutlet=\"titleTpl; context: { $implicit: first }\" />\n }\n <ng-content select=\"[calendarHint]\" />\n <rt-icon-button\n rtElem=\"nav\"\n qa-dataid=\"calendar-next-month\"\n icon=\"chevron-right\"\n variant=\"secondary\"\n radius=\"full\"\n [ariaLabel]=\"nextAriaLabel()\"\n [disabled]=\"!canNext()\"\n (clicked)=\"nextMonth.emit()\" />\n </div>\n\n <div rtElem=\"months\" qa-dataid=\"calendar-months\" (mouseleave)=\"dayHover.emit(null)\">\n @for (month of months(); track month.key) {\n <div rtElem=\"month\" qa-dataid=\"calendar-month\">\n @if (!headerTitle()) {\n <ng-container *ngTemplateOutlet=\"titleTpl; context: { $implicit: month }\" />\n }\n <div rtElem=\"grid\" qa-dataid=\"calendar-grid\">\n @for (weekday of weekdayLabels(); track $index) {\n <span rtElem=\"weekday\" qa-dataid=\"calendar-weekday\">{{ weekday }}</span>\n }\n @for (blank of month.leadingBlanks; track blank) {\n <!-- Пустая ячейка сетки до первого дня месяца: занимает место и ничего не красит. -->\n <span qa-dataid=\"calendar-blank\" aria-hidden=\"true\"></span>\n }\n @for (day of month.days; track day.key) {\n <button\n #dayButton\n rtElem=\"day\"\n qa-dataid=\"calendar-day\"\n type=\"button\"\n [attr.data-iso]=\"day.key\"\n [attr.data-state]=\"day.state\"\n [attr.data-today]=\"day.today ? '' : null\"\n [attr.aria-current]=\"day.today ? 'date' : null\"\n [attr.aria-pressed]=\"day.state === chosenState ? true : null\"\n [attr.tabindex]=\"rovingKey() === null ? null : day.key === rovingKey() ? 0 : -1\"\n [disabled]=\"day.disabled\"\n (keydown)=\"onDayKey($event, day)\"\n (mouseenter)=\"onDayHover(day)\"\n (focus)=\"onDayHover(day)\"\n (click)=\"onDayClick(day)\">\n <span rtElem=\"day-num\" qa-dataid=\"calendar-day-num\">{{ day.dayOfMonth }}</span>\n @if (sublabelsLoading()) {\n <rt-skeleton\n rtElem=\"day-sublabel\"\n qa-dataid=\"calendar-day-price-skeleton\"\n width=\"80%\"\n radius=\"sm\"\n [height]=\"sublabelSkeletonHeight\" />\n } @else if (day.sublabel) {\n <span rtElem=\"day-sublabel\" qa-dataid=\"calendar-day-price\">{{ day.sublabel }}</span>\n }\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <ng-content />\n\n <ng-template #titleTpl let-month>\n @if (titleAction()) {\n <button rtElem=\"month-title\" qa-dataid=\"calendar-month-title\" type=\"button\" (click)=\"titleClick.emit(month)\">\n {{ month.label }}\n </button>\n } @else {\n <p rtElem=\"month-title\" qa-dataid=\"calendar-month-title\">{{ month.label }}</p>\n }\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,72 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, booleanAttribute, output, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';
|
|
4
|
+
import * as i1 from '@rt-tools/ui-kit-v2/radius';
|
|
5
|
+
import { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';
|
|
6
|
+
|
|
7
|
+
const BEM_BLOCK = 'rt-card';
|
|
8
|
+
/**
|
|
9
|
+
* Контейнер-карточка с опциональным header (текст ИЛИ projected slot) и footer
|
|
10
|
+
* (projected slot). Default content проецируется в основную область. Поддерживает
|
|
11
|
+
* clickable mode для card-as-button сценариев: при `clickable=true` корневой
|
|
12
|
+
* `<article>` получает `role="button"`, `tabindex="0"` и эмиттит `cardClick`
|
|
13
|
+
* MouseEvent на клик и Enter/Space с клавиатуры.
|
|
14
|
+
*
|
|
15
|
+
* Две стратегии header:
|
|
16
|
+
* 1. Текстом через `header="..."` input — рендерит `<h3 class="rt-card__title">`.
|
|
17
|
+
* 2. Произвольный контент через attribute-selector slot `[rtCardHeader]`.
|
|
18
|
+
*
|
|
19
|
+
* Footer — только через slot `[rtCardFooter]`. Пустые header/footer слоты
|
|
20
|
+
* визуально скрываются через `:empty` CSS-селектор.
|
|
21
|
+
*
|
|
22
|
+
* Все цвета и размеры — через семантические `--rt-*` токены; BEM-разметка через
|
|
23
|
+
* директивы `rtBlock` / `rtElem` / `rtMod` из `@rt-tools/core`.
|
|
24
|
+
*/
|
|
25
|
+
class RtCardComponent {
|
|
26
|
+
constructor() {
|
|
27
|
+
/** Заголовок-текст; если задан — рендерится `<h3 class="rt-card__title">`. */
|
|
28
|
+
this.header = input(null, /* @ts-ignore */
|
|
29
|
+
...(ngDevMode ? [{ debugName: "header" }] : /* istanbul ignore next */ []));
|
|
30
|
+
/** ARIA-label на корневом `<article>`. */
|
|
31
|
+
this.ariaLabel = input(null, /* @ts-ignore */
|
|
32
|
+
...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
33
|
+
/** Делает карточку интерактивной: `role="button"`, `tabindex="0"`, клавиатура. */
|
|
34
|
+
this.clickable = input(false, { ...(ngDevMode ? { debugName: "clickable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
35
|
+
/** Эмиттит MouseEvent при клике (или Enter/Space) — только если `clickable=true`. */
|
|
36
|
+
this.cardClick = output();
|
|
37
|
+
}
|
|
38
|
+
onClick(event) {
|
|
39
|
+
if (this.clickable()) {
|
|
40
|
+
this.cardClick.emit(event);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
onKeyActivate(event) {
|
|
44
|
+
if (!this.clickable()) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
this.cardClick.emit(event);
|
|
49
|
+
}
|
|
50
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
51
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtCardComponent, isStandalone: true, selector: "rt-card", inputs: { header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, clickable: { classPropertyName: "clickable", publicName: "clickable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cardClick: "cardClick" }, host: { classAttribute: "rt-card" }, hostDirectives: [{ directive: i1.RtRadiusDirective, inputs: ["radius", "radius"] }], ngImport: i0, template: "<article\n rtBlock=\"rt-card\"\n qa-dataid=\"card\"\n [rtMod]=\"{ clickable: clickable() }\"\n [attr.role]=\"clickable() ? 'button' : null\"\n [attr.tabindex]=\"clickable() ? 0 : null\"\n [attr.aria-label]=\"ariaLabel()\"\n (click)=\"onClick($event)\"\n (keydown.enter)=\"onKeyActivate($event)\"\n (keydown.space)=\"onKeyActivate($event)\">\n <header rtElem=\"header\">\n @if (header(); as h) {\n <h3 rtElem=\"title\" qa-dataid=\"card-title\">{{ h }}</h3>\n }\n <ng-content select=\"[rtCardHeader]\" />\n </header>\n <div rtElem=\"content\">\n <ng-content />\n </div>\n <footer rtElem=\"footer\">\n <ng-content select=\"[rtCardFooter]\" />\n </footer>\n</article>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{rt-card{display:block}rt-card .rt-card{--rt-card-radius: var(--rt-radius-xl);--rt-card-shadow: var(--rt-shadow-card);--rt-card-shadow-hover: var(--rt-shadow-lg);--rt-card-focus-shadow: var(--rt-shadow-focus-ring);--rt-card-transition-duration: var(--rt-duration-fast);display:block;padding:var(--rt-space-lg);border-radius:var(--rt-card-radius);background:var(--rt-color-bg-surface);box-shadow:var(--rt-card-shadow);color:var(--rt-color-text-primary)}rt-card .rt-card--clickable{cursor:pointer;transition:box-shadow var(--rt-card-transition-duration) ease,transform var(--rt-card-transition-duration) ease}rt-card .rt-card--clickable:hover{box-shadow:var(--rt-card-shadow-hover)}rt-card .rt-card--clickable:focus-visible{box-shadow:var(--rt-card-focus-shadow);outline:2px solid transparent;outline-offset:2px}rt-card .rt-card__header{margin-block-end:var(--rt-space-md)}rt-card .rt-card__header:empty{display:none}rt-card .rt-card__title{margin:0;font-size:var(--rt-text-lg);line-height:var(--rt-leading-snug)}rt-card .rt-card__content{display:block}rt-card .rt-card__footer{margin-block-start:var(--rt-space-md)}rt-card .rt-card__footer:empty{display:none}rt-card[data-rt-radius=none]>.rt-card{--rt-card-radius: var(--rt-radius-none)}rt-card[data-rt-radius=xs]>.rt-card{--rt-card-radius: var(--rt-radius-xs)}rt-card[data-rt-radius=sm]>.rt-card{--rt-card-radius: var(--rt-radius-sm)}rt-card[data-rt-radius=ms]>.rt-card{--rt-card-radius: var(--rt-radius-ms)}rt-card[data-rt-radius=md]>.rt-card{--rt-card-radius: var(--rt-radius-md)}rt-card[data-rt-radius=lg]>.rt-card{--rt-card-radius: var(--rt-radius-lg)}rt-card[data-rt-radius=xl]>.rt-card{--rt-card-radius: var(--rt-radius-xl)}rt-card[data-rt-radius=\"2xl\"]>.rt-card{--rt-card-radius: var(--rt-radius-2xl)}rt-card[data-rt-radius=full]>.rt-card{--rt-card-radius: var(--rt-radius-full)}}\n"], dependencies: [{ kind: "directive", type:
|
|
52
|
+
// standalone components / directives
|
|
53
|
+
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 }); }
|
|
54
|
+
}
|
|
55
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtCardComponent, decorators: [{
|
|
56
|
+
type: Component,
|
|
57
|
+
args: [{ selector: 'rt-card', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
58
|
+
// standalone components / directives
|
|
59
|
+
BlockDirective,
|
|
60
|
+
ElemDirective,
|
|
61
|
+
ModDirective,
|
|
62
|
+
], hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }], host: {
|
|
63
|
+
class: BEM_BLOCK,
|
|
64
|
+
}, template: "<article\n rtBlock=\"rt-card\"\n qa-dataid=\"card\"\n [rtMod]=\"{ clickable: clickable() }\"\n [attr.role]=\"clickable() ? 'button' : null\"\n [attr.tabindex]=\"clickable() ? 0 : null\"\n [attr.aria-label]=\"ariaLabel()\"\n (click)=\"onClick($event)\"\n (keydown.enter)=\"onKeyActivate($event)\"\n (keydown.space)=\"onKeyActivate($event)\">\n <header rtElem=\"header\">\n @if (header(); as h) {\n <h3 rtElem=\"title\" qa-dataid=\"card-title\">{{ h }}</h3>\n }\n <ng-content select=\"[rtCardHeader]\" />\n </header>\n <div rtElem=\"content\">\n <ng-content />\n </div>\n <footer rtElem=\"footer\">\n <ng-content select=\"[rtCardFooter]\" />\n </footer>\n</article>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{rt-card{display:block}rt-card .rt-card{--rt-card-radius: var(--rt-radius-xl);--rt-card-shadow: var(--rt-shadow-card);--rt-card-shadow-hover: var(--rt-shadow-lg);--rt-card-focus-shadow: var(--rt-shadow-focus-ring);--rt-card-transition-duration: var(--rt-duration-fast);display:block;padding:var(--rt-space-lg);border-radius:var(--rt-card-radius);background:var(--rt-color-bg-surface);box-shadow:var(--rt-card-shadow);color:var(--rt-color-text-primary)}rt-card .rt-card--clickable{cursor:pointer;transition:box-shadow var(--rt-card-transition-duration) ease,transform var(--rt-card-transition-duration) ease}rt-card .rt-card--clickable:hover{box-shadow:var(--rt-card-shadow-hover)}rt-card .rt-card--clickable:focus-visible{box-shadow:var(--rt-card-focus-shadow);outline:2px solid transparent;outline-offset:2px}rt-card .rt-card__header{margin-block-end:var(--rt-space-md)}rt-card .rt-card__header:empty{display:none}rt-card .rt-card__title{margin:0;font-size:var(--rt-text-lg);line-height:var(--rt-leading-snug)}rt-card .rt-card__content{display:block}rt-card .rt-card__footer{margin-block-start:var(--rt-space-md)}rt-card .rt-card__footer:empty{display:none}rt-card[data-rt-radius=none]>.rt-card{--rt-card-radius: var(--rt-radius-none)}rt-card[data-rt-radius=xs]>.rt-card{--rt-card-radius: var(--rt-radius-xs)}rt-card[data-rt-radius=sm]>.rt-card{--rt-card-radius: var(--rt-radius-sm)}rt-card[data-rt-radius=ms]>.rt-card{--rt-card-radius: var(--rt-radius-ms)}rt-card[data-rt-radius=md]>.rt-card{--rt-card-radius: var(--rt-radius-md)}rt-card[data-rt-radius=lg]>.rt-card{--rt-card-radius: var(--rt-radius-lg)}rt-card[data-rt-radius=xl]>.rt-card{--rt-card-radius: var(--rt-radius-xl)}rt-card[data-rt-radius=\"2xl\"]>.rt-card{--rt-card-radius: var(--rt-radius-2xl)}rt-card[data-rt-radius=full]>.rt-card{--rt-card-radius: var(--rt-radius-full)}}\n"] }]
|
|
65
|
+
}], propDecorators: { header: [{ type: i0.Input, args: [{ isSignal: true, alias: "header", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], clickable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clickable", required: false }] }], cardClick: [{ type: i0.Output, args: ["cardClick"] }] } });
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Generated bundle index. Do not edit.
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
export { RtCardComponent };
|
|
72
|
+
//# sourceMappingURL=rt-tools-ui-kit-v2-card.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-card.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/card/rt-card.component.ts","../../../projects/ui-kit-v2/src/lib/components/card/rt-card.component.html","../../../projects/ui-kit-v2/src/lib/components/card/rt-tools-ui-kit-v2-card.ts"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n input,\n InputSignal,\n InputSignalWithTransform,\n output,\n OutputEmitterRef,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\n\nconst BEM_BLOCK: string = 'rt-card';\n\n/**\n * Контейнер-карточка с опциональным header (текст ИЛИ projected slot) и footer\n * (projected slot). Default content проецируется в основную область. Поддерживает\n * clickable mode для card-as-button сценариев: при `clickable=true` корневой\n * `<article>` получает `role=\"button\"`, `tabindex=\"0\"` и эмиттит `cardClick`\n * MouseEvent на клик и Enter/Space с клавиатуры.\n *\n * Две стратегии header:\n * 1. Текстом через `header=\"...\"` input — рендерит `<h3 class=\"rt-card__title\">`.\n * 2. Произвольный контент через attribute-selector slot `[rtCardHeader]`.\n *\n * Footer — только через slot `[rtCardFooter]`. Пустые header/footer слоты\n * визуально скрываются через `:empty` CSS-селектор.\n *\n * Все цвета и размеры — через семантические `--rt-*` токены; BEM-разметка через\n * директивы `rtBlock` / `rtElem` / `rtMod` из `@rt-tools/core`.\n */\n@Component({\n selector: 'rt-card',\n templateUrl: './rt-card.component.html',\n styleUrl: './rt-card.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtCardComponent {\n /** Заголовок-текст; если задан — рендерится `<h3 class=\"rt-card__title\">`. */\n public readonly header: InputSignal<string | null> = input<string | null>(null);\n\n /** ARIA-label на корневом `<article>`. */\n public readonly ariaLabel: InputSignal<string | null> = input<string | null>(null);\n\n /** Делает карточку интерактивной: `role=\"button\"`, `tabindex=\"0\"`, клавиатура. */\n public readonly clickable: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Эмиттит MouseEvent при клике (или Enter/Space) — только если `clickable=true`. */\n public readonly cardClick: OutputEmitterRef<MouseEvent> = output<MouseEvent>();\n\n protected onClick(event: MouseEvent): void {\n if (this.clickable()) {\n this.cardClick.emit(event);\n }\n }\n\n protected onKeyActivate(event: Event): void {\n if (!this.clickable()) {\n return;\n }\n event.preventDefault();\n this.cardClick.emit(event as unknown as MouseEvent);\n }\n}\n","<article\n rtBlock=\"rt-card\"\n qa-dataid=\"card\"\n [rtMod]=\"{ clickable: clickable() }\"\n [attr.role]=\"clickable() ? 'button' : null\"\n [attr.tabindex]=\"clickable() ? 0 : null\"\n [attr.aria-label]=\"ariaLabel()\"\n (click)=\"onClick($event)\"\n (keydown.enter)=\"onKeyActivate($event)\"\n (keydown.space)=\"onKeyActivate($event)\">\n <header rtElem=\"header\">\n @if (header(); as h) {\n <h3 rtElem=\"title\" qa-dataid=\"card-title\">{{ h }}</h3>\n }\n <ng-content select=\"[rtCardHeader]\" />\n </header>\n <div rtElem=\"content\">\n <ng-content />\n </div>\n <footer rtElem=\"footer\">\n <ng-content select=\"[rtCardFooter]\" />\n </footer>\n</article>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;AAiBA,MAAM,SAAS,GAAW,SAAS;AAEnC;;;;;;;;;;;;;;;;AAgBG;MAkBU,eAAe,CAAA;AAjB5B,IAAA,WAAA,GAAA;;QAmBoB,IAAA,CAAA,MAAM,GAA+B,KAAK,CAAgB,IAAI;mFAAC;;QAG/D,IAAA,CAAA,SAAS,GAA+B,KAAK,CAAgB,IAAI;sFAAC;;QAGlE,IAAA,CAAA,SAAS,GAAoD,KAAK,CAAwB,KAAK,iFAC3G,SAAS,EAAE,gBAAgB,EAAA,CAC7B;;QAGc,IAAA,CAAA,SAAS,GAAiC,MAAM,EAAc;AAejF,IAAA;AAba,IAAA,OAAO,CAAC,KAAiB,EAAA;AAC/B,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE;AAClB,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;QAC9B;IACJ;AAEU,IAAA,aAAa,CAAC,KAAY,EAAA;AAChC,QAAA,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE;YACnB;QACJ;QACA,KAAK,CAAC,cAAc,EAAE;AACtB,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAA8B,CAAC;IACvD;8GA3BS,eAAe,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAf,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,eAAe,inBCrD5B,svBAuBA,EAAA,MAAA,EAAA,CAAA,81DAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA;;gBDqBQ,cAAc,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACd,aAAa,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACb,YAAY,EAAA,QAAA,EAAA,SAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA,CAAA;;2FAOP,eAAe,EAAA,UAAA,EAAA,CAAA;kBAjB3B,SAAS;+BACI,SAAS,EAAA,eAAA,EAGF,uBAAuB,CAAC,MAAM,iBAChC,iBAAiB,CAAC,IAAI,EAAA,OAAA,EAC5B;;wBAEL,cAAc;wBACd,aAAa;wBACb,YAAY;AACf,qBAAA,EAAA,cAAA,EACe,CAAC,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAA,IAAA,EAChE;AACF,wBAAA,KAAK,EAAE,SAAS;AACnB,qBAAA,EAAA,QAAA,EAAA,svBAAA,EAAA,MAAA,EAAA,CAAA,81DAAA,CAAA,EAAA;;;AEnDL;;AAEG;;;;"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { signal, computed, input, booleanAttribute, forwardRef, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
4
|
+
import { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';
|
|
5
|
+
import { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';
|
|
6
|
+
import * as i1 from '@rt-tools/ui-kit-v2/radius';
|
|
7
|
+
import { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';
|
|
8
|
+
|
|
9
|
+
const BEM_BLOCK = 'rt-checkbox';
|
|
10
|
+
/**
|
|
11
|
+
* Чекбокс с `role="checkbox"` + `aria-checked` (`true`/`false`/`mixed`) поверх
|
|
12
|
+
* нативного `<button>` — клавиатурный toggle (Enter/Space) работает «из коробки»
|
|
13
|
+
* без отдельных keydown-хендлеров. Галочка/прочерк рисуются через `rt-icon`
|
|
14
|
+
* (`check`/`minus`), бокс и цвета — на токенах `--rt-*`.
|
|
15
|
+
*
|
|
16
|
+
* Реализует `ControlValueAccessor` для `boolean` value через
|
|
17
|
+
* `useExisting: forwardRef(...)` — `useClass` на self-reference вызывает
|
|
18
|
+
* NG0200 cycle при boot'е.
|
|
19
|
+
*
|
|
20
|
+
* Отключение складывается из двух независимых источников: входа `disabled` и
|
|
21
|
+
* слова формы (CVA `setDisabledState`). Отключено, если так сказал любой из
|
|
22
|
+
* них. Сводить их в один signal нельзя: форма зовёт `setDisabledState` при
|
|
23
|
+
* связывании контрола, то есть раньше, чем чекбокс впервые обновит своё вью,
|
|
24
|
+
* и мирроринг входа затирал бы её слово — контрол, созданный отключённым,
|
|
25
|
+
* оказывался бы кликабельным.
|
|
26
|
+
*
|
|
27
|
+
* `indeterminate` — чисто визуальное mixed-состояние; клик по нему разрешается
|
|
28
|
+
* в `true` (стандартное поведение tri-state чекбокса).
|
|
29
|
+
*
|
|
30
|
+
* Текстовая подпись проецируется через `<ng-content>`.
|
|
31
|
+
*/
|
|
32
|
+
class RtCheckboxComponent {
|
|
33
|
+
constructor() {
|
|
34
|
+
this.#onChange = () => undefined;
|
|
35
|
+
this.#onTouched = () => undefined;
|
|
36
|
+
/** Отключение, назначенное формой через CVA (`setDisabledState`). */
|
|
37
|
+
this.#disabledByForm = signal(false, /* @ts-ignore */
|
|
38
|
+
...(ngDevMode ? [{ debugName: "#disabledByForm" }] : /* istanbul ignore next */ []));
|
|
39
|
+
this.isChecked = signal(false, /* @ts-ignore */
|
|
40
|
+
...(ngDevMode ? [{ debugName: "isChecked" }] : /* istanbul ignore next */ []));
|
|
41
|
+
this.isDisabled = computed(() => this.disabled() || this.#disabledByForm(), /* @ts-ignore */
|
|
42
|
+
...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
43
|
+
this.inputId = input(null, /* @ts-ignore */
|
|
44
|
+
...(ngDevMode ? [{ debugName: "inputId" }] : /* istanbul ignore next */ []));
|
|
45
|
+
this.ariaLabel = input(null, /* @ts-ignore */
|
|
46
|
+
...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
47
|
+
this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
48
|
+
this.indeterminate = input(false, { ...(ngDevMode ? { debugName: "indeterminate" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
49
|
+
}
|
|
50
|
+
#onChange;
|
|
51
|
+
#onTouched;
|
|
52
|
+
/** Отключение, назначенное формой через CVA (`setDisabledState`). */
|
|
53
|
+
#disabledByForm;
|
|
54
|
+
writeValue(value) {
|
|
55
|
+
this.isChecked.set(value === true);
|
|
56
|
+
}
|
|
57
|
+
registerOnChange(fn) {
|
|
58
|
+
this.#onChange = fn;
|
|
59
|
+
}
|
|
60
|
+
registerOnTouched(fn) {
|
|
61
|
+
this.#onTouched = fn;
|
|
62
|
+
}
|
|
63
|
+
setDisabledState(disabled) {
|
|
64
|
+
this.#disabledByForm.set(disabled);
|
|
65
|
+
}
|
|
66
|
+
toggle() {
|
|
67
|
+
if (this.isDisabled()) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// mixed-состояние при клике разрешается в checked (tri-state контракт).
|
|
71
|
+
const next = this.indeterminate() ? true : !this.isChecked();
|
|
72
|
+
this.isChecked.set(next);
|
|
73
|
+
this.#onChange(next);
|
|
74
|
+
this.#onTouched();
|
|
75
|
+
}
|
|
76
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtCheckboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
77
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtCheckboxComponent, isStandalone: true, selector: "rt-checkbox", inputs: { inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "rt-checkbox" }, providers: [
|
|
78
|
+
{
|
|
79
|
+
provide: NG_VALUE_ACCESSOR,
|
|
80
|
+
useExisting: forwardRef(() => RtCheckboxComponent),
|
|
81
|
+
multi: true,
|
|
82
|
+
},
|
|
83
|
+
], hostDirectives: [{ directive: i1.RtRadiusDirective, inputs: ["radius", "radius"] }], ngImport: i0, template: "<button\n rtBlock=\"rt-checkbox\"\n qa-dataid=\"checkbox-control\"\n type=\"button\"\n role=\"checkbox\"\n [rtMod]=\"{\n checked: isChecked() && !indeterminate(),\n indeterminate: indeterminate(),\n disabled: isDisabled(),\n }\"\n [attr.id]=\"inputId()\"\n [attr.aria-checked]=\"indeterminate() ? 'mixed' : isChecked()\"\n [attr.aria-label]=\"ariaLabel()\"\n [disabled]=\"isDisabled()\"\n (click)=\"toggle()\">\n <span rtElem=\"box\">\n @if (indeterminate()) {\n <rt-icon rtElem=\"icon\" name=\"minus\" size=\"xs\" color=\"inverse\" />\n } @else if (isChecked()) {\n <rt-icon rtElem=\"icon\" name=\"check\" size=\"xs\" color=\"inverse\" />\n }\n </span>\n\n <span rtElem=\"label\" qa-dataid=\"checkbox-label\">\n <ng-content />\n </span>\n</button>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{rt-checkbox{display:inline-block}rt-checkbox[data-rt-radius=none]>.rt-checkbox{--rt-checkbox-box-radius: var(--rt-radius-none)}rt-checkbox[data-rt-radius=xs]>.rt-checkbox{--rt-checkbox-box-radius: var(--rt-radius-xs)}rt-checkbox[data-rt-radius=sm]>.rt-checkbox{--rt-checkbox-box-radius: var(--rt-radius-sm)}rt-checkbox[data-rt-radius=ms]>.rt-checkbox{--rt-checkbox-box-radius: var(--rt-radius-ms)}rt-checkbox[data-rt-radius=md]>.rt-checkbox{--rt-checkbox-box-radius: var(--rt-radius-md)}rt-checkbox[data-rt-radius=lg]>.rt-checkbox{--rt-checkbox-box-radius: var(--rt-radius-lg)}rt-checkbox[data-rt-radius=xl]>.rt-checkbox{--rt-checkbox-box-radius: var(--rt-radius-xl)}rt-checkbox[data-rt-radius=\"2xl\"]>.rt-checkbox{--rt-checkbox-box-radius: var(--rt-radius-2xl)}rt-checkbox[data-rt-radius=full]>.rt-checkbox{--rt-checkbox-box-radius: var(--rt-radius-full)}rt-checkbox .rt-checkbox{--rt-checkbox-focus-radius: var(--rt-radius-sm);--rt-checkbox-focus-shadow: var(--rt-shadow-focus-ring);--rt-checkbox-box-radius: var(--rt-radius-sm);--rt-checkbox-transition-duration: var(--rt-duration-fast);--rt-checkbox-color-label: var(--rt-color-text-primary);display:inline-flex;align-items:center;padding:0;border:none;background:none;cursor:pointer;font:inherit;gap:var(--rt-space-sm);text-align:start;vertical-align:top}rt-checkbox .rt-checkbox:focus-visible{border-radius:var(--rt-checkbox-focus-radius);box-shadow:var(--rt-checkbox-focus-shadow);outline:2px solid transparent;outline-offset:2px}rt-checkbox .rt-checkbox--disabled{cursor:not-allowed;opacity:.5}rt-checkbox .rt-checkbox__box{display:inline-flex;width:18px;height:18px;flex-shrink:0;align-items:center;justify-content:center;border:var(--rt-input-border-width) solid var(--rt-color-border-strong);border-radius:var(--rt-checkbox-box-radius);background:var(--rt-color-bg-surface);transition:background var(--rt-checkbox-transition-duration) ease,border-color var(--rt-checkbox-transition-duration) ease}rt-checkbox .rt-checkbox--checked .rt-checkbox__box,rt-checkbox .rt-checkbox--indeterminate .rt-checkbox__box{border-color:var(--rt-color-action-primary);background:var(--rt-color-action-primary)}rt-checkbox .rt-checkbox__label{color:var(--rt-checkbox-color-label);font-size:var(--rt-text-sm);-webkit-user-select:none;user-select:none}rt-checkbox .rt-checkbox__label:empty{display:none}}\n"], dependencies: [{ kind: "component", type:
|
|
84
|
+
// standalone components / directives
|
|
85
|
+
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 }); }
|
|
86
|
+
}
|
|
87
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtCheckboxComponent, decorators: [{
|
|
88
|
+
type: Component,
|
|
89
|
+
args: [{ selector: 'rt-checkbox', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
90
|
+
// standalone components / directives
|
|
91
|
+
RtIconComponent,
|
|
92
|
+
BlockDirective,
|
|
93
|
+
ElemDirective,
|
|
94
|
+
ModDirective,
|
|
95
|
+
], providers: [
|
|
96
|
+
{
|
|
97
|
+
provide: NG_VALUE_ACCESSOR,
|
|
98
|
+
useExisting: forwardRef(() => RtCheckboxComponent),
|
|
99
|
+
multi: true,
|
|
100
|
+
},
|
|
101
|
+
], hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }], host: {
|
|
102
|
+
class: BEM_BLOCK,
|
|
103
|
+
}, template: "<button\n rtBlock=\"rt-checkbox\"\n qa-dataid=\"checkbox-control\"\n type=\"button\"\n role=\"checkbox\"\n [rtMod]=\"{\n checked: isChecked() && !indeterminate(),\n indeterminate: indeterminate(),\n disabled: isDisabled(),\n }\"\n [attr.id]=\"inputId()\"\n [attr.aria-checked]=\"indeterminate() ? 'mixed' : isChecked()\"\n [attr.aria-label]=\"ariaLabel()\"\n [disabled]=\"isDisabled()\"\n (click)=\"toggle()\">\n <span rtElem=\"box\">\n @if (indeterminate()) {\n <rt-icon rtElem=\"icon\" name=\"minus\" size=\"xs\" color=\"inverse\" />\n } @else if (isChecked()) {\n <rt-icon rtElem=\"icon\" name=\"check\" size=\"xs\" color=\"inverse\" />\n }\n </span>\n\n <span rtElem=\"label\" qa-dataid=\"checkbox-label\">\n <ng-content />\n </span>\n</button>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{rt-checkbox{display:inline-block}rt-checkbox[data-rt-radius=none]>.rt-checkbox{--rt-checkbox-box-radius: var(--rt-radius-none)}rt-checkbox[data-rt-radius=xs]>.rt-checkbox{--rt-checkbox-box-radius: var(--rt-radius-xs)}rt-checkbox[data-rt-radius=sm]>.rt-checkbox{--rt-checkbox-box-radius: var(--rt-radius-sm)}rt-checkbox[data-rt-radius=ms]>.rt-checkbox{--rt-checkbox-box-radius: var(--rt-radius-ms)}rt-checkbox[data-rt-radius=md]>.rt-checkbox{--rt-checkbox-box-radius: var(--rt-radius-md)}rt-checkbox[data-rt-radius=lg]>.rt-checkbox{--rt-checkbox-box-radius: var(--rt-radius-lg)}rt-checkbox[data-rt-radius=xl]>.rt-checkbox{--rt-checkbox-box-radius: var(--rt-radius-xl)}rt-checkbox[data-rt-radius=\"2xl\"]>.rt-checkbox{--rt-checkbox-box-radius: var(--rt-radius-2xl)}rt-checkbox[data-rt-radius=full]>.rt-checkbox{--rt-checkbox-box-radius: var(--rt-radius-full)}rt-checkbox .rt-checkbox{--rt-checkbox-focus-radius: var(--rt-radius-sm);--rt-checkbox-focus-shadow: var(--rt-shadow-focus-ring);--rt-checkbox-box-radius: var(--rt-radius-sm);--rt-checkbox-transition-duration: var(--rt-duration-fast);--rt-checkbox-color-label: var(--rt-color-text-primary);display:inline-flex;align-items:center;padding:0;border:none;background:none;cursor:pointer;font:inherit;gap:var(--rt-space-sm);text-align:start;vertical-align:top}rt-checkbox .rt-checkbox:focus-visible{border-radius:var(--rt-checkbox-focus-radius);box-shadow:var(--rt-checkbox-focus-shadow);outline:2px solid transparent;outline-offset:2px}rt-checkbox .rt-checkbox--disabled{cursor:not-allowed;opacity:.5}rt-checkbox .rt-checkbox__box{display:inline-flex;width:18px;height:18px;flex-shrink:0;align-items:center;justify-content:center;border:var(--rt-input-border-width) solid var(--rt-color-border-strong);border-radius:var(--rt-checkbox-box-radius);background:var(--rt-color-bg-surface);transition:background var(--rt-checkbox-transition-duration) ease,border-color var(--rt-checkbox-transition-duration) ease}rt-checkbox .rt-checkbox--checked .rt-checkbox__box,rt-checkbox .rt-checkbox--indeterminate .rt-checkbox__box{border-color:var(--rt-color-action-primary);background:var(--rt-color-action-primary)}rt-checkbox .rt-checkbox__label{color:var(--rt-checkbox-color-label);font-size:var(--rt-text-sm);-webkit-user-select:none;user-select:none}rt-checkbox .rt-checkbox__label:empty{display:none}}\n"] }]
|
|
104
|
+
}], propDecorators: { inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }] } });
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Generated bundle index. Do not edit.
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
export { RtCheckboxComponent };
|
|
111
|
+
//# sourceMappingURL=rt-tools-ui-kit-v2-checkbox.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rt-tools-ui-kit-v2-checkbox.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/checkbox/rt-checkbox.component.ts","../../../projects/ui-kit-v2/src/lib/components/checkbox/rt-checkbox.component.html","../../../projects/ui-kit-v2/src/lib/components/checkbox/rt-tools-ui-kit-v2-checkbox.ts"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n forwardRef,\n input,\n InputSignal,\n InputSignalWithTransform,\n Signal,\n signal,\n ViewEncapsulation,\n WritableSignal,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\n\nconst BEM_BLOCK: string = 'rt-checkbox';\n\n/**\n * Чекбокс с `role=\"checkbox\"` + `aria-checked` (`true`/`false`/`mixed`) поверх\n * нативного `<button>` — клавиатурный toggle (Enter/Space) работает «из коробки»\n * без отдельных keydown-хендлеров. Галочка/прочерк рисуются через `rt-icon`\n * (`check`/`minus`), бокс и цвета — на токенах `--rt-*`.\n *\n * Реализует `ControlValueAccessor` для `boolean` value через\n * `useExisting: forwardRef(...)` — `useClass` на self-reference вызывает\n * NG0200 cycle при boot'е.\n *\n * Отключение складывается из двух независимых источников: входа `disabled` и\n * слова формы (CVA `setDisabledState`). Отключено, если так сказал любой из\n * них. Сводить их в один signal нельзя: форма зовёт `setDisabledState` при\n * связывании контрола, то есть раньше, чем чекбокс впервые обновит своё вью,\n * и мирроринг входа затирал бы её слово — контрол, созданный отключённым,\n * оказывался бы кликабельным.\n *\n * `indeterminate` — чисто визуальное mixed-состояние; клик по нему разрешается\n * в `true` (стандартное поведение tri-state чекбокса).\n *\n * Текстовая подпись проецируется через `<ng-content>`.\n */\n@Component({\n selector: 'rt-checkbox',\n templateUrl: './rt-checkbox.component.html',\n styleUrl: './rt-checkbox.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtIconComponent,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef((): typeof RtCheckboxComponent => RtCheckboxComponent),\n multi: true,\n },\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtCheckboxComponent implements ControlValueAccessor {\n #onChange: (value: boolean) => void = (): void => undefined;\n #onTouched: () => void = (): void => undefined;\n\n /** Отключение, назначенное формой через CVA (`setDisabledState`). */\n readonly #disabledByForm: WritableSignal<boolean> = signal<boolean>(false);\n\n protected readonly isChecked: WritableSignal<boolean> = signal<boolean>(false);\n protected readonly isDisabled: Signal<boolean> = computed((): boolean => this.disabled() || this.#disabledByForm());\n\n public readonly inputId: InputSignal<string | null> = input<string | null>(null);\n\n public readonly ariaLabel: InputSignal<string | null> = input<string | null>(null);\n\n public readonly disabled: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public readonly indeterminate: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n public writeValue(value: boolean | null | undefined): void {\n this.isChecked.set(value === true);\n }\n\n public registerOnChange(fn: (value: boolean) => void): void {\n this.#onChange = fn;\n }\n\n public registerOnTouched(fn: () => void): void {\n this.#onTouched = fn;\n }\n\n public setDisabledState(disabled: boolean): void {\n this.#disabledByForm.set(disabled);\n }\n\n protected toggle(): void {\n if (this.isDisabled()) {\n return;\n }\n // mixed-состояние при клике разрешается в checked (tri-state контракт).\n const next: boolean = this.indeterminate() ? true : !this.isChecked();\n this.isChecked.set(next);\n this.#onChange(next);\n this.#onTouched();\n }\n}\n","<button\n rtBlock=\"rt-checkbox\"\n qa-dataid=\"checkbox-control\"\n type=\"button\"\n role=\"checkbox\"\n [rtMod]=\"{\n checked: isChecked() && !indeterminate(),\n indeterminate: indeterminate(),\n disabled: isDisabled(),\n }\"\n [attr.id]=\"inputId()\"\n [attr.aria-checked]=\"indeterminate() ? 'mixed' : isChecked()\"\n [attr.aria-label]=\"ariaLabel()\"\n [disabled]=\"isDisabled()\"\n (click)=\"toggle()\">\n <span rtElem=\"box\">\n @if (indeterminate()) {\n <rt-icon rtElem=\"icon\" name=\"minus\" size=\"xs\" color=\"inverse\" />\n } @else if (isChecked()) {\n <rt-icon rtElem=\"icon\" name=\"check\" size=\"xs\" color=\"inverse\" />\n }\n </span>\n\n <span rtElem=\"label\" qa-dataid=\"checkbox-label\">\n <ng-content />\n </span>\n</button>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { inject, viewChild, signal, input, numberAttribute, afterRenderEffect, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';
|
|
4
|
+
import { RT_KIT_LABELS } from '@rt-tools/ui-kit-v2/core';
|
|
5
|
+
|
|
6
|
+
const BEM_BLOCK = 'rt-collapsible-text';
|
|
7
|
+
class RtCollapsibleTextComponent {
|
|
8
|
+
#resizeObserver;
|
|
9
|
+
constructor() {
|
|
10
|
+
this.#resizeObserver = null;
|
|
11
|
+
this.t = inject(RT_KIT_LABELS);
|
|
12
|
+
this.textRef = viewChild('text', /* @ts-ignore */
|
|
13
|
+
...(ngDevMode ? [{ debugName: "textRef" }] : /* istanbul ignore next */ []));
|
|
14
|
+
this.expanded = signal(false, /* @ts-ignore */
|
|
15
|
+
...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
|
|
16
|
+
this.overflowing = signal(false, /* @ts-ignore */
|
|
17
|
+
...(ngDevMode ? [{ debugName: "overflowing" }] : /* istanbul ignore next */ []));
|
|
18
|
+
this.paragraphs = input.required(/* @ts-ignore */
|
|
19
|
+
...(ngDevMode ? [{ debugName: "paragraphs" }] : /* istanbul ignore next */ []));
|
|
20
|
+
this.clampLines = input(6, { ...(ngDevMode ? { debugName: "clampLines" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
21
|
+
afterRenderEffect(() => {
|
|
22
|
+
this.paragraphs();
|
|
23
|
+
this.#observeText();
|
|
24
|
+
this.#measure();
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
ngOnDestroy() {
|
|
28
|
+
this.#resizeObserver?.disconnect();
|
|
29
|
+
}
|
|
30
|
+
toggle() {
|
|
31
|
+
this.expanded.update((expanded) => !expanded);
|
|
32
|
+
}
|
|
33
|
+
#observeText() {
|
|
34
|
+
const el = this.textRef()?.nativeElement;
|
|
35
|
+
if (el === undefined || this.#resizeObserver !== null) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (typeof ResizeObserver === 'undefined') {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
this.#resizeObserver = new ResizeObserver(() => this.#measure());
|
|
42
|
+
this.#resizeObserver.observe(el);
|
|
43
|
+
}
|
|
44
|
+
#measure() {
|
|
45
|
+
if (this.expanded()) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const el = this.textRef()?.nativeElement;
|
|
49
|
+
if (el === undefined) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
this.overflowing.set(el.scrollHeight > el.clientHeight + 1);
|
|
53
|
+
}
|
|
54
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtCollapsibleTextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
55
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtCollapsibleTextComponent, isStandalone: true, selector: "rt-collapsible-text", inputs: { paragraphs: { classPropertyName: "paragraphs", publicName: "paragraphs", isSignal: true, isRequired: true, transformFunction: null }, clampLines: { classPropertyName: "clampLines", publicName: "clampLines", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "rt-collapsible-text" }, viewQueries: [{ propertyName: "textRef", first: true, predicate: ["text"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container rtBlock=\"rt-collapsible-text\">\n <div\n #text\n rtElem=\"text\"\n qa-dataid=\"collapsible-text-body\"\n [rtMod]=\"{ clamped: !expanded() }\"\n [style.-webkit-line-clamp]=\"expanded() ? null : clampLines()\">\n @for (paragraph of paragraphs(); track $index) {\n <p rtElem=\"paragraph\" qa-dataid=\"collapsible-text-paragraph\">{{ paragraph }}</p>\n }\n </div>\n @if (overflowing() || expanded()) {\n <button rtElem=\"toggle\" qa-dataid=\"collapsible-text-toggle\" type=\"button\" [attr.aria-expanded]=\"expanded()\" (click)=\"toggle()\">\n {{ expanded() ? t().uiCollapse : t().uiMore }}\n </button>\n }\n</ng-container>\n", styles: ["@layer rt-kit.components{.rt-collapsible-text{display:flex;flex-direction:column;gap:var(--rt-space-sm)}.rt-collapsible-text__text{display:block}.rt-collapsible-text__text--clamped{display:-webkit-box;overflow:hidden;-webkit-box-orient:vertical}.rt-collapsible-text__paragraph{margin:0;color:var(--rt-color-text-primary);font-family:var(--rt-font-family-sans);font-size:var(--rt-text-xs);font-weight:var(--rt-font-weight-regular);letter-spacing:var(--rt-letter-spacing-wide);line-height:var(--rt-leading-snug)}.rt-collapsible-text__paragraph+.rt-collapsible-text__paragraph{margin-top:var(--rt-space-sm)}.rt-collapsible-text__toggle{align-self:flex-start;padding:0;border:0;background:transparent;color:var(--rt-color-text-link);cursor:pointer;font-family:var(--rt-font-family-sans);font-size:var(--rt-text-xs);font-weight:var(--rt-font-weight-medium);letter-spacing:var(--rt-letter-spacing-wide);line-height:var(--rt-leading-snug)}}\n"], dependencies: [{ kind: "directive", type:
|
|
56
|
+
// standalone components / directives
|
|
57
|
+
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 }); }
|
|
58
|
+
}
|
|
59
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtCollapsibleTextComponent, decorators: [{
|
|
60
|
+
type: Component,
|
|
61
|
+
args: [{ selector: 'rt-collapsible-text', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [
|
|
62
|
+
// standalone components / directives
|
|
63
|
+
BlockDirective,
|
|
64
|
+
ElemDirective,
|
|
65
|
+
ModDirective,
|
|
66
|
+
], host: {
|
|
67
|
+
class: BEM_BLOCK,
|
|
68
|
+
}, template: "<ng-container rtBlock=\"rt-collapsible-text\">\n <div\n #text\n rtElem=\"text\"\n qa-dataid=\"collapsible-text-body\"\n [rtMod]=\"{ clamped: !expanded() }\"\n [style.-webkit-line-clamp]=\"expanded() ? null : clampLines()\">\n @for (paragraph of paragraphs(); track $index) {\n <p rtElem=\"paragraph\" qa-dataid=\"collapsible-text-paragraph\">{{ paragraph }}</p>\n }\n </div>\n @if (overflowing() || expanded()) {\n <button rtElem=\"toggle\" qa-dataid=\"collapsible-text-toggle\" type=\"button\" [attr.aria-expanded]=\"expanded()\" (click)=\"toggle()\">\n {{ expanded() ? t().uiCollapse : t().uiMore }}\n </button>\n }\n</ng-container>\n", styles: ["@layer rt-kit.components{.rt-collapsible-text{display:flex;flex-direction:column;gap:var(--rt-space-sm)}.rt-collapsible-text__text{display:block}.rt-collapsible-text__text--clamped{display:-webkit-box;overflow:hidden;-webkit-box-orient:vertical}.rt-collapsible-text__paragraph{margin:0;color:var(--rt-color-text-primary);font-family:var(--rt-font-family-sans);font-size:var(--rt-text-xs);font-weight:var(--rt-font-weight-regular);letter-spacing:var(--rt-letter-spacing-wide);line-height:var(--rt-leading-snug)}.rt-collapsible-text__paragraph+.rt-collapsible-text__paragraph{margin-top:var(--rt-space-sm)}.rt-collapsible-text__toggle{align-self:flex-start;padding:0;border:0;background:transparent;color:var(--rt-color-text-link);cursor:pointer;font-family:var(--rt-font-family-sans);font-size:var(--rt-text-xs);font-weight:var(--rt-font-weight-medium);letter-spacing:var(--rt-letter-spacing-wide);line-height:var(--rt-leading-snug)}}\n"] }]
|
|
69
|
+
}], ctorParameters: () => [], propDecorators: { textRef: [{ type: i0.ViewChild, args: ['text', { isSignal: true }] }], paragraphs: [{ type: i0.Input, args: [{ isSignal: true, alias: "paragraphs", required: true }] }], clampLines: [{ type: i0.Input, args: [{ isSignal: true, alias: "clampLines", required: false }] }] } });
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Generated bundle index. Do not edit.
|
|
73
|
+
*/
|
|
74
|
+
|
|
75
|
+
export { RtCollapsibleTextComponent };
|
|
76
|
+
//# sourceMappingURL=rt-tools-ui-kit-v2-collapsible-text.mjs.map
|