@rt-tools/ui-kit-v2 0.18.0 → 0.19.1

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.
Files changed (144) hide show
  1. package/README.md +3 -2
  2. package/fesm2022/rt-tools-ui-kit-v2-accordion.mjs +1 -1
  3. package/fesm2022/rt-tools-ui-kit-v2-accordion.mjs.map +1 -1
  4. package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs +14 -8
  5. package/fesm2022/rt-tools-ui-kit-v2-action-bar.mjs.map +1 -1
  6. package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs +97 -0
  7. package/fesm2022/rt-tools-ui-kit-v2-ai-run-status.mjs.map +1 -0
  8. package/fesm2022/rt-tools-ui-kit-v2-aside.mjs +10 -3
  9. package/fesm2022/rt-tools-ui-kit-v2-aside.mjs.map +1 -1
  10. package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs +1 -1
  11. package/fesm2022/rt-tools-ui-kit-v2-autocomplete.mjs.map +1 -1
  12. package/fesm2022/rt-tools-ui-kit-v2-bar-list.mjs +1 -1
  13. package/fesm2022/rt-tools-ui-kit-v2-bar-list.mjs.map +1 -1
  14. package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs +1 -1
  15. package/fesm2022/rt-tools-ui-kit-v2-checkbox.mjs.map +1 -1
  16. package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs +81 -0
  17. package/fesm2022/rt-tools-ui-kit-v2-copy-value.mjs.map +1 -0
  18. package/fesm2022/rt-tools-ui-kit-v2-core.mjs +99 -1
  19. package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -1
  20. package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs +5 -5
  21. package/fesm2022/rt-tools-ui-kit-v2-data-list.mjs.map +1 -1
  22. package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs +16 -4
  23. package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs.map +1 -1
  24. package/fesm2022/rt-tools-ui-kit-v2-download-link.mjs +1 -1
  25. package/fesm2022/rt-tools-ui-kit-v2-download-link.mjs.map +1 -1
  26. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs +124 -25
  27. package/fesm2022/rt-tools-ui-kit-v2-dynamic-selector.mjs.map +1 -1
  28. package/fesm2022/rt-tools-ui-kit-v2-empty-state.mjs +3 -3
  29. package/fesm2022/rt-tools-ui-kit-v2-empty-state.mjs.map +1 -1
  30. package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs +1 -1
  31. package/fesm2022/rt-tools-ui-kit-v2-expansion-panel.mjs.map +1 -1
  32. package/fesm2022/rt-tools-ui-kit-v2-field.mjs +1 -1
  33. package/fesm2022/rt-tools-ui-kit-v2-field.mjs.map +1 -1
  34. package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs +1 -1
  35. package/fesm2022/rt-tools-ui-kit-v2-file-card.mjs.map +1 -1
  36. package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs +1 -1
  37. package/fesm2022/rt-tools-ui-kit-v2-icon-button.mjs.map +1 -1
  38. package/fesm2022/rt-tools-ui-kit-v2-icon.mjs +64 -27
  39. package/fesm2022/rt-tools-ui-kit-v2-icon.mjs.map +1 -1
  40. package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs +1 -1
  41. package/fesm2022/rt-tools-ui-kit-v2-input-number.mjs.map +1 -1
  42. package/fesm2022/rt-tools-ui-kit-v2-input.mjs +1 -1
  43. package/fesm2022/rt-tools-ui-kit-v2-input.mjs.map +1 -1
  44. package/fesm2022/rt-tools-ui-kit-v2-menu.mjs +1 -1
  45. package/fesm2022/rt-tools-ui-kit-v2-menu.mjs.map +1 -1
  46. package/fesm2022/rt-tools-ui-kit-v2-message.mjs +1 -1
  47. package/fesm2022/rt-tools-ui-kit-v2-message.mjs.map +1 -1
  48. package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs +1 -1
  49. package/fesm2022/rt-tools-ui-kit-v2-multiselect.mjs.map +1 -1
  50. package/fesm2022/rt-tools-ui-kit-v2-notifications-bell.mjs +1 -1
  51. package/fesm2022/rt-tools-ui-kit-v2-notifications-bell.mjs.map +1 -1
  52. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs +1 -1
  53. package/fesm2022/rt-tools-ui-kit-v2-page-header.mjs.map +1 -1
  54. package/fesm2022/rt-tools-ui-kit-v2-prompt-suggestion.mjs +46 -0
  55. package/fesm2022/rt-tools-ui-kit-v2-prompt-suggestion.mjs.map +1 -0
  56. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +336 -12
  57. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
  58. package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs +1 -1
  59. package/fesm2022/rt-tools-ui-kit-v2-scroll-area.mjs.map +1 -1
  60. package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs +1 -1
  61. package/fesm2022/rt-tools-ui-kit-v2-section-nav.mjs.map +1 -1
  62. package/fesm2022/rt-tools-ui-kit-v2-select.mjs +16 -2
  63. package/fesm2022/rt-tools-ui-kit-v2-select.mjs.map +1 -1
  64. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs +3 -3
  65. package/fesm2022/rt-tools-ui-kit-v2-side-menu.mjs.map +1 -1
  66. package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs +1 -1
  67. package/fesm2022/rt-tools-ui-kit-v2-stat-tile.mjs.map +1 -1
  68. package/fesm2022/rt-tools-ui-kit-v2-table.mjs +2 -2
  69. package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -1
  70. package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs +1 -1
  71. package/fesm2022/rt-tools-ui-kit-v2-tabs.mjs.map +1 -1
  72. package/fesm2022/rt-tools-ui-kit-v2-tag.mjs +1 -1
  73. package/fesm2022/rt-tools-ui-kit-v2-tag.mjs.map +1 -1
  74. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +31 -5
  75. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -1
  76. package/fesm2022/rt-tools-ui-kit-v2-toast.mjs +1 -1
  77. package/fesm2022/rt-tools-ui-kit-v2-toast.mjs.map +1 -1
  78. package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs +1 -1
  79. package/fesm2022/rt-tools-ui-kit-v2-toggle-button-group.mjs.map +1 -1
  80. package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs +1 -1
  81. package/fesm2022/rt-tools-ui-kit-v2-toggle-switch.mjs.map +1 -1
  82. package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs +2 -2
  83. package/fesm2022/rt-tools-ui-kit-v2-toolbar.mjs.map +1 -1
  84. package/fesm2022/rt-tools-ui-kit-v2.mjs +3 -0
  85. package/fesm2022/rt-tools-ui-kit-v2.mjs.map +1 -1
  86. package/package.json +13 -1
  87. package/rt-tools-ui-kit-v2-0.19.1.tgz +0 -0
  88. package/src/assets/icons/sparkle.svg +9 -0
  89. package/src/assets/icons/thumb-down.svg +10 -0
  90. package/src/assets/icons/thumb-up.svg +9 -0
  91. package/src/assets/icons/trash-x.svg +7 -0
  92. package/src/assets/icons-material/sparkle.fill.svg +5 -0
  93. package/src/assets/icons-material/sparkle.svg +5 -0
  94. package/src/assets/icons-material/thumb-down.fill.svg +5 -0
  95. package/src/assets/icons-material/thumb-down.svg +5 -0
  96. package/src/assets/icons-material/thumb-up.fill.svg +5 -0
  97. package/src/assets/icons-material/thumb-up.svg +5 -0
  98. package/src/assets/icons-material/trash-x.fill.svg +5 -0
  99. package/src/assets/icons-material/trash-x.svg +5 -0
  100. package/src/lib/components/action-bar/CONTEXT.md +8 -2
  101. package/src/lib/components/action-bar/rt-action-bar-holder.component.scss +10 -7
  102. package/src/lib/components/action-bar/rt-action-bar.component.scss +82 -34
  103. package/src/lib/components/ai-run-status/CONTEXT.md +41 -0
  104. package/src/lib/components/ai-run-status/rt-ai-run-status.component.scss +158 -0
  105. package/src/lib/components/aside/CONTEXT.md +1 -0
  106. package/src/lib/components/aside/header/rt-aside-header.component.scss +27 -11
  107. package/src/lib/components/copy-value/CONTEXT.md +31 -0
  108. package/src/lib/components/copy-value/rt-copy-value.component.scss +39 -0
  109. package/src/lib/components/data-list/settings/rt-data-list-settings-aside.component.scss +5 -5
  110. package/src/lib/components/data-table/CONTEXT.md +5 -0
  111. package/src/lib/components/dynamic-selector/CONTEXT.md +18 -0
  112. package/src/lib/components/dynamic-selector/list/rt-dynamic-selector-list.component.scss +29 -1
  113. package/src/lib/components/dynamic-selector/popup/rt-dynamic-selector-popup.component.scss +84 -25
  114. package/src/lib/components/empty-state/CONTEXT.md +2 -1
  115. package/src/lib/components/empty-state/rt-empty-state.component.scss +4 -2
  116. package/src/lib/components/icon/CONTEXT.md +16 -12
  117. package/src/lib/components/icon/rt-icon.component.scss +13 -3
  118. package/src/lib/components/prompt-suggestion/CONTEXT.md +29 -0
  119. package/src/lib/components/prompt-suggestion/rt-prompt-suggestion.component.scss +58 -0
  120. package/src/lib/components/select/CONTEXT.md +2 -2
  121. package/src/lib/components/thread-list/CONTEXT.md +4 -0
  122. package/src/lib/components/thread-list/rt-thread-list.component.scss +29 -0
  123. package/src/lib/components/toolbar/CONTEXT.md +4 -0
  124. package/src/lib/components/toolbar/rt-toolbar.component.scss +7 -0
  125. package/src/rich-editor/lib/components/ai-chat/CONTEXT.md +58 -0
  126. package/src/rich-editor/lib/components/ai-chat/answer/rt-ai-chat-answer.component.scss +12 -0
  127. package/src/rich-editor/lib/components/ai-chat/rt-ai-chat.component.scss +222 -0
  128. package/src/rich-editor/lib/components/rich-editor/rt-rich-editor.component.scss +3 -0
  129. package/src/styles/_scrollbar.scss +9 -0
  130. package/styles/tokens.css +3 -0
  131. package/types/rt-tools-ui-kit-v2-action-bar.d.ts +11 -2
  132. package/types/rt-tools-ui-kit-v2-ai-run-status.d.ts +49 -0
  133. package/types/rt-tools-ui-kit-v2-aside.d.ts +9 -1
  134. package/types/rt-tools-ui-kit-v2-copy-value.d.ts +29 -0
  135. package/types/rt-tools-ui-kit-v2-core.d.ts +94 -54
  136. package/types/rt-tools-ui-kit-v2-data-table.d.ts +7 -0
  137. package/types/rt-tools-ui-kit-v2-dynamic-selector.d.ts +44 -5
  138. package/types/rt-tools-ui-kit-v2-icon.d.ts +12 -4
  139. package/types/rt-tools-ui-kit-v2-prompt-suggestion.d.ts +21 -0
  140. package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +186 -2
  141. package/types/rt-tools-ui-kit-v2-select.d.ts +6 -0
  142. package/types/rt-tools-ui-kit-v2-thread-list.d.ts +15 -2
  143. package/types/rt-tools-ui-kit-v2.d.ts +3 -0
  144. package/rt-tools-ui-kit-v2-0.18.0.tgz +0 -0
@@ -31,9 +31,9 @@ class RtEmptyStateComponent {
31
31
  this.framed = input(false, { ...(ngDevMode ? { debugName: "framed" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
32
32
  }
33
33
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtEmptyStateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
34
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtEmptyStateComponent, isStandalone: true, selector: "rt-empty-state", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, glyph: { classPropertyName: "glyph", publicName: "glyph", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, framed: { classPropertyName: "framed", publicName: "framed", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.rt-empty-state--framed": "framed()" }, classAttribute: "rt-empty-state" }, hostDirectives: [{ directive: i1.RtRadiusDirective, inputs: ["radius", "radius"] }], ngImport: i0, template: "<ng-container rtBlock=\"rt-empty-state\">\n <div rtElem=\"illustration\">\n <ng-content select=\"[rtEmptyIllustration]\" />\n </div>\n\n @if (icon() || glyph()) {\n <span rtElem=\"icon-wrap\" qa-dataid=\"empty-state-icon\">\n <rt-icon size=\"xl\" color=\"muted\" [name]=\"icon()\" [glyph]=\"glyph()\" />\n </span>\n }\n\n @if (title()) {\n <p rtElem=\"title\" qa-dataid=\"empty-state-title\">{{ title() }}</p>\n }\n\n @if (description(); as desc) {\n <p rtElem=\"description\" qa-dataid=\"empty-state-description\">{{ desc }}</p>\n }\n\n <div rtElem=\"action\" qa-dataid=\"empty-state-action\">\n <ng-content />\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-empty-state{--rt-empty-state-icon-radius: var(--rt-radius-full);--rt-empty-state-icon-wrap-size: var(--rt-size-16);--rt-empty-state-icon-wrap-bg: var(--rt-color-bg-subtle);--rt-empty-state-icon-size: var(--rt-size-8);--rt-empty-state-title-size: var(--rt-text-md);--rt-empty-state-title-weight: var(--rt-font-weight-medium);--rt-empty-state-frame-width: var(--rt-border-width-medium);--rt-empty-state-frame-color: var(--rt-color-border-strong);--rt-empty-state-frame-radius: var(--rt-radius-lg);display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--rt-space-xl) var(--rt-space-lg);gap:var(--rt-space-sm);text-align:center}.rt-empty-state--framed{border:var(--rt-empty-state-frame-width) dashed var(--rt-empty-state-frame-color);border-radius:var(--rt-empty-state-frame-radius)}.rt-empty-state__illustration:empty{display:none}.rt-empty-state__illustration{margin-bottom:var(--rt-space-xs)}.rt-empty-state__icon-wrap{display:flex;width:var(--rt-empty-state-icon-wrap-size);height:var(--rt-empty-state-icon-wrap-size);align-items:center;justify-content:center;border-radius:var(--rt-empty-state-icon-radius);margin-bottom:var(--rt-space-xs);background:var(--rt-empty-state-icon-wrap-bg);color:var(--rt-color-text-muted)}.rt-empty-state__icon-wrap .rt-icon{min-width:var(--rt-empty-state-icon-size);max-width:var(--rt-empty-state-icon-size);min-height:var(--rt-empty-state-icon-size);max-height:var(--rt-empty-state-icon-size)}.rt-empty-state__title{margin:0;color:var(--rt-color-text-primary);font-size:var(--rt-empty-state-title-size);font-weight:var(--rt-empty-state-title-weight)}.rt-empty-state__description{max-width:320px;margin:0;color:var(--rt-color-text-muted);font-size:var(--rt-text-sm);line-height:var(--rt-leading-normal)}.rt-empty-state__action:empty{display:none}.rt-empty-state__action{margin-top:var(--rt-space-sm)}.rt-empty-state[data-rt-radius=none]{--rt-empty-state-icon-radius: var(--rt-radius-none)}.rt-empty-state[data-rt-radius=xs]{--rt-empty-state-icon-radius: var(--rt-radius-xs)}.rt-empty-state[data-rt-radius=sm]{--rt-empty-state-icon-radius: var(--rt-radius-sm)}.rt-empty-state[data-rt-radius=ms]{--rt-empty-state-icon-radius: var(--rt-radius-ms)}.rt-empty-state[data-rt-radius=md]{--rt-empty-state-icon-radius: var(--rt-radius-md)}.rt-empty-state[data-rt-radius=lg]{--rt-empty-state-icon-radius: var(--rt-radius-lg)}.rt-empty-state[data-rt-radius=xl]{--rt-empty-state-icon-radius: var(--rt-radius-xl)}.rt-empty-state[data-rt-radius=\"2xl\"]{--rt-empty-state-icon-radius: var(--rt-radius-2xl)}.rt-empty-state[data-rt-radius=full]{--rt-empty-state-icon-radius: var(--rt-radius-full)}}\n"], dependencies: [{ kind: "component", type:
34
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtEmptyStateComponent, isStandalone: true, selector: "rt-empty-state", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, glyph: { classPropertyName: "glyph", publicName: "glyph", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, framed: { classPropertyName: "framed", publicName: "framed", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.rt-empty-state--framed": "framed()" }, classAttribute: "rt-empty-state" }, hostDirectives: [{ directive: i1.RtRadiusDirective, inputs: ["radius", "radius"] }], ngImport: i0, template: "<ng-container rtBlock=\"rt-empty-state\">\n <div rtElem=\"illustration\">\n <ng-content select=\"[rtEmptyIllustration]\" />\n </div>\n\n @if (icon() || glyph()) {\n <span rtElem=\"icon-wrap\" qa-dataid=\"empty-state-icon\">\n <rt-icon size=\"xl\" color=\"muted\" [name]=\"icon()\" [glyph]=\"glyph()\" />\n </span>\n }\n\n @if (title()) {\n <p rtElem=\"title\" qa-dataid=\"empty-state-title\">{{ title() }}</p>\n }\n\n @if (description(); as desc) {\n <p rtElem=\"description\" qa-dataid=\"empty-state-description\">{{ desc }}</p>\n }\n\n <div rtElem=\"action\" qa-dataid=\"empty-state-action\">\n <ng-content />\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-empty-state{--rt-empty-state-icon-radius: var(--rt-radius-full);--rt-empty-state-icon-wrap-size: var(--rt-size-16);--rt-empty-state-icon-wrap-bg: var(--rt-color-bg-subtle);--rt-empty-state-icon-size: var(--rt-size-8);--rt-empty-state-title-size: var(--rt-text-md);--rt-empty-state-title-weight: var(--rt-font-weight-medium);--rt-empty-state-title-color: var(--rt-color-text-primary);--rt-empty-state-description-size: var(--rt-text-sm);--rt-empty-state-frame-width: var(--rt-border-width-medium);--rt-empty-state-frame-color: var(--rt-color-border-strong);--rt-empty-state-frame-radius: var(--rt-radius-lg);display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--rt-space-xl) var(--rt-space-lg);gap:var(--rt-space-sm);text-align:center}.rt-empty-state--framed{border:var(--rt-empty-state-frame-width) dashed var(--rt-empty-state-frame-color);border-radius:var(--rt-empty-state-frame-radius)}.rt-empty-state__illustration:empty{display:none}.rt-empty-state__illustration{margin-bottom:var(--rt-space-xs)}.rt-empty-state__icon-wrap{display:flex;width:var(--rt-empty-state-icon-wrap-size);height:var(--rt-empty-state-icon-wrap-size);align-items:center;justify-content:center;border-radius:var(--rt-empty-state-icon-radius);margin-bottom:var(--rt-space-xs);background:var(--rt-empty-state-icon-wrap-bg);color:var(--rt-color-text-muted)}.rt-empty-state__icon-wrap .rt-icon{min-width:var(--rt-empty-state-icon-size);max-width:var(--rt-empty-state-icon-size);min-height:var(--rt-empty-state-icon-size);max-height:var(--rt-empty-state-icon-size)}.rt-empty-state__title{margin:0;color:var(--rt-empty-state-title-color);font-size:var(--rt-empty-state-title-size);font-weight:var(--rt-empty-state-title-weight)}.rt-empty-state__description{max-width:320px;margin:0;color:var(--rt-color-text-muted);font-size:var(--rt-empty-state-description-size);line-height:var(--rt-leading-normal)}.rt-empty-state__action:empty{display:none}.rt-empty-state__action{margin-top:var(--rt-space-sm)}.rt-empty-state[data-rt-radius=none]{--rt-empty-state-icon-radius: var(--rt-radius-none)}.rt-empty-state[data-rt-radius=xs]{--rt-empty-state-icon-radius: var(--rt-radius-xs)}.rt-empty-state[data-rt-radius=sm]{--rt-empty-state-icon-radius: var(--rt-radius-sm)}.rt-empty-state[data-rt-radius=ms]{--rt-empty-state-icon-radius: var(--rt-radius-ms)}.rt-empty-state[data-rt-radius=md]{--rt-empty-state-icon-radius: var(--rt-radius-md)}.rt-empty-state[data-rt-radius=lg]{--rt-empty-state-icon-radius: var(--rt-radius-lg)}.rt-empty-state[data-rt-radius=xl]{--rt-empty-state-icon-radius: var(--rt-radius-xl)}.rt-empty-state[data-rt-radius=\"2xl\"]{--rt-empty-state-icon-radius: var(--rt-radius-2xl)}.rt-empty-state[data-rt-radius=full]{--rt-empty-state-icon-radius: var(--rt-radius-full)}}\n"], dependencies: [{ kind: "component", type:
35
35
  // standalone components / directives
36
- 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
36
+ RtIconComponent, selector: "rt-icon", inputs: ["name", "glyph", "glyphStrategy", "size", "color", "fill", "spin", "rotate"] }, { kind: "directive", type: BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
37
37
  }
38
38
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtEmptyStateComponent, decorators: [{
39
39
  type: Component,
@@ -45,7 +45,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
45
45
  ], hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }], host: {
46
46
  class: BEM_BLOCK,
47
47
  '[class.rt-empty-state--framed]': 'framed()',
48
- }, template: "<ng-container rtBlock=\"rt-empty-state\">\n <div rtElem=\"illustration\">\n <ng-content select=\"[rtEmptyIllustration]\" />\n </div>\n\n @if (icon() || glyph()) {\n <span rtElem=\"icon-wrap\" qa-dataid=\"empty-state-icon\">\n <rt-icon size=\"xl\" color=\"muted\" [name]=\"icon()\" [glyph]=\"glyph()\" />\n </span>\n }\n\n @if (title()) {\n <p rtElem=\"title\" qa-dataid=\"empty-state-title\">{{ title() }}</p>\n }\n\n @if (description(); as desc) {\n <p rtElem=\"description\" qa-dataid=\"empty-state-description\">{{ desc }}</p>\n }\n\n <div rtElem=\"action\" qa-dataid=\"empty-state-action\">\n <ng-content />\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-empty-state{--rt-empty-state-icon-radius: var(--rt-radius-full);--rt-empty-state-icon-wrap-size: var(--rt-size-16);--rt-empty-state-icon-wrap-bg: var(--rt-color-bg-subtle);--rt-empty-state-icon-size: var(--rt-size-8);--rt-empty-state-title-size: var(--rt-text-md);--rt-empty-state-title-weight: var(--rt-font-weight-medium);--rt-empty-state-frame-width: var(--rt-border-width-medium);--rt-empty-state-frame-color: var(--rt-color-border-strong);--rt-empty-state-frame-radius: var(--rt-radius-lg);display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--rt-space-xl) var(--rt-space-lg);gap:var(--rt-space-sm);text-align:center}.rt-empty-state--framed{border:var(--rt-empty-state-frame-width) dashed var(--rt-empty-state-frame-color);border-radius:var(--rt-empty-state-frame-radius)}.rt-empty-state__illustration:empty{display:none}.rt-empty-state__illustration{margin-bottom:var(--rt-space-xs)}.rt-empty-state__icon-wrap{display:flex;width:var(--rt-empty-state-icon-wrap-size);height:var(--rt-empty-state-icon-wrap-size);align-items:center;justify-content:center;border-radius:var(--rt-empty-state-icon-radius);margin-bottom:var(--rt-space-xs);background:var(--rt-empty-state-icon-wrap-bg);color:var(--rt-color-text-muted)}.rt-empty-state__icon-wrap .rt-icon{min-width:var(--rt-empty-state-icon-size);max-width:var(--rt-empty-state-icon-size);min-height:var(--rt-empty-state-icon-size);max-height:var(--rt-empty-state-icon-size)}.rt-empty-state__title{margin:0;color:var(--rt-color-text-primary);font-size:var(--rt-empty-state-title-size);font-weight:var(--rt-empty-state-title-weight)}.rt-empty-state__description{max-width:320px;margin:0;color:var(--rt-color-text-muted);font-size:var(--rt-text-sm);line-height:var(--rt-leading-normal)}.rt-empty-state__action:empty{display:none}.rt-empty-state__action{margin-top:var(--rt-space-sm)}.rt-empty-state[data-rt-radius=none]{--rt-empty-state-icon-radius: var(--rt-radius-none)}.rt-empty-state[data-rt-radius=xs]{--rt-empty-state-icon-radius: var(--rt-radius-xs)}.rt-empty-state[data-rt-radius=sm]{--rt-empty-state-icon-radius: var(--rt-radius-sm)}.rt-empty-state[data-rt-radius=ms]{--rt-empty-state-icon-radius: var(--rt-radius-ms)}.rt-empty-state[data-rt-radius=md]{--rt-empty-state-icon-radius: var(--rt-radius-md)}.rt-empty-state[data-rt-radius=lg]{--rt-empty-state-icon-radius: var(--rt-radius-lg)}.rt-empty-state[data-rt-radius=xl]{--rt-empty-state-icon-radius: var(--rt-radius-xl)}.rt-empty-state[data-rt-radius=\"2xl\"]{--rt-empty-state-icon-radius: var(--rt-radius-2xl)}.rt-empty-state[data-rt-radius=full]{--rt-empty-state-icon-radius: var(--rt-radius-full)}}\n"] }]
48
+ }, template: "<ng-container rtBlock=\"rt-empty-state\">\n <div rtElem=\"illustration\">\n <ng-content select=\"[rtEmptyIllustration]\" />\n </div>\n\n @if (icon() || glyph()) {\n <span rtElem=\"icon-wrap\" qa-dataid=\"empty-state-icon\">\n <rt-icon size=\"xl\" color=\"muted\" [name]=\"icon()\" [glyph]=\"glyph()\" />\n </span>\n }\n\n @if (title()) {\n <p rtElem=\"title\" qa-dataid=\"empty-state-title\">{{ title() }}</p>\n }\n\n @if (description(); as desc) {\n <p rtElem=\"description\" qa-dataid=\"empty-state-description\">{{ desc }}</p>\n }\n\n <div rtElem=\"action\" qa-dataid=\"empty-state-action\">\n <ng-content />\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-empty-state{--rt-empty-state-icon-radius: var(--rt-radius-full);--rt-empty-state-icon-wrap-size: var(--rt-size-16);--rt-empty-state-icon-wrap-bg: var(--rt-color-bg-subtle);--rt-empty-state-icon-size: var(--rt-size-8);--rt-empty-state-title-size: var(--rt-text-md);--rt-empty-state-title-weight: var(--rt-font-weight-medium);--rt-empty-state-title-color: var(--rt-color-text-primary);--rt-empty-state-description-size: var(--rt-text-sm);--rt-empty-state-frame-width: var(--rt-border-width-medium);--rt-empty-state-frame-color: var(--rt-color-border-strong);--rt-empty-state-frame-radius: var(--rt-radius-lg);display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--rt-space-xl) var(--rt-space-lg);gap:var(--rt-space-sm);text-align:center}.rt-empty-state--framed{border:var(--rt-empty-state-frame-width) dashed var(--rt-empty-state-frame-color);border-radius:var(--rt-empty-state-frame-radius)}.rt-empty-state__illustration:empty{display:none}.rt-empty-state__illustration{margin-bottom:var(--rt-space-xs)}.rt-empty-state__icon-wrap{display:flex;width:var(--rt-empty-state-icon-wrap-size);height:var(--rt-empty-state-icon-wrap-size);align-items:center;justify-content:center;border-radius:var(--rt-empty-state-icon-radius);margin-bottom:var(--rt-space-xs);background:var(--rt-empty-state-icon-wrap-bg);color:var(--rt-color-text-muted)}.rt-empty-state__icon-wrap .rt-icon{min-width:var(--rt-empty-state-icon-size);max-width:var(--rt-empty-state-icon-size);min-height:var(--rt-empty-state-icon-size);max-height:var(--rt-empty-state-icon-size)}.rt-empty-state__title{margin:0;color:var(--rt-empty-state-title-color);font-size:var(--rt-empty-state-title-size);font-weight:var(--rt-empty-state-title-weight)}.rt-empty-state__description{max-width:320px;margin:0;color:var(--rt-color-text-muted);font-size:var(--rt-empty-state-description-size);line-height:var(--rt-leading-normal)}.rt-empty-state__action:empty{display:none}.rt-empty-state__action{margin-top:var(--rt-space-sm)}.rt-empty-state[data-rt-radius=none]{--rt-empty-state-icon-radius: var(--rt-radius-none)}.rt-empty-state[data-rt-radius=xs]{--rt-empty-state-icon-radius: var(--rt-radius-xs)}.rt-empty-state[data-rt-radius=sm]{--rt-empty-state-icon-radius: var(--rt-radius-sm)}.rt-empty-state[data-rt-radius=ms]{--rt-empty-state-icon-radius: var(--rt-radius-ms)}.rt-empty-state[data-rt-radius=md]{--rt-empty-state-icon-radius: var(--rt-radius-md)}.rt-empty-state[data-rt-radius=lg]{--rt-empty-state-icon-radius: var(--rt-radius-lg)}.rt-empty-state[data-rt-radius=xl]{--rt-empty-state-icon-radius: var(--rt-radius-xl)}.rt-empty-state[data-rt-radius=\"2xl\"]{--rt-empty-state-icon-radius: var(--rt-radius-2xl)}.rt-empty-state[data-rt-radius=full]{--rt-empty-state-icon-radius: var(--rt-radius-full)}}\n"] }]
49
49
  }], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], glyph: [{ type: i0.Input, args: [{ isSignal: true, alias: "glyph", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], framed: [{ type: i0.Input, args: [{ isSignal: true, alias: "framed", required: false }] }] } });
50
50
 
51
51
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-empty-state.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/empty-state/rt-empty-state.component.ts","../../../projects/ui-kit-v2/src/lib/components/empty-state/rt-empty-state.component.html","../../../projects/ui-kit-v2/src/lib/components/empty-state/rt-tools-ui-kit-v2-empty-state.ts"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n input,\n InputSignal,\n InputSignalWithTransform,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\n\nconst BEM_BLOCK: string = 'rt-empty-state';\n\n/**\n * Заглушка пустого состояния: центрированная иконка в круглой подложке, заголовок,\n * опциональное описание и проецируемый слот для действия (кнопка «Прикрепить»,\n * «Выбрать» и т.п.). Применяется в пустых вкладках/списках и зонах загрузки, когда\n * сущностей ещё нет.\n *\n * Иконка опциональна (`icon`), действие — через `<ng-content />` (если ничего не\n * спроецировано, слот скрыт `:empty`). Громких severity-цветов нет — приглушённая\n * палитра, как у `rt-note`.\n */\n@Component({\n selector: 'rt-empty-state',\n templateUrl: './rt-empty-state.component.html',\n styleUrl: './rt-empty-state.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtIconComponent,\n BlockDirective,\n ElemDirective,\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n '[class.rt-empty-state--framed]': 'framed()',\n },\n})\nexport class RtEmptyStateComponent {\n public readonly icon: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n\n /** Имя Material вместо `icon` — рисуется так же, как вход `glyph` у `rt-icon`. */\n public readonly glyph: InputSignal<string | null> = input<string | null>(null);\n\n public readonly title: InputSignal<string> = input<string>('');\n\n public readonly description: InputSignal<string | null> = input<string | null>(null);\n\n /** Пунктирная рамка вокруг заглушки — так она читается как зона, куда бросают файл. */\n public readonly framed: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n}\n","<ng-container rtBlock=\"rt-empty-state\">\n <div rtElem=\"illustration\">\n <ng-content select=\"[rtEmptyIllustration]\" />\n </div>\n\n @if (icon() || glyph()) {\n <span rtElem=\"icon-wrap\" qa-dataid=\"empty-state-icon\">\n <rt-icon size=\"xl\" color=\"muted\" [name]=\"icon()\" [glyph]=\"glyph()\" />\n </span>\n }\n\n @if (title()) {\n <p rtElem=\"title\" qa-dataid=\"empty-state-title\">{{ title() }}</p>\n }\n\n @if (description(); as desc) {\n <p rtElem=\"description\" qa-dataid=\"empty-state-description\">{{ desc }}</p>\n }\n\n <div rtElem=\"action\" qa-dataid=\"empty-state-action\">\n <ng-content />\n </div>\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;AAiBA,MAAM,SAAS,GAAW,gBAAgB;AAE1C;;;;;;;;;AASG;MAmBU,qBAAqB,CAAA;AAlBlC,IAAA,WAAA,GAAA;QAmBoB,IAAA,CAAA,IAAI,GAAqC,KAAK,CAAsB,IAAI;iFAAC;;QAGzE,IAAA,CAAA,KAAK,GAA+B,KAAK,CAAgB,IAAI;kFAAC;QAE9D,IAAA,CAAA,KAAK,GAAwB,KAAK,CAAS,EAAE;kFAAC;QAE9C,IAAA,CAAA,WAAW,GAA+B,KAAK,CAAgB,IAAI;wFAAC;;QAGpE,IAAA,CAAA,MAAM,GAAoD,KAAK,CAAwB,KAAK,8EACxG,SAAS,EAAE,gBAAgB,EAAA,CAC7B;AACL,IAAA;8GAdY,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAArB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,qBAAqB,63BC/ClC,otBAuBA,EAAA,MAAA,EAAA,CAAA,2oFAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA;;gBDcQ,eAAe,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,OAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,EAAA,MAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACf,cAAc,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACd,aAAa,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA,CAAA;;2FAQR,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBAlBjC,SAAS;+BACI,gBAAgB,EAAA,eAAA,EAGT,uBAAuB,CAAC,MAAM,iBAChC,iBAAiB,CAAC,IAAI,EAAA,OAAA,EAC5B;;wBAEL,eAAe;wBACf,cAAc;wBACd,aAAa;AAChB,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;AAChB,wBAAA,gCAAgC,EAAE,UAAU;AAC/C,qBAAA,EAAA,QAAA,EAAA,otBAAA,EAAA,MAAA,EAAA,CAAA,2oFAAA,CAAA,EAAA;;;AE7CL;;AAEG;;;;"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-empty-state.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/empty-state/rt-empty-state.component.ts","../../../projects/ui-kit-v2/src/lib/components/empty-state/rt-empty-state.component.html","../../../projects/ui-kit-v2/src/lib/components/empty-state/rt-tools-ui-kit-v2-empty-state.ts"],"sourcesContent":["import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n input,\n InputSignal,\n InputSignalWithTransform,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\n\nconst BEM_BLOCK: string = 'rt-empty-state';\n\n/**\n * Заглушка пустого состояния: центрированная иконка в круглой подложке, заголовок,\n * опциональное описание и проецируемый слот для действия (кнопка «Прикрепить»,\n * «Выбрать» и т.п.). Применяется в пустых вкладках/списках и зонах загрузки, когда\n * сущностей ещё нет.\n *\n * Иконка опциональна (`icon`), действие — через `<ng-content />` (если ничего не\n * спроецировано, слот скрыт `:empty`). Громких severity-цветов нет — приглушённая\n * палитра, как у `rt-note`.\n */\n@Component({\n selector: 'rt-empty-state',\n templateUrl: './rt-empty-state.component.html',\n styleUrl: './rt-empty-state.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtIconComponent,\n BlockDirective,\n ElemDirective,\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n '[class.rt-empty-state--framed]': 'framed()',\n },\n})\nexport class RtEmptyStateComponent {\n public readonly icon: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n\n /** Имя Material вместо `icon` — рисуется так же, как вход `glyph` у `rt-icon`. */\n public readonly glyph: InputSignal<string | null> = input<string | null>(null);\n\n public readonly title: InputSignal<string> = input<string>('');\n\n public readonly description: InputSignal<string | null> = input<string | null>(null);\n\n /** Пунктирная рамка вокруг заглушки — так она читается как зона, куда бросают файл. */\n public readonly framed: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n}\n","<ng-container rtBlock=\"rt-empty-state\">\n <div rtElem=\"illustration\">\n <ng-content select=\"[rtEmptyIllustration]\" />\n </div>\n\n @if (icon() || glyph()) {\n <span rtElem=\"icon-wrap\" qa-dataid=\"empty-state-icon\">\n <rt-icon size=\"xl\" color=\"muted\" [name]=\"icon()\" [glyph]=\"glyph()\" />\n </span>\n }\n\n @if (title()) {\n <p rtElem=\"title\" qa-dataid=\"empty-state-title\">{{ title() }}</p>\n }\n\n @if (description(); as desc) {\n <p rtElem=\"description\" qa-dataid=\"empty-state-description\">{{ desc }}</p>\n }\n\n <div rtElem=\"action\" qa-dataid=\"empty-state-action\">\n <ng-content />\n </div>\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;AAiBA,MAAM,SAAS,GAAW,gBAAgB;AAE1C;;;;;;;;;AASG;MAmBU,qBAAqB,CAAA;AAlBlC,IAAA,WAAA,GAAA;QAmBoB,IAAA,CAAA,IAAI,GAAqC,KAAK,CAAsB,IAAI;iFAAC;;QAGzE,IAAA,CAAA,KAAK,GAA+B,KAAK,CAAgB,IAAI;kFAAC;QAE9D,IAAA,CAAA,KAAK,GAAwB,KAAK,CAAS,EAAE;kFAAC;QAE9C,IAAA,CAAA,WAAW,GAA+B,KAAK,CAAgB,IAAI;wFAAC;;QAGpE,IAAA,CAAA,MAAM,GAAoD,KAAK,CAAwB,KAAK,8EACxG,SAAS,EAAE,gBAAgB,EAAA,CAC7B;AACL,IAAA;8GAdY,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAArB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,qBAAqB,63BC/ClC,otBAuBA,EAAA,MAAA,EAAA,CAAA,qxFAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA;;gBDcQ,eAAe,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,OAAA,EAAA,eAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,EAAA,MAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACf,cAAc,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACd,aAAa,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA,CAAA;;2FAQR,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBAlBjC,SAAS;+BACI,gBAAgB,EAAA,eAAA,EAGT,uBAAuB,CAAC,MAAM,iBAChC,iBAAiB,CAAC,IAAI,EAAA,OAAA,EAC5B;;wBAEL,eAAe;wBACf,cAAc;wBACd,aAAa;AAChB,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;AAChB,wBAAA,gCAAgC,EAAE,UAAU;AAC/C,qBAAA,EAAA,QAAA,EAAA,otBAAA,EAAA,MAAA,EAAA,CAAA,qxFAAA,CAAA,EAAA;;;AE7CL;;AAEG;;;;"}
@@ -79,7 +79,7 @@ class RtExpansionPanelComponent {
79
79
  // directives
80
80
  BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }, { kind: "directive", type: ModDirective, selector: "[rtMod]" }, { kind: "component", type:
81
81
  // components
82
- RtIconComponent, selector: "rt-icon", inputs: ["name", "glyph", "size", "color", "fill", "spin", "rotate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
82
+ RtIconComponent, selector: "rt-icon", inputs: ["name", "glyph", "glyphStrategy", "size", "color", "fill", "spin", "rotate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
83
83
  }
84
84
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtExpansionPanelComponent, decorators: [{
85
85
  type: Component,
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-expansion-panel.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/expansion-panel/rt-expansion-panel-content.directive.ts","../../../projects/ui-kit-v2/src/lib/components/expansion-panel/rt-expansion-panel.component.ts","../../../projects/ui-kit-v2/src/lib/components/expansion-panel/rt-expansion-panel.component.html","../../../projects/ui-kit-v2/src/lib/components/expansion-panel/rt-tools-ui-kit-v2-expansion-panel.ts"],"sourcesContent":["import { Directive, inject, TemplateRef } from '@angular/core';\n\n/**\n * Тело `rt-expansion-panel`, собираемое лениво: ставится на `<ng-template>` внутри панели, и его\n * содержимое создаётся при раскрытии и уходит после сворачивания. Сворачивание при этом доигрывает\n * движение до конца: тело уходит вместе со своим содержимым, а не пустым.\n */\n@Directive({\n selector: 'ng-template[rtExpansionPanelContent]',\n})\nexport class RtExpansionPanelContentDirective {\n public readonly templateRef: TemplateRef<unknown> = inject<TemplateRef<unknown>>(TemplateRef);\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n input,\n InputSignal,\n InputSignalWithTransform,\n model,\n ModelSignal,\n Signal,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtExpansionPanelContentDirective } from './rt-expansion-panel-content.directive';\nimport { IRtExpansionPanel } from './rt-expansion-panel.model';\n\nconst BEM_BLOCK: string = 'rt-expansion-panel';\n\nlet expansionPanelIdSeed: number = 0;\n\nfunction nextExpansionPanelId(): number {\n expansionPanelIdSeed += 1;\n return expansionPanelIdSeed;\n}\n\n/**\n * Раскрывающаяся панель: заголовок-кнопка во всю ширину с шевроном у правого края и тело под ним.\n * Нажатие на заголовок раскрывает и сворачивает тело, раскрытие и сворачивание идут с движением.\n * Заменяет во втором ките панель раскрытия Material первого кита.\n *\n * Заголовок — содержимое панели без отметки. Тело — узел с `rtExpansionPanelBody`, созданный сразу,\n * или `<ng-template rtExpansionPanelContent>`, созданный при раскрытии.\n *\n * Состояние раскрытия — `expanded`, двусторонняя привязка: панель пишет в него сама, а владелец\n * может держать его в своём сигнале и менять извне.\n */\n@Component({\n selector: 'rt-expansion-panel',\n templateUrl: './rt-expansion-panel.component.html',\n styleUrl: './rt-expansion-panel.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n NgTemplateOutlet,\n\n // directives\n BlockDirective,\n ElemDirective,\n ModDirective,\n\n // components\n RtIconComponent,\n ],\n host: {\n class: BEM_BLOCK,\n '[class.rt-expansion-panel--plain]': 'appearance() === \"plain\"',\n '[class.rt-expansion-panel--expanded]': 'expanded()',\n '[class.rt-expansion-panel--disabled]': 'disabled()',\n },\n})\nexport class RtExpansionPanelComponent {\n /** Основа id: две панели на одной странице не ссылаются на чужое тело. */\n readonly #idBase: string = `rt-expansion-panel-${nextExpansionPanelId()}`;\n\n /** Ленивое тело: шаблон создаётся при раскрытии. */\n protected readonly lazyContent: Signal<RtExpansionPanelContentDirective | undefined> = contentChild(RtExpansionPanelContentDirective);\n protected readonly bodyId: string = `${this.#idBase}-body`;\n protected readonly headerDomId: Signal<string> = computed((): string => this.headerId() ?? `${this.#idBase}-header`);\n\n /** Тело раскрыто. Двусторонняя привязка: нажатие на заголовок пишет сюда. */\n public readonly expanded: ModelSignal<boolean> = model<boolean>(false);\n\n /** Заголовок не нажимается, тело остаётся как было. */\n public readonly disabled: InputSignalWithTransform<boolean, unknown> = input(false, { transform: booleanAttribute });\n\n /** Шеврона нет: раскрытие читается по содержимому или его нечего раскрывать. */\n public readonly hideToggle: InputSignalWithTransform<boolean, unknown> = input(false, { transform: booleanAttribute });\n\n public readonly appearance: InputSignal<IRtExpansionPanel.Appearance> = input<IRtExpansionPanel.Appearance>('card');\n\n /** Id кнопки заголовка. Нужен владельцу, который ищет заголовок по своему номеру; иначе — свой. */\n public readonly headerId: InputSignal<string | null> = input<string | null>(null);\n\n /** Имя кнопки заголовка для вспомогательных средств, когда видимой подписи мало. */\n public readonly ariaLabel: InputSignal<string | null> = input<string | null>(null);\n\n /** Нажатие на заголовок: раскрывает свёрнутую панель и сворачивает раскрытую. */\n public toggle(): void {\n if (!this.disabled()) {\n this.expanded.set(!this.expanded());\n }\n }\n}\n","<ng-container rtBlock=\"rt-expansion-panel\">\n <button\n type=\"button\"\n rtElem=\"header\"\n qa-dataid=\"expansion-panel-header\"\n [id]=\"headerDomId()\"\n [disabled]=\"disabled()\"\n [attr.aria-expanded]=\"expanded()\"\n [attr.aria-controls]=\"expanded() ? bodyId : null\"\n [attr.aria-label]=\"ariaLabel()\"\n (click)=\"toggle()\">\n <ng-content />\n\n @if (!hideToggle()) {\n <!-- Шеврон — в обёртке: ширину столбца держит она, значок свою ширину ставит сам. -->\n <span rtElem=\"chevron\" aria-hidden=\"true\" [rtMod]=\"{ open: expanded() }\"><rt-icon size=\"sm\" name=\"chevron-down\" /></span>\n }\n </button>\n\n @if (expanded()) {\n <!-- Сворачивание доигрывает движение: класс ухода сводит высоту к нулю, и тело уходит после. -->\n <div\n rtElem=\"body\"\n role=\"region\"\n qa-dataid=\"expansion-panel-body\"\n animate.leave=\"rt-expansion-panel__body--leaving\"\n [id]=\"bodyId\"\n [attr.aria-labelledby]=\"headerDomId()\">\n <ng-content select=\"[rtExpansionPanelBody]\" />\n\n @if (lazyContent(); as content) {\n <ng-container [ngTemplateOutlet]=\"content.templateRef\" />\n }\n </div>\n }\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-expansion-panel.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/expansion-panel/rt-expansion-panel-content.directive.ts","../../../projects/ui-kit-v2/src/lib/components/expansion-panel/rt-expansion-panel.component.ts","../../../projects/ui-kit-v2/src/lib/components/expansion-panel/rt-expansion-panel.component.html","../../../projects/ui-kit-v2/src/lib/components/expansion-panel/rt-tools-ui-kit-v2-expansion-panel.ts"],"sourcesContent":["import { Directive, inject, TemplateRef } from '@angular/core';\n\n/**\n * Тело `rt-expansion-panel`, собираемое лениво: ставится на `<ng-template>` внутри панели, и его\n * содержимое создаётся при раскрытии и уходит после сворачивания. Сворачивание при этом доигрывает\n * движение до конца: тело уходит вместе со своим содержимым, а не пустым.\n */\n@Directive({\n selector: 'ng-template[rtExpansionPanelContent]',\n})\nexport class RtExpansionPanelContentDirective {\n public readonly templateRef: TemplateRef<unknown> = inject<TemplateRef<unknown>>(TemplateRef);\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n input,\n InputSignal,\n InputSignalWithTransform,\n model,\n ModelSignal,\n Signal,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtExpansionPanelContentDirective } from './rt-expansion-panel-content.directive';\nimport { IRtExpansionPanel } from './rt-expansion-panel.model';\n\nconst BEM_BLOCK: string = 'rt-expansion-panel';\n\nlet expansionPanelIdSeed: number = 0;\n\nfunction nextExpansionPanelId(): number {\n expansionPanelIdSeed += 1;\n return expansionPanelIdSeed;\n}\n\n/**\n * Раскрывающаяся панель: заголовок-кнопка во всю ширину с шевроном у правого края и тело под ним.\n * Нажатие на заголовок раскрывает и сворачивает тело, раскрытие и сворачивание идут с движением.\n * Заменяет во втором ките панель раскрытия Material первого кита.\n *\n * Заголовок — содержимое панели без отметки. Тело — узел с `rtExpansionPanelBody`, созданный сразу,\n * или `<ng-template rtExpansionPanelContent>`, созданный при раскрытии.\n *\n * Состояние раскрытия — `expanded`, двусторонняя привязка: панель пишет в него сама, а владелец\n * может держать его в своём сигнале и менять извне.\n */\n@Component({\n selector: 'rt-expansion-panel',\n templateUrl: './rt-expansion-panel.component.html',\n styleUrl: './rt-expansion-panel.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n NgTemplateOutlet,\n\n // directives\n BlockDirective,\n ElemDirective,\n ModDirective,\n\n // components\n RtIconComponent,\n ],\n host: {\n class: BEM_BLOCK,\n '[class.rt-expansion-panel--plain]': 'appearance() === \"plain\"',\n '[class.rt-expansion-panel--expanded]': 'expanded()',\n '[class.rt-expansion-panel--disabled]': 'disabled()',\n },\n})\nexport class RtExpansionPanelComponent {\n /** Основа id: две панели на одной странице не ссылаются на чужое тело. */\n readonly #idBase: string = `rt-expansion-panel-${nextExpansionPanelId()}`;\n\n /** Ленивое тело: шаблон создаётся при раскрытии. */\n protected readonly lazyContent: Signal<RtExpansionPanelContentDirective | undefined> = contentChild(RtExpansionPanelContentDirective);\n protected readonly bodyId: string = `${this.#idBase}-body`;\n protected readonly headerDomId: Signal<string> = computed((): string => this.headerId() ?? `${this.#idBase}-header`);\n\n /** Тело раскрыто. Двусторонняя привязка: нажатие на заголовок пишет сюда. */\n public readonly expanded: ModelSignal<boolean> = model<boolean>(false);\n\n /** Заголовок не нажимается, тело остаётся как было. */\n public readonly disabled: InputSignalWithTransform<boolean, unknown> = input(false, { transform: booleanAttribute });\n\n /** Шеврона нет: раскрытие читается по содержимому или его нечего раскрывать. */\n public readonly hideToggle: InputSignalWithTransform<boolean, unknown> = input(false, { transform: booleanAttribute });\n\n public readonly appearance: InputSignal<IRtExpansionPanel.Appearance> = input<IRtExpansionPanel.Appearance>('card');\n\n /** Id кнопки заголовка. Нужен владельцу, который ищет заголовок по своему номеру; иначе — свой. */\n public readonly headerId: InputSignal<string | null> = input<string | null>(null);\n\n /** Имя кнопки заголовка для вспомогательных средств, когда видимой подписи мало. */\n public readonly ariaLabel: InputSignal<string | null> = input<string | null>(null);\n\n /** Нажатие на заголовок: раскрывает свёрнутую панель и сворачивает раскрытую. */\n public toggle(): void {\n if (!this.disabled()) {\n this.expanded.set(!this.expanded());\n }\n }\n}\n","<ng-container rtBlock=\"rt-expansion-panel\">\n <button\n type=\"button\"\n rtElem=\"header\"\n qa-dataid=\"expansion-panel-header\"\n [id]=\"headerDomId()\"\n [disabled]=\"disabled()\"\n [attr.aria-expanded]=\"expanded()\"\n [attr.aria-controls]=\"expanded() ? bodyId : null\"\n [attr.aria-label]=\"ariaLabel()\"\n (click)=\"toggle()\">\n <ng-content />\n\n @if (!hideToggle()) {\n <!-- Шеврон — в обёртке: ширину столбца держит она, значок свою ширину ставит сам. -->\n <span rtElem=\"chevron\" aria-hidden=\"true\" [rtMod]=\"{ open: expanded() }\"><rt-icon size=\"sm\" name=\"chevron-down\" /></span>\n }\n </button>\n\n @if (expanded()) {\n <!-- Сворачивание доигрывает движение: класс ухода сводит высоту к нулю, и тело уходит после. -->\n <div\n rtElem=\"body\"\n role=\"region\"\n qa-dataid=\"expansion-panel-body\"\n animate.leave=\"rt-expansion-panel__body--leaving\"\n [id]=\"bodyId\"\n [attr.aria-labelledby]=\"headerDomId()\">\n <ng-content select=\"[rtExpansionPanelBody]\" />\n\n @if (lazyContent(); as content) {\n <ng-container [ngTemplateOutlet]=\"content.templateRef\" />\n }\n </div>\n }\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -160,7 +160,7 @@ class RtFieldComponent {
160
160
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
161
161
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtFieldComponent, isStandalone: true, selector: "rt-field", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, help: { classPropertyName: "help", publicName: "help", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, hideRequiredMark: { classPropertyName: "hideRequiredMark", publicName: "hideRequiredMark", isSignal: true, isRequired: false, transformFunction: null }, reserveHintSpace: { classPropertyName: "reserveHintSpace", publicName: "reserveHintSpace", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "rt-field" }, queries: [{ propertyName: "projectedControl", first: true, predicate: RtFormControlBase, descendants: true, isSignal: true }, { propertyName: "projectedHint", first: true, predicate: RtFieldHintDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container rtBlock=\"rt-field\">\n @if (label()) {\n <span rtElem=\"label-row\">\n <label rtElem=\"label\" qa-dataid=\"field-label\" [attr.for]=\"controlId()\">\n {{ label() }}\n @if (isRequired() && !hideRequiredMark()) {\n <span rtElem=\"required\" qa-dataid=\"field-required\" aria-hidden=\"true\">*</span>\n }\n </label>\n @if (help()) {\n <button\n rtElem=\"help\"\n qa-dataid=\"field-help\"\n type=\"button\"\n rtPopoverTrigger=\"hover\"\n [attr.aria-label]=\"t().uiHint\"\n [rtPopover]=\"helpTpl\">\n <rt-icon name=\"ico-help\" size=\"sm\" color=\"muted\" />\n </button>\n <ng-template #helpTpl>\n <span rtElem=\"help-popover\" qa-dataid=\"field-help-popover\">{{ help() }}</span>\n </ng-template>\n }\n </span>\n }\n\n <rt-skeleton-wrapper rtElem=\"control\" height=\"var(--rt-input-height)\" [isLoading]=\"loading()\">\n <ng-content />\n </rt-skeleton-wrapper>\n\n <!-- \u0421 \u0440\u0435\u0437\u0435\u0440\u0432\u043E\u043C hint \u043E\u0441\u0442\u0430\u0451\u0442\u0441\u044F \u0432 \u043F\u043E\u0442\u043E\u043A\u0435 \u0434\u0430\u0436\u0435 \u043F\u043E\u0434 \u043E\u0448\u0438\u0431\u043A\u043E\u0439 (\u0441\u043A\u0440\u044B\u0442\u044B\u0439), \u0430 \u0441\u0430\u043C\u0430\n \u043E\u0448\u0438\u0431\u043A\u0430 \u043A\u043B\u0430\u0434\u0451\u0442\u0441\u044F \u0432 \u0442\u0443 \u0436\u0435 \u044F\u0447\u0435\u0439\u043A\u0443 \u0433\u0440\u0438\u0434\u0430: \u0432\u044B\u0441\u043E\u0442\u0430 \u0437\u043E\u043D\u044B \u0440\u0430\u0432\u043D\u0430 \u0431\u043E\u043B\u044C\u0448\u0435\u043C\u0443 \u0438\u0437\n \u0434\u0432\u0443\u0445 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439 \u0438 \u043D\u0435 \u043C\u0435\u043D\u044F\u0435\u0442\u0441\u044F \u043F\u0440\u0438 \u0438\u0445 \u043F\u043E\u0434\u043C\u0435\u043D\u0435. \u0411\u0435\u0437 \u0440\u0435\u0437\u0435\u0440\u0432\u0430 \u2014 \u043A\u0430\u043A \u0431\u044B\u043B\u043E,\n \u043E\u0434\u043D\u043E \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u0437\u0430 \u0440\u0430\u0437, \u0447\u0442\u043E\u0431\u044B \u043F\u043B\u043E\u0442\u043D\u044B\u0435 \u0444\u043E\u0440\u043C\u044B \u043D\u0435 \u043D\u0430\u0431\u0438\u0440\u0430\u043B\u0438 \u043B\u0438\u0448\u043D\u0438\u0439 \u0432\u043E\u0437\u0434\u0443\u0445. -->\n <span rtElem=\"messages\" [rtMod]=\"{ reserved: reserveHintSpace() }\">\n @if (projectedHint() && (reserveHintSpace() || !showError())) {\n <small rtElem=\"hint\" qa-dataid=\"field-hint\" [rtMod]=\"{ hidden: showError() }\" [attr.aria-hidden]=\"showError() ? 'true' : null\">\n <ng-content select=\"[rtFieldHint]\" />\n </small>\n } @else if (hint() && (reserveHintSpace() || !showError())) {\n <small rtElem=\"hint\" qa-dataid=\"field-hint\" [rtMod]=\"{ hidden: showError() }\" [attr.aria-hidden]=\"showError() ? 'true' : null\">\n {{ hint() }}\n </small>\n }\n\n @if (showError()) {\n <small rtElem=\"error\" qa-dataid=\"field-error\">{{ errorText() }}</small>\n }\n </span>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-field{display:flex;flex-direction:column;gap:var(--rt-field-gap)}.rt-field__label-row{display:inline-flex;align-items:center;gap:var(--rt-field-label-help-gap)}.rt-field__label{color:var(--rt-field-label-color);font-size:var(--rt-field-label-font-size);font-weight:var(--rt-field-label-font-weight)}.rt-field__required{color:var(--rt-field-required-color)}.rt-field__control{color:var(--rt-field-value-color);font-size:var(--rt-field-value-font-size)}.rt-field__help{display:inline-flex;padding:0;border:none;margin:0;background:none;cursor:help}.rt-field__help-popover{display:block;max-width:240px;font-size:var(--rt-field-hint-font-size)}.rt-field__messages{display:grid}.rt-field__messages--reserved{font-size:var(--rt-field-error-font-size);min-block-size:1lh}.rt-field__messages--reserved>*{grid-area:1/1}.rt-field__hint{color:var(--rt-field-hint-color);font-size:var(--rt-field-hint-font-size)}.rt-field__hint--hidden{visibility:hidden}.rt-field__error{color:var(--rt-field-error-color);font-size:var(--rt-field-error-font-size)}}\n"], dependencies: [{ kind: "component", type:
162
162
  // standalone components / directives
163
- RtIconComponent, selector: "rt-icon", inputs: ["name", "glyph", "size", "color", "fill", "spin", "rotate"] }, { kind: "directive", type: RtPopoverDirective, selector: "[rtPopover]", inputs: ["rtPopover", "rtPopoverTrigger", "rtPopoverWidth", "rtPopoverAlign", "rtPopoverFitViewport", "rtPopoverContext", "rtPopoverPanelClass", "rtPopoverDisabled", "rtPopoverOffsetY", "rtPopoverOffsetX"], outputs: ["rtPopoverOpened", "rtPopoverClosed"], exportAs: ["rtPopover"] }, { kind: "component", type: RtSkeletonWrapperComponent, selector: "rt-skeleton-wrapper", inputs: ["width", "height", "shape", "size", "radius", "animation", "isLoading"] }, { kind: "directive", type: BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }, { kind: "directive", type: ModDirective, selector: "[rtMod]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
163
+ RtIconComponent, selector: "rt-icon", inputs: ["name", "glyph", "glyphStrategy", "size", "color", "fill", "spin", "rotate"] }, { kind: "directive", type: RtPopoverDirective, selector: "[rtPopover]", inputs: ["rtPopover", "rtPopoverTrigger", "rtPopoverWidth", "rtPopoverAlign", "rtPopoverFitViewport", "rtPopoverContext", "rtPopoverPanelClass", "rtPopoverDisabled", "rtPopoverOffsetY", "rtPopoverOffsetX"], outputs: ["rtPopoverOpened", "rtPopoverClosed"], exportAs: ["rtPopover"] }, { kind: "component", type: RtSkeletonWrapperComponent, selector: "rt-skeleton-wrapper", inputs: ["width", "height", "shape", "size", "radius", "animation", "isLoading"] }, { kind: "directive", type: BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }, { kind: "directive", type: ModDirective, selector: "[rtMod]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
164
164
  }
165
165
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtFieldComponent, decorators: [{
166
166
  type: Component,
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-field.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/field/rt-field-hint.directive.ts","../../../projects/ui-kit-v2/src/lib/components/field/rt-field.model.ts","../../../projects/ui-kit-v2/src/lib/components/field/rt-field.component.ts","../../../projects/ui-kit-v2/src/lib/components/field/rt-field.component.html","../../../projects/ui-kit-v2/src/lib/components/field/rt-tools-ui-kit-v2-field.ts"],"sourcesContent":["import { Directive } from '@angular/core';\n\n/**\n * Маркер проецируемого hint'а для rt-field. Нужен, когда подсказке требуется\n * разметка (`<strong>`, интерполяция значений), которую плоский string-input\n * `[hint]` передать не может. Если проецируемый hint присутствует — rt-field\n * рендерит его вместо строкового `[hint]` (тот остаётся fallback'ом).\n */\n@Directive({\n selector: '[rtFieldHint]',\n})\nexport class RtFieldHintDirective {}\n","import { TRtKitLabelKey } from '@rt-tools/ui-kit-v2/core';\n\n/** Контракт поля-обёртки common/ui. */\nexport namespace IRtField {\n /** Карта validatorKey → человекочитаемое сообщение. */\n export type ErrorMessages = Record<string, string>;\n}\n\n/**\n * Ключи сообщений об ошибках по имени валидатора (перекрываются input'ом\n * [errors] поштучно, уже готовым текстом).\n *\n * Здесь ключи, а не переводы: карта собирается при загрузке модуля, когда язык\n * страницы ещё неизвестен, и готовый текст остался бы на языке по умолчанию\n * даже под переведённой подписью поля. Переводит сам компонент поля.\n */\nexport const RT_FIELD_DEFAULT_ERROR_KEYS: Readonly<Record<string, TRtKitLabelKey>> = {\n required: 'fieldErrorRequired',\n email: 'fieldErrorEmail',\n minlength: 'fieldErrorMinLength',\n maxlength: 'fieldErrorMaxLength',\n min: 'fieldErrorMin',\n max: 'fieldErrorMax',\n pattern: 'fieldErrorPattern',\n};\n\n/** Текст-плейсхолдер read-only поля без значения. */\nexport const RT_FIELD_EMPTY_VALUE: string = '—';\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n computed,\n contentChild,\n effect,\n inject,\n input,\n AfterContentInit,\n ChangeDetectionStrategy,\n Component,\n InputSignal,\n InputSignalWithTransform,\n Signal,\n ViewEncapsulation,\n} from '@angular/core';\nimport { ValidationErrors } from '@angular/forms';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelKey, TRtKitLabelMap, rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { RtFormControlBase } from '@rt-tools/ui-kit-v2/form-control';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';\nimport { RtSkeletonWrapperComponent } from '@rt-tools/ui-kit-v2/skeleton-wrapper';\nimport { RtFieldHintDirective } from './rt-field-hint.directive';\nimport { RT_FIELD_DEFAULT_ERROR_KEYS, RT_FIELD_EMPTY_VALUE, IRtField } from './rt-field.model';\n\nconst BEM_BLOCK: string = 'rt-field';\n\n/** Счётчик для авто-id (связка label[for] ↔ controlId спроецированного контрола). */\nlet uidSeed: number = 0;\n\nfunction nextAutoId(): string {\n uidSeed += 1;\n return `rt-field-${uidSeed}`;\n}\n\n/**\n * Обёртка единой анатомии поля: label (+ опц. help-иконка с popover, + авто «*»\n * для required) сверху, спроецированный rt-контрол посередине, hint/error снизу.\n * `required` объявляет поле обязательным там, где валидатора на контроле нет (шаблонная форма).\n * `hideRequiredMark` глушит авто-«*» — для форм, где все поля обязательны и\n * маркер лишний (логин).\n * `reserveHintSpace` держит под контролом строку высотой в одно сообщение даже\n * когда ни ошибки, ни hint нет — чтобы появление ошибки не сдвигало форму вниз\n * (нужно для полей без постоянного hint, напр. логин).\n *\n * Читает контрол через contentChild(RtFormControlBase): авто-связывает label[for],\n * прокидывает read-only режим, показывает текст ошибки/required-маркер. На loading\n * оборачивает зону контрола в rt-skeleton-wrapper (label/hint остаются видимыми) —\n * нужно для route-aside, где поля рендерятся до прихода данных.\n */\n@Component({\n selector: 'rt-field',\n templateUrl: './rt-field.component.html',\n styleUrls: ['./rt-field.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtIconComponent,\n RtPopoverDirective,\n RtSkeletonWrapperComponent,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n host: { class: BEM_BLOCK },\n})\nexport class RtFieldComponent implements AfterContentInit {\n // contentChild нельзя объявлять на ES-private (#) поле — Angular это запрещает,\n // поэтому проекция контрола живёт в protected-поле.\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly projectedControl: Signal<RtFormControlBase<unknown> | undefined> = contentChild(RtFormControlBase);\n\n // Проецируемый hint (с разметкой) — если присутствует, рендерится вместо\n // строкового [hint].\n protected readonly projectedHint: Signal<RtFieldHintDirective | undefined> = contentChild(RtFieldHintDirective);\n\n readonly #autoId: string = nextAutoId();\n\n /** Итоговый id: явный controlId контрола важнее авто-id. */\n protected readonly controlId: Signal<string> = computed((): string => this.projectedControl()?.effectiveControlId() ?? this.#autoId);\n\n protected readonly isRequired: Signal<boolean> = computed((): boolean => this.projectedControl()?.required() ?? false);\n\n protected readonly showError: Signal<boolean> = computed((): boolean => !!this.projectedControl()?.invalid());\n\n /** Имя первого сработавшего валидатора: сообщений показываем по одному */\n readonly #failedValidator: Signal<string> = computed((): string => {\n const errs: ValidationErrors | null = this.projectedControl()?.errors() ?? null;\n return errs ? (Object.keys(errs)[0] ?? '') : '';\n });\n\n /**\n * Умолчание переводится по ключу.\n *\n * Ключ передаётся сигналом, а не строкой: так подпись пересчитывается и при\n * смене валидатора, и при смене языка — пользователь переключает его\n * на лету, и текст ошибки обязан переключиться вместе с формой.\n */\n readonly #defaultErrorText: Signal<string> = rtKitLabel(\n computed((): TRtKitLabelKey | '' => RT_FIELD_DEFAULT_ERROR_KEYS[this.#failedValidator()] ?? '')\n );\n\n /** Сообщение об ошибке: текст, переданный формой, важнее умолчания */\n protected readonly errorText: Signal<string> = computed((): string => {\n const validator: string = this.#failedValidator();\n if (!validator) {\n return '';\n }\n const own: string | undefined = this.errors()[validator];\n if (own) {\n return own;\n }\n return RT_FIELD_DEFAULT_ERROR_KEYS[validator] ? this.#defaultErrorText() : '';\n });\n\n protected readonly emptyValue: string = RT_FIELD_EMPTY_VALUE;\n\n public readonly label: InputSignal<string> = input<string>('');\n public readonly hint: InputSignal<string> = input<string>('');\n public readonly help: InputSignal<string> = input<string>('');\n public readonly readonly: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n public readonly loading: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n /**\n * Поле обязательно, хотя валидатора на контроле нет: шаблонная форма его не кладёт. Даёт «*» и\n * ошибку под тронутым пустым полем. Форму недействительной не делает — решение о записи\n * остаётся у формы.\n */\n public readonly required: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n public readonly hideRequiredMark: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n public readonly reserveHintSpace: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n public readonly errors: InputSignal<IRtField.ErrorMessages> = input<IRtField.ErrorMessages>({});\n\n constructor() {\n // Реактивно прокидываем read-only режим в спроецированный контрол.\n effect((): void => {\n this.projectedControl()?.setReadonly(this.readonly());\n });\n effect((): void => {\n this.projectedControl()?.setRequired(this.required());\n });\n }\n\n public ngAfterContentInit(): void {\n const ctrl: RtFormControlBase<unknown> | undefined = this.projectedControl();\n // Авто-id только если у контрола нет явного controlId — для label[for].\n if (ctrl && ctrl.effectiveControlId() === null) {\n ctrl.assignControlId(this.#autoId);\n }\n }\n}\n","<ng-container rtBlock=\"rt-field\">\n @if (label()) {\n <span rtElem=\"label-row\">\n <label rtElem=\"label\" qa-dataid=\"field-label\" [attr.for]=\"controlId()\">\n {{ label() }}\n @if (isRequired() && !hideRequiredMark()) {\n <span rtElem=\"required\" qa-dataid=\"field-required\" aria-hidden=\"true\">*</span>\n }\n </label>\n @if (help()) {\n <button\n rtElem=\"help\"\n qa-dataid=\"field-help\"\n type=\"button\"\n rtPopoverTrigger=\"hover\"\n [attr.aria-label]=\"t().uiHint\"\n [rtPopover]=\"helpTpl\">\n <rt-icon name=\"ico-help\" size=\"sm\" color=\"muted\" />\n </button>\n <ng-template #helpTpl>\n <span rtElem=\"help-popover\" qa-dataid=\"field-help-popover\">{{ help() }}</span>\n </ng-template>\n }\n </span>\n }\n\n <rt-skeleton-wrapper rtElem=\"control\" height=\"var(--rt-input-height)\" [isLoading]=\"loading()\">\n <ng-content />\n </rt-skeleton-wrapper>\n\n <!-- С резервом hint остаётся в потоке даже под ошибкой (скрытый), а сама\n ошибка кладётся в ту же ячейку грида: высота зоны равна большему из\n двух сообщений и не меняется при их подмене. Без резерва — как было,\n одно сообщение за раз, чтобы плотные формы не набирали лишний воздух. -->\n <span rtElem=\"messages\" [rtMod]=\"{ reserved: reserveHintSpace() }\">\n @if (projectedHint() && (reserveHintSpace() || !showError())) {\n <small rtElem=\"hint\" qa-dataid=\"field-hint\" [rtMod]=\"{ hidden: showError() }\" [attr.aria-hidden]=\"showError() ? 'true' : null\">\n <ng-content select=\"[rtFieldHint]\" />\n </small>\n } @else if (hint() && (reserveHintSpace() || !showError())) {\n <small rtElem=\"hint\" qa-dataid=\"field-hint\" [rtMod]=\"{ hidden: showError() }\" [attr.aria-hidden]=\"showError() ? 'true' : null\">\n {{ hint() }}\n </small>\n }\n\n @if (showError()) {\n <small rtElem=\"error\" qa-dataid=\"field-error\">{{ errorText() }}</small>\n }\n </span>\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-field.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/field/rt-field-hint.directive.ts","../../../projects/ui-kit-v2/src/lib/components/field/rt-field.model.ts","../../../projects/ui-kit-v2/src/lib/components/field/rt-field.component.ts","../../../projects/ui-kit-v2/src/lib/components/field/rt-field.component.html","../../../projects/ui-kit-v2/src/lib/components/field/rt-tools-ui-kit-v2-field.ts"],"sourcesContent":["import { Directive } from '@angular/core';\n\n/**\n * Маркер проецируемого hint'а для rt-field. Нужен, когда подсказке требуется\n * разметка (`<strong>`, интерполяция значений), которую плоский string-input\n * `[hint]` передать не может. Если проецируемый hint присутствует — rt-field\n * рендерит его вместо строкового `[hint]` (тот остаётся fallback'ом).\n */\n@Directive({\n selector: '[rtFieldHint]',\n})\nexport class RtFieldHintDirective {}\n","import { TRtKitLabelKey } from '@rt-tools/ui-kit-v2/core';\n\n/** Контракт поля-обёртки common/ui. */\nexport namespace IRtField {\n /** Карта validatorKey → человекочитаемое сообщение. */\n export type ErrorMessages = Record<string, string>;\n}\n\n/**\n * Ключи сообщений об ошибках по имени валидатора (перекрываются input'ом\n * [errors] поштучно, уже готовым текстом).\n *\n * Здесь ключи, а не переводы: карта собирается при загрузке модуля, когда язык\n * страницы ещё неизвестен, и готовый текст остался бы на языке по умолчанию\n * даже под переведённой подписью поля. Переводит сам компонент поля.\n */\nexport const RT_FIELD_DEFAULT_ERROR_KEYS: Readonly<Record<string, TRtKitLabelKey>> = {\n required: 'fieldErrorRequired',\n email: 'fieldErrorEmail',\n minlength: 'fieldErrorMinLength',\n maxlength: 'fieldErrorMaxLength',\n min: 'fieldErrorMin',\n max: 'fieldErrorMax',\n pattern: 'fieldErrorPattern',\n};\n\n/** Текст-плейсхолдер read-only поля без значения. */\nexport const RT_FIELD_EMPTY_VALUE: string = '—';\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n computed,\n contentChild,\n effect,\n inject,\n input,\n AfterContentInit,\n ChangeDetectionStrategy,\n Component,\n InputSignal,\n InputSignalWithTransform,\n Signal,\n ViewEncapsulation,\n} from '@angular/core';\nimport { ValidationErrors } from '@angular/forms';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelKey, TRtKitLabelMap, rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { RtFormControlBase } from '@rt-tools/ui-kit-v2/form-control';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';\nimport { RtSkeletonWrapperComponent } from '@rt-tools/ui-kit-v2/skeleton-wrapper';\nimport { RtFieldHintDirective } from './rt-field-hint.directive';\nimport { RT_FIELD_DEFAULT_ERROR_KEYS, RT_FIELD_EMPTY_VALUE, IRtField } from './rt-field.model';\n\nconst BEM_BLOCK: string = 'rt-field';\n\n/** Счётчик для авто-id (связка label[for] ↔ controlId спроецированного контрола). */\nlet uidSeed: number = 0;\n\nfunction nextAutoId(): string {\n uidSeed += 1;\n return `rt-field-${uidSeed}`;\n}\n\n/**\n * Обёртка единой анатомии поля: label (+ опц. help-иконка с popover, + авто «*»\n * для required) сверху, спроецированный rt-контрол посередине, hint/error снизу.\n * `required` объявляет поле обязательным там, где валидатора на контроле нет (шаблонная форма).\n * `hideRequiredMark` глушит авто-«*» — для форм, где все поля обязательны и\n * маркер лишний (логин).\n * `reserveHintSpace` держит под контролом строку высотой в одно сообщение даже\n * когда ни ошибки, ни hint нет — чтобы появление ошибки не сдвигало форму вниз\n * (нужно для полей без постоянного hint, напр. логин).\n *\n * Читает контрол через contentChild(RtFormControlBase): авто-связывает label[for],\n * прокидывает read-only режим, показывает текст ошибки/required-маркер. На loading\n * оборачивает зону контрола в rt-skeleton-wrapper (label/hint остаются видимыми) —\n * нужно для route-aside, где поля рендерятся до прихода данных.\n */\n@Component({\n selector: 'rt-field',\n templateUrl: './rt-field.component.html',\n styleUrls: ['./rt-field.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtIconComponent,\n RtPopoverDirective,\n RtSkeletonWrapperComponent,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n host: { class: BEM_BLOCK },\n})\nexport class RtFieldComponent implements AfterContentInit {\n // contentChild нельзя объявлять на ES-private (#) поле — Angular это запрещает,\n // поэтому проекция контрола живёт в protected-поле.\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly projectedControl: Signal<RtFormControlBase<unknown> | undefined> = contentChild(RtFormControlBase);\n\n // Проецируемый hint (с разметкой) — если присутствует, рендерится вместо\n // строкового [hint].\n protected readonly projectedHint: Signal<RtFieldHintDirective | undefined> = contentChild(RtFieldHintDirective);\n\n readonly #autoId: string = nextAutoId();\n\n /** Итоговый id: явный controlId контрола важнее авто-id. */\n protected readonly controlId: Signal<string> = computed((): string => this.projectedControl()?.effectiveControlId() ?? this.#autoId);\n\n protected readonly isRequired: Signal<boolean> = computed((): boolean => this.projectedControl()?.required() ?? false);\n\n protected readonly showError: Signal<boolean> = computed((): boolean => !!this.projectedControl()?.invalid());\n\n /** Имя первого сработавшего валидатора: сообщений показываем по одному */\n readonly #failedValidator: Signal<string> = computed((): string => {\n const errs: ValidationErrors | null = this.projectedControl()?.errors() ?? null;\n return errs ? (Object.keys(errs)[0] ?? '') : '';\n });\n\n /**\n * Умолчание переводится по ключу.\n *\n * Ключ передаётся сигналом, а не строкой: так подпись пересчитывается и при\n * смене валидатора, и при смене языка — пользователь переключает его\n * на лету, и текст ошибки обязан переключиться вместе с формой.\n */\n readonly #defaultErrorText: Signal<string> = rtKitLabel(\n computed((): TRtKitLabelKey | '' => RT_FIELD_DEFAULT_ERROR_KEYS[this.#failedValidator()] ?? '')\n );\n\n /** Сообщение об ошибке: текст, переданный формой, важнее умолчания */\n protected readonly errorText: Signal<string> = computed((): string => {\n const validator: string = this.#failedValidator();\n if (!validator) {\n return '';\n }\n const own: string | undefined = this.errors()[validator];\n if (own) {\n return own;\n }\n return RT_FIELD_DEFAULT_ERROR_KEYS[validator] ? this.#defaultErrorText() : '';\n });\n\n protected readonly emptyValue: string = RT_FIELD_EMPTY_VALUE;\n\n public readonly label: InputSignal<string> = input<string>('');\n public readonly hint: InputSignal<string> = input<string>('');\n public readonly help: InputSignal<string> = input<string>('');\n public readonly readonly: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n public readonly loading: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n /**\n * Поле обязательно, хотя валидатора на контроле нет: шаблонная форма его не кладёт. Даёт «*» и\n * ошибку под тронутым пустым полем. Форму недействительной не делает — решение о записи\n * остаётся у формы.\n */\n public readonly required: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n public readonly hideRequiredMark: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n public readonly reserveHintSpace: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n public readonly errors: InputSignal<IRtField.ErrorMessages> = input<IRtField.ErrorMessages>({});\n\n constructor() {\n // Реактивно прокидываем read-only режим в спроецированный контрол.\n effect((): void => {\n this.projectedControl()?.setReadonly(this.readonly());\n });\n effect((): void => {\n this.projectedControl()?.setRequired(this.required());\n });\n }\n\n public ngAfterContentInit(): void {\n const ctrl: RtFormControlBase<unknown> | undefined = this.projectedControl();\n // Авто-id только если у контрола нет явного controlId — для label[for].\n if (ctrl && ctrl.effectiveControlId() === null) {\n ctrl.assignControlId(this.#autoId);\n }\n }\n}\n","<ng-container rtBlock=\"rt-field\">\n @if (label()) {\n <span rtElem=\"label-row\">\n <label rtElem=\"label\" qa-dataid=\"field-label\" [attr.for]=\"controlId()\">\n {{ label() }}\n @if (isRequired() && !hideRequiredMark()) {\n <span rtElem=\"required\" qa-dataid=\"field-required\" aria-hidden=\"true\">*</span>\n }\n </label>\n @if (help()) {\n <button\n rtElem=\"help\"\n qa-dataid=\"field-help\"\n type=\"button\"\n rtPopoverTrigger=\"hover\"\n [attr.aria-label]=\"t().uiHint\"\n [rtPopover]=\"helpTpl\">\n <rt-icon name=\"ico-help\" size=\"sm\" color=\"muted\" />\n </button>\n <ng-template #helpTpl>\n <span rtElem=\"help-popover\" qa-dataid=\"field-help-popover\">{{ help() }}</span>\n </ng-template>\n }\n </span>\n }\n\n <rt-skeleton-wrapper rtElem=\"control\" height=\"var(--rt-input-height)\" [isLoading]=\"loading()\">\n <ng-content />\n </rt-skeleton-wrapper>\n\n <!-- С резервом hint остаётся в потоке даже под ошибкой (скрытый), а сама\n ошибка кладётся в ту же ячейку грида: высота зоны равна большему из\n двух сообщений и не меняется при их подмене. Без резерва — как было,\n одно сообщение за раз, чтобы плотные формы не набирали лишний воздух. -->\n <span rtElem=\"messages\" [rtMod]=\"{ reserved: reserveHintSpace() }\">\n @if (projectedHint() && (reserveHintSpace() || !showError())) {\n <small rtElem=\"hint\" qa-dataid=\"field-hint\" [rtMod]=\"{ hidden: showError() }\" [attr.aria-hidden]=\"showError() ? 'true' : null\">\n <ng-content select=\"[rtFieldHint]\" />\n </small>\n } @else if (hint() && (reserveHintSpace() || !showError())) {\n <small rtElem=\"hint\" qa-dataid=\"field-hint\" [rtMod]=\"{ hidden: showError() }\" [attr.aria-hidden]=\"showError() ? 'true' : null\">\n {{ hint() }}\n </small>\n }\n\n @if (showError()) {\n <small rtElem=\"error\" qa-dataid=\"field-error\">{{ errorText() }}</small>\n }\n </span>\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -188,7 +188,7 @@ class RtFileCardComponent {
188
188
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtFileCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
189
189
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtFileCardComponent, isStandalone: true, selector: "rt-file-card", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, sizeBytes: { classPropertyName: "sizeBytes", publicName: "sizeBytes", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, showDownload: { classPropertyName: "showDownload", publicName: "showDownload", isSignal: true, isRequired: false, transformFunction: null }, showRemove: { classPropertyName: "showRemove", publicName: "showRemove", isSignal: true, isRequired: false, transformFunction: null }, showRename: { classPropertyName: "showRename", publicName: "showRename", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { download: "download", removed: "removed", rename: "rename" }, host: { properties: { "class.rt-file-card--sm": "size() === 'sm'", "class.rt-file-card--md": "size() === 'md'", "class.rt-file-card--lg": "size() === 'lg'" }, classAttribute: "rt-file-card" }, hostDirectives: [{ directive: i1.RtRadiusDirective, inputs: ["radius", "radius"] }], ngImport: i0, template: "<ng-container rtBlock=\"rt-file-card\">\n <rt-icon rtElem=\"icon\" [size]=\"iconSize()\" [name]=\"iconName()\" />\n\n <span rtElem=\"text\">\n <span rtElem=\"title\" qa-dataid=\"file-card-title\" [rtTooltip]=\"title()\">{{ title() }}</span>\n <span rtElem=\"name\" qa-dataid=\"file-card-name\" [rtTooltip]=\"name()\">{{ name() | rtTruncateMiddle }}</span>\n </span>\n\n <span rtElem=\"meta\">\n @if (hasSize()) {\n <span rtElem=\"size\" qa-dataid=\"file-card-size\">{{ sizeLabel() }}</span>\n }\n\n @if (showDownload()) {\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"file-card-download\"\n icon=\"ico-download\"\n variant=\"ghost\"\n [ariaLabel]=\"t().uiDownload\"\n [tooltip]=\"t().uiDownload\"\n [size]=\"actionSize()\"\n [disabled]=\"disabled()\"\n (clicked)=\"onDownload()\" />\n }\n\n @if (showRename()) {\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"file-card-rename\"\n icon=\"ico-edit\"\n variant=\"ghost\"\n [ariaLabel]=\"t().uiRename\"\n [tooltip]=\"t().uiRename\"\n [size]=\"actionSize()\"\n [disabled]=\"disabled()\"\n (clicked)=\"onRename()\" />\n }\n\n @if (showRemove()) {\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"file-card-remove\"\n icon=\"ico-trash\"\n variant=\"ghost\"\n [ariaLabel]=\"t().uiRemove\"\n [tooltip]=\"t().uiRemove\"\n [size]=\"actionSize()\"\n [disabled]=\"disabled()\"\n (clicked)=\"onRemove()\" />\n }\n </span>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-file-card{--rt-file-card-radius: var(--rt-radius-lg);--rt-file-card-border-width: var(--rt-border-width-thin);--rt-file-card-badge-radius: var(--rt-radius-full);--rt-file-card-padding-block: var(--rt-space-sm);--rt-file-card-padding-inline: var(--rt-space-md);--rt-file-card-gap: var(--rt-space-sm);--rt-file-card-title-size: var(--rt-text-md);--rt-file-card-name-size: var(--rt-text-sm);--rt-file-card-badge-size: var(--rt-text-xs);display:flex;align-items:center;padding:var(--rt-file-card-padding-block) var(--rt-file-card-padding-inline);border:var(--rt-file-card-border-width) solid var(--rt-color-border-subtle);border-radius:var(--rt-file-card-radius);background-color:var(--rt-color-bg-surface);gap:var(--rt-file-card-gap);max-inline-size:100%;min-inline-size:0}.rt-file-card--sm{--rt-file-card-padding-block: var(--rt-space-xs);--rt-file-card-padding-inline: var(--rt-space-sm);--rt-file-card-gap: var(--rt-space-xs);--rt-file-card-title-size: var(--rt-text-xs);--rt-file-card-name-size: var(--rt-text-2xs);--rt-file-card-badge-size: var(--rt-text-2xs)}.rt-file-card--md{--rt-file-card-padding-block: var(--rt-space-sm);--rt-file-card-padding-inline: var(--rt-space-md);--rt-file-card-gap: var(--rt-space-sm);--rt-file-card-title-size: var(--rt-text-md);--rt-file-card-name-size: var(--rt-text-sm);--rt-file-card-badge-size: var(--rt-text-xs)}.rt-file-card--lg{--rt-file-card-padding-block: var(--rt-space-md);--rt-file-card-padding-inline: var(--rt-space-lg);--rt-file-card-gap: var(--rt-space-md);--rt-file-card-title-size: var(--rt-text-lg);--rt-file-card-name-size: var(--rt-text-md);--rt-file-card-badge-size: var(--rt-text-sm)}.rt-file-card__icon{flex-shrink:0}.rt-file-card__text{display:flex;min-width:0;flex:1 1 auto;flex-direction:column;gap:var(--rt-space-2xs)}.rt-file-card__title{overflow:hidden;color:var(--rt-color-text-primary);font-size:var(--rt-file-card-title-size);font-weight:var(--rt-font-weight-semibold);text-overflow:ellipsis;white-space:nowrap}.rt-file-card__name{overflow:hidden;color:var(--rt-color-text-muted);font-size:var(--rt-file-card-name-size);text-overflow:ellipsis;white-space:nowrap}.rt-file-card__meta{display:flex;flex-shrink:0;align-items:center;gap:var(--rt-space-xs)}.rt-file-card__size{padding:var(--rt-space-2xs) var(--rt-space-sm);border:var(--rt-file-card-border-width) solid var(--rt-color-border-subtle);border-radius:var(--rt-file-card-badge-radius);color:var(--rt-color-text-muted);font-size:var(--rt-file-card-badge-size);white-space:nowrap}.rt-file-card__action{flex-shrink:0}.rt-file-card[data-rt-radius=none]{--rt-file-card-radius: var(--rt-radius-none)}.rt-file-card[data-rt-radius=xs]{--rt-file-card-radius: var(--rt-radius-xs)}.rt-file-card[data-rt-radius=sm]{--rt-file-card-radius: var(--rt-radius-sm)}.rt-file-card[data-rt-radius=ms]{--rt-file-card-radius: var(--rt-radius-ms)}.rt-file-card[data-rt-radius=md]{--rt-file-card-radius: var(--rt-radius-md)}.rt-file-card[data-rt-radius=lg]{--rt-file-card-radius: var(--rt-radius-lg)}.rt-file-card[data-rt-radius=xl]{--rt-file-card-radius: var(--rt-radius-xl)}.rt-file-card[data-rt-radius=\"2xl\"]{--rt-file-card-radius: var(--rt-radius-2xl)}.rt-file-card[data-rt-radius=full]{--rt-file-card-radius: var(--rt-radius-full)}}\n"], dependencies: [{ kind: "component", type:
190
190
  // standalone components / directives
191
- RtIconComponent, selector: "rt-icon", inputs: ["name", "glyph", "size", "color", "fill", "spin", "rotate"] }, { kind: "component", type: RtIconButtonComponent, selector: "rt-icon-button", inputs: ["icon", "glyph", "ariaLabel", "variant", "iconColor", "iconFill", "size", "iconSize", "type", "tooltip", "tabIndex", "loading", "disabled", "active", "indicator"], outputs: ["clicked"] }, { kind: "directive", type: RtTooltipDirective, selector: "[rtTooltip]", inputs: ["rtTooltip", "rtTooltipPlacement", "rtTooltipWhenTruncated"], exportAs: ["rtTooltip"] }, { kind: "directive", type: BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }, { kind: "pipe", type:
191
+ RtIconComponent, selector: "rt-icon", inputs: ["name", "glyph", "glyphStrategy", "size", "color", "fill", "spin", "rotate"] }, { kind: "component", type: RtIconButtonComponent, selector: "rt-icon-button", inputs: ["icon", "glyph", "ariaLabel", "variant", "iconColor", "iconFill", "size", "iconSize", "type", "tooltip", "tabIndex", "loading", "disabled", "active", "indicator"], outputs: ["clicked"] }, { kind: "directive", type: RtTooltipDirective, selector: "[rtTooltip]", inputs: ["rtTooltip", "rtTooltipPlacement", "rtTooltipWhenTruncated"], exportAs: ["rtTooltip"] }, { kind: "directive", type: BlockDirective, selector: "[rtBlock]", inputs: ["rtMod"] }, { kind: "directive", type: ElemDirective, selector: "[rtElem]", inputs: ["rtMod"] }, { kind: "pipe", type:
192
192
  // pipes
193
193
  RtTruncateMiddlePipe, name: "rtTruncateMiddle" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
194
194
  }
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-file-card.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/file-card/file-card.helper.ts","../../../projects/ui-kit-v2/src/lib/components/file-card/rt-truncate-middle.pipe.ts","../../../projects/ui-kit-v2/src/lib/components/file-card/rt-file-card.component.ts","../../../projects/ui-kit-v2/src/lib/components/file-card/rt-file-card.component.html","../../../projects/ui-kit-v2/src/lib/components/file-card/rt-tools-ui-kit-v2-file-card.ts"],"sourcesContent":["import { IRtIcon } from '@rt-tools/ui-kit-v2/core';\n\n/** Иконка Word-семейства (несколько расширений делят один глиф). */\nconst ICON_WORD: IRtIcon.Name = 'attach-docx-doc';\n\n/** Иконка растровых изображений. */\nconst ICON_IMAGE: IRtIcon.Name = 'attach-jpg-png';\n\n/** Иконка презентаций. */\nconst ICON_PRESENTATION: IRtIcon.Name = 'attach-ppt-pptx';\n\n/** Иконка таблиц Excel-семейства. */\nconst ICON_SPREADSHEET: IRtIcon.Name = 'attach-xlsx-xls';\n\n/** Иконка архивов. */\nconst ICON_ARCHIVE: IRtIcon.Name = 'attach-zip-rar';\n\n/** Иконка web-форматов изображений/видео. */\nconst ICON_WEB_MEDIA: IRtIcon.Name = 'attach-webp';\n\n/**\n * Маппинг расширения файла → имя цветной иконки типа (`attach-*` в rt-icon-реестре).\n */\nconst FILE_TYPE_ICON: Readonly<Record<string, IRtIcon.Name>> = {\n doc: ICON_WORD,\n docx: ICON_WORD,\n odt: ICON_WORD,\n gif: ICON_IMAGE,\n jpg: ICON_IMAGE,\n jpeg: ICON_IMAGE,\n png: ICON_IMAGE,\n pdf: 'attach-pdf',\n ppt: ICON_PRESENTATION,\n pptx: ICON_PRESENTATION,\n txt: 'attach-txt',\n webp: ICON_WEB_MEDIA,\n webm: ICON_WEB_MEDIA,\n xls: ICON_SPREADSHEET,\n xlsx: ICON_SPREADSHEET,\n zip: ICON_ARCHIVE,\n rar: ICON_ARCHIVE,\n msg: 'attach-msg',\n eml: 'attach-eml',\n};\n\n/**\n * Возвращает имя иконки типа файла по его имени (берётся расширение после\n * последней точки). Неизвестное/отсутствующее расширение → нейтральный `attach-other`.\n */\nexport function getFileTypeIcon(fileName: string): IRtIcon.Name {\n const ext: string = fileName.split('.').pop()?.toLowerCase() ?? '';\n return FILE_TYPE_ICON[ext] ?? 'attach-other';\n}\n\n/**\n * Выводит читаемый заголовок из имени файла: отбрасывает расширение и заменяет\n * разделители `_`/`-` на пробелы (CamelCase намеренно НЕ разбивается — это давало\n * бы непредсказуемый результат на произвольных именах). Если после очистки строка\n * пустая (например имя было `.pdf`) — возвращается исходное имя.\n */\nexport function deriveFileTitle(fileName: string): string {\n const withoutExt: string = fileName.replace(/\\.[^./\\\\]+$/, '');\n const cleaned: string = withoutExt.replace(/[_-]+/g, ' ').replace(/\\s+/g, ' ').trim();\n return cleaned || fileName;\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n/** Многоточие, вставляемое в середину строки при усечении. */\nconst ELLIPSIS: string = '...';\n\n/** Длина строки по умолчанию, при которой включается усечение. */\nconst DEFAULT_MAX_LENGTH: number = 32;\n\n/**\n * Усекает длинное имя файла по середине, сохраняя расширение видимым:\n * `10588-1_EvaluationSearchReport.pdf` → `10588-1_EvaluationSearchRe...pdf`.\n *\n * Обычный CSS `text-overflow: ellipsis` режет хвост и теряет расширение —\n * поэтому усечение по середине делается здесь, а не в стилях. Усечение\n * посимвольное (не по ширине контейнера): предсказуемо и без измерений DOM.\n *\n * Pure-pipe: пересчитывается только при смене входа.\n */\n@Pipe({ name: 'rtTruncateMiddle' })\nexport class RtTruncateMiddlePipe implements PipeTransform {\n public transform(value: string | null | undefined, maxLength: number = DEFAULT_MAX_LENGTH): string {\n if (!value) {\n return '';\n }\n if (value.length <= maxLength) {\n return value;\n }\n\n const lastDot: number = value.lastIndexOf('.');\n const hasExt: boolean = lastDot > 0 && lastDot < value.length - 1;\n const ext: string = hasExt ? value.slice(lastDot + 1) : '';\n const base: string = hasExt ? value.slice(0, lastDot) : value;\n\n const headLength: number = maxLength - ext.length - ELLIPSIS.length;\n if (headLength <= 0) {\n // Расширение длиннее лимита — деградируем до простого усечения хвоста.\n return value.slice(0, Math.max(0, maxLength - ELLIPSIS.length)) + ELLIPSIS;\n }\n\n return base.slice(0, headLength) + ELLIPSIS + ext;\n }\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n ChangeDetectionStrategy,\n Component,\n InputSignal,\n InputSignalWithTransform,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { formatFileSize } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { IRtIconButton } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { deriveFileTitle, getFileTypeIcon } from './file-card.helper';\nimport { IRtFileCard } from './rt-file-card.model';\nimport { RtTruncateMiddlePipe } from './rt-truncate-middle.pipe';\n\nconst BEM_BLOCK: string = 'rt-file-card';\n\n/** Иконка типа файла крупнее прочего: по ней карточку находят взглядом. */\nconst ICON_SIZES: Readonly<Record<IRtFileCard.Size, IRtIcon.Size>> = {\n sm: 'sm',\n md: 'xl',\n lg: 'xl',\n};\n\n/** Кнопки действий: в компактной карточке они не должны задавать её высоту. */\nconst ACTION_SIZES: Readonly<Record<IRtFileCard.Size, IRtIconButton.Size>> = {\n sm: 'sm',\n md: 'sm',\n lg: 'md',\n};\n\n/**\n * Карточка загруженного файла: цветная иконка типа, заголовок (выведенный из имени),\n * усечённое по середине имя файла, бейдж размера и опциональные действия справа\n * (скачать / переименовать / удалить).\n *\n * Презентационный компонент: сам ничего не решает, только эмиттит события действий.\n * Кнопки включаются точечно через `showDownload`/`showRemove`/`showRename` — в режиме\n * загрузки обычно нужен только remove, при показе сохранённых файлов — download.\n *\n * `showRename` по умолчанию выключен и сейчас нигде не включается: бэкенд не\n * поддерживает переименование (`original_name` неизменяем после создания). Вход\n * оставлен, чтобы кнопку можно было включить без правки компонента, когда появится API.\n */\n@Component({\n selector: 'rt-file-card',\n templateUrl: './rt-file-card.component.html',\n styleUrls: ['./rt-file-card.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtIconComponent,\n RtIconButtonComponent,\n RtTooltipDirective,\n BlockDirective,\n ElemDirective,\n\n // pipes\n RtTruncateMiddlePipe,\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n '[class.rt-file-card--sm]': \"size() === 'sm'\",\n '[class.rt-file-card--md]': \"size() === 'md'\",\n '[class.rt-file-card--lg]': \"size() === 'lg'\",\n },\n})\nexport class RtFileCardComponent {\n /** Имя цветной иконки типа файла по расширению. */\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly iconName: Signal<IRtIcon.Name> = computed((): IRtIcon.Name => getFileTypeIcon(this.name()));\n\n /** Заголовок карточки, выведенный из имени файла (без расширения, разделители → пробелы). */\n protected readonly title: Signal<string> = computed((): string => deriveFileTitle(this.name()));\n\n /** Отформатированный размер; пустая строка → размер неизвестен. */\n protected readonly sizeLabel: Signal<string> = computed((): string => formatFileSize(this.sizeBytes()));\n\n /** Показывать ли бейдж размера. */\n protected readonly hasSize: Signal<boolean> = computed((): boolean => this.sizeLabel() !== '');\n\n /** Размер иконки типа файла — маппится от размера карточки. */\n protected readonly iconSize: Signal<IRtIcon.Size> = computed((): IRtIcon.Size => ICON_SIZES[this.size()]);\n\n /** Размер кнопок действий — маппится от размера карточки. */\n protected readonly actionSize: Signal<IRtIconButton.Size> = computed((): IRtIconButton.Size => ACTION_SIZES[this.size()]);\n\n /** Имя файла с расширением — обязательно. */\n public readonly name: InputSignal<string> = input.required<string>();\n\n /** Размер в байтах. `null` → бейдж размера скрыт. */\n public readonly sizeBytes: InputSignal<number | null> = input<number | null>(null);\n\n /** Плотность карточки: `sm` для тесных мест вроде композера, `lg` — для страниц. */\n public readonly size: InputSignal<IRtFileCard.Size> = input<IRtFileCard.Size>('md');\n\n /** Показывать кнопку скачивания. */\n public readonly showDownload: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Показывать кнопку удаления. */\n public readonly showRemove: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Показывать кнопку переименования (отключена до появления API на бэке). */\n public readonly showRename: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Блокирует кнопки действий (например, во время сабмита формы). */\n public readonly disabled: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Запрошено скачивание файла. */\n public readonly download: OutputEmitterRef<void> = output<void>();\n\n /** Запрошено удаление файла. */\n public readonly removed: OutputEmitterRef<void> = output<void>();\n\n /** Запрошено переименование файла. */\n public readonly rename: OutputEmitterRef<void> = output<void>();\n\n protected onDownload(): void {\n this.download.emit();\n }\n\n protected onRemove(): void {\n this.removed.emit();\n }\n\n protected onRename(): void {\n this.rename.emit();\n }\n}\n","<ng-container rtBlock=\"rt-file-card\">\n <rt-icon rtElem=\"icon\" [size]=\"iconSize()\" [name]=\"iconName()\" />\n\n <span rtElem=\"text\">\n <span rtElem=\"title\" qa-dataid=\"file-card-title\" [rtTooltip]=\"title()\">{{ title() }}</span>\n <span rtElem=\"name\" qa-dataid=\"file-card-name\" [rtTooltip]=\"name()\">{{ name() | rtTruncateMiddle }}</span>\n </span>\n\n <span rtElem=\"meta\">\n @if (hasSize()) {\n <span rtElem=\"size\" qa-dataid=\"file-card-size\">{{ sizeLabel() }}</span>\n }\n\n @if (showDownload()) {\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"file-card-download\"\n icon=\"ico-download\"\n variant=\"ghost\"\n [ariaLabel]=\"t().uiDownload\"\n [tooltip]=\"t().uiDownload\"\n [size]=\"actionSize()\"\n [disabled]=\"disabled()\"\n (clicked)=\"onDownload()\" />\n }\n\n @if (showRename()) {\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"file-card-rename\"\n icon=\"ico-edit\"\n variant=\"ghost\"\n [ariaLabel]=\"t().uiRename\"\n [tooltip]=\"t().uiRename\"\n [size]=\"actionSize()\"\n [disabled]=\"disabled()\"\n (clicked)=\"onRename()\" />\n }\n\n @if (showRemove()) {\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"file-card-remove\"\n icon=\"ico-trash\"\n variant=\"ghost\"\n [ariaLabel]=\"t().uiRemove\"\n [tooltip]=\"t().uiRemove\"\n [size]=\"actionSize()\"\n [disabled]=\"disabled()\"\n (clicked)=\"onRemove()\" />\n }\n </span>\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-file-card.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/file-card/file-card.helper.ts","../../../projects/ui-kit-v2/src/lib/components/file-card/rt-truncate-middle.pipe.ts","../../../projects/ui-kit-v2/src/lib/components/file-card/rt-file-card.component.ts","../../../projects/ui-kit-v2/src/lib/components/file-card/rt-file-card.component.html","../../../projects/ui-kit-v2/src/lib/components/file-card/rt-tools-ui-kit-v2-file-card.ts"],"sourcesContent":["import { IRtIcon } from '@rt-tools/ui-kit-v2/core';\n\n/** Иконка Word-семейства (несколько расширений делят один глиф). */\nconst ICON_WORD: IRtIcon.Name = 'attach-docx-doc';\n\n/** Иконка растровых изображений. */\nconst ICON_IMAGE: IRtIcon.Name = 'attach-jpg-png';\n\n/** Иконка презентаций. */\nconst ICON_PRESENTATION: IRtIcon.Name = 'attach-ppt-pptx';\n\n/** Иконка таблиц Excel-семейства. */\nconst ICON_SPREADSHEET: IRtIcon.Name = 'attach-xlsx-xls';\n\n/** Иконка архивов. */\nconst ICON_ARCHIVE: IRtIcon.Name = 'attach-zip-rar';\n\n/** Иконка web-форматов изображений/видео. */\nconst ICON_WEB_MEDIA: IRtIcon.Name = 'attach-webp';\n\n/**\n * Маппинг расширения файла → имя цветной иконки типа (`attach-*` в rt-icon-реестре).\n */\nconst FILE_TYPE_ICON: Readonly<Record<string, IRtIcon.Name>> = {\n doc: ICON_WORD,\n docx: ICON_WORD,\n odt: ICON_WORD,\n gif: ICON_IMAGE,\n jpg: ICON_IMAGE,\n jpeg: ICON_IMAGE,\n png: ICON_IMAGE,\n pdf: 'attach-pdf',\n ppt: ICON_PRESENTATION,\n pptx: ICON_PRESENTATION,\n txt: 'attach-txt',\n webp: ICON_WEB_MEDIA,\n webm: ICON_WEB_MEDIA,\n xls: ICON_SPREADSHEET,\n xlsx: ICON_SPREADSHEET,\n zip: ICON_ARCHIVE,\n rar: ICON_ARCHIVE,\n msg: 'attach-msg',\n eml: 'attach-eml',\n};\n\n/**\n * Возвращает имя иконки типа файла по его имени (берётся расширение после\n * последней точки). Неизвестное/отсутствующее расширение → нейтральный `attach-other`.\n */\nexport function getFileTypeIcon(fileName: string): IRtIcon.Name {\n const ext: string = fileName.split('.').pop()?.toLowerCase() ?? '';\n return FILE_TYPE_ICON[ext] ?? 'attach-other';\n}\n\n/**\n * Выводит читаемый заголовок из имени файла: отбрасывает расширение и заменяет\n * разделители `_`/`-` на пробелы (CamelCase намеренно НЕ разбивается — это давало\n * бы непредсказуемый результат на произвольных именах). Если после очистки строка\n * пустая (например имя было `.pdf`) — возвращается исходное имя.\n */\nexport function deriveFileTitle(fileName: string): string {\n const withoutExt: string = fileName.replace(/\\.[^./\\\\]+$/, '');\n const cleaned: string = withoutExt.replace(/[_-]+/g, ' ').replace(/\\s+/g, ' ').trim();\n return cleaned || fileName;\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n/** Многоточие, вставляемое в середину строки при усечении. */\nconst ELLIPSIS: string = '...';\n\n/** Длина строки по умолчанию, при которой включается усечение. */\nconst DEFAULT_MAX_LENGTH: number = 32;\n\n/**\n * Усекает длинное имя файла по середине, сохраняя расширение видимым:\n * `10588-1_EvaluationSearchReport.pdf` → `10588-1_EvaluationSearchRe...pdf`.\n *\n * Обычный CSS `text-overflow: ellipsis` режет хвост и теряет расширение —\n * поэтому усечение по середине делается здесь, а не в стилях. Усечение\n * посимвольное (не по ширине контейнера): предсказуемо и без измерений DOM.\n *\n * Pure-pipe: пересчитывается только при смене входа.\n */\n@Pipe({ name: 'rtTruncateMiddle' })\nexport class RtTruncateMiddlePipe implements PipeTransform {\n public transform(value: string | null | undefined, maxLength: number = DEFAULT_MAX_LENGTH): string {\n if (!value) {\n return '';\n }\n if (value.length <= maxLength) {\n return value;\n }\n\n const lastDot: number = value.lastIndexOf('.');\n const hasExt: boolean = lastDot > 0 && lastDot < value.length - 1;\n const ext: string = hasExt ? value.slice(lastDot + 1) : '';\n const base: string = hasExt ? value.slice(0, lastDot) : value;\n\n const headLength: number = maxLength - ext.length - ELLIPSIS.length;\n if (headLength <= 0) {\n // Расширение длиннее лимита — деградируем до простого усечения хвоста.\n return value.slice(0, Math.max(0, maxLength - ELLIPSIS.length)) + ELLIPSIS;\n }\n\n return base.slice(0, headLength) + ELLIPSIS + ext;\n }\n}\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n computed,\n inject,\n input,\n output,\n ChangeDetectionStrategy,\n Component,\n InputSignal,\n InputSignalWithTransform,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelMap } from '@rt-tools/ui-kit-v2/core';\nimport { formatFileSize } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtIconButtonComponent } from '@rt-tools/ui-kit-v2/icon-button';\nimport { IRtIconButton } from '@rt-tools/ui-kit-v2/icon-button';\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { deriveFileTitle, getFileTypeIcon } from './file-card.helper';\nimport { IRtFileCard } from './rt-file-card.model';\nimport { RtTruncateMiddlePipe } from './rt-truncate-middle.pipe';\n\nconst BEM_BLOCK: string = 'rt-file-card';\n\n/** Иконка типа файла крупнее прочего: по ней карточку находят взглядом. */\nconst ICON_SIZES: Readonly<Record<IRtFileCard.Size, IRtIcon.Size>> = {\n sm: 'sm',\n md: 'xl',\n lg: 'xl',\n};\n\n/** Кнопки действий: в компактной карточке они не должны задавать её высоту. */\nconst ACTION_SIZES: Readonly<Record<IRtFileCard.Size, IRtIconButton.Size>> = {\n sm: 'sm',\n md: 'sm',\n lg: 'md',\n};\n\n/**\n * Карточка загруженного файла: цветная иконка типа, заголовок (выведенный из имени),\n * усечённое по середине имя файла, бейдж размера и опциональные действия справа\n * (скачать / переименовать / удалить).\n *\n * Презентационный компонент: сам ничего не решает, только эмиттит события действий.\n * Кнопки включаются точечно через `showDownload`/`showRemove`/`showRename` — в режиме\n * загрузки обычно нужен только remove, при показе сохранённых файлов — download.\n *\n * `showRename` по умолчанию выключен и сейчас нигде не включается: бэкенд не\n * поддерживает переименование (`original_name` неизменяем после создания). Вход\n * оставлен, чтобы кнопку можно было включить без правки компонента, когда появится API.\n */\n@Component({\n selector: 'rt-file-card',\n templateUrl: './rt-file-card.component.html',\n styleUrls: ['./rt-file-card.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtIconComponent,\n RtIconButtonComponent,\n RtTooltipDirective,\n BlockDirective,\n ElemDirective,\n\n // pipes\n RtTruncateMiddlePipe,\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n '[class.rt-file-card--sm]': \"size() === 'sm'\",\n '[class.rt-file-card--md]': \"size() === 'md'\",\n '[class.rt-file-card--lg]': \"size() === 'lg'\",\n },\n})\nexport class RtFileCardComponent {\n /** Имя цветной иконки типа файла по расширению. */\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly iconName: Signal<IRtIcon.Name> = computed((): IRtIcon.Name => getFileTypeIcon(this.name()));\n\n /** Заголовок карточки, выведенный из имени файла (без расширения, разделители → пробелы). */\n protected readonly title: Signal<string> = computed((): string => deriveFileTitle(this.name()));\n\n /** Отформатированный размер; пустая строка → размер неизвестен. */\n protected readonly sizeLabel: Signal<string> = computed((): string => formatFileSize(this.sizeBytes()));\n\n /** Показывать ли бейдж размера. */\n protected readonly hasSize: Signal<boolean> = computed((): boolean => this.sizeLabel() !== '');\n\n /** Размер иконки типа файла — маппится от размера карточки. */\n protected readonly iconSize: Signal<IRtIcon.Size> = computed((): IRtIcon.Size => ICON_SIZES[this.size()]);\n\n /** Размер кнопок действий — маппится от размера карточки. */\n protected readonly actionSize: Signal<IRtIconButton.Size> = computed((): IRtIconButton.Size => ACTION_SIZES[this.size()]);\n\n /** Имя файла с расширением — обязательно. */\n public readonly name: InputSignal<string> = input.required<string>();\n\n /** Размер в байтах. `null` → бейдж размера скрыт. */\n public readonly sizeBytes: InputSignal<number | null> = input<number | null>(null);\n\n /** Плотность карточки: `sm` для тесных мест вроде композера, `lg` — для страниц. */\n public readonly size: InputSignal<IRtFileCard.Size> = input<IRtFileCard.Size>('md');\n\n /** Показывать кнопку скачивания. */\n public readonly showDownload: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Показывать кнопку удаления. */\n public readonly showRemove: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Показывать кнопку переименования (отключена до появления API на бэке). */\n public readonly showRename: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Блокирует кнопки действий (например, во время сабмита формы). */\n public readonly disabled: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Запрошено скачивание файла. */\n public readonly download: OutputEmitterRef<void> = output<void>();\n\n /** Запрошено удаление файла. */\n public readonly removed: OutputEmitterRef<void> = output<void>();\n\n /** Запрошено переименование файла. */\n public readonly rename: OutputEmitterRef<void> = output<void>();\n\n protected onDownload(): void {\n this.download.emit();\n }\n\n protected onRemove(): void {\n this.removed.emit();\n }\n\n protected onRename(): void {\n this.rename.emit();\n }\n}\n","<ng-container rtBlock=\"rt-file-card\">\n <rt-icon rtElem=\"icon\" [size]=\"iconSize()\" [name]=\"iconName()\" />\n\n <span rtElem=\"text\">\n <span rtElem=\"title\" qa-dataid=\"file-card-title\" [rtTooltip]=\"title()\">{{ title() }}</span>\n <span rtElem=\"name\" qa-dataid=\"file-card-name\" [rtTooltip]=\"name()\">{{ name() | rtTruncateMiddle }}</span>\n </span>\n\n <span rtElem=\"meta\">\n @if (hasSize()) {\n <span rtElem=\"size\" qa-dataid=\"file-card-size\">{{ sizeLabel() }}</span>\n }\n\n @if (showDownload()) {\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"file-card-download\"\n icon=\"ico-download\"\n variant=\"ghost\"\n [ariaLabel]=\"t().uiDownload\"\n [tooltip]=\"t().uiDownload\"\n [size]=\"actionSize()\"\n [disabled]=\"disabled()\"\n (clicked)=\"onDownload()\" />\n }\n\n @if (showRename()) {\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"file-card-rename\"\n icon=\"ico-edit\"\n variant=\"ghost\"\n [ariaLabel]=\"t().uiRename\"\n [tooltip]=\"t().uiRename\"\n [size]=\"actionSize()\"\n [disabled]=\"disabled()\"\n (clicked)=\"onRename()\" />\n }\n\n @if (showRemove()) {\n <rt-icon-button\n rtElem=\"action\"\n qa-dataid=\"file-card-remove\"\n icon=\"ico-trash\"\n variant=\"ghost\"\n [ariaLabel]=\"t().uiRemove\"\n [tooltip]=\"t().uiRemove\"\n [size]=\"actionSize()\"\n [disabled]=\"disabled()\"\n (clicked)=\"onRemove()\" />\n }\n </span>\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -131,7 +131,7 @@ class RtIconButtonComponent {
131
131
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtIconButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
132
132
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtIconButtonComponent, isStandalone: true, selector: "rt-icon-button", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, glyph: { classPropertyName: "glyph", publicName: "glyph", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: true, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, iconColor: { classPropertyName: "iconColor", publicName: "iconColor", isSignal: true, isRequired: false, transformFunction: null }, iconFill: { classPropertyName: "iconFill", publicName: "iconFill", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, iconSize: { classPropertyName: "iconSize", publicName: "iconSize", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, indicator: { classPropertyName: "indicator", publicName: "indicator", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, host: { classAttribute: "rt-icon-button" }, hostDirectives: [{ directive: i1.RtRadiusDirective, inputs: ["radius", "radius"] }], ngImport: i0, template: "<button\n rtBlock=\"rt-icon-button\"\n qa-dataid=\"icon-button-control\"\n rtRipple\n [rippleDisabled]=\"isDisabled() || loading()\"\n [rtTooltip]=\"tooltip()\"\n [rtMod]=\"bemMods()\"\n [type]=\"type()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-pressed]=\"active() ? 'true' : null\"\n [attr.tabindex]=\"tabIndex()\"\n (click)=\"onClick($event)\">\n @if (loading()) {\n <rt-icon rtElem=\"spinner\" name=\"spinner\" color=\"current\" [size]=\"resolvedIconSize()\" />\n } @else if (icon() || glyph()) {\n <rt-icon rtElem=\"icon\" [color]=\"iconColor()\" [name]=\"icon()\" [glyph]=\"glyph()\" [size]=\"resolvedIconSize()\" [fill]=\"iconFill()\" />\n } @else {\n <span rtElem=\"content\" qa-dataid=\"icon-button-content\"><ng-content /></span>\n }\n @if (indicator()) {\n <span rtElem=\"indicator\" aria-hidden=\"true\"></span>\n }\n</button>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{rt-icon-button{display:inline-flex;--rt-icon-button-color: var(--rt-color-text-primary)}rt-icon-button .rt-icon-button{--rt-icon-button-radius: var(--rt-radius-md);--rt-icon-button-indicator-radius: var(--rt-radius-full);--rt-icon-button-focus-shadow: var(--rt-shadow-focus-ring);--rt-icon-button-shadow: var(--rt-shadow-none);--rt-icon-button-shadow-hover: var(--rt-icon-button-shadow);--rt-icon-button-color-hover: var(--rt-icon-button-color);--rt-icon-button-transition-duration: var(--rt-duration-fast);--rt-icon-button-bg-variant: transparent;--rt-icon-button-size-step: var(--rt-control-height-md);position:relative;display:inline-flex;width:var(--rt-icon-button-size, var(--rt-icon-button-size-step));height:var(--rt-icon-button-size, var(--rt-icon-button-size-step));align-items:center;justify-content:center;padding:0;border:0;border-radius:var(--rt-icon-button-radius);background-color:var(--rt-icon-button-bg, var(--rt-icon-button-bg-variant));box-shadow:var(--rt-icon-button-shadow);color:var(--rt-icon-button-color);cursor:pointer;transition:background-color var(--rt-icon-button-transition-duration) ease,box-shadow var(--rt-icon-button-transition-duration) ease}rt-icon-button .rt-icon-button--2xs{--rt-icon-button-size-step: var(--rt-size-5)}rt-icon-button .rt-icon-button--xs{--rt-icon-button-size-step: 22px}rt-icon-button .rt-icon-button--sm{--rt-icon-button-size-step: var(--rt-control-height-sm)}rt-icon-button .rt-icon-button--md{--rt-icon-button-size-step: var(--rt-control-height-md)}rt-icon-button .rt-icon-button--lg{--rt-icon-button-size-step: var(--rt-control-height-lg)}rt-icon-button .rt-icon-button--xl{--rt-icon-button-size-step: var(--rt-control-height-xl)}rt-icon-button .rt-icon-button--2xl{--rt-icon-button-size-step: var(--rt-control-height-2xl)}rt-icon-button .rt-icon-button:hover:not(:disabled){box-shadow:var(--rt-icon-button-shadow-hover)}rt-icon-button .rt-icon-button--ghost:hover:not(:disabled){background-color:var(--rt-icon-button-bg-hover, var(--rt-icon-button-color-bg-hover));color:var(--rt-icon-button-color-hover)}rt-icon-button .rt-icon-button--ghost.rt-icon-button--active{background-color:var(--rt-icon-button-color-bg-hover)}rt-icon-button .rt-icon-button--primary{--rt-icon-button-bg-variant: var(--rt-color-action-primary);color:var(--rt-color-action-on-primary)}rt-icon-button .rt-icon-button--primary:hover:not(:disabled){background-color:var(--rt-icon-button-bg-hover, var(--rt-color-action-primary-hover))}rt-icon-button .rt-icon-button--secondary{--rt-icon-button-bg-variant: var(--rt-color-bg-surface-subtle);color:var(--rt-color-text-primary)}rt-icon-button .rt-icon-button--secondary:hover:not(:disabled){background-color:var(--rt-icon-button-bg-hover, var(--rt-icon-button-color-bg-hover))}rt-icon-button .rt-icon-button--danger{color:var(--rt-color-state-danger)}rt-icon-button .rt-icon-button--danger:hover:not(:disabled){background-color:var(--rt-icon-button-bg-hover, var(--rt-icon-button-color-bg-hover))}rt-icon-button .rt-icon-button--danger.rt-icon-button--active{background-color:var(--rt-icon-button-color-bg-hover)}rt-icon-button .rt-icon-button--success{color:var(--rt-color-state-success)}rt-icon-button .rt-icon-button--success:hover:not(:disabled){background-color:var(--rt-icon-button-bg-hover, var(--rt-icon-button-color-bg-hover))}rt-icon-button .rt-icon-button--success.rt-icon-button--active{background-color:var(--rt-icon-button-color-bg-hover)}rt-icon-button .rt-icon-button--warning{color:var(--rt-color-state-warning)}rt-icon-button .rt-icon-button--warning:hover:not(:disabled){background-color:var(--rt-icon-button-bg-hover, var(--rt-icon-button-color-bg-hover))}rt-icon-button .rt-icon-button--warning.rt-icon-button--active{background-color:var(--rt-icon-button-color-bg-hover)}rt-icon-button .rt-icon-button:disabled{background-color:color-mix(in srgb,var(--rt-icon-button-bg, var(--rt-icon-button-bg-variant)) var(--rt-icon-button-disabled-fill),transparent);cursor:not-allowed;opacity:var(--rt-icon-button-disabled-opacity)}rt-icon-button .rt-icon-button:disabled .rt-icon svg{color:var(--rt-icon-button-disabled-color)}rt-icon-button .rt-icon-button:focus-visible{box-shadow:var(--rt-icon-button-focus-shadow);outline:2px solid transparent;outline-offset:2px}rt-icon-button .rt-icon-button__content{display:inline-flex;align-items:center;justify-content:center;color:inherit;line-height:1}rt-icon-button .rt-icon-button__spinner{--rt-icon-button-spin-duration: 1s;animation:rt-icon-button-spin var(--rt-icon-button-spin-duration) linear infinite}rt-icon-button .rt-icon-button__indicator{position:absolute;width:8px;height:8px;border-radius:var(--rt-icon-button-indicator-radius);background:var(--rt-color-state-danger);inset-block-start:-2px;inset-inline-end:-2px;pointer-events:none}rt-icon-button[data-rt-radius=none]>.rt-icon-button{--rt-icon-button-radius: var(--rt-radius-none)}rt-icon-button[data-rt-radius=xs]>.rt-icon-button{--rt-icon-button-radius: var(--rt-radius-xs)}rt-icon-button[data-rt-radius=sm]>.rt-icon-button{--rt-icon-button-radius: var(--rt-radius-sm)}rt-icon-button[data-rt-radius=ms]>.rt-icon-button{--rt-icon-button-radius: var(--rt-radius-ms)}rt-icon-button[data-rt-radius=md]>.rt-icon-button{--rt-icon-button-radius: var(--rt-radius-md)}rt-icon-button[data-rt-radius=lg]>.rt-icon-button{--rt-icon-button-radius: var(--rt-radius-lg)}rt-icon-button[data-rt-radius=xl]>.rt-icon-button{--rt-icon-button-radius: var(--rt-radius-xl)}rt-icon-button[data-rt-radius=\"2xl\"]>.rt-icon-button{--rt-icon-button-radius: var(--rt-radius-2xl)}rt-icon-button[data-rt-radius=full]>.rt-icon-button{--rt-icon-button-radius: var(--rt-radius-full)}@keyframes rt-icon-button-spin{to{transform:rotate(360deg)}}}\n"], dependencies: [{ kind: "component", type:
133
133
  // standalone components / directives
134
- RtIconComponent, selector: "rt-icon", inputs: ["name", "glyph", "size", "color", "fill", "spin", "rotate"] }, { kind: "directive", type: RtRippleDirective, selector: "[rtRipple]", inputs: ["rippleDisabled"] }, { kind: "directive", type: RtTooltipDirective, selector: "[rtTooltip]", inputs: ["rtTooltip", "rtTooltipPlacement", "rtTooltipWhenTruncated"], exportAs: ["rtTooltip"] }, { 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 }); }
134
+ RtIconComponent, selector: "rt-icon", inputs: ["name", "glyph", "glyphStrategy", "size", "color", "fill", "spin", "rotate"] }, { kind: "directive", type: RtRippleDirective, selector: "[rtRipple]", inputs: ["rippleDisabled"] }, { kind: "directive", type: RtTooltipDirective, selector: "[rtTooltip]", inputs: ["rtTooltip", "rtTooltipPlacement", "rtTooltipWhenTruncated"], exportAs: ["rtTooltip"] }, { 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 }); }
135
135
  }
136
136
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtIconButtonComponent, decorators: [{
137
137
  type: Component,
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-icon-button.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/icon-button/rt-icon-button.component.ts","../../../projects/ui-kit-v2/src/lib/components/icon-button/rt-icon-button.component.html","../../../projects/ui-kit-v2/src/lib/components/icon-button/rt-icon-button.model.ts","../../../projects/ui-kit-v2/src/lib/components/icon-button/rt-tools-ui-kit-v2-icon-button.ts"],"sourcesContent":["import { BooleanInput, NumberInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n input,\n InputSignal,\n InputSignalWithTransform,\n numberAttribute,\n output,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { RtRippleDirective } from '@rt-tools/ui-kit-v2/ripple';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { IRtIconButton } from './rt-icon-button.model';\n\nconst BEM_BLOCK: string = 'rt-icon-button';\n\n/**\n * Универсальная icon-only кнопка кита.\n *\n * Рендерит свой собственный `<button type=\"...\">` внутри template (НЕ host-button).\n * Все цвета и размеры — через семантические `--rt-*` токены; геометрия квадрата\n * берётся из `--rt-icon-button-size`, а без него — из шага `size`. Свойство, заданное на теге\n * `<rt-icon-button>` или выше, доходит до кнопки; так же и `--rt-icon-button-bg`.\n *\n * Loading state — заменяет иконку на `<rt-icon name=\"spinner\">` и блокирует\n * клики (`button[disabled]`). Active state управляет `aria-pressed` (для toggle-кнопок).\n * Indicator — небольшой dot top-right через BEM-элемент `__indicator`.\n *\n * BEM-разметка — через `rtBlock=\"rt-icon-button\"` + `[rtMod]` объект; камелкейс\n * модификаторов автоматически конвертируется директивой в kebab-case\n * (`hasIndicator` → `rt-icon-button--has-indicator`).\n */\n@Component({\n selector: 'rt-icon-button',\n templateUrl: './rt-icon-button.component.html',\n styleUrls: ['./rt-icon-button.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtIconComponent,\n RtRippleDirective,\n RtTooltipDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtIconButtonComponent {\n /**\n * Размер дочерней `<rt-icon>`. По умолчанию маппится 1-к-1 от размера кнопки,\n * но потребитель может задать свой: у крупной кнопки-действия (плавающая\n * кнопка чата) иконка во весь диаметр выглядит тяжеловесно, а сама кнопка\n * должна остаться большой — в неё целятся пальцем.\n */\n protected readonly resolvedIconSize: Signal<IRtIcon.Size> = computed((): IRtIcon.Size => {\n const map: Readonly<Record<IRtIconButton.Size, IRtIcon.Size>> = {\n '2xs': 'sm',\n xs: 'sm',\n sm: 'sm',\n md: 'md',\n lg: 'lg',\n xl: 'xl',\n '2xl': '2xl',\n };\n return this.iconSize() ?? map[this.size()];\n });\n\n /** Кнопка отключена, если установлен disabled ИЛИ loading. */\n protected readonly isDisabled: Signal<boolean> = computed((): boolean => this.disabled() || this.loading());\n\n /**\n * BEM-модификаторы для `[rtMod]`. Собираем в .ts (а не в шаблоне), потому что\n * Angular template-parser не поддерживает computed property keys в inline-объектах.\n * camelCase ключи `hasIndicator` директива автоматически конвертирует в `has-indicator`.\n */\n protected readonly bemMods: Signal<Record<string, boolean>> = computed((): Record<string, boolean> => ({\n [this.variant()]: true,\n [this.size()]: true,\n loading: this.loading(),\n active: this.active(),\n hasIndicator: this.indicator(),\n }));\n\n /**\n * Имя иконки в наборе кита. Нужно оно или `glyph`; когда переданы оба, побеждает имя. Нет ни\n * того ни другого — значок кит не рисует, и кнопка показывает вложенное содержимое: свой\n * рисунок приложения встаёт в кнопку с её размером, формой и состояниями.\n */\n public readonly icon: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n\n /** Имя Material вместо имени кита — рисуется так же, как вход `glyph` у `rt-icon`. */\n public readonly glyph: InputSignal<string | null> = input<string | null>(null);\n\n /** Доступное имя для screen-reader'ов — обязательно (icon-only кнопка). */\n public readonly ariaLabel: InputSignal<string> = input.required<string>();\n\n /** Семантическая палитра. */\n public readonly variant: InputSignal<IRtIconButton.Variant> = input<IRtIconButton.Variant>('ghost');\n\n /**\n * Цвет самой иконки. Default `current` — иконка наследует цвет текста кнопки\n * (поведение по умолчанию). Явное значение нужно, когда иконка должна\n * отличаться от текста кнопки — например крестик-очистка внутри поля,\n * который должен совпадать по цвету с иконками-аффордансами самого поля.\n */\n public readonly iconColor: InputSignal<IRtIcon.Color> = input<IRtIcon.Color>('current');\n\n /**\n * Залитый рисунок значка вместо контурного — как `fill` у `rt-icon`. Рисует его материальный\n * набор; значок своего набора один и от признака не меняется.\n */\n public readonly iconFill: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Размер квадрата. */\n public readonly size: InputSignal<IRtIconButton.Size> = input<IRtIconButton.Size>('md');\n\n /** Размер иконки; пусто — берётся от размера кнопки. */\n public readonly iconSize: InputSignal<IRtIcon.Size | null> = input<IRtIcon.Size | null>(null);\n\n /** HTML-type для нативного `<button>`. */\n public readonly type: InputSignal<IRtIconButton.Type> = input<IRtIconButton.Type>('button');\n\n /**\n * Текст styled-tooltip'а (`rtTooltip`), показывается на hover/focus. Пустая\n * строка → tooltip выключен. Для icon-only кнопок обычно дублирует `ariaLabel`.\n */\n public readonly tooltip: InputSignal<string> = input<string>('');\n\n /**\n * Tabindex внутренней `<button>`. Default `0` (в обычном таб-порядке).\n * Значение `-1` исключает кнопку из таб-навигации, оставляя клик мышью —\n * нужно для вспомогательных аффордансов вроде крестика-очистки внутри поля.\n */\n public readonly tabIndex: InputSignalWithTransform<number, NumberInput> = input<number, NumberInput>(0, { transform: numberAttribute });\n\n /** Состояние загрузки: показывает spinner вместо иконки + disabled. */\n public readonly loading: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Нативное отключение кнопки. */\n public readonly disabled: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Toggle-состояние — превращается в `aria-pressed=\"true\"`. */\n public readonly active: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Бейдж-индикатор (dot top-right через BEM-модификатор). */\n public readonly indicator: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Эмиттит MouseEvent при клике (только когда не disabled и не loading). */\n public readonly clicked: OutputEmitterRef<MouseEvent> = output<MouseEvent>();\n\n protected onClick(event: MouseEvent): void {\n if (this.isDisabled()) {\n return;\n }\n this.clicked.emit(event);\n }\n}\n","<button\n rtBlock=\"rt-icon-button\"\n qa-dataid=\"icon-button-control\"\n rtRipple\n [rippleDisabled]=\"isDisabled() || loading()\"\n [rtTooltip]=\"tooltip()\"\n [rtMod]=\"bemMods()\"\n [type]=\"type()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-pressed]=\"active() ? 'true' : null\"\n [attr.tabindex]=\"tabIndex()\"\n (click)=\"onClick($event)\">\n @if (loading()) {\n <rt-icon rtElem=\"spinner\" name=\"spinner\" color=\"current\" [size]=\"resolvedIconSize()\" />\n } @else if (icon() || glyph()) {\n <rt-icon rtElem=\"icon\" [color]=\"iconColor()\" [name]=\"icon()\" [glyph]=\"glyph()\" [size]=\"resolvedIconSize()\" [fill]=\"iconFill()\" />\n } @else {\n <span rtElem=\"content\" qa-dataid=\"icon-button-content\"><ng-content /></span>\n }\n @if (indicator()) {\n <span rtElem=\"indicator\" aria-hidden=\"true\"></span>\n }\n</button>\n","/**\n * Модель `<rt-icon-button>`: один корневой неймспейс с префиксом `I`.\n * Внутри — литеральные union-типы для variant / size / type, чтобы:\n * - использовать как контракт `input()` сигналов компонента;\n * - переиспользовать в `argTypes` Storybook.\n */\n\nexport namespace IRtIconButton {\n /** Семантическая палитра кнопки. */\n export type Variant = 'primary' | 'secondary' | 'ghost' | 'danger' | 'success' | 'warning';\n\n /**\n * Размер квадрата кнопки. Шаги — в SCSS; `xs` — 22px и `2xs` — 20px, оба со значком 16px.\n * Свой размер задаёт `--rt-icon-button-size` на теге или выше.\n */\n export type Size = '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';\n\n /** HTML-тип нативного `<button>`. */\n export type Type = 'button' | 'submit';\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-icon-button.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/icon-button/rt-icon-button.component.ts","../../../projects/ui-kit-v2/src/lib/components/icon-button/rt-icon-button.component.html","../../../projects/ui-kit-v2/src/lib/components/icon-button/rt-icon-button.model.ts","../../../projects/ui-kit-v2/src/lib/components/icon-button/rt-tools-ui-kit-v2-icon-button.ts"],"sourcesContent":["import { BooleanInput, NumberInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n input,\n InputSignal,\n InputSignalWithTransform,\n numberAttribute,\n output,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n} from '@angular/core';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RtIconComponent } from '@rt-tools/ui-kit-v2/icon';\nimport { IRtIcon } from '@rt-tools/ui-kit-v2/core';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { RtRippleDirective } from '@rt-tools/ui-kit-v2/ripple';\nimport { RtTooltipDirective } from '@rt-tools/ui-kit-v2/tooltip';\nimport { IRtIconButton } from './rt-icon-button.model';\n\nconst BEM_BLOCK: string = 'rt-icon-button';\n\n/**\n * Универсальная icon-only кнопка кита.\n *\n * Рендерит свой собственный `<button type=\"...\">` внутри template (НЕ host-button).\n * Все цвета и размеры — через семантические `--rt-*` токены; геометрия квадрата\n * берётся из `--rt-icon-button-size`, а без него — из шага `size`. Свойство, заданное на теге\n * `<rt-icon-button>` или выше, доходит до кнопки; так же и `--rt-icon-button-bg`.\n *\n * Loading state — заменяет иконку на `<rt-icon name=\"spinner\">` и блокирует\n * клики (`button[disabled]`). Active state управляет `aria-pressed` (для toggle-кнопок).\n * Indicator — небольшой dot top-right через BEM-элемент `__indicator`.\n *\n * BEM-разметка — через `rtBlock=\"rt-icon-button\"` + `[rtMod]` объект; камелкейс\n * модификаторов автоматически конвертируется директивой в kebab-case\n * (`hasIndicator` → `rt-icon-button--has-indicator`).\n */\n@Component({\n selector: 'rt-icon-button',\n templateUrl: './rt-icon-button.component.html',\n styleUrls: ['./rt-icon-button.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // standalone components / directives\n RtIconComponent,\n RtRippleDirective,\n RtTooltipDirective,\n BlockDirective,\n ElemDirective,\n ModDirective,\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtIconButtonComponent {\n /**\n * Размер дочерней `<rt-icon>`. По умолчанию маппится 1-к-1 от размера кнопки,\n * но потребитель может задать свой: у крупной кнопки-действия (плавающая\n * кнопка чата) иконка во весь диаметр выглядит тяжеловесно, а сама кнопка\n * должна остаться большой — в неё целятся пальцем.\n */\n protected readonly resolvedIconSize: Signal<IRtIcon.Size> = computed((): IRtIcon.Size => {\n const map: Readonly<Record<IRtIconButton.Size, IRtIcon.Size>> = {\n '2xs': 'sm',\n xs: 'sm',\n sm: 'sm',\n md: 'md',\n lg: 'lg',\n xl: 'xl',\n '2xl': '2xl',\n };\n return this.iconSize() ?? map[this.size()];\n });\n\n /** Кнопка отключена, если установлен disabled ИЛИ loading. */\n protected readonly isDisabled: Signal<boolean> = computed((): boolean => this.disabled() || this.loading());\n\n /**\n * BEM-модификаторы для `[rtMod]`. Собираем в .ts (а не в шаблоне), потому что\n * Angular template-parser не поддерживает computed property keys в inline-объектах.\n * camelCase ключи `hasIndicator` директива автоматически конвертирует в `has-indicator`.\n */\n protected readonly bemMods: Signal<Record<string, boolean>> = computed((): Record<string, boolean> => ({\n [this.variant()]: true,\n [this.size()]: true,\n loading: this.loading(),\n active: this.active(),\n hasIndicator: this.indicator(),\n }));\n\n /**\n * Имя иконки в наборе кита. Нужно оно или `glyph`; когда переданы оба, побеждает имя. Нет ни\n * того ни другого — значок кит не рисует, и кнопка показывает вложенное содержимое: свой\n * рисунок приложения встаёт в кнопку с её размером, формой и состояниями.\n */\n public readonly icon: InputSignal<IRtIcon.Name | null> = input<IRtIcon.Name | null>(null);\n\n /** Имя Material вместо имени кита — рисуется так же, как вход `glyph` у `rt-icon`. */\n public readonly glyph: InputSignal<string | null> = input<string | null>(null);\n\n /** Доступное имя для screen-reader'ов — обязательно (icon-only кнопка). */\n public readonly ariaLabel: InputSignal<string> = input.required<string>();\n\n /** Семантическая палитра. */\n public readonly variant: InputSignal<IRtIconButton.Variant> = input<IRtIconButton.Variant>('ghost');\n\n /**\n * Цвет самой иконки. Default `current` — иконка наследует цвет текста кнопки\n * (поведение по умолчанию). Явное значение нужно, когда иконка должна\n * отличаться от текста кнопки — например крестик-очистка внутри поля,\n * который должен совпадать по цвету с иконками-аффордансами самого поля.\n */\n public readonly iconColor: InputSignal<IRtIcon.Color> = input<IRtIcon.Color>('current');\n\n /**\n * Залитый рисунок значка вместо контурного — как `fill` у `rt-icon`. Рисует его материальный\n * набор; значок своего набора один и от признака не меняется.\n */\n public readonly iconFill: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Размер квадрата. */\n public readonly size: InputSignal<IRtIconButton.Size> = input<IRtIconButton.Size>('md');\n\n /** Размер иконки; пусто — берётся от размера кнопки. */\n public readonly iconSize: InputSignal<IRtIcon.Size | null> = input<IRtIcon.Size | null>(null);\n\n /** HTML-type для нативного `<button>`. */\n public readonly type: InputSignal<IRtIconButton.Type> = input<IRtIconButton.Type>('button');\n\n /**\n * Текст styled-tooltip'а (`rtTooltip`), показывается на hover/focus. Пустая\n * строка → tooltip выключен. Для icon-only кнопок обычно дублирует `ariaLabel`.\n */\n public readonly tooltip: InputSignal<string> = input<string>('');\n\n /**\n * Tabindex внутренней `<button>`. Default `0` (в обычном таб-порядке).\n * Значение `-1` исключает кнопку из таб-навигации, оставляя клик мышью —\n * нужно для вспомогательных аффордансов вроде крестика-очистки внутри поля.\n */\n public readonly tabIndex: InputSignalWithTransform<number, NumberInput> = input<number, NumberInput>(0, { transform: numberAttribute });\n\n /** Состояние загрузки: показывает spinner вместо иконки + disabled. */\n public readonly loading: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Нативное отключение кнопки. */\n public readonly disabled: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Toggle-состояние — превращается в `aria-pressed=\"true\"`. */\n public readonly active: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Бейдж-индикатор (dot top-right через BEM-модификатор). */\n public readonly indicator: InputSignalWithTransform<boolean, BooleanInput> = input<boolean, BooleanInput>(false, {\n transform: booleanAttribute,\n });\n\n /** Эмиттит MouseEvent при клике (только когда не disabled и не loading). */\n public readonly clicked: OutputEmitterRef<MouseEvent> = output<MouseEvent>();\n\n protected onClick(event: MouseEvent): void {\n if (this.isDisabled()) {\n return;\n }\n this.clicked.emit(event);\n }\n}\n","<button\n rtBlock=\"rt-icon-button\"\n qa-dataid=\"icon-button-control\"\n rtRipple\n [rippleDisabled]=\"isDisabled() || loading()\"\n [rtTooltip]=\"tooltip()\"\n [rtMod]=\"bemMods()\"\n [type]=\"type()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-pressed]=\"active() ? 'true' : null\"\n [attr.tabindex]=\"tabIndex()\"\n (click)=\"onClick($event)\">\n @if (loading()) {\n <rt-icon rtElem=\"spinner\" name=\"spinner\" color=\"current\" [size]=\"resolvedIconSize()\" />\n } @else if (icon() || glyph()) {\n <rt-icon rtElem=\"icon\" [color]=\"iconColor()\" [name]=\"icon()\" [glyph]=\"glyph()\" [size]=\"resolvedIconSize()\" [fill]=\"iconFill()\" />\n } @else {\n <span rtElem=\"content\" qa-dataid=\"icon-button-content\"><ng-content /></span>\n }\n @if (indicator()) {\n <span rtElem=\"indicator\" aria-hidden=\"true\"></span>\n }\n</button>\n","/**\n * Модель `<rt-icon-button>`: один корневой неймспейс с префиксом `I`.\n * Внутри — литеральные union-типы для variant / size / type, чтобы:\n * - использовать как контракт `input()` сигналов компонента;\n * - переиспользовать в `argTypes` Storybook.\n */\n\nexport namespace IRtIconButton {\n /** Семантическая палитра кнопки. */\n export type Variant = 'primary' | 'secondary' | 'ghost' | 'danger' | 'success' | 'warning';\n\n /**\n * Размер квадрата кнопки. Шаги — в SCSS; `xs` — 22px и `2xs` — 20px, оба со значком 16px.\n * Свой размер задаёт `--rt-icon-button-size` на теге или выше.\n */\n export type Size = '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';\n\n /** HTML-тип нативного `<button>`. */\n export type Type = 'button' | 'submit';\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}