@rt-tools/ui-kit-v2 0.20.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/fesm2022/rt-tools-ui-kit-v2-core.mjs +44 -1
  2. package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -1
  3. package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs +2 -2
  4. package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs.map +1 -1
  5. package/fesm2022/rt-tools-ui-kit-v2-icon.mjs +14 -3
  6. package/fesm2022/rt-tools-ui-kit-v2-icon.mjs.map +1 -1
  7. package/fesm2022/rt-tools-ui-kit-v2-menu.mjs +6 -3
  8. package/fesm2022/rt-tools-ui-kit-v2-menu.mjs.map +1 -1
  9. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +108 -20
  10. package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
  11. package/fesm2022/rt-tools-ui-kit-v2-table.mjs +1 -1
  12. package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -1
  13. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +2 -2
  14. package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -1
  15. package/package.json +1 -1
  16. package/rt-tools-ui-kit-v2-0.22.0.tgz +0 -0
  17. package/src/assets/icons-material/history.fill.svg +5 -0
  18. package/src/assets/icons-material/history.svg +5 -0
  19. package/src/assets/icons-material/window-minimize.fill.svg +5 -0
  20. package/src/assets/icons-material/window-minimize.svg +5 -0
  21. package/src/lib/components/icon/CONTEXT.md +7 -0
  22. package/src/lib/components/markdown-text/CONTEXT.md +3 -0
  23. package/src/lib/components/menu/CONTEXT.md +7 -6
  24. package/src/lib/components/thread-list/CONTEXT.md +2 -1
  25. package/src/lib/components/thread-list/rt-thread-list.component.scss +4 -1
  26. package/src/rich-editor/lib/components/ai-chat/CONTEXT.md +19 -0
  27. package/src/rich-editor/lib/components/ai-chat/copy/rt-ai-chat-copy.component.scss +5 -0
  28. package/src/rich-editor/lib/components/ai-chat/rt-ai-chat.component.scss +8 -1
  29. package/types/rt-tools-ui-kit-v2-core.d.ts +13 -1
  30. package/types/rt-tools-ui-kit-v2-icon.d.ts +11 -2
  31. package/types/rt-tools-ui-kit-v2-menu.d.ts +4 -1
  32. package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +27 -6
  33. package/rt-tools-ui-kit-v2-0.20.0.tgz +0 -0
@@ -192,7 +192,7 @@ class RtThreadListComponent {
192
192
  this.loadMore.emit();
193
193
  }
194
194
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RtThreadListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
195
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtThreadListComponent, isStandalone: true, selector: "rt-thread-list", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, activeId: { classPropertyName: "activeId", publicName: "activeId", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, emptyPreviewIcons: { classPropertyName: "emptyPreviewIcons", publicName: "emptyPreviewIcons", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, fetching: { classPropertyName: "fetching", publicName: "fetching", isSignal: true, isRequired: false, transformFunction: null }, hasMore: { classPropertyName: "hasMore", publicName: "hasMore", isSignal: true, isRequired: false, transformFunction: null }, filtersActive: { classPropertyName: "filtersActive", publicName: "filtersActive", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectRow: "selectRow", openInNewTab: "openInNewTab", searchChange: "searchChange", loadMore: "loadMore" }, host: { classAttribute: "rt-thread-list" }, queries: [{ propertyName: "rowTemplate", first: true, predicate: (RtThreadListRowDirective), descendants: true, isSignal: true }, { propertyName: "rowActionsTemplate", first: true, predicate: (RtThreadListRowActionsDirective), descendants: true, isSignal: true }, { propertyName: "filtersTemplate", first: true, predicate: RtThreadListFiltersDirective, descendants: true, isSignal: true }, { propertyName: "searchTemplate", first: true, predicate: RtThreadListSearchDirective, descendants: true, isSignal: true }], hostDirectives: [{ directive: i1.RtRadiusDirective, inputs: ["radius", "radius"] }], ngImport: i0, template: "<ng-container rtBlock=\"rt-thread-list\">\n <header rtElem=\"head\">\n @if (searchTemplate()) {\n <div rtElem=\"search\" qa-dataid=\"thread-list-search\">\n <ng-container [ngTemplateOutlet]=\"searchTemplate()?.templateRef ?? null\" />\n </div>\n } @else {\n <rt-input\n rtElem=\"search\"\n qa-dataid=\"thread-list-search\"\n iconLeft=\"search\"\n [placeholder]=\"searchPlaceholderText()\"\n [formControl]=\"searchControl\" />\n }\n @if (filtersTemplate()) {\n <rt-icon-button\n rtElem=\"filter-trigger\"\n qa-dataid=\"thread-list-filter\"\n icon=\"filter\"\n variant=\"secondary\"\n rtPopoverAlign=\"end\"\n [ariaLabel]=\"t().uiFilters\"\n [indicator]=\"filtersActive()\"\n [rtPopover]=\"filtersPanel\" />\n }\n </header>\n\n <ng-template #rowButton let-row>\n <button\n rtElem=\"row\"\n qa-dataid=\"thread-list-row\"\n type=\"button\"\n [attr.data-id]=\"row.id\"\n [attr.data-unread]=\"row.hasUnread\"\n [attr.aria-current]=\"row.id === activeId() ? 'true' : null\"\n [rtMod]=\"{\n active: row.id === activeId(),\n unread: row.hasUnread,\n overdue: !!row.overdue,\n }\"\n (click)=\"onSelect(row.id, $event)\">\n <ng-container [ngTemplateOutlet]=\"rowTemplate()?.templateRef ?? null\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </button>\n </ng-template>\n\n <ng-template #filtersPanel>\n <div rtElem=\"filters-panel\" qa-dataid=\"thread-list-filters-panel\">\n <ng-container [ngTemplateOutlet]=\"filtersTemplate()?.templateRef ?? null\" />\n </div>\n </ng-template>\n\n <div rtElem=\"rows\" qa-dataid=\"thread-list-rows\">\n @if (loading() && !rows().length) {\n @for (i of skeletonRows; track i) {\n <div rtElem=\"row-skeleton\" qa-dataid=\"thread-list-row-skeleton\" aria-hidden=\"true\">\n <rt-skeleton width=\"60%\" height=\"14px\" />\n <rt-skeleton width=\"90%\" height=\"12px\" />\n </div>\n }\n } @else if (!rows().length) {\n <rt-empty-state rtElem=\"empty\" qa-dataid=\"thread-list-empty\" [description]=\"t().uiThreadListEmptyHint\" [title]=\"emptyTitle()\">\n <div rtEmptyIllustration rtElem=\"empty-preview\">\n @for (row of emptyPreviewRows(); track row.id) {\n <div rtElem=\"empty-card\" [rtMod]=\"{ offset: row.offset }\">\n <span rtElem=\"empty-avatar\">\n <rt-icon size=\"sm\" [name]=\"row.icon\" />\n </span>\n <span rtElem=\"empty-lines\">\n <span rtElem=\"empty-line\" [rtMod]=\"{ short: true }\"></span>\n <span rtElem=\"empty-line\"></span>\n </span>\n </div>\n }\n </div>\n </rt-empty-state>\n } @else {\n @for (row of rows(); track row.id) {\n @if (rowActionsTemplate(); as actions) {\n <div rtElem=\"row-wrap\" qa-dataid=\"thread-list-row-wrap\">\n <ng-container [ngTemplateOutlet]=\"rowButton\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n <div rtElem=\"row-actions\" qa-dataid=\"thread-list-row-actions\">\n <ng-container [ngTemplateOutlet]=\"actions.templateRef\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </div>\n </div>\n } @else {\n <ng-container [ngTemplateOutlet]=\"rowButton\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n }\n }\n @if (fetching()) {\n <div rtElem=\"row-loader\" qa-dataid=\"thread-list-row-loader\">\n <rt-skeleton width=\"90%\" height=\"12px\" />\n </div>\n }\n @if (hasMore()) {\n <div\n rtElem=\"load-anchor\"\n qa-dataid=\"thread-list-load-more\"\n aria-hidden=\"true\"\n rtInfiniteScroll\n [disabled]=\"fetching()\"\n (loadMore)=\"onLoadMore()\"></div>\n }\n }\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-thread-list{--rt-thread-list-border-width: var(--rt-border-width-thin);--rt-thread-list-card-radius: var(--rt-radius-lg);--rt-thread-list-tag-radius: var(--rt-radius-sm);--rt-thread-list-dot-radius: var(--rt-radius-full);--rt-thread-list-avatar-radius: var(--rt-radius-full);--rt-thread-list-line-radius: var(--rt-radius-full);display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0}.rt-thread-list__head{display:flex;flex:0 0 auto;align-items:center;block-size:56px;border-block-end:var(--rt-thread-list-border-width) solid var(--rt-color-border-strong);gap:var(--rt-space-2);padding-inline:var(--rt-space-4)}.rt-thread-list__search{flex:1 1 auto;max-inline-size:400px;min-inline-size:0}.rt-thread-list__filter-trigger{flex:0 0 auto}.rt-thread-list__filters-panel{display:flex;flex-direction:column;padding:var(--rt-space-4);gap:var(--rt-space-2);min-inline-size:220px}.rt-thread-list__rows{display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0;overflow-y:auto}.rt-thread-list__row{display:flex;align-items:center;justify-content:space-between;padding:var(--rt-space-2) var(--rt-space-4);border:none;background:none;border-inline-start:3px solid transparent;cursor:pointer;font-family:inherit;font-size:var(--rt-text-sm);gap:var(--rt-space-4);inline-size:100%;text-align:start}.rt-thread-list__row:hover{background:var(--rt-color-bg-subtle)}.rt-thread-list__row--active,.rt-thread-list__row--active:hover{background:var(--rt-color-state-info-bg);border-inline-start-color:var(--rt-color-action-primary)}.rt-thread-list__row--unread{position:relative;background:var(--rt-color-bg-subtle);border-inline-start-color:var(--rt-color-action-primary)}.rt-thread-list__row--unread .rt-thread-list__row-title{font-weight:var(--rt-font-weight-semibold)}.rt-thread-list__row--unread:before{position:absolute;border-radius:var(--rt-thread-list-dot-radius);background:var(--rt-color-action-primary);block-size:var(--rt-space-2);content:\"\";inline-size:var(--rt-space-2);inset-block-start:50%;inset-inline-start:var(--rt-space-2);transform:translateY(-50%)}.rt-thread-list__row--active,.rt-thread-list__row--active:hover{background:var(--rt-color-state-info-bg)}.rt-thread-list__row--overdue .rt-thread-list__row-time{color:var(--rt-color-state-error-text)}.rt-thread-list__row-wrap{position:relative}.rt-thread-list__row-wrap:hover .rt-thread-list__row-actions,.rt-thread-list__row-wrap:focus-within .rt-thread-list__row-actions{opacity:1;pointer-events:auto}.rt-thread-list__row-actions{position:absolute;display:flex;align-items:center;background:var(--rt-color-bg-subtle);gap:var(--rt-space-1);inset-block:0;inset-inline-end:0;opacity:0;padding-inline:var(--rt-space-2) var(--rt-space-4);pointer-events:none}.rt-thread-list__row--active+.rt-thread-list__row-actions{background:var(--rt-color-state-info-bg)}.rt-thread-list__row-body{display:flex;flex-direction:column;gap:var(--rt-space-0-5);min-inline-size:0}.rt-thread-list__row-title{overflow:hidden;color:var(--rt-color-text-primary);text-overflow:ellipsis;white-space:nowrap}.rt-thread-list__row-id{color:var(--rt-color-text-muted);font-size:var(--rt-text-sm)}.rt-thread-list__row:hover .rt-copy-cell__button,.rt-thread-list__row:focus-within .rt-copy-cell__button{opacity:1}.rt-thread-list__row-subtitle{overflow:hidden;color:var(--rt-color-text-muted);text-overflow:ellipsis;white-space:nowrap}.rt-thread-list__row-meta{display:flex;flex:0 0 auto;align-items:center;gap:var(--rt-space-2)}.rt-thread-list__row-time{color:var(--rt-color-text-muted);white-space:nowrap}.rt-thread-list__row-tag{padding:var(--rt-space-0-5) var(--rt-space-2);border-radius:var(--rt-thread-list-tag-radius);background:var(--rt-color-state-warning-bg);color:var(--rt-color-state-warning-text);font-size:var(--rt-text-xs);white-space:nowrap}.rt-thread-list__row-dot{display:inline-block;border-radius:var(--rt-thread-list-dot-radius);background:var(--rt-color-text-link);block-size:6px;inline-size:6px}.rt-thread-list__row-skeleton{display:flex;flex-direction:column;padding:var(--rt-space-2) var(--rt-space-4);gap:var(--rt-space-2)}.rt-thread-list__row-loader{display:flex;justify-content:center;padding:var(--rt-space-2) var(--rt-space-4)}.rt-thread-list__load-anchor{block-size:1px}.rt-thread-list__empty{padding:var(--rt-space-6) var(--rt-space-4)}.rt-thread-list__empty-preview{display:flex;flex-direction:column;gap:var(--rt-space-1)}.rt-thread-list__empty-card{display:flex;align-items:center;padding:var(--rt-space-2);border:var(--rt-thread-list-border-width) solid var(--rt-color-border-subtle);border-radius:var(--rt-thread-list-card-radius);background:var(--rt-color-bg-surface-subtle);gap:var(--rt-space-2)}.rt-thread-list__empty-card--offset{transform:translate(20px)}.rt-thread-list__empty-avatar{display:grid;flex:0 0 auto;border-radius:var(--rt-thread-list-avatar-radius);background:var(--rt-color-text-muted);block-size:24px;color:var(--rt-color-bg-surface);inline-size:24px;place-items:center}.rt-thread-list__empty-lines{display:flex;flex-direction:column;gap:var(--rt-space-2)}.rt-thread-list__empty-line{border-radius:var(--rt-thread-list-line-radius);background:var(--rt-color-border-strong);block-size:6px;inline-size:112px}.rt-thread-list__empty-line--short{inline-size:48px}.rt-thread-list[data-rt-radius=none]{--rt-thread-list-card-radius: var(--rt-radius-none)}.rt-thread-list[data-rt-radius=xs]{--rt-thread-list-card-radius: var(--rt-radius-xs)}.rt-thread-list[data-rt-radius=sm]{--rt-thread-list-card-radius: var(--rt-radius-sm)}.rt-thread-list[data-rt-radius=ms]{--rt-thread-list-card-radius: var(--rt-radius-ms)}.rt-thread-list[data-rt-radius=md]{--rt-thread-list-card-radius: var(--rt-radius-md)}.rt-thread-list[data-rt-radius=lg]{--rt-thread-list-card-radius: var(--rt-radius-lg)}.rt-thread-list[data-rt-radius=xl]{--rt-thread-list-card-radius: var(--rt-radius-xl)}.rt-thread-list[data-rt-radius=\"2xl\"]{--rt-thread-list-card-radius: var(--rt-radius-2xl)}.rt-thread-list[data-rt-radius=full]{--rt-thread-list-card-radius: var(--rt-radius-full)}}\n"], dependencies: [{ kind: "directive", type:
195
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RtThreadListComponent, isStandalone: true, selector: "rt-thread-list", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, activeId: { classPropertyName: "activeId", publicName: "activeId", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, emptyPreviewIcons: { classPropertyName: "emptyPreviewIcons", publicName: "emptyPreviewIcons", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, fetching: { classPropertyName: "fetching", publicName: "fetching", isSignal: true, isRequired: false, transformFunction: null }, hasMore: { classPropertyName: "hasMore", publicName: "hasMore", isSignal: true, isRequired: false, transformFunction: null }, filtersActive: { classPropertyName: "filtersActive", publicName: "filtersActive", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectRow: "selectRow", openInNewTab: "openInNewTab", searchChange: "searchChange", loadMore: "loadMore" }, host: { classAttribute: "rt-thread-list" }, queries: [{ propertyName: "rowTemplate", first: true, predicate: (RtThreadListRowDirective), descendants: true, isSignal: true }, { propertyName: "rowActionsTemplate", first: true, predicate: (RtThreadListRowActionsDirective), descendants: true, isSignal: true }, { propertyName: "filtersTemplate", first: true, predicate: RtThreadListFiltersDirective, descendants: true, isSignal: true }, { propertyName: "searchTemplate", first: true, predicate: RtThreadListSearchDirective, descendants: true, isSignal: true }], hostDirectives: [{ directive: i1.RtRadiusDirective, inputs: ["radius", "radius"] }], ngImport: i0, template: "<ng-container rtBlock=\"rt-thread-list\">\n <header rtElem=\"head\">\n @if (searchTemplate()) {\n <div rtElem=\"search\" qa-dataid=\"thread-list-search\">\n <ng-container [ngTemplateOutlet]=\"searchTemplate()?.templateRef ?? null\" />\n </div>\n } @else {\n <rt-input\n rtElem=\"search\"\n qa-dataid=\"thread-list-search\"\n iconLeft=\"search\"\n [placeholder]=\"searchPlaceholderText()\"\n [formControl]=\"searchControl\" />\n }\n @if (filtersTemplate()) {\n <rt-icon-button\n rtElem=\"filter-trigger\"\n qa-dataid=\"thread-list-filter\"\n icon=\"filter\"\n variant=\"secondary\"\n rtPopoverAlign=\"end\"\n [ariaLabel]=\"t().uiFilters\"\n [indicator]=\"filtersActive()\"\n [rtPopover]=\"filtersPanel\" />\n }\n </header>\n\n <ng-template #rowButton let-row>\n <button\n rtElem=\"row\"\n qa-dataid=\"thread-list-row\"\n type=\"button\"\n [attr.data-id]=\"row.id\"\n [attr.data-unread]=\"row.hasUnread\"\n [attr.aria-current]=\"row.id === activeId() ? 'true' : null\"\n [rtMod]=\"{\n active: row.id === activeId(),\n unread: row.hasUnread,\n overdue: !!row.overdue,\n }\"\n (click)=\"onSelect(row.id, $event)\">\n <ng-container [ngTemplateOutlet]=\"rowTemplate()?.templateRef ?? null\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </button>\n </ng-template>\n\n <ng-template #filtersPanel>\n <div rtElem=\"filters-panel\" qa-dataid=\"thread-list-filters-panel\">\n <ng-container [ngTemplateOutlet]=\"filtersTemplate()?.templateRef ?? null\" />\n </div>\n </ng-template>\n\n <div rtElem=\"rows\" qa-dataid=\"thread-list-rows\">\n @if (loading() && !rows().length) {\n @for (i of skeletonRows; track i) {\n <div rtElem=\"row-skeleton\" qa-dataid=\"thread-list-row-skeleton\" aria-hidden=\"true\">\n <rt-skeleton width=\"60%\" height=\"14px\" />\n <rt-skeleton width=\"90%\" height=\"12px\" />\n </div>\n }\n } @else if (!rows().length) {\n <rt-empty-state rtElem=\"empty\" qa-dataid=\"thread-list-empty\" [description]=\"t().uiThreadListEmptyHint\" [title]=\"emptyTitle()\">\n <div rtEmptyIllustration rtElem=\"empty-preview\">\n @for (row of emptyPreviewRows(); track row.id) {\n <div rtElem=\"empty-card\" [rtMod]=\"{ offset: row.offset }\">\n <span rtElem=\"empty-avatar\">\n <rt-icon size=\"sm\" [name]=\"row.icon\" />\n </span>\n <span rtElem=\"empty-lines\">\n <span rtElem=\"empty-line\" [rtMod]=\"{ short: true }\"></span>\n <span rtElem=\"empty-line\"></span>\n </span>\n </div>\n }\n </div>\n </rt-empty-state>\n } @else {\n @for (row of rows(); track row.id) {\n @if (rowActionsTemplate(); as actions) {\n <div rtElem=\"row-wrap\" qa-dataid=\"thread-list-row-wrap\">\n <ng-container [ngTemplateOutlet]=\"rowButton\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n <div rtElem=\"row-actions\" qa-dataid=\"thread-list-row-actions\">\n <ng-container [ngTemplateOutlet]=\"actions.templateRef\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </div>\n </div>\n } @else {\n <ng-container [ngTemplateOutlet]=\"rowButton\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n }\n }\n @if (fetching()) {\n <div rtElem=\"row-loader\" qa-dataid=\"thread-list-row-loader\">\n <rt-skeleton width=\"90%\" height=\"12px\" />\n </div>\n }\n @if (hasMore()) {\n <div\n rtElem=\"load-anchor\"\n qa-dataid=\"thread-list-load-more\"\n aria-hidden=\"true\"\n rtInfiniteScroll\n [disabled]=\"fetching()\"\n (loadMore)=\"onLoadMore()\"></div>\n }\n }\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-thread-list{--rt-thread-list-border-width: var(--rt-border-width-thin);--rt-thread-list-card-radius: var(--rt-radius-lg);--rt-thread-list-tag-radius: var(--rt-radius-sm);--rt-thread-list-dot-radius: var(--rt-radius-full);--rt-thread-list-avatar-radius: var(--rt-radius-full);--rt-thread-list-line-radius: var(--rt-radius-full);display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0}.rt-thread-list__head{display:flex;flex:0 0 auto;align-items:center;block-size:56px;border-block-end:var(--rt-thread-list-border-width) solid var(--rt-color-border-strong);gap:var(--rt-space-2);padding-inline:var(--rt-space-4)}.rt-thread-list__search{flex:1 1 auto;max-inline-size:400px;min-inline-size:0}.rt-thread-list__filter-trigger{flex:0 0 auto}.rt-thread-list__filters-panel{display:flex;flex-direction:column;padding:var(--rt-space-4);gap:var(--rt-space-2);min-inline-size:220px}.rt-thread-list__rows{display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0;overflow-y:auto}.rt-thread-list__row{display:flex;align-items:center;justify-content:space-between;padding:var(--rt-space-2) var(--rt-space-4);border:none;background:none;border-inline-start:3px solid transparent;cursor:pointer;font-family:inherit;font-size:var(--rt-text-sm);gap:var(--rt-space-4);inline-size:100%;text-align:start}.rt-thread-list__row:hover{background:var(--rt-color-bg-subtle)}.rt-thread-list__row--active,.rt-thread-list__row--active:hover{background:var(--rt-color-state-info-bg);border-inline-start-color:var(--rt-color-action-primary)}.rt-thread-list__row--unread{position:relative;background:var(--rt-color-bg-subtle);border-inline-start-color:var(--rt-color-action-primary)}.rt-thread-list__row--unread .rt-thread-list__row-title{font-weight:var(--rt-font-weight-semibold)}.rt-thread-list__row--unread:before{position:absolute;border-radius:var(--rt-thread-list-dot-radius);background:var(--rt-color-action-primary);block-size:var(--rt-space-2);content:\"\";inline-size:var(--rt-space-2);inset-block-start:50%;inset-inline-start:var(--rt-space-2);transform:translateY(-50%)}.rt-thread-list__row--active,.rt-thread-list__row--active:hover{background:var(--rt-color-state-info-bg)}.rt-thread-list__row--overdue .rt-thread-list__row-time{color:var(--rt-color-state-error-text)}.rt-thread-list__row-wrap{position:relative}.rt-thread-list__row-wrap:hover .rt-thread-list__row-actions,.rt-thread-list__row-wrap:focus-within .rt-thread-list__row-actions,.rt-thread-list__row-wrap:has(.rt-menu--open) .rt-thread-list__row-actions{opacity:1;pointer-events:auto}.rt-thread-list__row-actions{position:absolute;display:flex;align-items:center;background:var(--rt-color-bg-subtle);gap:var(--rt-space-1);inset-block:0;inset-inline-end:0;opacity:0;padding-inline:var(--rt-space-2) var(--rt-space-4);pointer-events:none}.rt-thread-list__row--active+.rt-thread-list__row-actions{background:var(--rt-color-state-info-bg)}.rt-thread-list__row-body{display:flex;flex-direction:column;gap:var(--rt-space-0-5);min-inline-size:0}.rt-thread-list__row-title{overflow:hidden;color:var(--rt-color-text-primary);text-overflow:ellipsis;white-space:nowrap}.rt-thread-list__row-id{color:var(--rt-color-text-muted);font-size:var(--rt-text-sm)}.rt-thread-list__row:hover .rt-copy-cell__button,.rt-thread-list__row:focus-within .rt-copy-cell__button{opacity:1}.rt-thread-list__row-subtitle{overflow:hidden;color:var(--rt-color-text-muted);text-overflow:ellipsis;white-space:nowrap}.rt-thread-list__row-meta{display:flex;flex:0 0 auto;align-items:center;gap:var(--rt-space-2)}.rt-thread-list__row-time{color:var(--rt-color-text-muted);white-space:nowrap}.rt-thread-list__row-tag{padding:var(--rt-space-0-5) var(--rt-space-2);border-radius:var(--rt-thread-list-tag-radius);background:var(--rt-color-state-warning-bg);color:var(--rt-color-state-warning-text);font-size:var(--rt-text-xs);white-space:nowrap}.rt-thread-list__row-dot{display:inline-block;border-radius:var(--rt-thread-list-dot-radius);background:var(--rt-color-text-link);block-size:6px;inline-size:6px}.rt-thread-list__row-skeleton{display:flex;flex-direction:column;padding:var(--rt-space-2) var(--rt-space-4);gap:var(--rt-space-2)}.rt-thread-list__row-loader{display:flex;justify-content:center;padding:var(--rt-space-2) var(--rt-space-4)}.rt-thread-list__load-anchor{block-size:1px}.rt-thread-list__empty{padding:var(--rt-space-6) var(--rt-space-4)}.rt-thread-list__empty-preview{display:flex;flex-direction:column;gap:var(--rt-space-1)}.rt-thread-list__empty-card{display:flex;align-items:center;padding:var(--rt-space-2);border:var(--rt-thread-list-border-width) solid var(--rt-color-border-subtle);border-radius:var(--rt-thread-list-card-radius);background:var(--rt-color-bg-surface-subtle);gap:var(--rt-space-2)}.rt-thread-list__empty-card--offset{transform:translate(20px)}.rt-thread-list__empty-avatar{display:grid;flex:0 0 auto;border-radius:var(--rt-thread-list-avatar-radius);background:var(--rt-color-text-muted);block-size:24px;color:var(--rt-color-bg-surface);inline-size:24px;place-items:center}.rt-thread-list__empty-lines{display:flex;flex-direction:column;gap:var(--rt-space-2)}.rt-thread-list__empty-line{border-radius:var(--rt-thread-list-line-radius);background:var(--rt-color-border-strong);block-size:6px;inline-size:112px}.rt-thread-list__empty-line--short{inline-size:48px}.rt-thread-list[data-rt-radius=none]{--rt-thread-list-card-radius: var(--rt-radius-none)}.rt-thread-list[data-rt-radius=xs]{--rt-thread-list-card-radius: var(--rt-radius-xs)}.rt-thread-list[data-rt-radius=sm]{--rt-thread-list-card-radius: var(--rt-radius-sm)}.rt-thread-list[data-rt-radius=ms]{--rt-thread-list-card-radius: var(--rt-radius-ms)}.rt-thread-list[data-rt-radius=md]{--rt-thread-list-card-radius: var(--rt-radius-md)}.rt-thread-list[data-rt-radius=lg]{--rt-thread-list-card-radius: var(--rt-radius-lg)}.rt-thread-list[data-rt-radius=xl]{--rt-thread-list-card-radius: var(--rt-radius-xl)}.rt-thread-list[data-rt-radius=\"2xl\"]{--rt-thread-list-card-radius: var(--rt-radius-2xl)}.rt-thread-list[data-rt-radius=full]{--rt-thread-list-card-radius: var(--rt-radius-full)}}\n"], dependencies: [{ kind: "directive", type:
196
196
  // Angular
197
197
  NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type:
198
198
  // standalone components / directives
@@ -217,7 +217,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
217
217
  ModDirective,
218
218
  ], hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }], host: {
219
219
  class: BEM_BLOCK,
220
- }, template: "<ng-container rtBlock=\"rt-thread-list\">\n <header rtElem=\"head\">\n @if (searchTemplate()) {\n <div rtElem=\"search\" qa-dataid=\"thread-list-search\">\n <ng-container [ngTemplateOutlet]=\"searchTemplate()?.templateRef ?? null\" />\n </div>\n } @else {\n <rt-input\n rtElem=\"search\"\n qa-dataid=\"thread-list-search\"\n iconLeft=\"search\"\n [placeholder]=\"searchPlaceholderText()\"\n [formControl]=\"searchControl\" />\n }\n @if (filtersTemplate()) {\n <rt-icon-button\n rtElem=\"filter-trigger\"\n qa-dataid=\"thread-list-filter\"\n icon=\"filter\"\n variant=\"secondary\"\n rtPopoverAlign=\"end\"\n [ariaLabel]=\"t().uiFilters\"\n [indicator]=\"filtersActive()\"\n [rtPopover]=\"filtersPanel\" />\n }\n </header>\n\n <ng-template #rowButton let-row>\n <button\n rtElem=\"row\"\n qa-dataid=\"thread-list-row\"\n type=\"button\"\n [attr.data-id]=\"row.id\"\n [attr.data-unread]=\"row.hasUnread\"\n [attr.aria-current]=\"row.id === activeId() ? 'true' : null\"\n [rtMod]=\"{\n active: row.id === activeId(),\n unread: row.hasUnread,\n overdue: !!row.overdue,\n }\"\n (click)=\"onSelect(row.id, $event)\">\n <ng-container [ngTemplateOutlet]=\"rowTemplate()?.templateRef ?? null\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </button>\n </ng-template>\n\n <ng-template #filtersPanel>\n <div rtElem=\"filters-panel\" qa-dataid=\"thread-list-filters-panel\">\n <ng-container [ngTemplateOutlet]=\"filtersTemplate()?.templateRef ?? null\" />\n </div>\n </ng-template>\n\n <div rtElem=\"rows\" qa-dataid=\"thread-list-rows\">\n @if (loading() && !rows().length) {\n @for (i of skeletonRows; track i) {\n <div rtElem=\"row-skeleton\" qa-dataid=\"thread-list-row-skeleton\" aria-hidden=\"true\">\n <rt-skeleton width=\"60%\" height=\"14px\" />\n <rt-skeleton width=\"90%\" height=\"12px\" />\n </div>\n }\n } @else if (!rows().length) {\n <rt-empty-state rtElem=\"empty\" qa-dataid=\"thread-list-empty\" [description]=\"t().uiThreadListEmptyHint\" [title]=\"emptyTitle()\">\n <div rtEmptyIllustration rtElem=\"empty-preview\">\n @for (row of emptyPreviewRows(); track row.id) {\n <div rtElem=\"empty-card\" [rtMod]=\"{ offset: row.offset }\">\n <span rtElem=\"empty-avatar\">\n <rt-icon size=\"sm\" [name]=\"row.icon\" />\n </span>\n <span rtElem=\"empty-lines\">\n <span rtElem=\"empty-line\" [rtMod]=\"{ short: true }\"></span>\n <span rtElem=\"empty-line\"></span>\n </span>\n </div>\n }\n </div>\n </rt-empty-state>\n } @else {\n @for (row of rows(); track row.id) {\n @if (rowActionsTemplate(); as actions) {\n <div rtElem=\"row-wrap\" qa-dataid=\"thread-list-row-wrap\">\n <ng-container [ngTemplateOutlet]=\"rowButton\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n <div rtElem=\"row-actions\" qa-dataid=\"thread-list-row-actions\">\n <ng-container [ngTemplateOutlet]=\"actions.templateRef\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </div>\n </div>\n } @else {\n <ng-container [ngTemplateOutlet]=\"rowButton\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n }\n }\n @if (fetching()) {\n <div rtElem=\"row-loader\" qa-dataid=\"thread-list-row-loader\">\n <rt-skeleton width=\"90%\" height=\"12px\" />\n </div>\n }\n @if (hasMore()) {\n <div\n rtElem=\"load-anchor\"\n qa-dataid=\"thread-list-load-more\"\n aria-hidden=\"true\"\n rtInfiniteScroll\n [disabled]=\"fetching()\"\n (loadMore)=\"onLoadMore()\"></div>\n }\n }\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-thread-list{--rt-thread-list-border-width: var(--rt-border-width-thin);--rt-thread-list-card-radius: var(--rt-radius-lg);--rt-thread-list-tag-radius: var(--rt-radius-sm);--rt-thread-list-dot-radius: var(--rt-radius-full);--rt-thread-list-avatar-radius: var(--rt-radius-full);--rt-thread-list-line-radius: var(--rt-radius-full);display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0}.rt-thread-list__head{display:flex;flex:0 0 auto;align-items:center;block-size:56px;border-block-end:var(--rt-thread-list-border-width) solid var(--rt-color-border-strong);gap:var(--rt-space-2);padding-inline:var(--rt-space-4)}.rt-thread-list__search{flex:1 1 auto;max-inline-size:400px;min-inline-size:0}.rt-thread-list__filter-trigger{flex:0 0 auto}.rt-thread-list__filters-panel{display:flex;flex-direction:column;padding:var(--rt-space-4);gap:var(--rt-space-2);min-inline-size:220px}.rt-thread-list__rows{display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0;overflow-y:auto}.rt-thread-list__row{display:flex;align-items:center;justify-content:space-between;padding:var(--rt-space-2) var(--rt-space-4);border:none;background:none;border-inline-start:3px solid transparent;cursor:pointer;font-family:inherit;font-size:var(--rt-text-sm);gap:var(--rt-space-4);inline-size:100%;text-align:start}.rt-thread-list__row:hover{background:var(--rt-color-bg-subtle)}.rt-thread-list__row--active,.rt-thread-list__row--active:hover{background:var(--rt-color-state-info-bg);border-inline-start-color:var(--rt-color-action-primary)}.rt-thread-list__row--unread{position:relative;background:var(--rt-color-bg-subtle);border-inline-start-color:var(--rt-color-action-primary)}.rt-thread-list__row--unread .rt-thread-list__row-title{font-weight:var(--rt-font-weight-semibold)}.rt-thread-list__row--unread:before{position:absolute;border-radius:var(--rt-thread-list-dot-radius);background:var(--rt-color-action-primary);block-size:var(--rt-space-2);content:\"\";inline-size:var(--rt-space-2);inset-block-start:50%;inset-inline-start:var(--rt-space-2);transform:translateY(-50%)}.rt-thread-list__row--active,.rt-thread-list__row--active:hover{background:var(--rt-color-state-info-bg)}.rt-thread-list__row--overdue .rt-thread-list__row-time{color:var(--rt-color-state-error-text)}.rt-thread-list__row-wrap{position:relative}.rt-thread-list__row-wrap:hover .rt-thread-list__row-actions,.rt-thread-list__row-wrap:focus-within .rt-thread-list__row-actions{opacity:1;pointer-events:auto}.rt-thread-list__row-actions{position:absolute;display:flex;align-items:center;background:var(--rt-color-bg-subtle);gap:var(--rt-space-1);inset-block:0;inset-inline-end:0;opacity:0;padding-inline:var(--rt-space-2) var(--rt-space-4);pointer-events:none}.rt-thread-list__row--active+.rt-thread-list__row-actions{background:var(--rt-color-state-info-bg)}.rt-thread-list__row-body{display:flex;flex-direction:column;gap:var(--rt-space-0-5);min-inline-size:0}.rt-thread-list__row-title{overflow:hidden;color:var(--rt-color-text-primary);text-overflow:ellipsis;white-space:nowrap}.rt-thread-list__row-id{color:var(--rt-color-text-muted);font-size:var(--rt-text-sm)}.rt-thread-list__row:hover .rt-copy-cell__button,.rt-thread-list__row:focus-within .rt-copy-cell__button{opacity:1}.rt-thread-list__row-subtitle{overflow:hidden;color:var(--rt-color-text-muted);text-overflow:ellipsis;white-space:nowrap}.rt-thread-list__row-meta{display:flex;flex:0 0 auto;align-items:center;gap:var(--rt-space-2)}.rt-thread-list__row-time{color:var(--rt-color-text-muted);white-space:nowrap}.rt-thread-list__row-tag{padding:var(--rt-space-0-5) var(--rt-space-2);border-radius:var(--rt-thread-list-tag-radius);background:var(--rt-color-state-warning-bg);color:var(--rt-color-state-warning-text);font-size:var(--rt-text-xs);white-space:nowrap}.rt-thread-list__row-dot{display:inline-block;border-radius:var(--rt-thread-list-dot-radius);background:var(--rt-color-text-link);block-size:6px;inline-size:6px}.rt-thread-list__row-skeleton{display:flex;flex-direction:column;padding:var(--rt-space-2) var(--rt-space-4);gap:var(--rt-space-2)}.rt-thread-list__row-loader{display:flex;justify-content:center;padding:var(--rt-space-2) var(--rt-space-4)}.rt-thread-list__load-anchor{block-size:1px}.rt-thread-list__empty{padding:var(--rt-space-6) var(--rt-space-4)}.rt-thread-list__empty-preview{display:flex;flex-direction:column;gap:var(--rt-space-1)}.rt-thread-list__empty-card{display:flex;align-items:center;padding:var(--rt-space-2);border:var(--rt-thread-list-border-width) solid var(--rt-color-border-subtle);border-radius:var(--rt-thread-list-card-radius);background:var(--rt-color-bg-surface-subtle);gap:var(--rt-space-2)}.rt-thread-list__empty-card--offset{transform:translate(20px)}.rt-thread-list__empty-avatar{display:grid;flex:0 0 auto;border-radius:var(--rt-thread-list-avatar-radius);background:var(--rt-color-text-muted);block-size:24px;color:var(--rt-color-bg-surface);inline-size:24px;place-items:center}.rt-thread-list__empty-lines{display:flex;flex-direction:column;gap:var(--rt-space-2)}.rt-thread-list__empty-line{border-radius:var(--rt-thread-list-line-radius);background:var(--rt-color-border-strong);block-size:6px;inline-size:112px}.rt-thread-list__empty-line--short{inline-size:48px}.rt-thread-list[data-rt-radius=none]{--rt-thread-list-card-radius: var(--rt-radius-none)}.rt-thread-list[data-rt-radius=xs]{--rt-thread-list-card-radius: var(--rt-radius-xs)}.rt-thread-list[data-rt-radius=sm]{--rt-thread-list-card-radius: var(--rt-radius-sm)}.rt-thread-list[data-rt-radius=ms]{--rt-thread-list-card-radius: var(--rt-radius-ms)}.rt-thread-list[data-rt-radius=md]{--rt-thread-list-card-radius: var(--rt-radius-md)}.rt-thread-list[data-rt-radius=lg]{--rt-thread-list-card-radius: var(--rt-radius-lg)}.rt-thread-list[data-rt-radius=xl]{--rt-thread-list-card-radius: var(--rt-radius-xl)}.rt-thread-list[data-rt-radius=\"2xl\"]{--rt-thread-list-card-radius: var(--rt-radius-2xl)}.rt-thread-list[data-rt-radius=full]{--rt-thread-list-card-radius: var(--rt-radius-full)}}\n"] }]
220
+ }, template: "<ng-container rtBlock=\"rt-thread-list\">\n <header rtElem=\"head\">\n @if (searchTemplate()) {\n <div rtElem=\"search\" qa-dataid=\"thread-list-search\">\n <ng-container [ngTemplateOutlet]=\"searchTemplate()?.templateRef ?? null\" />\n </div>\n } @else {\n <rt-input\n rtElem=\"search\"\n qa-dataid=\"thread-list-search\"\n iconLeft=\"search\"\n [placeholder]=\"searchPlaceholderText()\"\n [formControl]=\"searchControl\" />\n }\n @if (filtersTemplate()) {\n <rt-icon-button\n rtElem=\"filter-trigger\"\n qa-dataid=\"thread-list-filter\"\n icon=\"filter\"\n variant=\"secondary\"\n rtPopoverAlign=\"end\"\n [ariaLabel]=\"t().uiFilters\"\n [indicator]=\"filtersActive()\"\n [rtPopover]=\"filtersPanel\" />\n }\n </header>\n\n <ng-template #rowButton let-row>\n <button\n rtElem=\"row\"\n qa-dataid=\"thread-list-row\"\n type=\"button\"\n [attr.data-id]=\"row.id\"\n [attr.data-unread]=\"row.hasUnread\"\n [attr.aria-current]=\"row.id === activeId() ? 'true' : null\"\n [rtMod]=\"{\n active: row.id === activeId(),\n unread: row.hasUnread,\n overdue: !!row.overdue,\n }\"\n (click)=\"onSelect(row.id, $event)\">\n <ng-container [ngTemplateOutlet]=\"rowTemplate()?.templateRef ?? null\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </button>\n </ng-template>\n\n <ng-template #filtersPanel>\n <div rtElem=\"filters-panel\" qa-dataid=\"thread-list-filters-panel\">\n <ng-container [ngTemplateOutlet]=\"filtersTemplate()?.templateRef ?? null\" />\n </div>\n </ng-template>\n\n <div rtElem=\"rows\" qa-dataid=\"thread-list-rows\">\n @if (loading() && !rows().length) {\n @for (i of skeletonRows; track i) {\n <div rtElem=\"row-skeleton\" qa-dataid=\"thread-list-row-skeleton\" aria-hidden=\"true\">\n <rt-skeleton width=\"60%\" height=\"14px\" />\n <rt-skeleton width=\"90%\" height=\"12px\" />\n </div>\n }\n } @else if (!rows().length) {\n <rt-empty-state rtElem=\"empty\" qa-dataid=\"thread-list-empty\" [description]=\"t().uiThreadListEmptyHint\" [title]=\"emptyTitle()\">\n <div rtEmptyIllustration rtElem=\"empty-preview\">\n @for (row of emptyPreviewRows(); track row.id) {\n <div rtElem=\"empty-card\" [rtMod]=\"{ offset: row.offset }\">\n <span rtElem=\"empty-avatar\">\n <rt-icon size=\"sm\" [name]=\"row.icon\" />\n </span>\n <span rtElem=\"empty-lines\">\n <span rtElem=\"empty-line\" [rtMod]=\"{ short: true }\"></span>\n <span rtElem=\"empty-line\"></span>\n </span>\n </div>\n }\n </div>\n </rt-empty-state>\n } @else {\n @for (row of rows(); track row.id) {\n @if (rowActionsTemplate(); as actions) {\n <div rtElem=\"row-wrap\" qa-dataid=\"thread-list-row-wrap\">\n <ng-container [ngTemplateOutlet]=\"rowButton\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n <div rtElem=\"row-actions\" qa-dataid=\"thread-list-row-actions\">\n <ng-container [ngTemplateOutlet]=\"actions.templateRef\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </div>\n </div>\n } @else {\n <ng-container [ngTemplateOutlet]=\"rowButton\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n }\n }\n @if (fetching()) {\n <div rtElem=\"row-loader\" qa-dataid=\"thread-list-row-loader\">\n <rt-skeleton width=\"90%\" height=\"12px\" />\n </div>\n }\n @if (hasMore()) {\n <div\n rtElem=\"load-anchor\"\n qa-dataid=\"thread-list-load-more\"\n aria-hidden=\"true\"\n rtInfiniteScroll\n [disabled]=\"fetching()\"\n (loadMore)=\"onLoadMore()\"></div>\n }\n }\n </div>\n</ng-container>\n", styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-thread-list{--rt-thread-list-border-width: var(--rt-border-width-thin);--rt-thread-list-card-radius: var(--rt-radius-lg);--rt-thread-list-tag-radius: var(--rt-radius-sm);--rt-thread-list-dot-radius: var(--rt-radius-full);--rt-thread-list-avatar-radius: var(--rt-radius-full);--rt-thread-list-line-radius: var(--rt-radius-full);display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0}.rt-thread-list__head{display:flex;flex:0 0 auto;align-items:center;block-size:56px;border-block-end:var(--rt-thread-list-border-width) solid var(--rt-color-border-strong);gap:var(--rt-space-2);padding-inline:var(--rt-space-4)}.rt-thread-list__search{flex:1 1 auto;max-inline-size:400px;min-inline-size:0}.rt-thread-list__filter-trigger{flex:0 0 auto}.rt-thread-list__filters-panel{display:flex;flex-direction:column;padding:var(--rt-space-4);gap:var(--rt-space-2);min-inline-size:220px}.rt-thread-list__rows{display:flex;flex:1 1 auto;flex-direction:column;min-block-size:0;overflow-y:auto}.rt-thread-list__row{display:flex;align-items:center;justify-content:space-between;padding:var(--rt-space-2) var(--rt-space-4);border:none;background:none;border-inline-start:3px solid transparent;cursor:pointer;font-family:inherit;font-size:var(--rt-text-sm);gap:var(--rt-space-4);inline-size:100%;text-align:start}.rt-thread-list__row:hover{background:var(--rt-color-bg-subtle)}.rt-thread-list__row--active,.rt-thread-list__row--active:hover{background:var(--rt-color-state-info-bg);border-inline-start-color:var(--rt-color-action-primary)}.rt-thread-list__row--unread{position:relative;background:var(--rt-color-bg-subtle);border-inline-start-color:var(--rt-color-action-primary)}.rt-thread-list__row--unread .rt-thread-list__row-title{font-weight:var(--rt-font-weight-semibold)}.rt-thread-list__row--unread:before{position:absolute;border-radius:var(--rt-thread-list-dot-radius);background:var(--rt-color-action-primary);block-size:var(--rt-space-2);content:\"\";inline-size:var(--rt-space-2);inset-block-start:50%;inset-inline-start:var(--rt-space-2);transform:translateY(-50%)}.rt-thread-list__row--active,.rt-thread-list__row--active:hover{background:var(--rt-color-state-info-bg)}.rt-thread-list__row--overdue .rt-thread-list__row-time{color:var(--rt-color-state-error-text)}.rt-thread-list__row-wrap{position:relative}.rt-thread-list__row-wrap:hover .rt-thread-list__row-actions,.rt-thread-list__row-wrap:focus-within .rt-thread-list__row-actions,.rt-thread-list__row-wrap:has(.rt-menu--open) .rt-thread-list__row-actions{opacity:1;pointer-events:auto}.rt-thread-list__row-actions{position:absolute;display:flex;align-items:center;background:var(--rt-color-bg-subtle);gap:var(--rt-space-1);inset-block:0;inset-inline-end:0;opacity:0;padding-inline:var(--rt-space-2) var(--rt-space-4);pointer-events:none}.rt-thread-list__row--active+.rt-thread-list__row-actions{background:var(--rt-color-state-info-bg)}.rt-thread-list__row-body{display:flex;flex-direction:column;gap:var(--rt-space-0-5);min-inline-size:0}.rt-thread-list__row-title{overflow:hidden;color:var(--rt-color-text-primary);text-overflow:ellipsis;white-space:nowrap}.rt-thread-list__row-id{color:var(--rt-color-text-muted);font-size:var(--rt-text-sm)}.rt-thread-list__row:hover .rt-copy-cell__button,.rt-thread-list__row:focus-within .rt-copy-cell__button{opacity:1}.rt-thread-list__row-subtitle{overflow:hidden;color:var(--rt-color-text-muted);text-overflow:ellipsis;white-space:nowrap}.rt-thread-list__row-meta{display:flex;flex:0 0 auto;align-items:center;gap:var(--rt-space-2)}.rt-thread-list__row-time{color:var(--rt-color-text-muted);white-space:nowrap}.rt-thread-list__row-tag{padding:var(--rt-space-0-5) var(--rt-space-2);border-radius:var(--rt-thread-list-tag-radius);background:var(--rt-color-state-warning-bg);color:var(--rt-color-state-warning-text);font-size:var(--rt-text-xs);white-space:nowrap}.rt-thread-list__row-dot{display:inline-block;border-radius:var(--rt-thread-list-dot-radius);background:var(--rt-color-text-link);block-size:6px;inline-size:6px}.rt-thread-list__row-skeleton{display:flex;flex-direction:column;padding:var(--rt-space-2) var(--rt-space-4);gap:var(--rt-space-2)}.rt-thread-list__row-loader{display:flex;justify-content:center;padding:var(--rt-space-2) var(--rt-space-4)}.rt-thread-list__load-anchor{block-size:1px}.rt-thread-list__empty{padding:var(--rt-space-6) var(--rt-space-4)}.rt-thread-list__empty-preview{display:flex;flex-direction:column;gap:var(--rt-space-1)}.rt-thread-list__empty-card{display:flex;align-items:center;padding:var(--rt-space-2);border:var(--rt-thread-list-border-width) solid var(--rt-color-border-subtle);border-radius:var(--rt-thread-list-card-radius);background:var(--rt-color-bg-surface-subtle);gap:var(--rt-space-2)}.rt-thread-list__empty-card--offset{transform:translate(20px)}.rt-thread-list__empty-avatar{display:grid;flex:0 0 auto;border-radius:var(--rt-thread-list-avatar-radius);background:var(--rt-color-text-muted);block-size:24px;color:var(--rt-color-bg-surface);inline-size:24px;place-items:center}.rt-thread-list__empty-lines{display:flex;flex-direction:column;gap:var(--rt-space-2)}.rt-thread-list__empty-line{border-radius:var(--rt-thread-list-line-radius);background:var(--rt-color-border-strong);block-size:6px;inline-size:112px}.rt-thread-list__empty-line--short{inline-size:48px}.rt-thread-list[data-rt-radius=none]{--rt-thread-list-card-radius: var(--rt-radius-none)}.rt-thread-list[data-rt-radius=xs]{--rt-thread-list-card-radius: var(--rt-radius-xs)}.rt-thread-list[data-rt-radius=sm]{--rt-thread-list-card-radius: var(--rt-radius-sm)}.rt-thread-list[data-rt-radius=ms]{--rt-thread-list-card-radius: var(--rt-radius-ms)}.rt-thread-list[data-rt-radius=md]{--rt-thread-list-card-radius: var(--rt-radius-md)}.rt-thread-list[data-rt-radius=lg]{--rt-thread-list-card-radius: var(--rt-radius-lg)}.rt-thread-list[data-rt-radius=xl]{--rt-thread-list-card-radius: var(--rt-radius-xl)}.rt-thread-list[data-rt-radius=\"2xl\"]{--rt-thread-list-card-radius: var(--rt-radius-2xl)}.rt-thread-list[data-rt-radius=full]{--rt-thread-list-card-radius: var(--rt-radius-full)}}\n"] }]
221
221
  }], propDecorators: { rowTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => RtThreadListRowDirective), { isSignal: true }] }], rowActionsTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => RtThreadListRowActionsDirective), { isSignal: true }] }], filtersTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => RtThreadListFiltersDirective), { isSignal: true }] }], searchTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => RtThreadListSearchDirective), { isSignal: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], activeId: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeId", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], emptyPreviewIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyPreviewIcons", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], fetching: [{ type: i0.Input, args: [{ isSignal: true, alias: "fetching", required: false }] }], hasMore: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMore", required: false }] }], filtersActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "filtersActive", required: false }] }], selectRow: [{ type: i0.Output, args: ["selectRow"] }], openInNewTab: [{ type: i0.Output, args: ["openInNewTab"] }], searchChange: [{ type: i0.Output, args: ["searchChange"] }], loadMore: [{ type: i0.Output, args: ["loadMore"] }] } });
222
222
 
223
223
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"rt-tools-ui-kit-v2-thread-list.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/thread-list/rt-thread-list.directives.ts","../../../projects/ui-kit-v2/src/lib/components/thread-list/rt-thread-list.component.ts","../../../projects/ui-kit-v2/src/lib/components/thread-list/rt-thread-list.component.html","../../../projects/ui-kit-v2/src/lib/components/thread-list/rt-tools-ui-kit-v2-thread-list.ts"],"sourcesContent":["import { Directive, inject, input, InputSignal, TemplateRef } from '@angular/core';\n\nimport { IRtThreadList } from './rt-thread-list.model';\n\n/**\n * Помечает `<ng-template>` содержимого строки списка. Входом `[rtThreadListRow]`\n * потребитель передаёт свой массив строк — из него выводится тип `TRow`, поэтому\n * `let-row` в темплейте типизируется строго (context-guard ниже это подтверждает).\n */\n@Directive({\n selector: 'ng-template[rtThreadListRow]',\n})\nexport class RtThreadListRowDirective<TRow extends IRtThreadList.Row> {\n public readonly templateRef: TemplateRef<IRtThreadList.RowContext<TRow>> =\n inject<TemplateRef<IRtThreadList.RowContext<TRow>>>(TemplateRef);\n\n public readonly rows: InputSignal<readonly TRow[]> = input<readonly TRow[]>([], {\n alias: 'rtThreadListRow',\n });\n\n public static ngTemplateContextGuard<TRow extends IRtThreadList.Row>(\n _directive: RtThreadListRowDirective<TRow>,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- второй довод стража контекста шаблона стоит только в типе-предикате; убрать его нечем, подпись задаёт каркас\n context: unknown\n ): context is IRtThreadList.RowContext<TRow> {\n return true;\n }\n}\n\n/**\n * Помечает `<ng-template>` действий строки (удалить, закрепить). Действия рисуются рядом с\n * кнопкой строки, а не внутри неё: вложенная кнопка в `<button>` недопустима и крадёт клик\n * выбора строки. Видны при наведении и фокусе внутри строки.\n */\n@Directive({\n selector: 'ng-template[rtThreadListRowActions]',\n})\nexport class RtThreadListRowActionsDirective<TRow extends IRtThreadList.Row> {\n public readonly templateRef: TemplateRef<IRtThreadList.RowContext<TRow>> =\n inject<TemplateRef<IRtThreadList.RowContext<TRow>>>(TemplateRef);\n\n public readonly rows: InputSignal<readonly TRow[]> = input<readonly TRow[]>([], {\n alias: 'rtThreadListRowActions',\n });\n\n public static ngTemplateContextGuard<TRow extends IRtThreadList.Row>(\n _directive: RtThreadListRowActionsDirective<TRow>,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- второй довод стража контекста шаблона стоит только в типе-предикате; убрать его нечем, подпись задаёт каркас\n context: unknown\n ): context is IRtThreadList.RowContext<TRow> {\n return true;\n }\n}\n\n/**\n * Помечает `<ng-template>` с фильтрами — его содержимое рендерится в поповере,\n * который открывает иконка-фильтр в шапке списка.\n */\n@Directive({\n selector: 'ng-template[rtThreadListFilters]',\n})\nexport class RtThreadListFiltersDirective {\n public readonly templateRef: TemplateRef<unknown> = inject<TemplateRef<unknown>>(TemplateRef);\n}\n\n/**\n * Помечает `<ng-template>` с кастомным контролом поиска. Когда потребитель его\n * проецирует, шапка списка рендерит его содержимое вместо встроенного `rt-input`\n * — так воркспейс подставляет свой автокомплит по каталогу вместо текстового\n * поиска, не ломая generic-природу списка.\n */\n@Directive({\n selector: 'ng-template[rtThreadListSearch]',\n})\nexport class RtThreadListSearchDirective {\n public readonly templateRef: TemplateRef<unknown> = inject<TemplateRef<unknown>>(TemplateRef);\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n computed,\n contentChild,\n inject,\n input,\n output,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n InputSignal,\n InputSignalWithTransform,\n OnInit,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\n\nimport { distinctUntilChanged, map } from 'rxjs';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelMap, rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { searchDebounce } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtInfiniteScrollDirective } from '@rt-tools/ui-kit-v2/core';\nimport { RtEmptyStateComponent } from '@rt-tools/ui-kit-v2/empty-state';\nimport { RtIconButtonComponent } 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 { RtInputComponent } from '@rt-tools/ui-kit-v2/input';\nimport { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { RtSkeletonComponent } from '@rt-tools/ui-kit-v2/skeleton';\nimport {\n RtThreadListFiltersDirective,\n RtThreadListRowActionsDirective,\n RtThreadListRowDirective,\n RtThreadListSearchDirective,\n} from './rt-thread-list.directives';\nimport { IRtThreadList } from './rt-thread-list.model';\n\nconst BEM_BLOCK: string = 'rt-thread-list';\n\n/** Кол-во скелетон-строк на первичной загрузке (пока `rows` пусты). */\nconst SKELETON_ROWS_COUNT: number = 6;\n\n/** Значки строк-превью пустого списка по умолчанию: люди переписки. */\nconst PREVIEW_ICONS: readonly IRtIcon.Name[] = ['user', 'users', 'user'];\n\n/**\n * Презентационный список тредов для воркспейсов:\n * поиск с дебаунсом, фильтр-поповер и бесконечная прокрутка. Данные и оркестрация\n * — на вызывающем; список стора/api не видит.\n *\n * Строку рисует потребитель через `<ng-template rtThreadListRow let-row>` (body +\n * meta); оболочка владеет кнопкой строки (active/unread/overdue), поиском, кнопкой\n * фильтров (точка-индикатор при `filtersActive`) и скроллом. Фильтры потребитель\n * кладёт в `<ng-template rtThreadListFilters>` — они рендерятся в поповере.\n */\n@Component({\n selector: 'rt-thread-list',\n templateUrl: './rt-thread-list.component.html',\n styleUrls: ['./rt-thread-list.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // Angular\n NgTemplateOutlet,\n ReactiveFormsModule,\n\n // standalone components / directives\n RtEmptyStateComponent,\n RtIconComponent,\n RtIconButtonComponent,\n RtInputComponent,\n RtPopoverDirective,\n RtSkeletonComponent,\n BlockDirective,\n ElemDirective,\n RtInfiniteScrollDirective,\n ModDirective,\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtThreadListComponent<TRow extends IRtThreadList.Row> implements OnInit {\n readonly #destroyRef: DestroyRef = inject(DestroyRef);\n\n readonly #t_uiSearch: Signal<string> = rtKitLabel('uiSearch');\n readonly #t_uiNothingFound: Signal<string> = rtKitLabel('uiNothingFound');\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly searchPlaceholderText: Signal<string> = computed((): string => this.searchPlaceholder() || this.#t_uiSearch());\n protected readonly emptyTitle: Signal<string> = computed((): string => this.emptyText() || this.#t_uiNothingFound());\n\n protected readonly skeletonRows: number[] = Array.from({ length: SKELETON_ROWS_COUNT }, (_: unknown, i: number): number => i);\n\n /** Декоративные строки-превью пустого состояния: значок строки из `emptyPreviewIcons`, каждая вторая сдвинута. */\n protected readonly emptyPreviewRows: Signal<readonly IRtThreadList.PreviewRow[]> = computed((): readonly IRtThreadList.PreviewRow[] =>\n this.emptyPreviewIcons().map((icon: IRtIcon.Name, index: number): IRtThreadList.PreviewRow => ({\n icon,\n id: index,\n offset: index % 2 === 1,\n }))\n );\n\n protected readonly searchControl: FormControl<string> = new FormControl<string>('', {\n nonNullable: true,\n });\n\n protected readonly rowTemplate: Signal<RtThreadListRowDirective<TRow> | undefined> = contentChild(RtThreadListRowDirective<TRow>);\n\n protected readonly rowActionsTemplate: Signal<RtThreadListRowActionsDirective<TRow> | undefined> = contentChild(\n RtThreadListRowActionsDirective<TRow>\n );\n\n protected readonly filtersTemplate: Signal<RtThreadListFiltersDirective | undefined> = contentChild(RtThreadListFiltersDirective);\n\n protected readonly searchTemplate: Signal<RtThreadListSearchDirective | undefined> = contentChild(RtThreadListSearchDirective);\n\n public readonly rows: InputSignal<readonly TRow[]> = input<readonly TRow[]>([]);\n\n public readonly activeId: InputSignal<IRtThreadList.TRowId | null> = input<IRtThreadList.TRowId | null>(null);\n\n /** Пусто — берётся переведённая подпись по умолчанию */\n public readonly searchPlaceholder: InputSignal<string> = input<string>('');\n\n public readonly emptyText: InputSignal<string> = input<string>('');\n\n /** Значки декоративных строк-превью пустого состояния, по строке на значок */\n public readonly emptyPreviewIcons: InputSignal<readonly IRtIcon.Name[]> = input<readonly IRtIcon.Name[]>(PREVIEW_ICONS);\n\n public readonly loading: InputSignalWithTransform<boolean, boolean | string> = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n\n public readonly fetching: InputSignalWithTransform<boolean, boolean | string> = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n\n public readonly hasMore: InputSignalWithTransform<boolean, boolean | string> = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n\n public readonly filtersActive: InputSignalWithTransform<boolean, boolean | string> = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n\n // Имя `select` зарезервировано под нативное DOM-событие\n // (@angular-eslint/no-output-native), поэтому output переименован.\n public readonly selectRow: OutputEmitterRef<IRtThreadList.TRowId> = output<IRtThreadList.TRowId>();\n\n // Ctrl/⌘+клик по строке: потребитель открывает строку в новой вкладке.\n // Обычный клик остаётся на `selectRow`.\n public readonly openInNewTab: OutputEmitterRef<IRtThreadList.TRowId> = output<IRtThreadList.TRowId>();\n\n public readonly searchChange: OutputEmitterRef<string> = output<string>();\n\n public readonly loadMore: OutputEmitterRef<void> = output<void>();\n\n public ngOnInit(): void {\n // Дебаунс непустого ввода; очистка крестиком применяется сразу (searchDebounce).\n this.searchControl.valueChanges\n .pipe(\n map((value: string): string => value.trim()),\n searchDebounce(),\n distinctUntilChanged(),\n takeUntilDestroyed(this.#destroyRef)\n )\n .subscribe((value: string): void => this.searchChange.emit(value));\n }\n\n protected onSelect(id: IRtThreadList.TRowId, event: MouseEvent): void {\n // Ctrl (Win/Linux) или ⌘ (macOS) — «открыть в новой вкладке», как у\n // нативных ссылок. Иначе — обычный выбор строки в текущей вкладке.\n if (event.ctrlKey || event.metaKey) {\n this.openInNewTab.emit(id);\n return;\n }\n this.selectRow.emit(id);\n }\n\n protected onLoadMore(): void {\n this.loadMore.emit();\n }\n}\n","<ng-container rtBlock=\"rt-thread-list\">\n <header rtElem=\"head\">\n @if (searchTemplate()) {\n <div rtElem=\"search\" qa-dataid=\"thread-list-search\">\n <ng-container [ngTemplateOutlet]=\"searchTemplate()?.templateRef ?? null\" />\n </div>\n } @else {\n <rt-input\n rtElem=\"search\"\n qa-dataid=\"thread-list-search\"\n iconLeft=\"search\"\n [placeholder]=\"searchPlaceholderText()\"\n [formControl]=\"searchControl\" />\n }\n @if (filtersTemplate()) {\n <rt-icon-button\n rtElem=\"filter-trigger\"\n qa-dataid=\"thread-list-filter\"\n icon=\"filter\"\n variant=\"secondary\"\n rtPopoverAlign=\"end\"\n [ariaLabel]=\"t().uiFilters\"\n [indicator]=\"filtersActive()\"\n [rtPopover]=\"filtersPanel\" />\n }\n </header>\n\n <ng-template #rowButton let-row>\n <button\n rtElem=\"row\"\n qa-dataid=\"thread-list-row\"\n type=\"button\"\n [attr.data-id]=\"row.id\"\n [attr.data-unread]=\"row.hasUnread\"\n [attr.aria-current]=\"row.id === activeId() ? 'true' : null\"\n [rtMod]=\"{\n active: row.id === activeId(),\n unread: row.hasUnread,\n overdue: !!row.overdue,\n }\"\n (click)=\"onSelect(row.id, $event)\">\n <ng-container [ngTemplateOutlet]=\"rowTemplate()?.templateRef ?? null\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </button>\n </ng-template>\n\n <ng-template #filtersPanel>\n <div rtElem=\"filters-panel\" qa-dataid=\"thread-list-filters-panel\">\n <ng-container [ngTemplateOutlet]=\"filtersTemplate()?.templateRef ?? null\" />\n </div>\n </ng-template>\n\n <div rtElem=\"rows\" qa-dataid=\"thread-list-rows\">\n @if (loading() && !rows().length) {\n @for (i of skeletonRows; track i) {\n <div rtElem=\"row-skeleton\" qa-dataid=\"thread-list-row-skeleton\" aria-hidden=\"true\">\n <rt-skeleton width=\"60%\" height=\"14px\" />\n <rt-skeleton width=\"90%\" height=\"12px\" />\n </div>\n }\n } @else if (!rows().length) {\n <rt-empty-state rtElem=\"empty\" qa-dataid=\"thread-list-empty\" [description]=\"t().uiThreadListEmptyHint\" [title]=\"emptyTitle()\">\n <div rtEmptyIllustration rtElem=\"empty-preview\">\n @for (row of emptyPreviewRows(); track row.id) {\n <div rtElem=\"empty-card\" [rtMod]=\"{ offset: row.offset }\">\n <span rtElem=\"empty-avatar\">\n <rt-icon size=\"sm\" [name]=\"row.icon\" />\n </span>\n <span rtElem=\"empty-lines\">\n <span rtElem=\"empty-line\" [rtMod]=\"{ short: true }\"></span>\n <span rtElem=\"empty-line\"></span>\n </span>\n </div>\n }\n </div>\n </rt-empty-state>\n } @else {\n @for (row of rows(); track row.id) {\n @if (rowActionsTemplate(); as actions) {\n <div rtElem=\"row-wrap\" qa-dataid=\"thread-list-row-wrap\">\n <ng-container [ngTemplateOutlet]=\"rowButton\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n <div rtElem=\"row-actions\" qa-dataid=\"thread-list-row-actions\">\n <ng-container [ngTemplateOutlet]=\"actions.templateRef\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </div>\n </div>\n } @else {\n <ng-container [ngTemplateOutlet]=\"rowButton\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n }\n }\n @if (fetching()) {\n <div rtElem=\"row-loader\" qa-dataid=\"thread-list-row-loader\">\n <rt-skeleton width=\"90%\" height=\"12px\" />\n </div>\n }\n @if (hasMore()) {\n <div\n rtElem=\"load-anchor\"\n qa-dataid=\"thread-list-load-more\"\n aria-hidden=\"true\"\n rtInfiniteScroll\n [disabled]=\"fetching()\"\n (loadMore)=\"onLoadMore()\"></div>\n }\n }\n </div>\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rt-tools-ui-kit-v2-thread-list.mjs","sources":["../../../projects/ui-kit-v2/src/lib/components/thread-list/rt-thread-list.directives.ts","../../../projects/ui-kit-v2/src/lib/components/thread-list/rt-thread-list.component.ts","../../../projects/ui-kit-v2/src/lib/components/thread-list/rt-thread-list.component.html","../../../projects/ui-kit-v2/src/lib/components/thread-list/rt-tools-ui-kit-v2-thread-list.ts"],"sourcesContent":["import { Directive, inject, input, InputSignal, TemplateRef } from '@angular/core';\n\nimport { IRtThreadList } from './rt-thread-list.model';\n\n/**\n * Помечает `<ng-template>` содержимого строки списка. Входом `[rtThreadListRow]`\n * потребитель передаёт свой массив строк — из него выводится тип `TRow`, поэтому\n * `let-row` в темплейте типизируется строго (context-guard ниже это подтверждает).\n */\n@Directive({\n selector: 'ng-template[rtThreadListRow]',\n})\nexport class RtThreadListRowDirective<TRow extends IRtThreadList.Row> {\n public readonly templateRef: TemplateRef<IRtThreadList.RowContext<TRow>> =\n inject<TemplateRef<IRtThreadList.RowContext<TRow>>>(TemplateRef);\n\n public readonly rows: InputSignal<readonly TRow[]> = input<readonly TRow[]>([], {\n alias: 'rtThreadListRow',\n });\n\n public static ngTemplateContextGuard<TRow extends IRtThreadList.Row>(\n _directive: RtThreadListRowDirective<TRow>,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- второй довод стража контекста шаблона стоит только в типе-предикате; убрать его нечем, подпись задаёт каркас\n context: unknown\n ): context is IRtThreadList.RowContext<TRow> {\n return true;\n }\n}\n\n/**\n * Помечает `<ng-template>` действий строки (удалить, закрепить). Действия рисуются рядом с\n * кнопкой строки, а не внутри неё: вложенная кнопка в `<button>` недопустима и крадёт клик\n * выбора строки. Видны при наведении и фокусе внутри строки.\n */\n@Directive({\n selector: 'ng-template[rtThreadListRowActions]',\n})\nexport class RtThreadListRowActionsDirective<TRow extends IRtThreadList.Row> {\n public readonly templateRef: TemplateRef<IRtThreadList.RowContext<TRow>> =\n inject<TemplateRef<IRtThreadList.RowContext<TRow>>>(TemplateRef);\n\n public readonly rows: InputSignal<readonly TRow[]> = input<readonly TRow[]>([], {\n alias: 'rtThreadListRowActions',\n });\n\n public static ngTemplateContextGuard<TRow extends IRtThreadList.Row>(\n _directive: RtThreadListRowActionsDirective<TRow>,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- второй довод стража контекста шаблона стоит только в типе-предикате; убрать его нечем, подпись задаёт каркас\n context: unknown\n ): context is IRtThreadList.RowContext<TRow> {\n return true;\n }\n}\n\n/**\n * Помечает `<ng-template>` с фильтрами — его содержимое рендерится в поповере,\n * который открывает иконка-фильтр в шапке списка.\n */\n@Directive({\n selector: 'ng-template[rtThreadListFilters]',\n})\nexport class RtThreadListFiltersDirective {\n public readonly templateRef: TemplateRef<unknown> = inject<TemplateRef<unknown>>(TemplateRef);\n}\n\n/**\n * Помечает `<ng-template>` с кастомным контролом поиска. Когда потребитель его\n * проецирует, шапка списка рендерит его содержимое вместо встроенного `rt-input`\n * — так воркспейс подставляет свой автокомплит по каталогу вместо текстового\n * поиска, не ломая generic-природу списка.\n */\n@Directive({\n selector: 'ng-template[rtThreadListSearch]',\n})\nexport class RtThreadListSearchDirective {\n public readonly templateRef: TemplateRef<unknown> = inject<TemplateRef<unknown>>(TemplateRef);\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n computed,\n contentChild,\n inject,\n input,\n output,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n InputSignal,\n InputSignalWithTransform,\n OnInit,\n OutputEmitterRef,\n Signal,\n ViewEncapsulation,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\n\nimport { distinctUntilChanged, map } from 'rxjs';\n\nimport { BlockDirective, ElemDirective, ModDirective } from '@rt-tools/core';\n\nimport { RT_KIT_LABELS, TRtKitLabelMap, rtKitLabel } from '@rt-tools/ui-kit-v2/core';\nimport { searchDebounce } from '@rt-tools/ui-kit-v2/core';\n\nimport { RtInfiniteScrollDirective } from '@rt-tools/ui-kit-v2/core';\nimport { RtEmptyStateComponent } from '@rt-tools/ui-kit-v2/empty-state';\nimport { RtIconButtonComponent } 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 { RtInputComponent } from '@rt-tools/ui-kit-v2/input';\nimport { RtPopoverDirective } from '@rt-tools/ui-kit-v2/popover';\nimport { RtRadiusDirective } from '@rt-tools/ui-kit-v2/radius';\nimport { RtSkeletonComponent } from '@rt-tools/ui-kit-v2/skeleton';\nimport {\n RtThreadListFiltersDirective,\n RtThreadListRowActionsDirective,\n RtThreadListRowDirective,\n RtThreadListSearchDirective,\n} from './rt-thread-list.directives';\nimport { IRtThreadList } from './rt-thread-list.model';\n\nconst BEM_BLOCK: string = 'rt-thread-list';\n\n/** Кол-во скелетон-строк на первичной загрузке (пока `rows` пусты). */\nconst SKELETON_ROWS_COUNT: number = 6;\n\n/** Значки строк-превью пустого списка по умолчанию: люди переписки. */\nconst PREVIEW_ICONS: readonly IRtIcon.Name[] = ['user', 'users', 'user'];\n\n/**\n * Презентационный список тредов для воркспейсов:\n * поиск с дебаунсом, фильтр-поповер и бесконечная прокрутка. Данные и оркестрация\n * — на вызывающем; список стора/api не видит.\n *\n * Строку рисует потребитель через `<ng-template rtThreadListRow let-row>` (body +\n * meta); оболочка владеет кнопкой строки (active/unread/overdue), поиском, кнопкой\n * фильтров (точка-индикатор при `filtersActive`) и скроллом. Фильтры потребитель\n * кладёт в `<ng-template rtThreadListFilters>` — они рендерятся в поповере.\n */\n@Component({\n selector: 'rt-thread-list',\n templateUrl: './rt-thread-list.component.html',\n styleUrls: ['./rt-thread-list.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n imports: [\n // Angular\n NgTemplateOutlet,\n ReactiveFormsModule,\n\n // standalone components / directives\n RtEmptyStateComponent,\n RtIconComponent,\n RtIconButtonComponent,\n RtInputComponent,\n RtPopoverDirective,\n RtSkeletonComponent,\n BlockDirective,\n ElemDirective,\n RtInfiniteScrollDirective,\n ModDirective,\n ],\n hostDirectives: [{ directive: RtRadiusDirective, inputs: ['radius'] }],\n host: {\n class: BEM_BLOCK,\n },\n})\nexport class RtThreadListComponent<TRow extends IRtThreadList.Row> implements OnInit {\n readonly #destroyRef: DestroyRef = inject(DestroyRef);\n\n readonly #t_uiSearch: Signal<string> = rtKitLabel('uiSearch');\n readonly #t_uiNothingFound: Signal<string> = rtKitLabel('uiNothingFound');\n\n protected readonly t: Signal<TRtKitLabelMap> = inject(RT_KIT_LABELS);\n\n protected readonly searchPlaceholderText: Signal<string> = computed((): string => this.searchPlaceholder() || this.#t_uiSearch());\n protected readonly emptyTitle: Signal<string> = computed((): string => this.emptyText() || this.#t_uiNothingFound());\n\n protected readonly skeletonRows: number[] = Array.from({ length: SKELETON_ROWS_COUNT }, (_: unknown, i: number): number => i);\n\n /** Декоративные строки-превью пустого состояния: значок строки из `emptyPreviewIcons`, каждая вторая сдвинута. */\n protected readonly emptyPreviewRows: Signal<readonly IRtThreadList.PreviewRow[]> = computed((): readonly IRtThreadList.PreviewRow[] =>\n this.emptyPreviewIcons().map((icon: IRtIcon.Name, index: number): IRtThreadList.PreviewRow => ({\n icon,\n id: index,\n offset: index % 2 === 1,\n }))\n );\n\n protected readonly searchControl: FormControl<string> = new FormControl<string>('', {\n nonNullable: true,\n });\n\n protected readonly rowTemplate: Signal<RtThreadListRowDirective<TRow> | undefined> = contentChild(RtThreadListRowDirective<TRow>);\n\n protected readonly rowActionsTemplate: Signal<RtThreadListRowActionsDirective<TRow> | undefined> = contentChild(\n RtThreadListRowActionsDirective<TRow>\n );\n\n protected readonly filtersTemplate: Signal<RtThreadListFiltersDirective | undefined> = contentChild(RtThreadListFiltersDirective);\n\n protected readonly searchTemplate: Signal<RtThreadListSearchDirective | undefined> = contentChild(RtThreadListSearchDirective);\n\n public readonly rows: InputSignal<readonly TRow[]> = input<readonly TRow[]>([]);\n\n public readonly activeId: InputSignal<IRtThreadList.TRowId | null> = input<IRtThreadList.TRowId | null>(null);\n\n /** Пусто — берётся переведённая подпись по умолчанию */\n public readonly searchPlaceholder: InputSignal<string> = input<string>('');\n\n public readonly emptyText: InputSignal<string> = input<string>('');\n\n /** Значки декоративных строк-превью пустого состояния, по строке на значок */\n public readonly emptyPreviewIcons: InputSignal<readonly IRtIcon.Name[]> = input<readonly IRtIcon.Name[]>(PREVIEW_ICONS);\n\n public readonly loading: InputSignalWithTransform<boolean, boolean | string> = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n\n public readonly fetching: InputSignalWithTransform<boolean, boolean | string> = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n\n public readonly hasMore: InputSignalWithTransform<boolean, boolean | string> = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n\n public readonly filtersActive: InputSignalWithTransform<boolean, boolean | string> = input<boolean, boolean | string>(false, {\n transform: booleanAttribute,\n });\n\n // Имя `select` зарезервировано под нативное DOM-событие\n // (@angular-eslint/no-output-native), поэтому output переименован.\n public readonly selectRow: OutputEmitterRef<IRtThreadList.TRowId> = output<IRtThreadList.TRowId>();\n\n // Ctrl/⌘+клик по строке: потребитель открывает строку в новой вкладке.\n // Обычный клик остаётся на `selectRow`.\n public readonly openInNewTab: OutputEmitterRef<IRtThreadList.TRowId> = output<IRtThreadList.TRowId>();\n\n public readonly searchChange: OutputEmitterRef<string> = output<string>();\n\n public readonly loadMore: OutputEmitterRef<void> = output<void>();\n\n public ngOnInit(): void {\n // Дебаунс непустого ввода; очистка крестиком применяется сразу (searchDebounce).\n this.searchControl.valueChanges\n .pipe(\n map((value: string): string => value.trim()),\n searchDebounce(),\n distinctUntilChanged(),\n takeUntilDestroyed(this.#destroyRef)\n )\n .subscribe((value: string): void => this.searchChange.emit(value));\n }\n\n protected onSelect(id: IRtThreadList.TRowId, event: MouseEvent): void {\n // Ctrl (Win/Linux) или ⌘ (macOS) — «открыть в новой вкладке», как у\n // нативных ссылок. Иначе — обычный выбор строки в текущей вкладке.\n if (event.ctrlKey || event.metaKey) {\n this.openInNewTab.emit(id);\n return;\n }\n this.selectRow.emit(id);\n }\n\n protected onLoadMore(): void {\n this.loadMore.emit();\n }\n}\n","<ng-container rtBlock=\"rt-thread-list\">\n <header rtElem=\"head\">\n @if (searchTemplate()) {\n <div rtElem=\"search\" qa-dataid=\"thread-list-search\">\n <ng-container [ngTemplateOutlet]=\"searchTemplate()?.templateRef ?? null\" />\n </div>\n } @else {\n <rt-input\n rtElem=\"search\"\n qa-dataid=\"thread-list-search\"\n iconLeft=\"search\"\n [placeholder]=\"searchPlaceholderText()\"\n [formControl]=\"searchControl\" />\n }\n @if (filtersTemplate()) {\n <rt-icon-button\n rtElem=\"filter-trigger\"\n qa-dataid=\"thread-list-filter\"\n icon=\"filter\"\n variant=\"secondary\"\n rtPopoverAlign=\"end\"\n [ariaLabel]=\"t().uiFilters\"\n [indicator]=\"filtersActive()\"\n [rtPopover]=\"filtersPanel\" />\n }\n </header>\n\n <ng-template #rowButton let-row>\n <button\n rtElem=\"row\"\n qa-dataid=\"thread-list-row\"\n type=\"button\"\n [attr.data-id]=\"row.id\"\n [attr.data-unread]=\"row.hasUnread\"\n [attr.aria-current]=\"row.id === activeId() ? 'true' : null\"\n [rtMod]=\"{\n active: row.id === activeId(),\n unread: row.hasUnread,\n overdue: !!row.overdue,\n }\"\n (click)=\"onSelect(row.id, $event)\">\n <ng-container [ngTemplateOutlet]=\"rowTemplate()?.templateRef ?? null\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </button>\n </ng-template>\n\n <ng-template #filtersPanel>\n <div rtElem=\"filters-panel\" qa-dataid=\"thread-list-filters-panel\">\n <ng-container [ngTemplateOutlet]=\"filtersTemplate()?.templateRef ?? null\" />\n </div>\n </ng-template>\n\n <div rtElem=\"rows\" qa-dataid=\"thread-list-rows\">\n @if (loading() && !rows().length) {\n @for (i of skeletonRows; track i) {\n <div rtElem=\"row-skeleton\" qa-dataid=\"thread-list-row-skeleton\" aria-hidden=\"true\">\n <rt-skeleton width=\"60%\" height=\"14px\" />\n <rt-skeleton width=\"90%\" height=\"12px\" />\n </div>\n }\n } @else if (!rows().length) {\n <rt-empty-state rtElem=\"empty\" qa-dataid=\"thread-list-empty\" [description]=\"t().uiThreadListEmptyHint\" [title]=\"emptyTitle()\">\n <div rtEmptyIllustration rtElem=\"empty-preview\">\n @for (row of emptyPreviewRows(); track row.id) {\n <div rtElem=\"empty-card\" [rtMod]=\"{ offset: row.offset }\">\n <span rtElem=\"empty-avatar\">\n <rt-icon size=\"sm\" [name]=\"row.icon\" />\n </span>\n <span rtElem=\"empty-lines\">\n <span rtElem=\"empty-line\" [rtMod]=\"{ short: true }\"></span>\n <span rtElem=\"empty-line\"></span>\n </span>\n </div>\n }\n </div>\n </rt-empty-state>\n } @else {\n @for (row of rows(); track row.id) {\n @if (rowActionsTemplate(); as actions) {\n <div rtElem=\"row-wrap\" qa-dataid=\"thread-list-row-wrap\">\n <ng-container [ngTemplateOutlet]=\"rowButton\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n <div rtElem=\"row-actions\" qa-dataid=\"thread-list-row-actions\">\n <ng-container [ngTemplateOutlet]=\"actions.templateRef\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n </div>\n </div>\n } @else {\n <ng-container [ngTemplateOutlet]=\"rowButton\" [ngTemplateOutletContext]=\"{ $implicit: row }\" />\n }\n }\n @if (fetching()) {\n <div rtElem=\"row-loader\" qa-dataid=\"thread-list-row-loader\">\n <rt-skeleton width=\"90%\" height=\"12px\" />\n </div>\n }\n @if (hasMore()) {\n <div\n rtElem=\"load-anchor\"\n qa-dataid=\"thread-list-load-more\"\n aria-hidden=\"true\"\n rtInfiniteScroll\n [disabled]=\"fetching()\"\n (loadMore)=\"onLoadMore()\"></div>\n }\n }\n </div>\n</ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rt-tools/ui-kit-v2",
3
- "version": "0.20.0",
3
+ "version": "0.22.0",
4
4
  "license": "Apache-2.0",
5
5
  "author": "Yauheni Krumin",
6
6
  "type": "module",
Binary file
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24">
2
+ <path
3
+ fill="currentColor"
4
+ d="M476.06-95Q315-95 203.8-207.43 92.59-319.85 94-481h94q1.15 121.3 84.01 206.65Q354.86-189 476-189q122 0 208-86.32t86-209.5Q770-605 683.63-688 597.25-771 476-771q-60 0-113.5 24.5T268-680h84v73H123v-227h71v95q55-59 127.5-93T476-866q80 0 150.5 30.5t123.74 82.51q53.24 52.01 83.5 121.5Q864-562 864-482q0 80-30.26 150.49-30.26 70.49-83.5 123Q697-156 626.5-125.5 556-95 476.06-95ZM600-311 446-463v-220h71v189l135 131-52 52Z" />
5
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24">
2
+ <path
3
+ fill="currentColor"
4
+ d="M476.06-95Q315-95 203.8-207.43 92.59-319.85 94-481h94q1.15 121.3 84.01 206.65Q354.86-189 476-189q122 0 208-86.32t86-209.5Q770-605 683.63-688 597.25-771 476-771q-60 0-113.5 24.5T268-680h84v73H123v-227h71v95q55-59 127.5-93T476-866q80 0 150.5 30.5t123.74 82.51q53.24 52.01 83.5 121.5Q864-562 864-482q0 80-30.26 150.49-30.26 70.49-83.5 123Q697-156 626.5-125.5 556-95 476.06-95ZM600-311 446-463v-220h71v189l135 131-52 52Z" />
5
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24">
2
+ <path
3
+ fill="currentColor"
4
+ d="M238-95v-143H95v-95h238v238h-95Zm390 0v-238h238v95H723v143h-95ZM95-628v-95h143v-143h95v238H95Zm533 0v-238h95v143h143v95H628Z" />
5
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24">
2
+ <path
3
+ fill="currentColor"
4
+ d="M238-95v-143H95v-95h238v238h-95Zm390 0v-238h238v95H723v143h-95ZM95-628v-95h143v-143h95v238H95Zm533 0v-238h95v143h143v95H628Z" />
5
+ </svg>
@@ -39,6 +39,13 @@ symbol внутри спрайта — и тем же движением про
39
39
  и на контейнере, и на одной странице законно живут оба набора рядом. Ставит его приложение своей
40
40
  разметкой, своей службы у набора нет — этим он и отличается от темы.
41
41
 
42
+ Второй признак — `data-rt-icon-preset='material'`, имя атрибута `RT_ICON_PRESET_ATTRIBUTE`. Он
43
+ стоит в том же `RT_ICON_MATERIAL_PRESET_SELECTOR`, поэтому его читают и значок, и кнопка
44
+ `rtButton`, но стили его не знают: токены набора оформления строятся только из `data-preset` и
45
+ `.rt-preset-material`. Так участок страницы получает материальные значки без чужих токенов.
46
+ Значение `'base'` у признака ничего не делает: выбирается ближайший материальный предок, а не
47
+ ближайший признак.
48
+
42
49
  Стилями набор не выбирается, хотя набор оформления работает именно так: ссылку на символ спрайта
43
50
  CSS подменить нечем. Второй `<use>` рядом с первым тоже не годится — он вечно указывает на символ,
44
51
  за которым никто не ходил, а обвязка снимков ждёт, пока нарисуется каждый значок на странице.
@@ -38,3 +38,6 @@
38
38
  директивами, а число столбцов здесь приходит из текста.
39
39
  - **Пустой текст не рисует ничего** — ни пустого абзаца, ни отступа: показывать или прятать
40
40
  заголовок раздела, решает потребитель.
41
+ - **Видимый текст без знаков разметки даёт `markdownToPlainText`** (`@rt-tools/ui-kit-v2/core`). Он
42
+ идёт по тому же дереву `parseMarkdown`: блоки через пустую строку, пункты списка и строки таблицы
43
+ построчно без маркеров, ячейки через табуляцию, у ссылки — её текст без адреса.
@@ -17,12 +17,13 @@
17
17
 
18
18
  ## `rt-menu`
19
19
 
20
- | вход | тип | умолчание |
21
- | ----------- | ------------------ | ------------------ |
22
- | `icon` | `IRtIcon.Name` | `'ellipsis-h'` |
23
- | `ariaLabel` | `string` | `''` → `uiActions` |
24
- | `align` | `'start' \| 'end'` | `'end'` |
25
- | `disabled` | `boolean` | `false` |
20
+ | вход | тип | умолчание |
21
+ | ------------- | -------------------- | ------------------ |
22
+ | `icon` | `IRtIcon.Name` | `'ellipsis-h'` |
23
+ | `ariaLabel` | `string` | `''` → `uiActions` |
24
+ | `align` | `'start' \| 'end'` | `'end'` |
25
+ | `triggerSize` | `IRtIconButton.Size` | `'md'` |
26
+ | `disabled` | `boolean` | `false` |
26
27
 
27
28
  | выход | тип |
28
29
  | -------------- | --------- |
@@ -30,7 +30,8 @@
30
30
 
31
31
  Действия строки — `<ng-template let-row [rtThreadListRowActions]="rows()">`: кнопки стоят поверх
32
32
  правого края строки, рядом с её кнопкой, а не внутри: вложенная кнопка в `<button>` недопустима и
33
- забирала бы клик выбора. Видны при наведении и фокусе. Без шаблона строка стоит без обёртки.
33
+ забирала бы клик выбора. Видны при наведении, фокусе и пока открыто `rt-menu` из них (`rt-menu--open`):
34
+ панель меню лежит вне строки, и фокус уходит в неё. Без шаблона строка стоит без обёртки.
34
35
 
35
36
  ## Главное, что нужно знать
36
37
 
@@ -130,8 +130,11 @@
130
130
  &__row-wrap {
131
131
  position: relative;
132
132
 
133
+ // Открытое меню действий держит их видимыми: фокус ушёл в панель поверх страницы, и без
134
+ // этого кнопка меню гасла под своей же панелью, когда указатель покидал строку.
133
135
  &:hover .rt-thread-list__row-actions,
134
- &:focus-within .rt-thread-list__row-actions {
136
+ &:focus-within .rt-thread-list__row-actions,
137
+ &:has(.rt-menu--open) .rt-thread-list__row-actions {
135
138
  opacity: 1;
136
139
  pointer-events: auto;
137
140
  }
@@ -47,11 +47,30 @@
47
47
  логики `rt-chat`. Отправка вопроса и выбор беседы прижимают ленту к низу всегда.
48
48
  - Удаление беседы — действие строки `rt-thread-list` (`rtThreadListRowActions`), подтверждение —
49
49
  на приложении.
50
+ - `threadMenu` ставит в действия строки вместо кнопки удаления `rt-menu` «More actions»
51
+ (`ellipsis-v`, `triggerSize="xs"` — размер прежней кнопки удаления). Пункты: «Copy ID» —
52
+ `onCopyThreadId`, CDK `Clipboard`, без состояния «скопировано»: меню закрывается выбором;
53
+ «Delete» — `danger`, отдаёт `deleteThread` без `confirmMessage`, подтверждение на приложении.
54
+ Подписи — `uiMoreActions`, `aiCopyThreadId`, `uiRemove`. Пока панель открыта, действия строки
55
+ видны: правило `:has(.rt-menu--open)` в `rt-thread-list`.
50
56
  - Подсветка совпадений поиска по беседам — `splitSideMenuTitle`.
51
57
  - Строки-превью пустого списка бесед — `emptyPreviewIcons`, по умолчанию `sparkle`, `bot`, `sparkle`:
52
58
  беседы идут с ассистентом, а не с людьми. Вход уходит в `rt-thread-list` как есть.
53
59
  - Ответ рисует внутренний `rt-ai-chat-answer` (папка `answer/`): без него шаблон организма
54
60
  превышает предел цикломатической сложности.
61
+ - Копирование — внутренний `rt-ai-chat-copy` (папка `copy/`): у вопроса строкой под пузырём, у
62
+ ответа первым в строке оценки. Состояние «скопировано» своё у каждой кнопки, приём —
63
+ `rt-copy-value`: CDK `Clipboard`, `check` и `uiCopied` на 2000 мс. Подписи — `uiCopy`, `uiCopied`
64
+ кита, своих `ai*` нет. Вопрос копирует `message.text` как есть. Ответ — видимый текст без знаков
65
+ разметки: `plainText` через `markdownToPlainText` кита, по тому же дереву `parseMarkdown`, что
66
+ рисует `rt-markdown-text`. Ход работы, вложения `extra` и строка действий в буфер не попадают —
67
+ их нет в `message.text`. `innerText` отображённого текста не взят: в jsdom спек его нет, и
68
+ проверялась бы подмена, а не настоящий путь. `copyable` выключает обе.
69
+ - `headerIconPreset="material"` ставит на `<header>` признак `data-rt-icon-preset='material'`
70
+ (`RT_ICON_PRESET_ATTRIBUTE`): значки шапки — назад, знак ассистента в заголовке, полный экран,
71
+ беседы, новая беседа, закрыть — рисуются материальным набором, токены набора оформления не
72
+ меняются. При `'base'` признака нет. Значок читает признак один раз после первой отрисовки:
73
+ смена входа на живой панели перерисовывает только значки, появившиеся после неё.
55
74
 
56
75
  ## Рядом
57
76
 
@@ -0,0 +1,5 @@
1
+ @layer rt-kit.components {
2
+ .rt-ai-chat-copy {
3
+ display: inline-flex;
4
+ }
5
+ }
@@ -119,7 +119,14 @@
119
119
 
120
120
  &__question {
121
121
  display: flex;
122
- justify-content: flex-end;
122
+ flex-direction: column;
123
+ align-items: flex-end;
124
+ gap: var(--rt-space-2xs);
125
+ }
126
+
127
+ &__question-actions {
128
+ display: flex;
129
+ gap: var(--rt-space-xs);
123
130
  }
124
131
 
125
132
  &__bubble {
@@ -461,6 +461,7 @@ declare const RT_KIT_LABELS_EN: {
461
461
  readonly aiBackToChat: "Back to conversation";
462
462
  readonly aiClose: "Close assistant";
463
463
  readonly aiCopyReference: "Copy reference";
464
+ readonly aiCopyThreadId: "Copy ID";
464
465
  readonly aiDeleteThread: "Delete conversation";
465
466
  readonly aiDisclaimer: "AI can make mistakes. Check important information.";
466
467
  readonly aiDislike: "Bad answer";
@@ -1208,6 +1209,17 @@ declare function parseInline(source: string): IRtMarkdownInlineNode[];
1208
1209
  */
1209
1210
  declare function parseMarkdown(source: string | null | undefined): IRtMarkdownBlockNode[];
1210
1211
 
1212
+ /**
1213
+ * Видимый текст разметки без её знаков: то, что `rt-markdown-text` показывает читателю.
1214
+ *
1215
+ * Строится по тому же дереву узлов, что рисует компонент, поэтому `##`, `**`, маркеры списков и
1216
+ * черта таблицы в вывод не попадают, а то, что разборщик оставил текстом, остаётся текстом.
1217
+ *
1218
+ * @param source Текст в разметке. Пустота и отсутствие значения дают пустую строку.
1219
+ * @returns Блоки через пустую строку, пункты списка и строки таблицы — построчно, ячейки — через табуляцию.
1220
+ */
1221
+ declare function markdownToPlainText(source: string | null | undefined): string;
1222
+
1211
1223
  /**
1212
1224
  * Готовая начинка `<picture>`: источники по форматам и запасной кадр на `<img>`.
1213
1225
  *
@@ -1323,5 +1335,5 @@ declare function themeScopeOfFocus(document: Document): string | null;
1323
1335
  */
1324
1336
  declare function carryThemeScopeOfFocus(pane: HTMLElement, document: Document): void;
1325
1337
 
1326
- export { BreakpointsService, ERtDataTableCellColor, ERtDataTableColumnType, ERtDataTableFilterType, ERtMarkdownBlock, ERtMarkdownInline, ERtStorageKeys, IButton, INotification, IRtDataTable, IRtIcon, IRtInput, IRtKitConfig, ITheme, MessageBus, NotificationBus, RT_CONSUMER_HANDLE_NAMES, RT_DATA_TABLE_PRESET_FROM_HOST, RT_DESIGN_TOKEN_NAMES, RT_KIT_CONFIG, RT_KIT_LABELS, RT_KIT_LABELS_EN, RT_KIT_LOCALE, RT_KIT_TRANSLATOR, RT_MATERIAL_PRESET_CLASS, RT_MATERIAL_PRESET_SELECTOR, RT_PRESET_MATERIAL_CLASS, RT_RADIUS_DEFAULT, RT_RADIUS_STEPS, RT_THEME_SCOPE_ATTRIBUTE, RtDayStampPipe, RtInfiniteScrollDirective, RtKitLabelPipe, RtThemeScopeDirective, SEARCH_DEBOUNCE_MS, ThemeService, breakNode, carryThemeScope, carryThemeScopeOfFocus, coerceQuillDeltaOutput, fileNameFromUrl, formatFileSize, iconsName, materialPresetClassesOf, materialPresetClassesOfFocus, normalizeQuillDelta, parseInline, parseMarkdown, provideRtKit, provideRtKitLabels, rtKitDefault, rtKitLabel, searchDebounce, themeScopeOf, themeScopeOfFocus };
1338
+ export { BreakpointsService, ERtDataTableCellColor, ERtDataTableColumnType, ERtDataTableFilterType, ERtMarkdownBlock, ERtMarkdownInline, ERtStorageKeys, IButton, INotification, IRtDataTable, IRtIcon, IRtInput, IRtKitConfig, ITheme, MessageBus, NotificationBus, RT_CONSUMER_HANDLE_NAMES, RT_DATA_TABLE_PRESET_FROM_HOST, RT_DESIGN_TOKEN_NAMES, RT_KIT_CONFIG, RT_KIT_LABELS, RT_KIT_LABELS_EN, RT_KIT_LOCALE, RT_KIT_TRANSLATOR, RT_MATERIAL_PRESET_CLASS, RT_MATERIAL_PRESET_SELECTOR, RT_PRESET_MATERIAL_CLASS, RT_RADIUS_DEFAULT, RT_RADIUS_STEPS, RT_THEME_SCOPE_ATTRIBUTE, RtDayStampPipe, RtInfiniteScrollDirective, RtKitLabelPipe, RtThemeScopeDirective, SEARCH_DEBOUNCE_MS, ThemeService, breakNode, carryThemeScope, carryThemeScopeOfFocus, coerceQuillDeltaOutput, fileNameFromUrl, formatFileSize, iconsName, markdownToPlainText, materialPresetClassesOf, materialPresetClassesOfFocus, normalizeQuillDelta, parseInline, parseMarkdown, provideRtKit, provideRtKitLabels, rtKitDefault, rtKitLabel, searchDebounce, themeScopeOf, themeScopeOfFocus };
1327
1339
  export type { IMessageBusEvent, IQuillDelta, IQuillDeltaAttributes, IQuillDeltaOp, IRtMarkdownBlockNode, IRtMarkdownInlineNode, IRtMarkdownListItem, IRtPicture, IRtPictureSource, TRtConsumerHandleName, TRtDataTableFilters, TRtDesignTokenName, TRtKitLabelKey, TRtKitLabelMap, TRtKitLabelParams, TRtKitTranslator, TRtRadius };
@@ -153,7 +153,16 @@ declare const RT_ICON_SYMBOL_ID_PREFIX: string;
153
153
  declare const RT_ICON_MATERIAL_SYMBOL_ID_PREFIX: string;
154
154
  /** Префикс `id` залитых рисунков материального набора: у имени их два, и `id` у каждого свой. */
155
155
  declare const RT_ICON_MATERIAL_FILL_SYMBOL_ID_PREFIX: string;
156
- /** Селекторы, которыми страница объявляет материальный набор. */
156
+ /**
157
+ * Атрибут, который переключает только набор рисунков значков: токенов набора оформления он не
158
+ * несёт. Ставится на контейнер со значением `'material'` там, где значки нужны материальные, а
159
+ * остальной вид — свой.
160
+ */
161
+ declare const RT_ICON_PRESET_ATTRIBUTE: string;
162
+ /**
163
+ * Селекторы, которыми страница объявляет материальный набор значков: признак набора оформления
164
+ * и признак одних значков. Стили читают только первые два — токены под третьим не меняются.
165
+ */
157
166
  declare const RT_ICON_MATERIAL_PRESET_SELECTOR: string;
158
167
 
159
168
  /**
@@ -244,5 +253,5 @@ declare const iconMaterialMap: readonly IRtIconMaterialEntry[];
244
253
  */
245
254
  declare const iconMaterialDrawn: ReadonlySet<IRtIcon.Name>;
246
255
 
247
- export { CATEGORY_ORDER, ICON_CATEGORY_RULES, RT_ICONS_BASE_URL, RT_ICONS_MATERIAL_BASE_URL, RT_ICON_GLYPH_STRATEGY, RT_ICON_MATERIAL_FILL_SYMBOL_ID_PREFIX, RT_ICON_MATERIAL_PRESET_SELECTOR, RT_ICON_MATERIAL_SYMBOL_ID_PREFIX, RT_ICON_SPRITE_ID, RT_ICON_SYMBOL_ID_PREFIX, RtIconComponent, RtIconFontService, RtIconRegistry, categoryOf, iconMaterialDrawn, iconMaterialMap, isKitIconName, materialPairOf, provideRtIcons, resolveIconGlyph };
256
+ export { CATEGORY_ORDER, ICON_CATEGORY_RULES, RT_ICONS_BASE_URL, RT_ICONS_MATERIAL_BASE_URL, RT_ICON_GLYPH_STRATEGY, RT_ICON_MATERIAL_FILL_SYMBOL_ID_PREFIX, RT_ICON_MATERIAL_PRESET_SELECTOR, RT_ICON_MATERIAL_SYMBOL_ID_PREFIX, RT_ICON_PRESET_ATTRIBUTE, RT_ICON_SPRITE_ID, RT_ICON_SYMBOL_ID_PREFIX, RtIconComponent, RtIconFontService, RtIconRegistry, categoryOf, iconMaterialDrawn, iconMaterialMap, isKitIconName, materialPairOf, provideRtIcons, resolveIconGlyph };
248
257
  export type { IRtIconMaterialEntry, IRtIconsOptions, TIconCategory };
@@ -6,6 +6,7 @@ import { IRtIcon } from '@rt-tools/ui-kit-v2/core';
6
6
  import * as i1 from '@rt-tools/ui-kit-v2/tooltip';
7
7
  import * as i2 from '@rt-tools/ui-kit-v2/radius';
8
8
  import { CdkConnectedOverlay, CdkOverlayOrigin, ConnectedPosition } from '@angular/cdk/overlay';
9
+ import { IRtIconButton } from '@rt-tools/ui-kit-v2/icon-button';
9
10
 
10
11
  /**
11
12
  * Помечает `<ng-template>` своего значка пункта меню. Кит ставит содержимое на место значка
@@ -193,6 +194,8 @@ declare class RtMenuComponent {
193
194
  * не доходят: семья, нарисованная своим набором, отдаёт его панели этим входом.
194
195
  */
195
196
  readonly panelClass: InputSignal<string | string[]>;
197
+ /** Размер кнопки-триггера: мельче `md` — в плотной строке рядом с другими действиями строки. */
198
+ readonly triggerSize: InputSignal<IRtIconButton.Size>;
196
199
  /** Размер панели: компактная — у меню действий строки таблицы. */
197
200
  readonly size: InputSignal<IRtMenu.Size>;
198
201
  /** Триггер отключён — меню не открыть. */
@@ -211,7 +214,7 @@ declare class RtMenuComponent {
211
214
  protected onSelect(): void;
212
215
  protected onKeydown(event: KeyboardEvent): void;
213
216
  static ɵfac: i0.ɵɵFactoryDeclaration<RtMenuComponent, never>;
214
- static ɵcmp: i0.ɵɵComponentDeclaration<RtMenuComponent, "rt-menu", never, { "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "panelClass": { "alias": "panelClass"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "openedChange": "openedChange"; }, never, ["*"], true, never>;
217
+ static ɵcmp: i0.ɵɵComponentDeclaration<RtMenuComponent, "rt-menu", never, { "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "panelClass": { "alias": "panelClass"; "required": false; "isSignal": true; }; "triggerSize": { "alias": "triggerSize"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "openedChange": "openedChange"; }, never, ["*"], true, never>;
215
218
  }
216
219
 
217
220
  export { IRtMenu, RT_MENU_SELECT_EVENT, RtMenuComponent, RtMenuItemComponent, RtMenuItemIconDirective };