@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.
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs +44 -1
- package/fesm2022/rt-tools-ui-kit-v2-core.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs +2 -2
- package/fesm2022/rt-tools-ui-kit-v2-data-table.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-icon.mjs +14 -3
- package/fesm2022/rt-tools-ui-kit-v2-icon.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-menu.mjs +6 -3
- package/fesm2022/rt-tools-ui-kit-v2-menu.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs +108 -20
- package/fesm2022/rt-tools-ui-kit-v2-rich-editor.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-table.mjs +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-table.mjs.map +1 -1
- package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs +2 -2
- package/fesm2022/rt-tools-ui-kit-v2-thread-list.mjs.map +1 -1
- package/package.json +1 -1
- package/rt-tools-ui-kit-v2-0.22.0.tgz +0 -0
- package/src/assets/icons-material/history.fill.svg +5 -0
- package/src/assets/icons-material/history.svg +5 -0
- package/src/assets/icons-material/window-minimize.fill.svg +5 -0
- package/src/assets/icons-material/window-minimize.svg +5 -0
- package/src/lib/components/icon/CONTEXT.md +7 -0
- package/src/lib/components/markdown-text/CONTEXT.md +3 -0
- package/src/lib/components/menu/CONTEXT.md +7 -6
- package/src/lib/components/thread-list/CONTEXT.md +2 -1
- package/src/lib/components/thread-list/rt-thread-list.component.scss +4 -1
- package/src/rich-editor/lib/components/ai-chat/CONTEXT.md +19 -0
- package/src/rich-editor/lib/components/ai-chat/copy/rt-ai-chat-copy.component.scss +5 -0
- package/src/rich-editor/lib/components/ai-chat/rt-ai-chat.component.scss +8 -1
- package/types/rt-tools-ui-kit-v2-core.d.ts +13 -1
- package/types/rt-tools-ui-kit-v2-icon.d.ts +11 -2
- package/types/rt-tools-ui-kit-v2-menu.d.ts +4 -1
- package/types/rt-tools-ui-kit-v2-rich-editor.d.ts +27 -6
- 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
|
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>
|
|
@@ -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`
|
|
23
|
-
| `ariaLabel`
|
|
24
|
-
| `align`
|
|
25
|
-
| `
|
|
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
|
|
|
@@ -119,7 +119,14 @@
|
|
|
119
119
|
|
|
120
120
|
&__question {
|
|
121
121
|
display: flex;
|
|
122
|
-
|
|
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 };
|