@acorex/components 22.4.13 → 22.4.15

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.
@@ -1,11 +1,15 @@
1
1
  import { AXComponent } from '@acorex/cdk/common';
2
- import { isPlatformBrowser, AsyncPipe } from '@angular/common';
2
+ import { isPlatformBrowser, AsyncPipe, NgTemplateOutlet } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { inject, DOCUMENT, PLATFORM_ID, ViewEncapsulation, Component, contentChild, input, model, afterNextRender, NgModule } from '@angular/core';
4
+ import { inject, DOCUMENT, PLATFORM_ID, contentChild, ChangeDetectionStrategy, ViewEncapsulation, Component, Directive, model, viewChild, input, output, computed, afterNextRender, DestroyRef, signal, effect, untracked, NgModule } from '@angular/core';
5
5
  import { AXAvatarComponent } from '@acorex/components/avatar';
6
- import { AXTranslatorPipe, AXTranslationModule } from '@acorex/core/translation';
6
+ import { AXBadgeComponent, AXBadgeModule } from '@acorex/components/badge';
7
+ import { AXButtonItemListComponent, AXButtonModule } from '@acorex/components/button';
7
8
  import { AXDecoratorIconComponent, AXDecoratorGenericComponent, AXDecoratorModule } from '@acorex/components/decorators';
8
- import { AXButtonModule } from '@acorex/components/button';
9
+ import { AXDropdownButtonComponent } from '@acorex/components/dropdown-button';
10
+ import { AXImageComponent } from '@acorex/components/image';
11
+ import { AXTranslatorPipe, AXTranslationModule } from '@acorex/core/translation';
12
+ import { AXSkeletonComponent } from '@acorex/components/skeleton';
9
13
  import { AXTextAreaModule } from '@acorex/components/text-area';
10
14
  import { AXWysiwygModule } from '@acorex/components/wysiwyg';
11
15
 
@@ -18,6 +22,10 @@ class AXCommentContainerComponent {
18
22
  constructor() {
19
23
  this.document = inject(DOCUMENT);
20
24
  this.platformID = inject(PLATFORM_ID);
25
+ this.projectedHeader = contentChild('ax-header', /* @ts-ignore */
26
+ ...(ngDevMode ? [{ debugName: "projectedHeader" }] : /* istanbul ignore next */ []));
27
+ this.projectedFooter = contentChild('ax-footer', /* @ts-ignore */
28
+ ...(ngDevMode ? [{ debugName: "projectedFooter" }] : /* istanbul ignore next */ []));
21
29
  }
22
30
  /**
23
31
  * Scrolls to a specific comment reply by its ID and highlights it temporarily.
@@ -27,7 +35,9 @@ class AXCommentContainerComponent {
27
35
  scrollToReply(id) {
28
36
  if (!isPlatformBrowser(this.platformID))
29
37
  return;
30
- const el = this.document.querySelector(`ax-comment-item[id="${id}"]`);
38
+ const key = String(id);
39
+ const el = this.document.querySelector(`ax-comment-item[id="${key}"]`) ??
40
+ this.document.querySelector(`ax-comment-item[id="comment-${key}"]`);
31
41
  if (!el)
32
42
  return;
33
43
  el.scrollIntoView({ behavior: 'smooth', block: 'center' });
@@ -35,47 +45,55 @@ class AXCommentContainerComponent {
35
45
  setTimeout(() => el.classList.remove('ax-state-highlight'), 1500);
36
46
  }
37
47
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
38
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: AXCommentContainerComponent, isStandalone: true, selector: "ax-comment-container", providers: [{ provide: AXComponent, useExisting: AXCommentContainerComponent }], ngImport: i0, template: '<ng-content />', isInline: true, styles: ["ax-comment-container{display:block;width:100%}\n"], encapsulation: i0.ViewEncapsulation.None }); }
48
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.6", type: AXCommentContainerComponent, isStandalone: true, selector: "ax-comment-container", host: { properties: { "class.ax-has-header": "!!projectedHeader()", "class.ax-has-footer": "!!projectedFooter()" } }, providers: [{ provide: AXComponent, useExisting: AXCommentContainerComponent }], queries: [{ propertyName: "projectedHeader", first: true, predicate: ["ax-header"], descendants: true, isSignal: true }, { propertyName: "projectedFooter", first: true, predicate: ["ax-footer"], descendants: true, isSignal: true }], ngImport: i0, template: `
49
+ <ng-content select="ax-header" />
50
+ <ng-content />
51
+ <ng-content select="ax-footer" />
52
+ `, isInline: true, styles: ["@layer components{ax-comment-container{--ax-comp-comment-padding-x: 0px;--ax-comp-comment-padding-y: 8px;--ax-comp-comment-gap: 8px;--ax-comp-comment-avatar-size: 32px;--ax-comp-comment-reply-avatar-size: 28px;display:block;width:100%;min-width:calc(var(--spacing, .25rem) * 0)}ax-comment-container>ax-header,ax-comment-container>ax-footer{display:none;width:100%;min-width:calc(var(--spacing, .25rem) * 0);flex-direction:column;align-items:stretch;justify-content:flex-start;gap:calc(var(--spacing, .25rem) * 2);padding-block:16px}ax-comment-container.ax-has-header>ax-header,ax-comment-container.ax-has-footer>ax-footer{display:flex}ax-comment-container.ax-has-header>ax-header>*,ax-comment-container.ax-has-footer>ax-footer>*{width:100%;min-width:calc(var(--spacing, .25rem) * 0)}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
39
53
  }
40
54
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentContainerComponent, decorators: [{
41
55
  type: Component,
42
- args: [{ selector: 'ax-comment-container', template: '<ng-content />', encapsulation: ViewEncapsulation.None, providers: [{ provide: AXComponent, useExisting: AXCommentContainerComponent }], styles: ["ax-comment-container{display:block;width:100%}\n"] }]
43
- }] });
56
+ args: [{ selector: 'ax-comment-container', template: `
57
+ <ng-content select="ax-header" />
58
+ <ng-content />
59
+ <ng-content select="ax-footer" />
60
+ `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: AXComponent, useExisting: AXCommentContainerComponent }], host: {
61
+ '[class.ax-has-header]': '!!projectedHeader()',
62
+ '[class.ax-has-footer]': '!!projectedFooter()',
63
+ }, styles: ["@layer components{ax-comment-container{--ax-comp-comment-padding-x: 0px;--ax-comp-comment-padding-y: 8px;--ax-comp-comment-gap: 8px;--ax-comp-comment-avatar-size: 32px;--ax-comp-comment-reply-avatar-size: 28px;display:block;width:100%;min-width:calc(var(--spacing, .25rem) * 0)}ax-comment-container>ax-header,ax-comment-container>ax-footer{display:none;width:100%;min-width:calc(var(--spacing, .25rem) * 0);flex-direction:column;align-items:stretch;justify-content:flex-start;gap:calc(var(--spacing, .25rem) * 2);padding-block:16px}ax-comment-container.ax-has-header>ax-header,ax-comment-container.ax-has-footer>ax-footer{display:flex}ax-comment-container.ax-has-header>ax-header>*,ax-comment-container.ax-has-footer>ax-footer>*{width:100%;min-width:calc(var(--spacing, .25rem) * 0)}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
64
+ }], propDecorators: { projectedHeader: [{ type: i0.ContentChild, args: ['ax-header', { isSignal: true }] }], projectedFooter: [{ type: i0.ContentChild, args: ['ax-footer', { isSignal: true }] }] } });
44
65
 
45
66
  /**
46
- * A component that represents an individual comment item in the comment system.
67
+ * Marks an `ng-template` as a custom comment item renderer.
68
+ * When omitted, `ax-comment-view` uses the built-in layout.
69
+ * Like and reply stay in the item actions row either way.
47
70
  *
48
- * @category Components
71
+ * @example
72
+ * ```html
73
+ * <ax-comment-view [datasource]="comments">
74
+ * <ng-template axCommentItem let-item>
75
+ * <ax-avatar [color]="item.color" look="twotone" shape="rounded">
76
+ * <ax-text>{{ item.initials }}</ax-text>
77
+ * </ax-avatar>
78
+ * <ax-title>{{ item.author }}</ax-title>
79
+ * <ax-content>{{ item.content }}</ax-content>
80
+ * </ng-template>
81
+ * </ax-comment-view>
82
+ * ```
49
83
  */
50
- class AXCommentItemComponent {
51
- constructor() {
52
- this.avatar = contentChild(AXAvatarComponent, /* @ts-ignore */
53
- ...(ngDevMode ? [{ debugName: "avatar" }] : /* istanbul ignore next */ []));
54
- this.replyCount = input(/* @ts-ignore */
55
- ...(ngDevMode ? [undefined, { debugName: "replyCount" }] : /* istanbul ignore next */ []));
56
- /** Two-way bindable state controlling whether nested replies are visible. */
57
- this.repliesExpanded = model(false, /* @ts-ignore */
58
- ...(ngDevMode ? [{ debugName: "repliesExpanded" }] : /* istanbul ignore next */ []));
59
- afterNextRender(() => {
60
- this.avatar()?.size?.set(40);
61
- });
62
- }
63
- toggleReplies() {
64
- this.repliesExpanded.update((v) => !v);
65
- }
66
- showReplies() {
67
- this.repliesExpanded.set(true);
68
- }
69
- hideReplies() {
70
- this.repliesExpanded.set(false);
84
+ class AXCommentItemTemplateDirective {
85
+ constructor(template) {
86
+ this.template = template;
71
87
  }
72
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
73
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: AXCommentItemComponent, isStandalone: true, selector: "ax-comment-item", inputs: { replyCount: { classPropertyName: "replyCount", publicName: "replyCount", isSignal: true, isRequired: false, transformFunction: null }, repliesExpanded: { classPropertyName: "repliesExpanded", publicName: "repliesExpanded", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { repliesExpanded: "repliesExpandedChange" }, providers: [{ provide: AXComponent, useExisting: AXCommentItemComponent }], queries: [{ propertyName: "avatar", first: true, predicate: AXAvatarComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"ax-comment-header\">\n <div class=\"ax-comment-header-start\">\n <ng-content select=\"ax-avatar\" />\n <div class=\"ax-comment-header-content\">\n <ng-content select=\"ax-title\" />\n <ng-content select=\"ax-comment-date\" />\n </div>\n </div>\n <ng-content select=\"ax-comment-menu-options\" />\n</div>\n\n<div class=\"ax-comment-body\">\n <ng-content select=\"ax-content\" />\n <div class=\"ax-comment-actions\">\n <ng-content select=\"ax-comment-like\" />\n <ng-content select=\"ax-comment-reply-text\" />\n </div>\n</div>\n\n@if (replyCount()) {\n <div class=\"ax-comment-replies\">\n <span class=\"ax-comment-replies-toggle\" (click)=\"toggleReplies()\">\n {{ (repliesExpanded() ? '@acorex:comment.hide' : '@acorex:comment.view') | translate | async }}\n {{ replyCount() }}\n {{ (replyCount() > 1 ? '@acorex:comment.replies' : '@acorex:comment.reply') | translate | async }}\n </span>\n @if (repliesExpanded()) {\n <div class=\"ax-comment-replies-content\">\n <ng-content select=\"ax-comment-item\" />\n <ng-content select=\"ax-comment-reply-more\" />\n </div>\n }\n </div>\n}\n", styles: ["@layer properties;@layer components{ax-comment-item{display:block;border-radius:.25rem;padding:calc(var(--spacing, .25rem) * 1);transition-property:background;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: 1s;transition-duration:1s;--tw-ease: var(--ease-in-out, cubic-bezier(.4, 0, .2, 1));transition-timing-function:var(--ease-in-out, cubic-bezier(.4, 0, .2, 1))}ax-comment-item:not(:last-child){margin-bottom:calc(var(--spacing, .25rem) * 4)}ax-comment-item.ax-state-highlight{background-color:rgba(var(--ax-sys-color-primary-surface),.1)}ax-comment-item .ax-comment-header{display:flex;align-items:center;justify-content:space-between}ax-comment-item .ax-comment-header .ax-comment-header-start{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}ax-comment-item .ax-comment-header .ax-comment-header-start .ax-comment-header-content{display:flex;align-items:baseline;gap:calc(var(--spacing, .25rem) * 2)}ax-comment-item .ax-comment-header ax-title{--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500)}ax-comment-item .ax-comment-body{margin-inline-start:calc(var(--spacing, .25rem) * 12);padding-top:calc(var(--spacing, .25rem) * 1);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgba(var(--ax-sys-color-on-surface))}ax-comment-item .ax-comment-actions{margin-top:calc(var(--spacing, .25rem) * 2);display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 4);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}ax-comment-item .ax-comment-actions ax-comment-like,ax-comment-item .ax-comment-actions ax-comment-reply-text{cursor:pointer;-webkit-user-select:none;user-select:none}ax-comment-item .ax-comment-replies{margin-inline-start:calc(var(--spacing, .25rem) * 10);margin-top:calc(var(--spacing, .25rem) * 2)}ax-comment-item .ax-comment-replies .ax-comment-replies-toggle{display:inline-flex;cursor:pointer;align-items:center;gap:calc(var(--spacing, .25rem) * 1);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-primary-surface));-webkit-user-select:none;user-select:none}ax-comment-item .ax-comment-replies .ax-comment-replies-toggle:hover{text-decoration-line:underline}ax-comment-item .ax-comment-replies .ax-comment-replies-content{margin-top:calc(var(--spacing, .25rem) * 2)}ax-comment-item .ax-comment-replies ax-comment-reply-more{cursor:pointer;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-primary-surface))}ax-comment-item .ax-comment-replies ax-comment-reply-more:hover{text-decoration-line:underline}}@property --tw-duration{syntax: \"*\"; inherits: false;}@property --tw-ease{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-duration: initial;--tw-ease: initial;--tw-font-weight: initial}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "pipe", type: AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None }); }
88
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentItemTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); }
89
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.6", type: AXCommentItemTemplateDirective, isStandalone: true, selector: "ng-template[axCommentItem]", ngImport: i0 }); }
74
90
  }
75
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentItemComponent, decorators: [{
76
- type: Component,
77
- args: [{ selector: 'ax-comment-item', encapsulation: ViewEncapsulation.None, imports: [AXTranslatorPipe, AsyncPipe], providers: [{ provide: AXComponent, useExisting: AXCommentItemComponent }], template: "<div class=\"ax-comment-header\">\n <div class=\"ax-comment-header-start\">\n <ng-content select=\"ax-avatar\" />\n <div class=\"ax-comment-header-content\">\n <ng-content select=\"ax-title\" />\n <ng-content select=\"ax-comment-date\" />\n </div>\n </div>\n <ng-content select=\"ax-comment-menu-options\" />\n</div>\n\n<div class=\"ax-comment-body\">\n <ng-content select=\"ax-content\" />\n <div class=\"ax-comment-actions\">\n <ng-content select=\"ax-comment-like\" />\n <ng-content select=\"ax-comment-reply-text\" />\n </div>\n</div>\n\n@if (replyCount()) {\n <div class=\"ax-comment-replies\">\n <span class=\"ax-comment-replies-toggle\" (click)=\"toggleReplies()\">\n {{ (repliesExpanded() ? '@acorex:comment.hide' : '@acorex:comment.view') | translate | async }}\n {{ replyCount() }}\n {{ (replyCount() > 1 ? '@acorex:comment.replies' : '@acorex:comment.reply') | translate | async }}\n </span>\n @if (repliesExpanded()) {\n <div class=\"ax-comment-replies-content\">\n <ng-content select=\"ax-comment-item\" />\n <ng-content select=\"ax-comment-reply-more\" />\n </div>\n }\n </div>\n}\n", styles: ["@layer properties;@layer components{ax-comment-item{display:block;border-radius:.25rem;padding:calc(var(--spacing, .25rem) * 1);transition-property:background;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: 1s;transition-duration:1s;--tw-ease: var(--ease-in-out, cubic-bezier(.4, 0, .2, 1));transition-timing-function:var(--ease-in-out, cubic-bezier(.4, 0, .2, 1))}ax-comment-item:not(:last-child){margin-bottom:calc(var(--spacing, .25rem) * 4)}ax-comment-item.ax-state-highlight{background-color:rgba(var(--ax-sys-color-primary-surface),.1)}ax-comment-item .ax-comment-header{display:flex;align-items:center;justify-content:space-between}ax-comment-item .ax-comment-header .ax-comment-header-start{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 2)}ax-comment-item .ax-comment-header .ax-comment-header-start .ax-comment-header-content{display:flex;align-items:baseline;gap:calc(var(--spacing, .25rem) * 2)}ax-comment-item .ax-comment-header ax-title{--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500)}ax-comment-item .ax-comment-body{margin-inline-start:calc(var(--spacing, .25rem) * 12);padding-top:calc(var(--spacing, .25rem) * 1);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgba(var(--ax-sys-color-on-surface))}ax-comment-item .ax-comment-actions{margin-top:calc(var(--spacing, .25rem) * 2);display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 4);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)))}ax-comment-item .ax-comment-actions ax-comment-like,ax-comment-item .ax-comment-actions ax-comment-reply-text{cursor:pointer;-webkit-user-select:none;user-select:none}ax-comment-item .ax-comment-replies{margin-inline-start:calc(var(--spacing, .25rem) * 10);margin-top:calc(var(--spacing, .25rem) * 2)}ax-comment-item .ax-comment-replies .ax-comment-replies-toggle{display:inline-flex;cursor:pointer;align-items:center;gap:calc(var(--spacing, .25rem) * 1);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-primary-surface));-webkit-user-select:none;user-select:none}ax-comment-item .ax-comment-replies .ax-comment-replies-toggle:hover{text-decoration-line:underline}ax-comment-item .ax-comment-replies .ax-comment-replies-content{margin-top:calc(var(--spacing, .25rem) * 2)}ax-comment-item .ax-comment-replies ax-comment-reply-more{cursor:pointer;font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-primary-surface))}ax-comment-item .ax-comment-replies ax-comment-reply-more:hover{text-decoration-line:underline}}@property --tw-duration{syntax: \"*\"; inherits: false;}@property --tw-ease{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-duration: initial;--tw-ease: initial;--tw-font-weight: initial}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
78
- }], ctorParameters: () => [], propDecorators: { avatar: [{ type: i0.ContentChild, args: [i0.forwardRef(() => AXAvatarComponent), { isSignal: true }] }], replyCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "replyCount", required: false }] }], repliesExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "repliesExpanded", required: false }] }, { type: i0.Output, args: ["repliesExpandedChange"] }] } });
91
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentItemTemplateDirective, decorators: [{
92
+ type: Directive,
93
+ args: [{
94
+ selector: 'ng-template[axCommentItem]',
95
+ }]
96
+ }], ctorParameters: () => [{ type: i0.TemplateRef }] });
79
97
 
80
98
  /**
81
99
  * A component for displaying date on a comment.
@@ -84,11 +102,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
84
102
  */
85
103
  class AXCommentDateComponent {
86
104
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentDateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
87
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: AXCommentDateComponent, isStandalone: true, selector: "ax-comment-date", providers: [{ provide: AXComponent, useExisting: AXCommentDateComponent }], ngImport: i0, template: '<ng-content />', isInline: true, styles: ["@layer components{ax-comment-date{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgba(var(--ax-sys-color-on-surface))}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], encapsulation: i0.ViewEncapsulation.None }); }
105
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: AXCommentDateComponent, isStandalone: true, selector: "ax-comment-date", providers: [{ provide: AXComponent, useExisting: AXCommentDateComponent }], ngImport: i0, template: '<ng-content />', isInline: true, styles: ["@layer properties;@layer components{ax-comment-date{display:inline-flex;align-items:center;font-size:12px;--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);--tw-font-weight: var(--font-weight-normal, 400);font-weight:var(--font-weight-normal, 400);color:rgba(var(--ax-sys-color-on-surface))}@supports (color: color-mix(in lab,red,red)){ax-comment-date{color:color-mix(in oklab,rgba(var(--ax-sys-color-on-surface)) 55%,transparent)}}ax-comment-date:before{content:\"\\b7\";margin-inline:.4rem .35rem;opacity:.7}}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading: initial;--tw-font-weight: initial}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
88
106
  }
89
107
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentDateComponent, decorators: [{
90
108
  type: Component,
91
- args: [{ selector: 'ax-comment-date', template: '<ng-content />', encapsulation: ViewEncapsulation.None, providers: [{ provide: AXComponent, useExisting: AXCommentDateComponent }], styles: ["@layer components{ax-comment-date{font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgba(var(--ax-sys-color-on-surface))}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
109
+ args: [{ selector: 'ax-comment-date', template: '<ng-content />', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: AXComponent, useExisting: AXCommentDateComponent }], styles: ["@layer properties;@layer components{ax-comment-date{display:inline-flex;align-items:center;font-size:12px;--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);--tw-font-weight: var(--font-weight-normal, 400);font-weight:var(--font-weight-normal, 400);color:rgba(var(--ax-sys-color-on-surface))}@supports (color: color-mix(in lab,red,red)){ax-comment-date{color:color-mix(in oklab,rgba(var(--ax-sys-color-on-surface)) 55%,transparent)}}ax-comment-date:before{content:\"\\b7\";margin-inline:.4rem .35rem;opacity:.7}}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-leading: initial;--tw-font-weight: initial}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
92
110
  }] });
93
111
 
94
112
  /**
@@ -105,13 +123,184 @@ class AXCommentLikeComponent {
105
123
  this.like.update((prev) => !prev);
106
124
  }
107
125
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentLikeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
108
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: AXCommentLikeComponent, isStandalone: true, selector: "ax-comment-like", inputs: { like: { classPropertyName: "like", publicName: "like", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { like: "likeChange" }, providers: [{ provide: AXComponent, useExisting: AXCommentLikeComponent }], ngImport: i0, template: "<div class=\"ax-comment-like-container\" [class.ax-state-liked]=\"like()\" (click)=\"toggleLike()\">\n <ax-icon class=\"ax-icon ax-icon-heart\"></ax-icon>\n <ax-text><ng-content /></ax-text>\n</div>\n", styles: ["@layer properties;@layer components{.ax-comment-like-container{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 1);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s))}.ax-comment-like-container ax-icon{font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s))}.ax-comment-like-container:hover:not(.ax-state-liked){color:rgba(var(--ax-sys-color-danger-400))}.ax-comment-like-container.ax-state-liked{color:rgba(var(--ax-sys-color-danger-surface))}.ax-comment-like-container.ax-state-liked ax-icon{--tw-font-weight: var(--font-weight-bold, 700);font-weight:var(--font-weight-bold, 700)}}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }], encapsulation: i0.ViewEncapsulation.None }); }
126
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: AXCommentLikeComponent, isStandalone: true, selector: "ax-comment-like", inputs: { like: { classPropertyName: "like", publicName: "like", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { like: "likeChange" }, providers: [{ provide: AXComponent, useExisting: AXCommentLikeComponent }], ngImport: i0, template: "<button\n type=\"button\"\n class=\"ax-comment-like-button\"\n [class.ax-state-liked]=\"like()\"\n [attr.aria-pressed]=\"like()\"\n (click)=\"toggleLike()\"\n>\n <ax-icon [icon]=\"like() ? 'ax-icon ax-icon-solid ax-icon-heart' : 'ax-icon ax-icon-heart'\"></ax-icon>\n <ax-text><ng-content /></ax-text>\n</button>\n", styles: ["@layer properties;@layer components{ax-comment-like{display:inline-flex}.ax-comment-like-button{display:inline-flex;min-height:calc(var(--spacing, .25rem) * 7);cursor:pointer;align-items:center;gap:calc(var(--spacing, .25rem) * 1.5);border-style:var(--tw-border-style);border-width:0px;background-color:transparent;padding:calc(var(--spacing, .25rem) * 0);font-size:12.5px;--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-on-surface));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s))}@supports (color: color-mix(in lab,red,red)){.ax-comment-like-button{color:color-mix(in oklab,rgba(var(--ax-sys-color-on-surface)) 70%,transparent)}}.ax-comment-like-button ax-icon{font-size:14px;--tw-leading: 1;line-height:1}.ax-comment-like-button:hover:not(.ax-state-liked){color:rgba(var(--ax-sys-color-danger-400))}.ax-comment-like-button.ax-state-liked{color:rgba(var(--ax-sys-color-danger-surface))}.ax-comment-like-button:focus-visible{--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color: rgba(var(--ax-sys-color-primary-surface));--tw-ring-offset-width: 2px;--tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style: none;outline-style:none}}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-leading: initial;--tw-font-weight: initial;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
109
127
  }
110
128
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentLikeComponent, decorators: [{
111
129
  type: Component,
112
- args: [{ selector: 'ax-comment-like', encapsulation: ViewEncapsulation.None, imports: [AXDecoratorIconComponent, AXDecoratorGenericComponent], providers: [{ provide: AXComponent, useExisting: AXCommentLikeComponent }], template: "<div class=\"ax-comment-like-container\" [class.ax-state-liked]=\"like()\" (click)=\"toggleLike()\">\n <ax-icon class=\"ax-icon ax-icon-heart\"></ax-icon>\n <ax-text><ng-content /></ax-text>\n</div>\n", styles: ["@layer properties;@layer components{.ax-comment-like-container{display:flex;align-items:center;gap:calc(var(--spacing, .25rem) * 1);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s))}.ax-comment-like-container ax-icon{font-size:var(--text-base, 1rem);line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ));transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s))}.ax-comment-like-container:hover:not(.ax-state-liked){color:rgba(var(--ax-sys-color-danger-400))}.ax-comment-like-container.ax-state-liked{color:rgba(var(--ax-sys-color-danger-surface))}.ax-comment-like-container.ax-state-liked ax-icon{--tw-font-weight: var(--font-weight-bold, 700);font-weight:var(--font-weight-bold, 700)}}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight: initial}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
130
+ args: [{ selector: 'ax-comment-like', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXDecoratorIconComponent, AXDecoratorGenericComponent], providers: [{ provide: AXComponent, useExisting: AXCommentLikeComponent }], template: "<button\n type=\"button\"\n class=\"ax-comment-like-button\"\n [class.ax-state-liked]=\"like()\"\n [attr.aria-pressed]=\"like()\"\n (click)=\"toggleLike()\"\n>\n <ax-icon [icon]=\"like() ? 'ax-icon ax-icon-solid ax-icon-heart' : 'ax-icon ax-icon-heart'\"></ax-icon>\n <ax-text><ng-content /></ax-text>\n</button>\n", styles: ["@layer properties;@layer components{ax-comment-like{display:inline-flex}.ax-comment-like-button{display:inline-flex;min-height:calc(var(--spacing, .25rem) * 7);cursor:pointer;align-items:center;gap:calc(var(--spacing, .25rem) * 1.5);border-style:var(--tw-border-style);border-width:0px;background-color:transparent;padding:calc(var(--spacing, .25rem) * 0);font-size:12.5px;--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-on-surface));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s))}@supports (color: color-mix(in lab,red,red)){.ax-comment-like-button{color:color-mix(in oklab,rgba(var(--ax-sys-color-on-surface)) 70%,transparent)}}.ax-comment-like-button ax-icon{font-size:14px;--tw-leading: 1;line-height:1}.ax-comment-like-button:hover:not(.ax-state-liked){color:rgba(var(--ax-sys-color-danger-400))}.ax-comment-like-button.ax-state-liked{color:rgba(var(--ax-sys-color-danger-surface))}.ax-comment-like-button:focus-visible{--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color: rgba(var(--ax-sys-color-primary-surface));--tw-ring-offset-width: 2px;--tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style: none;outline-style:none}}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-leading: initial;--tw-font-weight: initial;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
113
131
  }], propDecorators: { like: [{ type: i0.Input, args: [{ isSignal: true, alias: "like", required: true }] }, { type: i0.Output, args: ["likeChange"] }] } });
114
132
 
133
+ /**
134
+ * A component for displaying the reply action on a comment.
135
+ *
136
+ * @category Components
137
+ */
138
+ class AXCommentReplyTextComponent {
139
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentReplyTextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
140
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: AXCommentReplyTextComponent, isStandalone: true, selector: "ax-comment-reply-text", providers: [{ provide: AXComponent, useExisting: AXCommentReplyTextComponent }], ngImport: i0, template: `
141
+ <button type="button" class="ax-comment-reply-button">
142
+ <ax-icon icon="ax-icon ax-icon-arrow-turn-left"></ax-icon>
143
+ <ax-text>{{ '@acorex:comment.reply' | translate | async }}</ax-text>
144
+ </button>
145
+ `, isInline: true, styles: ["@layer properties;@layer components{ax-comment-reply-text{display:inline-flex}.ax-comment-reply-button{display:inline-flex;min-height:calc(var(--spacing, .25rem) * 7);cursor:pointer;align-items:center;gap:calc(var(--spacing, .25rem) * 1);border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:0px;background-color:transparent;padding:calc(var(--spacing, .25rem) * 0);font-size:12.5px;--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-on-surface))}@supports (color: color-mix(in lab,red,red)){.ax-comment-reply-button{color:color-mix(in oklab,rgba(var(--ax-sys-color-on-surface)) 60%,transparent)}}.ax-comment-reply-button ax-icon{font-size:13px;--tw-leading: 1;line-height:1}.ax-comment-reply-button:hover{color:rgba(var(--ax-sys-color-on-surface))}.ax-comment-reply-button:focus-visible{--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color: rgba(var(--ax-sys-color-primary-surface));--tw-ring-offset-width: 2px;--tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style: none;outline-style:none}}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-leading: initial;--tw-font-weight: initial;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "component", type: AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
146
+ }
147
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentReplyTextComponent, decorators: [{
148
+ type: Component,
149
+ args: [{ selector: 'ax-comment-reply-text', template: `
150
+ <button type="button" class="ax-comment-reply-button">
151
+ <ax-icon icon="ax-icon ax-icon-arrow-turn-left"></ax-icon>
152
+ <ax-text>{{ '@acorex:comment.reply' | translate | async }}</ax-text>
153
+ </button>
154
+ `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXDecoratorGenericComponent, AXDecoratorIconComponent, AXTranslatorPipe, AsyncPipe], providers: [{ provide: AXComponent, useExisting: AXCommentReplyTextComponent }], styles: ["@layer properties;@layer components{ax-comment-reply-text{display:inline-flex}.ax-comment-reply-button{display:inline-flex;min-height:calc(var(--spacing, .25rem) * 7);cursor:pointer;align-items:center;gap:calc(var(--spacing, .25rem) * 1);border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:0px;background-color:transparent;padding:calc(var(--spacing, .25rem) * 0);font-size:12.5px;--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-on-surface))}@supports (color: color-mix(in lab,red,red)){.ax-comment-reply-button{color:color-mix(in oklab,rgba(var(--ax-sys-color-on-surface)) 60%,transparent)}}.ax-comment-reply-button ax-icon{font-size:13px;--tw-leading: 1;line-height:1}.ax-comment-reply-button:hover{color:rgba(var(--ax-sys-color-on-surface))}.ax-comment-reply-button:focus-visible{--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color: rgba(var(--ax-sys-color-primary-surface));--tw-ring-offset-width: 2px;--tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style: none;outline-style:none}}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-leading: initial;--tw-font-weight: initial;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
155
+ }] });
156
+
157
+ /**
158
+ * A component that represents an individual comment item in the comment system.
159
+ *
160
+ * @category Components
161
+ */
162
+ class AXCommentItemComponent {
163
+ constructor() {
164
+ this.parentComment = inject(AXCommentItemComponent, { optional: true, skipSelf: true });
165
+ this.isReply = this.parentComment != null;
166
+ this.projectedAvatar = contentChild(AXAvatarComponent, /* @ts-ignore */
167
+ ...(ngDevMode ? [{ debugName: "projectedAvatar" }] : /* istanbul ignore next */ []));
168
+ this.viewAvatar = viewChild(AXAvatarComponent, /* @ts-ignore */
169
+ ...(ngDevMode ? [{ debugName: "viewAvatar" }] : /* istanbul ignore next */ []));
170
+ /** Data item used by `ax-comment-view`. When set, the default layout is rendered internally. */
171
+ this.item = input(null, /* @ts-ignore */
172
+ ...(ngDevMode ? [{ debugName: "item" }] : /* istanbul ignore next */ []));
173
+ this.replyCount = input(/* @ts-ignore */
174
+ ...(ngDevMode ? [undefined, { debugName: "replyCount" }] : /* istanbul ignore next */ []));
175
+ /** Two-way bindable state controlling whether nested replies are visible. */
176
+ this.repliesExpanded = model(false, /* @ts-ignore */
177
+ ...(ngDevMode ? [{ debugName: "repliesExpanded" }] : /* istanbul ignore next */ []));
178
+ /** Whether replies for this item are currently being loaded. */
179
+ this.loading = input(false, /* @ts-ignore */
180
+ ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
181
+ /**
182
+ * Custom renderer for the item body. When omitted, the default layout
183
+ * (or projected slots) is used.
184
+ */
185
+ this.itemTemplate = input(null, /* @ts-ignore */
186
+ ...(ngDevMode ? [{ debugName: "itemTemplate" }] : /* istanbul ignore next */ []));
187
+ /** Context passed to `itemTemplate`. */
188
+ this.itemContext = input(null, /* @ts-ignore */
189
+ ...(ngDevMode ? [{ debugName: "itemContext" }] : /* istanbul ignore next */ []));
190
+ this.likeChange = output();
191
+ this.replyClick = output();
192
+ this.actionClick = output();
193
+ this.avatarSize = 48;
194
+ this.showDefaultDataLayout = computed(() => !!this.item() && !this.itemTemplate(), /* @ts-ignore */
195
+ ...(ngDevMode ? [{ debugName: "showDefaultDataLayout" }] : /* istanbul ignore next */ []));
196
+ this.useProjectedSlots = computed(() => !this.item() && !this.itemTemplate(), /* @ts-ignore */
197
+ ...(ngDevMode ? [{ debugName: "useProjectedSlots" }] : /* istanbul ignore next */ []));
198
+ this.itemActions = computed(() => this.item()?.actions ?? [], /* @ts-ignore */
199
+ ...(ngDevMode ? [{ debugName: "itemActions" }] : /* istanbul ignore next */ []));
200
+ this.showOverflowMenu = computed(() => this.showDefaultDataLayout() && this.itemActions().length > 0, /* @ts-ignore */
201
+ ...(ngDevMode ? [{ debugName: "showOverflowMenu" }] : /* istanbul ignore next */ []));
202
+ this.overflowItems = computed(() => this.toButtonItems(this.itemActions()), /* @ts-ignore */
203
+ ...(ngDevMode ? [{ debugName: "overflowItems" }] : /* istanbul ignore next */ []));
204
+ afterNextRender(() => {
205
+ if (this.itemTemplate())
206
+ return;
207
+ (this.projectedAvatar() ?? this.viewAvatar())?.size?.set(this.avatarSize);
208
+ });
209
+ }
210
+ getColor(data) {
211
+ return data.color ?? 'default';
212
+ }
213
+ getInitials(data) {
214
+ if (data.initials)
215
+ return data.initials;
216
+ return (data.author || '')
217
+ .split(/\s+/)
218
+ .filter(Boolean)
219
+ .map((part) => part[0])
220
+ .join('')
221
+ .slice(0, 2)
222
+ .toUpperCase();
223
+ }
224
+ handleLike(liked) {
225
+ this.likeChange.emit(liked);
226
+ }
227
+ handleReply(event) {
228
+ this.replyClick.emit(event);
229
+ }
230
+ handleOverflowClick(event) {
231
+ const action = this.findAction(this.itemActions(), event.name) ?? {
232
+ text: event.item?.text ?? event.name ?? '',
233
+ name: event.name,
234
+ data: event.data,
235
+ };
236
+ this.actionClick.emit(action);
237
+ }
238
+ toButtonItems(items) {
239
+ return items.map((item) => ({
240
+ name: item.name ?? item.text,
241
+ text: item.text,
242
+ icon: item.icon ?? '',
243
+ color: item.color,
244
+ disabled: item.disabled,
245
+ divided: item.break,
246
+ items: item.items?.length ? this.toButtonItems(item.items) : undefined,
247
+ }));
248
+ }
249
+ findAction(items, name) {
250
+ if (name == null)
251
+ return undefined;
252
+ for (const item of items) {
253
+ if ((item.name ?? item.text) === name)
254
+ return item;
255
+ const nested = item.items?.length ? this.findAction(item.items, name) : undefined;
256
+ if (nested)
257
+ return nested;
258
+ }
259
+ return undefined;
260
+ }
261
+ /**
262
+ * Toggles the collapse state of the comment replies section.
263
+ */
264
+ toggleReplies() {
265
+ this.repliesExpanded.update((v) => !v);
266
+ }
267
+ /**
268
+ * Expands the nested replies section.
269
+ */
270
+ showReplies() {
271
+ this.repliesExpanded.set(true);
272
+ }
273
+ /**
274
+ * Collapses the nested replies section.
275
+ */
276
+ hideReplies() {
277
+ this.repliesExpanded.set(false);
278
+ }
279
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
280
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: AXCommentItemComponent, isStandalone: true, selector: "ax-comment-item", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null }, replyCount: { classPropertyName: "replyCount", publicName: "replyCount", isSignal: true, isRequired: false, transformFunction: null }, repliesExpanded: { classPropertyName: "repliesExpanded", publicName: "repliesExpanded", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, itemTemplate: { classPropertyName: "itemTemplate", publicName: "itemTemplate", isSignal: true, isRequired: false, transformFunction: null }, itemContext: { classPropertyName: "itemContext", publicName: "itemContext", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { repliesExpanded: "repliesExpandedChange", likeChange: "likeChange", replyClick: "replyClick", actionClick: "actionClick" }, host: { properties: { "class.ax-comment-item-reply": "isReply", "class.ax-comment-item-custom": "!!itemTemplate()" } }, providers: [{ provide: AXComponent, useExisting: AXCommentItemComponent }], queries: [{ propertyName: "projectedAvatar", first: true, predicate: AXAvatarComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "viewAvatar", first: true, predicate: AXAvatarComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"ax-comment-layout\">\n @if (showDefaultDataLayout()) {\n @if (item(); as data) {\n <ax-avatar [color]=\"getColor(data)\" [size]=\"avatarSize\" look=\"twotone\" shape=\"rounded\">\n @if (data.avatar) {\n <ax-image [src]=\"data.avatar\"></ax-image>\n } @else {\n <ax-text>{{ getInitials(data) }}</ax-text>\n }\n </ax-avatar>\n }\n }\n <ng-content select=\"ax-avatar\" />\n\n <div class=\"ax-comment-main\">\n @if (itemTemplate(); as tpl) {\n <div class=\"ax-comment-custom-body\">\n <ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"itemContext()\" />\n </div>\n } @else if (showDefaultDataLayout()) {\n @if (item(); as data) {\n <div class=\"ax-comment-header\">\n <div class=\"ax-comment-header-meta\">\n <ax-title>{{ data.author }}</ax-title>\n @if (data.isYou) {\n <ax-badge\n class=\"ax-sm ax-pill ax-comment-you-badge\"\n look=\"twotone\"\n color=\"primary\"\n [text]=\"('@acorex:comment.you' | translate | async) ?? 'You'\"\n ></ax-badge>\n }\n @if (data.date) {\n <ax-comment-date>{{ data.date }}</ax-comment-date>\n }\n </div>\n @if (showOverflowMenu()) {\n <ax-dropdown-button\n class=\"ax-sm ax-comment-menu-trigger\"\n mode=\"dropdown\"\n look=\"blank\"\n [iconOnly]=\"true\"\n text=\"More\"\n >\n <ax-prefix>\n <ax-icon icon=\"ax-icon ax-icon-more-horizontal\"></ax-icon>\n </ax-prefix>\n <ax-button-item-list [items]=\"overflowItems()\" (onItemClick)=\"handleOverflowClick($event)\">\n </ax-button-item-list>\n </ax-dropdown-button>\n }\n </div>\n <div class=\"ax-comment-body\">\n <ax-content>\n <div [innerHTML]=\"data.content\"></div>\n </ax-content>\n </div>\n }\n }\n\n <div class=\"ax-comment-default\" [hidden]=\"!useProjectedSlots()\">\n <div class=\"ax-comment-header\">\n <div class=\"ax-comment-header-meta\">\n <ng-content select=\"ax-title\" />\n <ng-content select=\"ax-subtitle\" />\n <ng-content select=\"ax-badge\" />\n <ng-content select=\"ax-comment-date\" />\n </div>\n <ng-content select=\"ax-comment-menu-options\" />\n </div>\n <div class=\"ax-comment-body\">\n <ng-content select=\"ax-content\" />\n </div>\n </div>\n\n <div class=\"ax-comment-actions\">\n @if (item(); as data) {\n <ax-comment-like [like]=\"!!data.liked\" (likeChange)=\"handleLike($event)\">\n {{ data.likes ?? 0 }}\n </ax-comment-like>\n <ax-comment-reply-text (click)=\"handleReply($event)\"></ax-comment-reply-text>\n }\n <ng-content select=\"ax-comment-like\" />\n <ng-content select=\"ax-comment-reply-text\" />\n @if (replyCount()) {\n <button\n type=\"button\"\n class=\"ax-comment-replies-toggle\"\n [attr.aria-expanded]=\"repliesExpanded()\"\n [attr.aria-busy]=\"loading()\"\n [disabled]=\"loading()\"\n (click)=\"toggleReplies()\"\n >\n <ax-icon\n [icon]=\"\n loading()\n ? 'ax-icon ax-icon-reload'\n : repliesExpanded()\n ? 'ax-icon ax-icon-chevron-up'\n : 'ax-icon ax-icon-chevron-down'\n \"\n [class.ax-comment-loading-icon]=\"loading()\"\n ></ax-icon>\n <span>\n {{ replyCount() }}\n {{ ((replyCount() ?? 0) > 1 ? '@acorex:comment.replies' : '@acorex:comment.reply') | translate | async }}\n </span>\n </button>\n }\n </div>\n\n <div class=\"ax-comment-replies\" [hidden]=\"!(replyCount() && repliesExpanded())\">\n @if (loading()) {\n <div class=\"ax-comment-replies-loading\">\n <ax-icon icon=\"ax-icon ax-icon-reload\" class=\"ax-comment-loading-icon\"></ax-icon>\n </div>\n }\n <ng-content select=\"ax-comment-item\" />\n <ng-content select=\"ax-comment-reply-more\" />\n <ng-content />\n </div>\n </div>\n</div>\n", styles: ["@layer properties;@layer components{ax-comment-item{display:block;transition-property:background-color;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .7s;transition-duration:.7s;--tw-ease: var(--ease-in-out, cubic-bezier(.4, 0, .2, 1));transition-timing-function:var(--ease-in-out, cubic-bezier(.4, 0, .2, 1));padding-block:var(--ax-comp-comment-padding-y, 12px)}ax-comment-item.ax-state-highlight{background-color:color-mix(in srgb,rgba(var(--ax-sys-color-primary-surface)) 8%,transparent);border-radius:8px}@supports (color: color-mix(in lab,red,red)){ax-comment-item.ax-state-highlight{background-color:color-mix(in srgb,var(--color-primary) 8%,transparent)}}ax-comment-item .ax-comment-layout{display:flex;min-width:calc(var(--spacing, .25rem) * 0);align-items:flex-start;gap:var(--ax-comp-comment-gap, .5rem)}ax-comment-item .ax-comment-layout>ax-avatar{flex-shrink:0}ax-comment-item .ax-comment-main{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;flex-direction:column}ax-comment-item .ax-comment-default[hidden]{display:none}ax-comment-item .ax-comment-header{display:flex;min-width:calc(var(--spacing, .25rem) * 0);align-items:center;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 2)}ax-comment-item .ax-comment-custom-body{width:100%;min-width:calc(var(--spacing, .25rem) * 0)}ax-comment-item .ax-comment-menu-trigger{flex-shrink:0}@media(hover:hover){ax-comment-item .ax-comment-menu-trigger{opacity:0%;transition:opacity .15s ease}ax-comment-item .ax-comment-layout:has(>ax-avatar:hover)>.ax-comment-main>.ax-comment-header>.ax-comment-menu-trigger,ax-comment-item .ax-comment-main:has(>.ax-comment-header:hover)>.ax-comment-header>.ax-comment-menu-trigger,ax-comment-item .ax-comment-main:has(>.ax-comment-body:hover)>.ax-comment-header>.ax-comment-menu-trigger,ax-comment-item .ax-comment-main:has(>.ax-comment-actions:hover)>.ax-comment-header>.ax-comment-menu-trigger,ax-comment-item .ax-comment-header:focus-within>.ax-comment-menu-trigger{opacity:100%}}ax-comment-item .ax-comment-header-meta{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex-wrap:wrap;align-items:center}ax-comment-item ax-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;--tw-leading: calc(var(--spacing, .25rem) * 5);line-height:calc(var(--spacing, .25rem) * 5);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-on-surface))}ax-comment-item ax-subtitle{margin-inline-start:calc(var(--spacing, .25rem) * 1.5);font-size:11px;--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);--tw-font-weight: var(--font-weight-normal, 400);font-weight:var(--font-weight-normal, 400);color:rgba(var(--ax-sys-color-on-surface))}@supports (color: color-mix(in lab,red,red)){ax-comment-item ax-subtitle{color:color-mix(in oklab,rgba(var(--ax-sys-color-on-surface)) 55%,transparent)}}ax-comment-item .ax-comment-you-badge{margin-inline-start:calc(var(--spacing, .25rem) * 1.5);flex-shrink:0}ax-comment-item .ax-comment-body{margin-top:calc(var(--spacing, .25rem) * 1)}ax-comment-item ax-content{display:block;font-size:13.5px;overflow-wrap:break-word;color:rgba(var(--ax-sys-color-on-surface));line-height:1.6}ax-comment-item ax-content a,ax-comment-item ax-content .ax-mention{--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-primary-surface));text-decoration-line:none}ax-comment-item ax-content a:hover,ax-comment-item ax-content .ax-mention:hover{text-decoration-line:underline}ax-comment-item ax-content ul,ax-comment-item ax-content ol{margin-top:calc(var(--spacing, .25rem) * 1);margin-bottom:calc(var(--spacing, .25rem) * 0);padding-inline-start:calc(var(--spacing, .25rem) * 5)}ax-comment-item ax-content li{margin-block:calc(var(--spacing, .25rem) * .5)}ax-comment-item ax-content p{margin:calc(var(--spacing, .25rem) * 0)}ax-comment-item .ax-comment-actions{margin-top:calc(var(--spacing, .25rem) * 1);display:flex;min-height:calc(var(--spacing, .25rem) * 7);flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 5)}ax-comment-item ax-comment-like,ax-comment-item ax-comment-reply-text,ax-comment-item .ax-comment-replies-toggle{-webkit-user-select:none;user-select:none}ax-comment-item .ax-comment-replies-toggle{display:inline-flex;min-height:calc(var(--spacing, .25rem) * 7);cursor:pointer;align-items:center;gap:calc(var(--spacing, .25rem) * 1);border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:0px;background-color:transparent;padding:calc(var(--spacing, .25rem) * 0);font-size:12.5px;--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-primary-surface))}ax-comment-item .ax-comment-replies-toggle ax-icon{font-size:11px;--tw-leading: 1;line-height:1}ax-comment-item .ax-comment-replies-toggle:hover:not(:disabled){text-decoration-line:underline}ax-comment-item .ax-comment-replies-toggle:disabled{cursor:wait;opacity:70%}ax-comment-item .ax-comment-replies-toggle:focus-visible{--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color: rgba(var(--ax-sys-color-primary-surface));--tw-ring-offset-width: 2px;--tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style: none;outline-style:none}ax-comment-item .ax-comment-loading-icon{animation:var(--animate-spin, spin 1s linear infinite)}ax-comment-item .ax-comment-replies-loading{display:flex;min-height:calc(var(--spacing, .25rem) * 8);align-items:center;padding-block:calc(var(--spacing, .25rem) * 1);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgba(var(--ax-sys-color-on-surface))}@supports (color: color-mix(in lab,red,red)){ax-comment-item .ax-comment-replies-loading{color:color-mix(in oklab,rgba(var(--ax-sys-color-on-surface)) 40%,transparent)}}ax-comment-item .ax-comment-replies{margin-top:calc(var(--spacing, .25rem) * 3);display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex-direction:column}ax-comment-item .ax-comment-replies[hidden]{display:none}ax-comment-item ax-comment-reply-more{margin-top:calc(var(--spacing, .25rem) * 1);cursor:pointer;font-size:12.5px;--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-primary-surface))}ax-comment-item ax-comment-reply-more:hover{text-decoration-line:underline}ax-comment-item ax-comment-menu-options{margin-inline-end:calc(var(--spacing, .25rem) * -1);margin-top:calc(var(--spacing, .25rem) * -1);flex-shrink:0}ax-comment-item.ax-comment-item-reply{padding-block:10px}ax-comment-item.ax-comment-item-custom .ax-comment-actions{margin-top:calc(var(--spacing, .25rem) * 2)}ax-comment-item.ax-comment-item-custom .ax-comment-replies{margin-inline-start:.5rem;padding-inline-start:1.25rem;border-inline-start:2px solid color-mix(in srgb,rgba(var(--ax-sys-color-primary-surface)) 35%,transparent)}@supports (color: color-mix(in lab,red,red)){ax-comment-item.ax-comment-item-custom .ax-comment-replies{border-inline-start:2px solid color-mix(in srgb,var(--color-primary) 35%,transparent)}}ax-comment-item.ax-comment-item-custom.ax-comment-item-reply{padding-block:8px}}@property --tw-duration{syntax: \"*\"; inherits: false;}@property --tw-ease{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@keyframes spin{to{transform:rotate(360deg)}}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-duration: initial;--tw-ease: initial;--tw-leading: initial;--tw-font-weight: initial;--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AXAvatarComponent, selector: "ax-avatar", inputs: ["color", "size", "shape", "look"], outputs: ["sizeChange"] }, { kind: "component", type: AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "component", type: AXImageComponent, selector: "ax-image", inputs: ["width", "height", "overlayMode", "src", "alt", "priority", "lazy"], outputs: ["onLoad", "onError"] }, { kind: "component", type: AXCommentDateComponent, selector: "ax-comment-date" }, { kind: "component", type: AXCommentLikeComponent, selector: "ax-comment-like", inputs: ["like"], outputs: ["likeChange"] }, { kind: "component", type: AXCommentReplyTextComponent, selector: "ax-comment-reply-text" }, { kind: "component", type: AXDropdownButtonComponent, selector: "ax-dropdown-button", inputs: ["disabled", "size", "text", "selected", "color", "look", "type", "mode", "iconOnly"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "lookChange", "colorChange", "disabledChange"] }, { kind: "component", type: AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items", "closeParentOnClick", "lockOnLoading"], outputs: ["onItemClick"] }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
281
+ }
282
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentItemComponent, decorators: [{
283
+ type: Component,
284
+ args: [{ selector: 'ax-comment-item', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
285
+ AXTranslatorPipe,
286
+ AsyncPipe,
287
+ AXDecoratorIconComponent,
288
+ AXDecoratorGenericComponent,
289
+ NgTemplateOutlet,
290
+ AXAvatarComponent,
291
+ AXBadgeComponent,
292
+ AXImageComponent,
293
+ AXCommentDateComponent,
294
+ AXCommentLikeComponent,
295
+ AXCommentReplyTextComponent,
296
+ AXDropdownButtonComponent,
297
+ AXButtonItemListComponent,
298
+ ], providers: [{ provide: AXComponent, useExisting: AXCommentItemComponent }], host: {
299
+ '[class.ax-comment-item-reply]': 'isReply',
300
+ '[class.ax-comment-item-custom]': '!!itemTemplate()',
301
+ }, template: "<div class=\"ax-comment-layout\">\n @if (showDefaultDataLayout()) {\n @if (item(); as data) {\n <ax-avatar [color]=\"getColor(data)\" [size]=\"avatarSize\" look=\"twotone\" shape=\"rounded\">\n @if (data.avatar) {\n <ax-image [src]=\"data.avatar\"></ax-image>\n } @else {\n <ax-text>{{ getInitials(data) }}</ax-text>\n }\n </ax-avatar>\n }\n }\n <ng-content select=\"ax-avatar\" />\n\n <div class=\"ax-comment-main\">\n @if (itemTemplate(); as tpl) {\n <div class=\"ax-comment-custom-body\">\n <ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"itemContext()\" />\n </div>\n } @else if (showDefaultDataLayout()) {\n @if (item(); as data) {\n <div class=\"ax-comment-header\">\n <div class=\"ax-comment-header-meta\">\n <ax-title>{{ data.author }}</ax-title>\n @if (data.isYou) {\n <ax-badge\n class=\"ax-sm ax-pill ax-comment-you-badge\"\n look=\"twotone\"\n color=\"primary\"\n [text]=\"('@acorex:comment.you' | translate | async) ?? 'You'\"\n ></ax-badge>\n }\n @if (data.date) {\n <ax-comment-date>{{ data.date }}</ax-comment-date>\n }\n </div>\n @if (showOverflowMenu()) {\n <ax-dropdown-button\n class=\"ax-sm ax-comment-menu-trigger\"\n mode=\"dropdown\"\n look=\"blank\"\n [iconOnly]=\"true\"\n text=\"More\"\n >\n <ax-prefix>\n <ax-icon icon=\"ax-icon ax-icon-more-horizontal\"></ax-icon>\n </ax-prefix>\n <ax-button-item-list [items]=\"overflowItems()\" (onItemClick)=\"handleOverflowClick($event)\">\n </ax-button-item-list>\n </ax-dropdown-button>\n }\n </div>\n <div class=\"ax-comment-body\">\n <ax-content>\n <div [innerHTML]=\"data.content\"></div>\n </ax-content>\n </div>\n }\n }\n\n <div class=\"ax-comment-default\" [hidden]=\"!useProjectedSlots()\">\n <div class=\"ax-comment-header\">\n <div class=\"ax-comment-header-meta\">\n <ng-content select=\"ax-title\" />\n <ng-content select=\"ax-subtitle\" />\n <ng-content select=\"ax-badge\" />\n <ng-content select=\"ax-comment-date\" />\n </div>\n <ng-content select=\"ax-comment-menu-options\" />\n </div>\n <div class=\"ax-comment-body\">\n <ng-content select=\"ax-content\" />\n </div>\n </div>\n\n <div class=\"ax-comment-actions\">\n @if (item(); as data) {\n <ax-comment-like [like]=\"!!data.liked\" (likeChange)=\"handleLike($event)\">\n {{ data.likes ?? 0 }}\n </ax-comment-like>\n <ax-comment-reply-text (click)=\"handleReply($event)\"></ax-comment-reply-text>\n }\n <ng-content select=\"ax-comment-like\" />\n <ng-content select=\"ax-comment-reply-text\" />\n @if (replyCount()) {\n <button\n type=\"button\"\n class=\"ax-comment-replies-toggle\"\n [attr.aria-expanded]=\"repliesExpanded()\"\n [attr.aria-busy]=\"loading()\"\n [disabled]=\"loading()\"\n (click)=\"toggleReplies()\"\n >\n <ax-icon\n [icon]=\"\n loading()\n ? 'ax-icon ax-icon-reload'\n : repliesExpanded()\n ? 'ax-icon ax-icon-chevron-up'\n : 'ax-icon ax-icon-chevron-down'\n \"\n [class.ax-comment-loading-icon]=\"loading()\"\n ></ax-icon>\n <span>\n {{ replyCount() }}\n {{ ((replyCount() ?? 0) > 1 ? '@acorex:comment.replies' : '@acorex:comment.reply') | translate | async }}\n </span>\n </button>\n }\n </div>\n\n <div class=\"ax-comment-replies\" [hidden]=\"!(replyCount() && repliesExpanded())\">\n @if (loading()) {\n <div class=\"ax-comment-replies-loading\">\n <ax-icon icon=\"ax-icon ax-icon-reload\" class=\"ax-comment-loading-icon\"></ax-icon>\n </div>\n }\n <ng-content select=\"ax-comment-item\" />\n <ng-content select=\"ax-comment-reply-more\" />\n <ng-content />\n </div>\n </div>\n</div>\n", styles: ["@layer properties;@layer components{ax-comment-item{display:block;transition-property:background-color;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .7s;transition-duration:.7s;--tw-ease: var(--ease-in-out, cubic-bezier(.4, 0, .2, 1));transition-timing-function:var(--ease-in-out, cubic-bezier(.4, 0, .2, 1));padding-block:var(--ax-comp-comment-padding-y, 12px)}ax-comment-item.ax-state-highlight{background-color:color-mix(in srgb,rgba(var(--ax-sys-color-primary-surface)) 8%,transparent);border-radius:8px}@supports (color: color-mix(in lab,red,red)){ax-comment-item.ax-state-highlight{background-color:color-mix(in srgb,var(--color-primary) 8%,transparent)}}ax-comment-item .ax-comment-layout{display:flex;min-width:calc(var(--spacing, .25rem) * 0);align-items:flex-start;gap:var(--ax-comp-comment-gap, .5rem)}ax-comment-item .ax-comment-layout>ax-avatar{flex-shrink:0}ax-comment-item .ax-comment-main{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;flex-direction:column}ax-comment-item .ax-comment-default[hidden]{display:none}ax-comment-item .ax-comment-header{display:flex;min-width:calc(var(--spacing, .25rem) * 0);align-items:center;justify-content:space-between;gap:calc(var(--spacing, .25rem) * 2)}ax-comment-item .ax-comment-custom-body{width:100%;min-width:calc(var(--spacing, .25rem) * 0)}ax-comment-item .ax-comment-menu-trigger{flex-shrink:0}@media(hover:hover){ax-comment-item .ax-comment-menu-trigger{opacity:0%;transition:opacity .15s ease}ax-comment-item .ax-comment-layout:has(>ax-avatar:hover)>.ax-comment-main>.ax-comment-header>.ax-comment-menu-trigger,ax-comment-item .ax-comment-main:has(>.ax-comment-header:hover)>.ax-comment-header>.ax-comment-menu-trigger,ax-comment-item .ax-comment-main:has(>.ax-comment-body:hover)>.ax-comment-header>.ax-comment-menu-trigger,ax-comment-item .ax-comment-main:has(>.ax-comment-actions:hover)>.ax-comment-header>.ax-comment-menu-trigger,ax-comment-item .ax-comment-header:focus-within>.ax-comment-menu-trigger{opacity:100%}}ax-comment-item .ax-comment-header-meta{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex-wrap:wrap;align-items:center}ax-comment-item ax-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;--tw-leading: calc(var(--spacing, .25rem) * 5);line-height:calc(var(--spacing, .25rem) * 5);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-on-surface))}ax-comment-item ax-subtitle{margin-inline-start:calc(var(--spacing, .25rem) * 1.5);font-size:11px;--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);--tw-font-weight: var(--font-weight-normal, 400);font-weight:var(--font-weight-normal, 400);color:rgba(var(--ax-sys-color-on-surface))}@supports (color: color-mix(in lab,red,red)){ax-comment-item ax-subtitle{color:color-mix(in oklab,rgba(var(--ax-sys-color-on-surface)) 55%,transparent)}}ax-comment-item .ax-comment-you-badge{margin-inline-start:calc(var(--spacing, .25rem) * 1.5);flex-shrink:0}ax-comment-item .ax-comment-body{margin-top:calc(var(--spacing, .25rem) * 1)}ax-comment-item ax-content{display:block;font-size:13.5px;overflow-wrap:break-word;color:rgba(var(--ax-sys-color-on-surface));line-height:1.6}ax-comment-item ax-content a,ax-comment-item ax-content .ax-mention{--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-primary-surface));text-decoration-line:none}ax-comment-item ax-content a:hover,ax-comment-item ax-content .ax-mention:hover{text-decoration-line:underline}ax-comment-item ax-content ul,ax-comment-item ax-content ol{margin-top:calc(var(--spacing, .25rem) * 1);margin-bottom:calc(var(--spacing, .25rem) * 0);padding-inline-start:calc(var(--spacing, .25rem) * 5)}ax-comment-item ax-content li{margin-block:calc(var(--spacing, .25rem) * .5)}ax-comment-item ax-content p{margin:calc(var(--spacing, .25rem) * 0)}ax-comment-item .ax-comment-actions{margin-top:calc(var(--spacing, .25rem) * 1);display:flex;min-height:calc(var(--spacing, .25rem) * 7);flex-wrap:wrap;align-items:center;gap:calc(var(--spacing, .25rem) * 5)}ax-comment-item ax-comment-like,ax-comment-item ax-comment-reply-text,ax-comment-item .ax-comment-replies-toggle{-webkit-user-select:none;user-select:none}ax-comment-item .ax-comment-replies-toggle{display:inline-flex;min-height:calc(var(--spacing, .25rem) * 7);cursor:pointer;align-items:center;gap:calc(var(--spacing, .25rem) * 1);border-radius:var(--radius-md, .375rem);border-style:var(--tw-border-style);border-width:0px;background-color:transparent;padding:calc(var(--spacing, .25rem) * 0);font-size:12.5px;--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-primary-surface))}ax-comment-item .ax-comment-replies-toggle ax-icon{font-size:11px;--tw-leading: 1;line-height:1}ax-comment-item .ax-comment-replies-toggle:hover:not(:disabled){text-decoration-line:underline}ax-comment-item .ax-comment-replies-toggle:disabled{cursor:wait;opacity:70%}ax-comment-item .ax-comment-replies-toggle:focus-visible{--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color: rgba(var(--ax-sys-color-primary-surface));--tw-ring-offset-width: 2px;--tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style: none;outline-style:none}ax-comment-item .ax-comment-loading-icon{animation:var(--animate-spin, spin 1s linear infinite)}ax-comment-item .ax-comment-replies-loading{display:flex;min-height:calc(var(--spacing, .25rem) * 8);align-items:center;padding-block:calc(var(--spacing, .25rem) * 1);font-size:var(--text-sm, .875rem);line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:rgba(var(--ax-sys-color-on-surface))}@supports (color: color-mix(in lab,red,red)){ax-comment-item .ax-comment-replies-loading{color:color-mix(in oklab,rgba(var(--ax-sys-color-on-surface)) 40%,transparent)}}ax-comment-item .ax-comment-replies{margin-top:calc(var(--spacing, .25rem) * 3);display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex-direction:column}ax-comment-item .ax-comment-replies[hidden]{display:none}ax-comment-item ax-comment-reply-more{margin-top:calc(var(--spacing, .25rem) * 1);cursor:pointer;font-size:12.5px;--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-primary-surface))}ax-comment-item ax-comment-reply-more:hover{text-decoration-line:underline}ax-comment-item ax-comment-menu-options{margin-inline-end:calc(var(--spacing, .25rem) * -1);margin-top:calc(var(--spacing, .25rem) * -1);flex-shrink:0}ax-comment-item.ax-comment-item-reply{padding-block:10px}ax-comment-item.ax-comment-item-custom .ax-comment-actions{margin-top:calc(var(--spacing, .25rem) * 2)}ax-comment-item.ax-comment-item-custom .ax-comment-replies{margin-inline-start:.5rem;padding-inline-start:1.25rem;border-inline-start:2px solid color-mix(in srgb,rgba(var(--ax-sys-color-primary-surface)) 35%,transparent)}@supports (color: color-mix(in lab,red,red)){ax-comment-item.ax-comment-item-custom .ax-comment-replies{border-inline-start:2px solid color-mix(in srgb,var(--color-primary) 35%,transparent)}}ax-comment-item.ax-comment-item-custom.ax-comment-item-reply{padding-block:8px}}@property --tw-duration{syntax: \"*\"; inherits: false;}@property --tw-ease{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@keyframes spin{to{transform:rotate(360deg)}}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-duration: initial;--tw-ease: initial;--tw-leading: initial;--tw-font-weight: initial;--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
302
+ }], ctorParameters: () => [], propDecorators: { projectedAvatar: [{ type: i0.ContentChild, args: [i0.forwardRef(() => AXAvatarComponent), { isSignal: true }] }], viewAvatar: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXAvatarComponent), { isSignal: true }] }], item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: false }] }], replyCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "replyCount", required: false }] }], repliesExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "repliesExpanded", required: false }] }, { type: i0.Output, args: ["repliesExpandedChange"] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], itemTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemTemplate", required: false }] }], itemContext: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemContext", required: false }] }], likeChange: [{ type: i0.Output, args: ["likeChange"] }], replyClick: [{ type: i0.Output, args: ["replyClick"] }], actionClick: [{ type: i0.Output, args: ["actionClick"] }] } });
303
+
115
304
  /**
116
305
  * A component for displaying and managing menu options on a comment.
117
306
  *
@@ -119,7 +308,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
119
308
  */
120
309
  class AXMenuOptionsComponent {
121
310
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXMenuOptionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
122
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: AXMenuOptionsComponent, isStandalone: true, selector: "ax-comment-menu-options", providers: [{ provide: AXComponent, useExisting: AXMenuOptionsComponent }], ngImport: i0, template: '<ng-content />', isInline: true, encapsulation: i0.ViewEncapsulation.None }); }
311
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: AXMenuOptionsComponent, isStandalone: true, selector: "ax-comment-menu-options", providers: [{ provide: AXComponent, useExisting: AXMenuOptionsComponent }], ngImport: i0, template: '<ng-content />', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
123
312
  }
124
313
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXMenuOptionsComponent, decorators: [{
125
314
  type: Component,
@@ -127,10 +316,163 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
127
316
  selector: 'ax-comment-menu-options',
128
317
  template: '<ng-content />',
129
318
  encapsulation: ViewEncapsulation.None,
319
+ changeDetection: ChangeDetectionStrategy.OnPush,
130
320
  providers: [{ provide: AXComponent, useExisting: AXMenuOptionsComponent }],
131
321
  }]
132
322
  }] });
133
323
 
324
+ /**
325
+ * Composer chrome shown while writing a reply. Projects the editor below a
326
+ * compact reply-context bar; hide the bar by leaving `item` empty.
327
+ *
328
+ * @category Components
329
+ */
330
+ class AXCommentReplyComponent {
331
+ constructor() {
332
+ this.document = inject(DOCUMENT);
333
+ this.platformId = inject(PLATFORM_ID);
334
+ this.destroyRef = inject(DestroyRef);
335
+ this.highlightTimer = null;
336
+ /** Comment currently being replied to. When null, only the projected composer is shown. */
337
+ this.item = input(null, /* @ts-ignore */
338
+ ...(ngDevMode ? [{ debugName: "item" }] : /* istanbul ignore next */ []));
339
+ /** Emitted when the close control on the reply banner is clicked. */
340
+ this.onClose = output();
341
+ /** Emitted when the banner is clicked to jump to the target comment. */
342
+ this.onTargetClick = output();
343
+ this.preview = computed(() => this.toPreview(this.item()?.content), /* @ts-ignore */
344
+ ...(ngDevMode ? [{ debugName: "preview" }] : /* istanbul ignore next */ []));
345
+ this.destroyRef.onDestroy(() => {
346
+ if (this.highlightTimer)
347
+ clearTimeout(this.highlightTimer);
348
+ });
349
+ }
350
+ close() {
351
+ this.onClose.emit();
352
+ }
353
+ revealTarget() {
354
+ const item = this.item();
355
+ if (!item)
356
+ return;
357
+ const id = String(item.id);
358
+ this.onTargetClick.emit(id);
359
+ this.scrollToComment(id);
360
+ }
361
+ scrollToComment(id) {
362
+ if (!isPlatformBrowser(this.platformId))
363
+ return;
364
+ const el = this.document.querySelector(`ax-comment-item[id="${id}"]`) ??
365
+ this.document.querySelector(`ax-comment-item[id="comment-${id}"]`);
366
+ if (!el)
367
+ return;
368
+ el.scrollIntoView({ behavior: 'smooth', block: 'center' });
369
+ el.classList.add('ax-state-highlight');
370
+ if (this.highlightTimer)
371
+ clearTimeout(this.highlightTimer);
372
+ this.highlightTimer = setTimeout(() => {
373
+ el.classList.remove('ax-state-highlight');
374
+ this.highlightTimer = null;
375
+ }, 1500);
376
+ }
377
+ toPreview(content) {
378
+ return String(content ?? '')
379
+ .replace(/<[^>]+>/g, ' ')
380
+ .replace(/&nbsp;|&#160;/gi, ' ')
381
+ .replace(/&amp;/gi, '&')
382
+ .replace(/&lt;/gi, '<')
383
+ .replace(/&gt;/gi, '>')
384
+ .replace(/&quot;/gi, '"')
385
+ .replace(/&#39;|&apos;/gi, "'")
386
+ .replace(/\s+/g, ' ')
387
+ .trim();
388
+ }
389
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentReplyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
390
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: AXCommentReplyComponent, isStandalone: true, selector: "ax-comment-reply", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClose: "onClose", onTargetClick: "onTargetClick" }, host: { properties: { "class.ax-comment-reply-open": "!!item()" }, classAttribute: "ax-comment-reply" }, providers: [{ provide: AXComponent, useExisting: AXCommentReplyComponent }], ngImport: i0, template: `
391
+ @if (item(); as target) {
392
+ <div class="ax-comment-reply-banner">
393
+ <button type="button" class="ax-comment-reply-target" (click)="revealTarget()">
394
+ <ax-icon
395
+ class="ax-comment-reply-lead-icon"
396
+ icon="ax-icon ax-icon-arrow-turn-left"
397
+ aria-hidden="true"
398
+ ></ax-icon>
399
+ <span class="ax-comment-reply-copy">
400
+ <span class="ax-comment-reply-label">
401
+ {{ '@acorex:comment.replying-to' | translate | async }}
402
+ <span class="ax-comment-reply-author">
403
+ @if (target.isYou) {
404
+ {{ '@acorex:comment.you' | translate | async }}
405
+ } @else {
406
+ {{ target.author }}
407
+ }
408
+ </span>
409
+ </span>
410
+ @if (preview(); as excerpt) {
411
+ <span class="ax-comment-reply-preview" [title]="excerpt">{{ excerpt }}</span>
412
+ }
413
+ </span>
414
+ </button>
415
+ <button
416
+ type="button"
417
+ class="ax-comment-reply-close"
418
+ [attr.aria-label]="'@acorex:common.general.close' | translate | async"
419
+ (click)="close()"
420
+ >
421
+ <ax-icon icon="ax-icon ax-icon-close" aria-hidden="true"></ax-icon>
422
+ </button>
423
+ </div>
424
+ }
425
+ <div class="ax-comment-reply-composer">
426
+ <ng-content />
427
+ </div>
428
+ `, isInline: true, styles: ["@layer properties;@layer components{ax-comment-reply{--ax-comp-comment-reply-bar-bg-color: color-mix(in srgb, rgba(var(--ax-sys-color-primary-surface)) 8%, rgba(var(--ax-sys-color-surface)));--ax-comp-comment-reply-bar-border-color: color-mix(in srgb, rgba(var(--ax-sys-color-primary-surface)) 16%, transparent);--ax-comp-comment-reply-bar-accent-color: var(--color-primary);--ax-comp-comment-reply-bar-radius: 6px;--ax-comp-comment-reply-bar-gap: 8px;display:flex;width:100%;min-width:calc(var(--spacing, .25rem) * 0);flex-direction:column;gap:var(--ax-comp-comment-reply-bar-gap)}@supports (color: color-mix(in lab,red,red)){ax-comment-reply{--ax-comp-comment-reply-bar-bg-color: color-mix(in srgb, var(--color-primary) 8%, var(--color-surface))}}@supports (color: color-mix(in lab,red,red)){ax-comment-reply{--ax-comp-comment-reply-bar-border-color: color-mix(in srgb, var(--color-primary) 16%, transparent)}}.ax-comment-reply-banner{display:flex;min-width:calc(var(--spacing, .25rem) * 0);align-items:flex-start;gap:calc(var(--spacing, .25rem) * 2);padding:8px 12px;border-radius:var(--ax-comp-comment-reply-bar-radius);background:var(--ax-comp-comment-reply-bar-bg-color);border:1px solid var(--ax-comp-comment-reply-bar-border-color);border-inline-start-width:2px;border-inline-start-color:var(--ax-comp-comment-reply-bar-accent-color)}.ax-comment-reply-target{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;cursor:pointer;align-items:flex-start;gap:calc(var(--spacing, .25rem) * 2);overflow:hidden;border-radius:var(--radius-sm, .25rem);border-style:var(--tw-border-style);border-width:0px;background-color:transparent;padding:calc(var(--spacing, .25rem) * 0);text-align:start}.ax-comment-reply-target:focus-visible{--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color: rgba(var(--ax-sys-color-primary-surface));--tw-ring-offset-width: 2px;--tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style: none;outline-style:none}.ax-comment-reply-lead-icon{margin-top:calc(var(--spacing, .25rem) * .5);flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: 1;line-height:1;color:rgba(var(--ax-sys-color-primary-surface))}.ax-comment-reply-copy{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * .5)}.ax-comment-reply-label{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);color:rgba(var(--ax-sys-color-on-surface))}@supports (color: color-mix(in lab,red,red)){.ax-comment-reply-label{color:color-mix(in oklab,rgba(var(--ax-sys-color-on-surface)) 70%,transparent)}}.ax-comment-reply-author{--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-on-surface))}.ax-comment-reply-preview{min-width:calc(var(--spacing, .25rem) * 0);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);color:rgba(var(--ax-sys-color-on-surface))}@supports (color: color-mix(in lab,red,red)){.ax-comment-reply-preview{color:color-mix(in oklab,rgba(var(--ax-sys-color-on-surface)) 50%,transparent)}}.ax-comment-reply-close{display:inline-flex;width:calc(var(--spacing, .25rem) * 7);height:calc(var(--spacing, .25rem) * 7);flex-shrink:0;cursor:pointer;align-items:center;justify-content:center;align-self:flex-start;border-radius:var(--radius-sm, .25rem);border-style:var(--tw-border-style);border-width:0px;background-color:transparent;padding:calc(var(--spacing, .25rem) * 0);color:rgba(var(--ax-sys-color-on-surface))}@supports (color: color-mix(in lab,red,red)){.ax-comment-reply-close{color:color-mix(in oklab,rgba(var(--ax-sys-color-on-surface)) 45%,transparent)}}.ax-comment-reply-close ax-icon{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: 1;line-height:1}.ax-comment-reply-close:hover{color:rgba(var(--ax-sys-color-on-surface));background:color-mix(in srgb,rgba(var(--ax-sys-color-on-surface)) 6%,transparent)}@supports (color: color-mix(in lab,red,red)){.ax-comment-reply-close:hover{background:color-mix(in srgb,var(--color-on-surface) 6%,transparent)}}.ax-comment-reply-close:focus-visible{--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color: rgba(var(--ax-sys-color-primary-surface));--tw-ring-offset-width: 2px;--tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style: none;outline-style:none}.ax-comment-reply-composer{width:100%;min-width:calc(var(--spacing, .25rem) * 0)}}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-leading: initial;--tw-font-weight: initial}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
429
+ }
430
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentReplyComponent, decorators: [{
431
+ type: Component,
432
+ args: [{ selector: 'ax-comment-reply', template: `
433
+ @if (item(); as target) {
434
+ <div class="ax-comment-reply-banner">
435
+ <button type="button" class="ax-comment-reply-target" (click)="revealTarget()">
436
+ <ax-icon
437
+ class="ax-comment-reply-lead-icon"
438
+ icon="ax-icon ax-icon-arrow-turn-left"
439
+ aria-hidden="true"
440
+ ></ax-icon>
441
+ <span class="ax-comment-reply-copy">
442
+ <span class="ax-comment-reply-label">
443
+ {{ '@acorex:comment.replying-to' | translate | async }}
444
+ <span class="ax-comment-reply-author">
445
+ @if (target.isYou) {
446
+ {{ '@acorex:comment.you' | translate | async }}
447
+ } @else {
448
+ {{ target.author }}
449
+ }
450
+ </span>
451
+ </span>
452
+ @if (preview(); as excerpt) {
453
+ <span class="ax-comment-reply-preview" [title]="excerpt">{{ excerpt }}</span>
454
+ }
455
+ </span>
456
+ </button>
457
+ <button
458
+ type="button"
459
+ class="ax-comment-reply-close"
460
+ [attr.aria-label]="'@acorex:common.general.close' | translate | async"
461
+ (click)="close()"
462
+ >
463
+ <ax-icon icon="ax-icon ax-icon-close" aria-hidden="true"></ax-icon>
464
+ </button>
465
+ </div>
466
+ }
467
+ <div class="ax-comment-reply-composer">
468
+ <ng-content />
469
+ </div>
470
+ `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXDecoratorIconComponent, AXTranslatorPipe, AsyncPipe], providers: [{ provide: AXComponent, useExisting: AXCommentReplyComponent }], host: {
471
+ class: 'ax-comment-reply',
472
+ '[class.ax-comment-reply-open]': '!!item()',
473
+ }, styles: ["@layer properties;@layer components{ax-comment-reply{--ax-comp-comment-reply-bar-bg-color: color-mix(in srgb, rgba(var(--ax-sys-color-primary-surface)) 8%, rgba(var(--ax-sys-color-surface)));--ax-comp-comment-reply-bar-border-color: color-mix(in srgb, rgba(var(--ax-sys-color-primary-surface)) 16%, transparent);--ax-comp-comment-reply-bar-accent-color: var(--color-primary);--ax-comp-comment-reply-bar-radius: 6px;--ax-comp-comment-reply-bar-gap: 8px;display:flex;width:100%;min-width:calc(var(--spacing, .25rem) * 0);flex-direction:column;gap:var(--ax-comp-comment-reply-bar-gap)}@supports (color: color-mix(in lab,red,red)){ax-comment-reply{--ax-comp-comment-reply-bar-bg-color: color-mix(in srgb, var(--color-primary) 8%, var(--color-surface))}}@supports (color: color-mix(in lab,red,red)){ax-comment-reply{--ax-comp-comment-reply-bar-border-color: color-mix(in srgb, var(--color-primary) 16%, transparent)}}.ax-comment-reply-banner{display:flex;min-width:calc(var(--spacing, .25rem) * 0);align-items:flex-start;gap:calc(var(--spacing, .25rem) * 2);padding:8px 12px;border-radius:var(--ax-comp-comment-reply-bar-radius);background:var(--ax-comp-comment-reply-bar-bg-color);border:1px solid var(--ax-comp-comment-reply-bar-border-color);border-inline-start-width:2px;border-inline-start-color:var(--ax-comp-comment-reply-bar-accent-color)}.ax-comment-reply-target{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;cursor:pointer;align-items:flex-start;gap:calc(var(--spacing, .25rem) * 2);overflow:hidden;border-radius:var(--radius-sm, .25rem);border-style:var(--tw-border-style);border-width:0px;background-color:transparent;padding:calc(var(--spacing, .25rem) * 0);text-align:start}.ax-comment-reply-target:focus-visible{--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color: rgba(var(--ax-sys-color-primary-surface));--tw-ring-offset-width: 2px;--tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style: none;outline-style:none}.ax-comment-reply-lead-icon{margin-top:calc(var(--spacing, .25rem) * .5);flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: 1;line-height:1;color:rgba(var(--ax-sys-color-primary-surface))}.ax-comment-reply-copy{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * .5)}.ax-comment-reply-label{flex-shrink:0;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);color:rgba(var(--ax-sys-color-on-surface))}@supports (color: color-mix(in lab,red,red)){.ax-comment-reply-label{color:color-mix(in oklab,rgba(var(--ax-sys-color-on-surface)) 70%,transparent)}}.ax-comment-reply-author{--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgba(var(--ax-sys-color-on-surface))}.ax-comment-reply-preview{min-width:calc(var(--spacing, .25rem) * 0);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: calc(var(--spacing, .25rem) * 4);line-height:calc(var(--spacing, .25rem) * 4);color:rgba(var(--ax-sys-color-on-surface))}@supports (color: color-mix(in lab,red,red)){.ax-comment-reply-preview{color:color-mix(in oklab,rgba(var(--ax-sys-color-on-surface)) 50%,transparent)}}.ax-comment-reply-close{display:inline-flex;width:calc(var(--spacing, .25rem) * 7);height:calc(var(--spacing, .25rem) * 7);flex-shrink:0;cursor:pointer;align-items:center;justify-content:center;align-self:flex-start;border-radius:var(--radius-sm, .25rem);border-style:var(--tw-border-style);border-width:0px;background-color:transparent;padding:calc(var(--spacing, .25rem) * 0);color:rgba(var(--ax-sys-color-on-surface))}@supports (color: color-mix(in lab,red,red)){.ax-comment-reply-close{color:color-mix(in oklab,rgba(var(--ax-sys-color-on-surface)) 45%,transparent)}}.ax-comment-reply-close ax-icon{font-size:var(--text-xs, .75rem);line-height:var(--tw-leading, var(--text-xs--line-height, calc(1 / .75)));--tw-leading: 1;line-height:1}.ax-comment-reply-close:hover{color:rgba(var(--ax-sys-color-on-surface));background:color-mix(in srgb,rgba(var(--ax-sys-color-on-surface)) 6%,transparent)}@supports (color: color-mix(in lab,red,red)){.ax-comment-reply-close:hover{background:color-mix(in srgb,var(--color-on-surface) 6%,transparent)}}.ax-comment-reply-close:focus-visible{--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color: rgba(var(--ax-sys-color-primary-surface));--tw-ring-offset-width: 2px;--tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style: none;outline-style:none}.ax-comment-reply-composer{width:100%;min-width:calc(var(--spacing, .25rem) * 0)}}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-leading: initial;--tw-font-weight: initial}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
474
+ }], ctorParameters: () => [], propDecorators: { item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: false }] }], onClose: [{ type: i0.Output, args: ["onClose"] }], onTargetClick: [{ type: i0.Output, args: ["onTargetClick"] }] } });
475
+
134
476
  /**
135
477
  * A component for displaying "show more replies" action on a comment.
136
478
  *
@@ -138,7 +480,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
138
480
  */
139
481
  class AXCommentReplyMoreComponent {
140
482
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentReplyMoreComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
141
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: AXCommentReplyMoreComponent, isStandalone: true, selector: "ax-comment-reply-more", providers: [{ provide: AXComponent, useExisting: AXCommentReplyMoreComponent }], ngImport: i0, template: '<ax-text><ng-content /></ax-text>', isInline: true, dependencies: [{ kind: "component", type: AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }], encapsulation: i0.ViewEncapsulation.None }); }
483
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: AXCommentReplyMoreComponent, isStandalone: true, selector: "ax-comment-reply-more", providers: [{ provide: AXComponent, useExisting: AXCommentReplyMoreComponent }], ngImport: i0, template: '<ax-text><ng-content /></ax-text>', isInline: true, dependencies: [{ kind: "component", type: AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
142
484
  }
143
485
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentReplyMoreComponent, decorators: [{
144
486
  type: Component,
@@ -146,44 +488,379 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
146
488
  selector: 'ax-comment-reply-more',
147
489
  template: '<ax-text><ng-content /></ax-text>',
148
490
  encapsulation: ViewEncapsulation.None,
491
+ changeDetection: ChangeDetectionStrategy.OnPush,
149
492
  imports: [AXDecoratorGenericComponent],
150
493
  providers: [{ provide: AXComponent, useExisting: AXCommentReplyMoreComponent }],
151
494
  }]
152
495
  }] });
153
496
 
154
497
  /**
155
- * A component for displaying the reply action text on a comment.
156
- *
157
- * @category Components
158
- */
159
- class AXCommentReplyTextComponent {
160
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentReplyTextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
161
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: AXCommentReplyTextComponent, isStandalone: true, selector: "ax-comment-reply-text", providers: [{ provide: AXComponent, useExisting: AXCommentReplyTextComponent }], ngImport: i0, template: `<ax-text>{{ '@acorex:comment.reply' | translate | async }}</ax-text>`, isInline: true, dependencies: [{ kind: "component", type: AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None }); }
162
- }
163
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentReplyTextComponent, decorators: [{
164
- type: Component,
165
- args: [{
166
- selector: 'ax-comment-reply-text',
167
- template: `<ax-text>{{ '@acorex:comment.reply' | translate | async }}</ax-text>`,
168
- encapsulation: ViewEncapsulation.None,
169
- imports: [AXDecoratorGenericComponent, AXTranslatorPipe, AsyncPipe],
170
- providers: [{ provide: AXComponent, useExisting: AXCommentReplyTextComponent }],
171
- }]
172
- }] });
173
-
174
- /**
175
- * A component for viewing comments with their details.
498
+ * Renders a comment thread from a datasource (array or lazy callback).
499
+ * Provide `itemTemplate` or `<ng-template axCommentItem>` to customize item UI;
500
+ * otherwise the built-in layout is used.
176
501
  *
177
502
  * @category Components
178
503
  */
179
504
  class AXCommentViewComponent {
505
+ constructor() {
506
+ /** Comment data — a static array or a lazy-loading function. */
507
+ this.datasource = model(null, /* @ts-ignore */
508
+ ...(ngDevMode ? [{ debugName: "datasource" }] : /* istanbul ignore next */ []));
509
+ /**
510
+ * Custom item template. When omitted, the default comment layout is used.
511
+ * You can also project `<ng-template axCommentItem>`.
512
+ */
513
+ this.itemTemplate = input(/* @ts-ignore */
514
+ ...(ngDevMode ? [undefined, { debugName: "itemTemplate" }] : /* istanbul ignore next */ []));
515
+ this.onReply = output();
516
+ this.onLikeChange = output();
517
+ this.onRepliesToggle = output();
518
+ this.onAction = output();
519
+ this.projectedItemTemplate = contentChild(AXCommentItemTemplateDirective, /* @ts-ignore */
520
+ ...(ngDevMode ? [{ debugName: "projectedItemTemplate" }] : /* istanbul ignore next */ []));
521
+ this.items = signal([], /* @ts-ignore */
522
+ ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
523
+ this.loadingIds = signal(new Set(), /* @ts-ignore */
524
+ ...(ngDevMode ? [{ debugName: "loadingIds" }] : /* istanbul ignore next */ []));
525
+ this._isLoading = signal(false, /* @ts-ignore */
526
+ ...(ngDevMode ? [{ debugName: "_isLoading" }] : /* istanbul ignore next */ []));
527
+ this.isLoading = this._isLoading.asReadonly();
528
+ this.loadGeneration = 0;
529
+ this.syncingFromDatasource = false;
530
+ this.isLazyDataSource = computed(() => typeof this.datasource() === 'function', /* @ts-ignore */
531
+ ...(ngDevMode ? [{ debugName: "isLazyDataSource" }] : /* istanbul ignore next */ []));
532
+ this.hasDatasource = computed(() => this.datasource() != null, /* @ts-ignore */
533
+ ...(ngDevMode ? [{ debugName: "hasDatasource" }] : /* istanbul ignore next */ []));
534
+ this.resolvedTemplate = computed(() => this.itemTemplate() ?? this.projectedItemTemplate()?.template ?? null, /* @ts-ignore */
535
+ ...(ngDevMode ? [{ debugName: "resolvedTemplate" }] : /* istanbul ignore next */ []));
536
+ effect(() => {
537
+ const ds = this.datasource();
538
+ if (this.syncingFromDatasource)
539
+ return;
540
+ untracked(() => void this.applyDatasource(ds));
541
+ });
542
+ }
543
+ /**
544
+ * Reloads root comments from the datasource.
545
+ *
546
+ * @returns Promise that resolves when the reload is complete.
547
+ */
548
+ async reloadData() {
549
+ await this.applyDatasource(this.datasource());
550
+ }
551
+ /**
552
+ * Appends a comment to the current root list.
553
+ *
554
+ * @param item - The comment to append.
555
+ * @returns void
556
+ */
557
+ appendItem(item) {
558
+ this.items.update((list) => [...list, item]);
559
+ }
560
+ /**
561
+ * Appends a reply under a loaded comment and expands that thread.
562
+ *
563
+ * @param parentId - The parent comment id.
564
+ * @param item - The reply to append.
565
+ * @returns Promise that resolves when any needed lazy load and the append are complete.
566
+ */
567
+ async appendReply(parentId, item) {
568
+ const parent = this.findItem(parentId);
569
+ if (!parent)
570
+ return;
571
+ if (this.canLazyLoad(parent)) {
572
+ await this.loadReplies(parent);
573
+ }
574
+ parent.replies = [...(parent.replies ?? []), item];
575
+ parent.replyCount = parent.replies.length;
576
+ parent.repliesExpanded = true;
577
+ this.refreshItems();
578
+ }
579
+ /**
580
+ * Finds a comment by id in the loaded tree.
581
+ *
582
+ * @param id - The comment id.
583
+ * @returns The matching item, or null if it is not loaded.
584
+ */
585
+ findItem(id) {
586
+ return this.findInTree(this.items(), id);
587
+ }
588
+ /**
589
+ * Removes a comment from the loaded tree. Nested replies are removed with it.
590
+ *
591
+ * @param id - The comment id.
592
+ * @returns True when the comment was found and removed.
593
+ */
594
+ removeItem(id) {
595
+ const key = String(id);
596
+ const roots = this.items();
597
+ if (roots.some((item) => this.getId(item) === key)) {
598
+ this.items.set(roots.filter((item) => this.getId(item) !== key));
599
+ this.refreshItems();
600
+ return true;
601
+ }
602
+ const parent = this.findParent(roots, key);
603
+ if (!parent?.replies?.length)
604
+ return false;
605
+ const before = parent.replies.length;
606
+ parent.replies = parent.replies.filter((child) => this.getId(child) !== key);
607
+ const removed = before - parent.replies.length;
608
+ if (!removed)
609
+ return false;
610
+ parent.replyCount = Math.max(0, (parent.replyCount ?? before) - removed);
611
+ this.refreshItems();
612
+ return true;
613
+ }
614
+ /**
615
+ * Patches a loaded comment in place.
616
+ *
617
+ * @param id - The comment id.
618
+ * @param patch - Fields to merge onto the existing item. The original id is kept.
619
+ * @returns The updated item, or null if it is not loaded.
620
+ */
621
+ updateItem(id, patch) {
622
+ const key = String(id);
623
+ let updated = null;
624
+ const apply = (items) => {
625
+ const index = items.findIndex((item) => this.getId(item) === key);
626
+ if (index >= 0) {
627
+ const current = items[index];
628
+ if (!current)
629
+ return null;
630
+ const nextItem = { ...current, ...patch, id: current.id };
631
+ updated = nextItem;
632
+ const next = items.slice();
633
+ next[index] = nextItem;
634
+ return next;
635
+ }
636
+ for (let i = 0; i < items.length; i++) {
637
+ const item = items[i];
638
+ if (!item.replies?.length)
639
+ continue;
640
+ const replies = apply(item.replies);
641
+ if (!replies)
642
+ continue;
643
+ const next = items.slice();
644
+ next[i] = { ...item, replies };
645
+ return next;
646
+ }
647
+ return null;
648
+ };
649
+ const next = apply(this.items());
650
+ if (!next || !updated)
651
+ return null;
652
+ this.items.set(next);
653
+ this.refreshItems();
654
+ return updated;
655
+ }
656
+ /**
657
+ * Expands or collapses replies for a comment, loading them when needed.
658
+ *
659
+ * @param id - The comment id.
660
+ * @param expanded - Whether replies should be visible.
661
+ * @returns Promise that resolves when expansion and any lazy load are complete.
662
+ */
663
+ async setExpanded(id, expanded) {
664
+ const item = this.findItem(id);
665
+ if (!item)
666
+ return;
667
+ await this.setItemExpanded(item, expanded);
668
+ }
669
+ getId(item) {
670
+ return String(item.id);
671
+ }
672
+ getReplies(item) {
673
+ return item.replies ?? [];
674
+ }
675
+ getReplyCount(item) {
676
+ return item.replyCount ?? item.replies?.length ?? 0;
677
+ }
678
+ isExpanded(item) {
679
+ return !!item.repliesExpanded;
680
+ }
681
+ isItemLoading(item) {
682
+ return this.loadingIds().has(this.getId(item));
683
+ }
684
+ getTemplateContext(item, level) {
685
+ return {
686
+ $implicit: item,
687
+ item,
688
+ level,
689
+ repliesExpanded: this.isExpanded(item),
690
+ replyCount: this.getReplyCount(item),
691
+ loading: this.isItemLoading(item),
692
+ liked: !!item.liked,
693
+ likes: item.likes ?? 0,
694
+ toggleReplies: () => void this.setItemExpanded(item, !this.isExpanded(item)),
695
+ toggleLike: () => this.toggleLike(item),
696
+ reply: (event) => this.replyTo(item, event),
697
+ };
698
+ }
699
+ async onRepliesExpandedChange(item, expanded) {
700
+ await this.setItemExpanded(item, expanded);
701
+ }
702
+ toggleLike(item, liked = !item.liked) {
703
+ const next = liked;
704
+ const current = !!item.liked;
705
+ if (next === current) {
706
+ this.refreshItems();
707
+ return;
708
+ }
709
+ item.liked = next;
710
+ item.likes = Math.max(0, (item.likes ?? 0) + (next ? 1 : -1));
711
+ this.refreshItems();
712
+ this.onLikeChange.emit({
713
+ component: this,
714
+ item,
715
+ liked: next,
716
+ likes: item.likes ?? 0,
717
+ isUserInteraction: true,
718
+ });
719
+ }
720
+ replyTo(item, event) {
721
+ this.onReply.emit({
722
+ component: this,
723
+ item,
724
+ nativeEvent: event,
725
+ isUserInteraction: true,
726
+ });
727
+ }
728
+ emitAction(item, action) {
729
+ this.onAction.emit({
730
+ component: this,
731
+ item,
732
+ action,
733
+ isUserInteraction: true,
734
+ });
735
+ }
736
+ async applyDatasource(ds) {
737
+ if (ds == null) {
738
+ this.items.set([]);
739
+ this._isLoading.set(false);
740
+ return;
741
+ }
742
+ if (Array.isArray(ds)) {
743
+ this.items.set(ds);
744
+ return;
745
+ }
746
+ await this.loadRootItems(ds);
747
+ }
748
+ async loadRootItems(loadFn) {
749
+ const generation = ++this.loadGeneration;
750
+ this._isLoading.set(true);
751
+ try {
752
+ const result = loadFn();
753
+ const roots = result instanceof Promise ? await result : result;
754
+ if (generation !== this.loadGeneration)
755
+ return;
756
+ this.items.set(roots);
757
+ await this.hydrateExpanded(roots);
758
+ }
759
+ catch {
760
+ if (generation !== this.loadGeneration)
761
+ return;
762
+ this.items.set([]);
763
+ }
764
+ finally {
765
+ if (generation === this.loadGeneration) {
766
+ this._isLoading.set(false);
767
+ }
768
+ }
769
+ }
770
+ async hydrateExpanded(items) {
771
+ for (const item of items) {
772
+ if (item.repliesExpanded && this.canLazyLoad(item)) {
773
+ await this.loadReplies(item);
774
+ }
775
+ const replies = this.getReplies(item);
776
+ if (replies.length) {
777
+ await this.hydrateExpanded(replies);
778
+ }
779
+ }
780
+ }
781
+ canLazyLoad(item) {
782
+ return this.isLazyDataSource() && this.getReplyCount(item) > 0 && this.getReplies(item).length === 0;
783
+ }
784
+ async setItemExpanded(item, expanded) {
785
+ item.repliesExpanded = expanded;
786
+ if (expanded && this.canLazyLoad(item)) {
787
+ await this.loadReplies(item);
788
+ }
789
+ this.refreshItems();
790
+ this.onRepliesToggle.emit({
791
+ component: this,
792
+ item,
793
+ expanded,
794
+ isUserInteraction: true,
795
+ });
796
+ }
797
+ async loadReplies(item) {
798
+ const ds = this.datasource();
799
+ if (typeof ds !== 'function')
800
+ return;
801
+ const id = this.getId(item);
802
+ if (this.loadingIds().has(id) || this.getReplies(item).length > 0)
803
+ return;
804
+ this.loadingIds.update((set) => new Set(set).add(id));
805
+ this.refreshItems();
806
+ try {
807
+ const result = ds(id);
808
+ const replies = result instanceof Promise ? await result : result;
809
+ item.replies = replies;
810
+ item.replyCount = replies.length;
811
+ }
812
+ catch {
813
+ item.replyCount = 0;
814
+ }
815
+ finally {
816
+ this.loadingIds.update((set) => {
817
+ const next = new Set(set);
818
+ next.delete(id);
819
+ return next;
820
+ });
821
+ this.refreshItems();
822
+ }
823
+ }
824
+ refreshItems() {
825
+ const current = this.items();
826
+ this.items.set([...current]);
827
+ const ds = this.datasource();
828
+ if (Array.isArray(ds)) {
829
+ this.syncingFromDatasource = true;
830
+ this.datasource.set([...current]);
831
+ queueMicrotask(() => {
832
+ this.syncingFromDatasource = false;
833
+ });
834
+ }
835
+ }
836
+ findInTree(items, id) {
837
+ for (const item of items) {
838
+ if (this.getId(item) === id)
839
+ return item;
840
+ const found = this.findInTree(this.getReplies(item), id);
841
+ if (found)
842
+ return found;
843
+ }
844
+ return null;
845
+ }
846
+ findParent(items, id) {
847
+ for (const item of items) {
848
+ const replies = this.getReplies(item);
849
+ if (replies.some((child) => this.getId(child) === id))
850
+ return item;
851
+ const nested = this.findParent(replies, id);
852
+ if (nested)
853
+ return nested;
854
+ }
855
+ return null;
856
+ }
180
857
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
181
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: AXCommentViewComponent, isStandalone: true, selector: "ax-comment-view", providers: [{ provide: AXComponent, useExisting: AXCommentViewComponent }], ngImport: i0, template: '<ng-content select="ax-comment-item" />', isInline: true, styles: ["ax-comment-view{display:block;margin-block-end:1rem}\n"], encapsulation: i0.ViewEncapsulation.None }); }
858
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: AXCommentViewComponent, isStandalone: true, selector: "ax-comment-view", inputs: { datasource: { classPropertyName: "datasource", publicName: "datasource", isSignal: true, isRequired: false, transformFunction: null }, itemTemplate: { classPropertyName: "itemTemplate", publicName: "itemTemplate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { datasource: "datasourceChange", onReply: "onReply", onLikeChange: "onLikeChange", onRepliesToggle: "onRepliesToggle", onAction: "onAction" }, providers: [{ provide: AXComponent, useExisting: AXCommentViewComponent }], queries: [{ propertyName: "projectedItemTemplate", first: true, predicate: AXCommentItemTemplateDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (hasDatasource()) {\n @if (isLoading()) {\n <div class=\"ax-comment-view-skeleton\">\n @for (row of [1, 2, 3]; track row) {\n <div class=\"ax-comment-skeleton-row\">\n <ax-skeleton class=\"ax-comment-skeleton-avatar\"></ax-skeleton>\n <div class=\"ax-comment-skeleton-main\">\n <ax-skeleton class=\"ax-comment-skeleton-title\"></ax-skeleton>\n <ax-skeleton class=\"ax-comment-skeleton-body\"></ax-skeleton>\n </div>\n </div>\n }\n </div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"itemsTpl\"\n [ngTemplateOutletContext]=\"{ items: items(), level: 0 }\"\n ></ng-container>\n }\n} @else {\n <ng-content select=\"ax-comment-item\" />\n}\n\n<ng-template #itemsTpl let-items=\"items\" let-level=\"level\">\n @for (item of items; track getId(item)) {\n <ax-comment-item\n [attr.id]=\"'comment-' + getId(item)\"\n [item]=\"item\"\n [replyCount]=\"getReplyCount(item)\"\n [repliesExpanded]=\"isExpanded(item)\"\n [loading]=\"isItemLoading(item)\"\n [itemTemplate]=\"resolvedTemplate()\"\n [itemContext]=\"resolvedTemplate() ? getTemplateContext(item, level) : null\"\n (repliesExpandedChange)=\"onRepliesExpandedChange(item, $event)\"\n (likeChange)=\"toggleLike(item, $event)\"\n (replyClick)=\"replyTo(item, $event)\"\n (actionClick)=\"emitAction(item, $event)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"itemsTpl\"\n [ngTemplateOutletContext]=\"{ items: getReplies(item), level: level + 1 }\"\n ></ng-container>\n </ax-comment-item>\n }\n</ng-template>\n", styles: ["@layer components{ax-comment-view{display:block}ax-comment-view>ax-comment-item:not(:last-child){border-bottom:1px solid color-mix(in srgb,rgba(var(--ax-sys-color-on-surface)) 8%,transparent)}@supports (color: color-mix(in lab,red,red)){ax-comment-view>ax-comment-item:not(:last-child){border-bottom:1px solid color-mix(in srgb,var(--color-on-surface) 8%,transparent)}}.ax-comment-view-skeleton{display:flex;flex-direction:column}.ax-comment-skeleton-row{display:flex;align-items:flex-start;gap:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 3)}.ax-comment-skeleton-avatar{width:calc(var(--spacing, .25rem) * 12);height:calc(var(--spacing, .25rem) * 12);flex-shrink:0;border-radius:calc(infinity * 1px)}.ax-comment-skeleton-main{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.ax-comment-skeleton-title{height:calc(var(--spacing, .25rem) * 3);width:calc(var(--spacing, .25rem) * 32);border-radius:.25rem}.ax-comment-skeleton-body{height:calc(var(--spacing, .25rem) * 3);width:100%;max-width:var(--container-md, 28rem);border-radius:.25rem}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AXCommentItemComponent, selector: "ax-comment-item", inputs: ["item", "replyCount", "repliesExpanded", "loading", "itemTemplate", "itemContext"], outputs: ["repliesExpandedChange", "likeChange", "replyClick", "actionClick"] }, { kind: "component", type: AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
182
859
  }
183
860
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentViewComponent, decorators: [{
184
861
  type: Component,
185
- args: [{ selector: 'ax-comment-view', template: '<ng-content select="ax-comment-item" />', encapsulation: ViewEncapsulation.None, providers: [{ provide: AXComponent, useExisting: AXCommentViewComponent }], styles: ["ax-comment-view{display:block;margin-block-end:1rem}\n"] }]
186
- }] });
862
+ args: [{ selector: 'ax-comment-view', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet, AXCommentItemComponent, AXSkeletonComponent], providers: [{ provide: AXComponent, useExisting: AXCommentViewComponent }], template: "@if (hasDatasource()) {\n @if (isLoading()) {\n <div class=\"ax-comment-view-skeleton\">\n @for (row of [1, 2, 3]; track row) {\n <div class=\"ax-comment-skeleton-row\">\n <ax-skeleton class=\"ax-comment-skeleton-avatar\"></ax-skeleton>\n <div class=\"ax-comment-skeleton-main\">\n <ax-skeleton class=\"ax-comment-skeleton-title\"></ax-skeleton>\n <ax-skeleton class=\"ax-comment-skeleton-body\"></ax-skeleton>\n </div>\n </div>\n }\n </div>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"itemsTpl\"\n [ngTemplateOutletContext]=\"{ items: items(), level: 0 }\"\n ></ng-container>\n }\n} @else {\n <ng-content select=\"ax-comment-item\" />\n}\n\n<ng-template #itemsTpl let-items=\"items\" let-level=\"level\">\n @for (item of items; track getId(item)) {\n <ax-comment-item\n [attr.id]=\"'comment-' + getId(item)\"\n [item]=\"item\"\n [replyCount]=\"getReplyCount(item)\"\n [repliesExpanded]=\"isExpanded(item)\"\n [loading]=\"isItemLoading(item)\"\n [itemTemplate]=\"resolvedTemplate()\"\n [itemContext]=\"resolvedTemplate() ? getTemplateContext(item, level) : null\"\n (repliesExpandedChange)=\"onRepliesExpandedChange(item, $event)\"\n (likeChange)=\"toggleLike(item, $event)\"\n (replyClick)=\"replyTo(item, $event)\"\n (actionClick)=\"emitAction(item, $event)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"itemsTpl\"\n [ngTemplateOutletContext]=\"{ items: getReplies(item), level: level + 1 }\"\n ></ng-container>\n </ax-comment-item>\n }\n</ng-template>\n", styles: ["@layer components{ax-comment-view{display:block}ax-comment-view>ax-comment-item:not(:last-child){border-bottom:1px solid color-mix(in srgb,rgba(var(--ax-sys-color-on-surface)) 8%,transparent)}@supports (color: color-mix(in lab,red,red)){ax-comment-view>ax-comment-item:not(:last-child){border-bottom:1px solid color-mix(in srgb,var(--color-on-surface) 8%,transparent)}}.ax-comment-view-skeleton{display:flex;flex-direction:column}.ax-comment-skeleton-row{display:flex;align-items:flex-start;gap:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 3)}.ax-comment-skeleton-avatar{width:calc(var(--spacing, .25rem) * 12);height:calc(var(--spacing, .25rem) * 12);flex-shrink:0;border-radius:calc(infinity * 1px)}.ax-comment-skeleton-main{display:flex;min-width:calc(var(--spacing, .25rem) * 0);flex:1;flex-direction:column;gap:calc(var(--spacing, .25rem) * 2)}.ax-comment-skeleton-title{height:calc(var(--spacing, .25rem) * 3);width:calc(var(--spacing, .25rem) * 32);border-radius:.25rem}.ax-comment-skeleton-body{height:calc(var(--spacing, .25rem) * 3);width:100%;max-width:var(--container-md, 28rem);border-radius:.25rem}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
863
+ }], ctorParameters: () => [], propDecorators: { datasource: [{ type: i0.Input, args: [{ isSignal: true, alias: "datasource", required: false }] }, { type: i0.Output, args: ["datasourceChange"] }], itemTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemTemplate", required: false }] }], onReply: [{ type: i0.Output, args: ["onReply"] }], onLikeChange: [{ type: i0.Output, args: ["onLikeChange"] }], onRepliesToggle: [{ type: i0.Output, args: ["onRepliesToggle"] }], onAction: [{ type: i0.Output, args: ["onAction"] }], projectedItemTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => AXCommentItemTemplateDirective), { isSignal: true }] }] } });
187
864
 
188
865
  const COMPONENTS = [
189
866
  AXCommentViewComponent,
@@ -191,29 +868,50 @@ const COMPONENTS = [
191
868
  AXCommentItemComponent,
192
869
  AXCommentLikeComponent,
193
870
  AXMenuOptionsComponent,
871
+ AXCommentReplyComponent,
194
872
  AXCommentReplyTextComponent,
195
873
  AXCommentDateComponent,
196
874
  AXCommentReplyMoreComponent,
875
+ AXCommentItemTemplateDirective,
876
+ ];
877
+ const MODULES = [
878
+ AXDecoratorModule,
879
+ AXWysiwygModule,
880
+ AXBadgeModule,
881
+ AXButtonModule,
882
+ AXTextAreaModule,
883
+ AXTranslationModule,
197
884
  ];
198
- const MODULES = [AXDecoratorModule, AXWysiwygModule, AXButtonModule, AXTextAreaModule, AXTranslationModule];
199
885
  class AXCommentModule {
200
886
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
201
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.6", ngImport: i0, type: AXCommentModule, imports: [AXDecoratorModule, AXWysiwygModule, AXButtonModule, AXTextAreaModule, AXTranslationModule, AXCommentViewComponent,
887
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.6", ngImport: i0, type: AXCommentModule, imports: [AXDecoratorModule,
888
+ AXWysiwygModule,
889
+ AXBadgeModule,
890
+ AXButtonModule,
891
+ AXTextAreaModule,
892
+ AXTranslationModule, AXCommentViewComponent,
202
893
  AXCommentContainerComponent,
203
894
  AXCommentItemComponent,
204
895
  AXCommentLikeComponent,
205
896
  AXMenuOptionsComponent,
897
+ AXCommentReplyComponent,
206
898
  AXCommentReplyTextComponent,
207
899
  AXCommentDateComponent,
208
- AXCommentReplyMoreComponent], exports: [AXCommentViewComponent,
900
+ AXCommentReplyMoreComponent,
901
+ AXCommentItemTemplateDirective], exports: [AXCommentViewComponent,
209
902
  AXCommentContainerComponent,
210
903
  AXCommentItemComponent,
211
904
  AXCommentLikeComponent,
212
905
  AXMenuOptionsComponent,
906
+ AXCommentReplyComponent,
213
907
  AXCommentReplyTextComponent,
214
908
  AXCommentDateComponent,
215
- AXCommentReplyMoreComponent] }); }
216
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentModule, imports: [MODULES, AXCommentLikeComponent,
909
+ AXCommentReplyMoreComponent,
910
+ AXCommentItemTemplateDirective] }); }
911
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: AXCommentModule, imports: [MODULES, AXCommentViewComponent,
912
+ AXCommentItemComponent,
913
+ AXCommentLikeComponent,
914
+ AXCommentReplyComponent,
217
915
  AXCommentReplyTextComponent,
218
916
  AXCommentReplyMoreComponent] }); }
219
917
  }
@@ -229,5 +927,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
229
927
  * Generated bundle index. Do not edit.
230
928
  */
231
929
 
232
- export { AXCommentContainerComponent, AXCommentDateComponent, AXCommentItemComponent, AXCommentLikeComponent, AXCommentModule, AXCommentReplyMoreComponent, AXCommentReplyTextComponent, AXCommentViewComponent, AXMenuOptionsComponent };
930
+ export { AXCommentContainerComponent, AXCommentDateComponent, AXCommentItemComponent, AXCommentItemTemplateDirective, AXCommentLikeComponent, AXCommentModule, AXCommentReplyComponent, AXCommentReplyMoreComponent, AXCommentReplyTextComponent, AXCommentViewComponent, AXMenuOptionsComponent };
233
931
  //# sourceMappingURL=acorex-components-comment.mjs.map