;
+}
+export {};
+//# sourceMappingURL=content-text.component.d.ts.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/content-text.component.d.ts.map b/packages/content-suggestions/dist/angular/angular/content-text.component.d.ts.map
new file mode 100644
index 0000000..383dd32
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/content-text.component.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"content-text.component.d.ts","sourceRoot":"","sources":["../../../src/angular/content-text.component.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/content-text.component.js b/packages/content-suggestions/dist/angular/angular/content-text.component.js
new file mode 100644
index 0000000..b93a8a5
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/content-text.component.js
@@ -0,0 +1,536 @@
+import { NgFor, NgIf, NgSwitch, NgSwitchCase, NgSwitchDefault } from "@angular/common";
+import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewChild, } from "@angular/core";
+import { TachTypographyComponent, } from "@hublib-web/tach-typography/angular";
+import { findAllEntities } from "../core";
+import { ContentSuggestionsRenderResultDirective } from "./render-result.directive";
+import * as i0 from "@angular/core";
+const READ_MORE_TEXT = "Читать полностью";
+const BODY_DATA_ATTR = "data-content-suggestions-body";
+const BASE_SELECTABLE_STYLE = {
+ whiteSpace: "pre-wrap",
+ WebkitTouchCallout: "default",
+ WebkitUserSelect: "text",
+ KhtmlUserSelect: "text",
+ MozUserSelect: "text",
+ msUserSelect: "text",
+ userSelect: "text",
+};
+const BLUR_STYLE = {
+ filter: "blur(3px)",
+ WebkitUserSelect: "none",
+ KhtmlUserSelect: "none",
+ MozUserSelect: "none",
+ msUserSelect: "none",
+ userSelect: "none",
+ pointerEvents: "none",
+};
+export class ContentTextComponent {
+ cdr;
+ className;
+ weight = "normal";
+ text;
+ ellipsis = false;
+ blur = false;
+ style;
+ onView;
+ renderMention;
+ renderTag;
+ renderLink;
+ viewed = new EventEmitter();
+ expandedChange = new EventEmitter();
+ containerRef;
+ visibleParts = [];
+ mergedStyle = { ...BASE_SELECTABLE_STYLE };
+ rowsEllipsis;
+ showTrailingEllipsis = false;
+ showInlineReadMore = false;
+ showBlockReadMore = false;
+ readMoreLabel = READ_MORE_TEXT;
+ paragraphHostProps = { [BODY_DATA_ATTR]: "true" };
+ expanded = false;
+ mergedExpanded = false;
+ isExpandedControlled = false;
+ isInsideView = false;
+ viewedFired = false;
+ pendingRowsOverflowCheck = false;
+ intersectionObserver = null;
+ constructor(cdr) {
+ this.cdr = cdr;
+ }
+ ngOnChanges(_changes) {
+ this.recomputeContent();
+ }
+ ngAfterViewInit() {
+ this.initObserver();
+ this.scheduleRowsOverflowCheck();
+ }
+ ngOnDestroy() {
+ if (this.intersectionObserver) {
+ this.intersectionObserver.disconnect();
+ this.intersectionObserver = null;
+ }
+ }
+ trackByKey(_index, part) {
+ return part.key;
+ }
+ buildDefaultLinkHostProps(url) {
+ return {
+ href: url,
+ target: "_blank",
+ referrerPolicy: "no-referrer",
+ };
+ }
+ handleExpand(event) {
+ event.preventDefault();
+ event.stopPropagation();
+ if (!this.isExpandedControlled) {
+ this.expanded = true;
+ }
+ this.notifyExpand(event, true);
+ this.recomputeContent();
+ }
+ recomputeContent() {
+ const content = this.text ?? "";
+ const entities = findAllEntities(content);
+ const ellipsisConfig = this.resolveEllipsisConfig();
+ this.isExpandedControlled = Boolean(ellipsisConfig && typeof ellipsisConfig.expanded === "boolean");
+ if (!this.isExpandedControlled && this.isCountConfig(ellipsisConfig)) {
+ const count = ellipsisConfig.count ?? 0;
+ if (content.length <= count && !this.expanded) {
+ this.expanded = true;
+ }
+ }
+ this.mergedExpanded = this.getMergedExpanded(ellipsisConfig, content);
+ this.readMoreLabel = this.resolveEllipsisSymbol(ellipsisConfig?.symbol, this.mergedExpanded);
+ this.mergedStyle = {
+ ...BASE_SELECTABLE_STYLE,
+ ...(this.blur ? BLUR_STYLE : {}),
+ ...(this.style ?? {}),
+ };
+ this.visibleParts = this.buildParts(content, entities, null);
+ this.rowsEllipsis = undefined;
+ this.showTrailingEllipsis = false;
+ this.showInlineReadMore = false;
+ this.showBlockReadMore = false;
+ this.pendingRowsOverflowCheck = false;
+ if (this.isCountConfig(ellipsisConfig)) {
+ const count = ellipsisConfig.count ?? 0;
+ const shouldTruncate = !this.mergedExpanded && count > 0 && content.length > count;
+ if (shouldTruncate) {
+ const cutoff = this.computeEntitySafeCutoff(count, entities);
+ this.visibleParts = this.buildParts(content, entities, cutoff);
+ this.showTrailingEllipsis = true;
+ this.showInlineReadMore = Boolean(ellipsisConfig.expandable);
+ }
+ }
+ else if (this.isRowsConfig(ellipsisConfig) && !this.mergedExpanded) {
+ this.rowsEllipsis = {
+ rows: ellipsisConfig.rows,
+ };
+ if (ellipsisConfig.expandable) {
+ this.pendingRowsOverflowCheck = true;
+ }
+ }
+ this.emitViewIfNeeded();
+ this.scheduleRowsOverflowCheck();
+ this.cdr.markForCheck();
+ }
+ buildParts(content, entities, upto) {
+ const parts = [];
+ let lastIndex = 0;
+ for (const [index, entity] of entities.entries()) {
+ if (upto !== null && entity.start >= upto) {
+ break;
+ }
+ const textEnd = upto !== null ? Math.min(entity.start, upto) : entity.start;
+ if (entity.start > lastIndex && lastIndex < textEnd) {
+ parts.push({
+ kind: "text",
+ key: `text-${lastIndex}-${textEnd}`,
+ text: content.slice(lastIndex, textEnd),
+ });
+ }
+ if (upto === null || entity.end <= upto) {
+ if (entity.type === "mention") {
+ parts.push({
+ kind: "mention",
+ key: `mention-${entity.start}-${index}`,
+ entity,
+ index,
+ customRender: this.resolveCustomRender(this.renderMention, entity, index),
+ });
+ }
+ else if (entity.type === "tag") {
+ parts.push({
+ kind: "tag",
+ key: `tag-${entity.start}-${index}`,
+ entity,
+ index,
+ customRender: this.resolveCustomRender(this.renderTag, entity, index),
+ });
+ }
+ else {
+ parts.push({
+ kind: "link",
+ key: `link-${entity.start}-${index}`,
+ entity,
+ index,
+ customRender: this.resolveCustomRender(this.renderLink, entity, index),
+ });
+ }
+ }
+ lastIndex = entity.end;
+ }
+ if (upto === null) {
+ if (lastIndex < content.length) {
+ parts.push({
+ kind: "text",
+ key: `text-${lastIndex}-${content.length}`,
+ text: content.slice(lastIndex),
+ });
+ }
+ }
+ else if (lastIndex < upto) {
+ parts.push({
+ kind: "text",
+ key: `text-${lastIndex}-${upto}`,
+ text: content.slice(lastIndex, upto),
+ });
+ }
+ return parts;
+ }
+ resolveCustomRender(rendererFn, entity, index) {
+ const rendered = rendererFn?.(entity, index);
+ return rendered ?? null;
+ }
+ resolveEllipsisConfig() {
+ if (!this.ellipsis || typeof this.ellipsis !== "object") {
+ return null;
+ }
+ return this.ellipsis;
+ }
+ isCountConfig(config) {
+ return Boolean(config && "count" in config);
+ }
+ isRowsConfig(config) {
+ return Boolean(config && "rows" in config);
+ }
+ getMergedExpanded(config, text) {
+ const controlledExpanded = config && typeof config.expanded === "boolean"
+ ? config.expanded
+ : undefined;
+ if (controlledExpanded !== undefined) {
+ return controlledExpanded;
+ }
+ if (this.isCountConfig(config)) {
+ const count = config.count ?? 0;
+ if (count <= 0 || text.length <= count) {
+ return true;
+ }
+ }
+ return this.expanded;
+ }
+ resolveEllipsisSymbol(symbol, expanded) {
+ if (typeof symbol === "function") {
+ return symbol(expanded);
+ }
+ return symbol ?? READ_MORE_TEXT;
+ }
+ notifyExpand(event, expanded) {
+ const config = this.resolveEllipsisConfig();
+ const onExpand = config?.onExpand;
+ if (onExpand) {
+ if (onExpand.length >= 2) {
+ onExpand(event, { expanded });
+ }
+ else {
+ onExpand(expanded);
+ }
+ }
+ this.expandedChange.emit(expanded);
+ }
+ computeEntitySafeCutoff(count, entities) {
+ let cutoff = count;
+ let extended = true;
+ while (extended) {
+ extended = false;
+ for (const entity of entities) {
+ if (entity.start < cutoff && entity.end > cutoff) {
+ cutoff = entity.end;
+ extended = true;
+ }
+ }
+ }
+ return cutoff;
+ }
+ initObserver() {
+ const host = this.containerRef?.nativeElement;
+ if (!host) {
+ return;
+ }
+ if (typeof IntersectionObserver === "undefined") {
+ this.isInsideView = true;
+ this.emitViewIfNeeded();
+ return;
+ }
+ this.intersectionObserver = new IntersectionObserver(entries => {
+ const entry = entries[0];
+ if (!entry) {
+ return;
+ }
+ if (entry.isIntersecting && !this.isInsideView) {
+ this.isInsideView = true;
+ this.emitViewIfNeeded();
+ }
+ }, { threshold: 0.5 });
+ this.intersectionObserver.observe(host);
+ }
+ emitViewIfNeeded() {
+ if (!this.mergedExpanded || this.viewedFired || !this.isInsideView) {
+ return;
+ }
+ this.viewedFired = true;
+ this.onView?.();
+ this.viewed.emit();
+ }
+ scheduleRowsOverflowCheck() {
+ if (!this.pendingRowsOverflowCheck) {
+ return;
+ }
+ queueMicrotask(() => {
+ this.refreshRowsOverflow();
+ });
+ }
+ refreshRowsOverflow() {
+ const paragraph = this.getParagraphElement();
+ if (!paragraph) {
+ return;
+ }
+ const hasOverflow = paragraph.scrollHeight - paragraph.clientHeight > 1;
+ if (this.showBlockReadMore !== hasOverflow) {
+ this.showBlockReadMore = hasOverflow;
+ this.cdr.markForCheck();
+ }
+ }
+ getParagraphElement() {
+ const host = this.containerRef?.nativeElement;
+ if (!host) {
+ return null;
+ }
+ return host.querySelector(`[${BODY_DATA_ATTR}="true"]`);
+ }
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ContentTextComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.18", type: ContentTextComponent, isStandalone: true, selector: "content-text", inputs: { className: "className", weight: "weight", text: "text", ellipsis: "ellipsis", blur: "blur", style: "style", onView: "onView", renderMention: "renderMention", renderTag: "renderTag", renderLink: "renderLink" }, outputs: { viewed: "viewed", expandedChange: "expandedChange" }, viewQueries: [{ propertyName: "containerRef", first: true, predicate: ["container"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: `
+
+
+
+
+ {{ part.text }}
+
+
+
+
+
+
+
+ {{ part.entity.displayText }}
+
+
+
+
+
+
+
+
+
+
+ {{ part.entity.text }}
+
+
+
+
+
+
+
+
+
+
+ {{ part.entity.text }}
+
+
+
+
+
+
+
+
+ …
+
+
+
+
+
+
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: TachTypographyComponent, selector: "tach-typography", inputs: ["as", "variant", "color", "weight", "clickable", "markdownEnabled", "markdown", "className", "ellipsis", "nzProps", "hostProps", "preserveStyle"], outputs: ["tachClick"] }, { kind: "directive", type: ContentSuggestionsRenderResultDirective, selector: "[contentSuggestionsRenderResult]", inputs: ["contentSuggestionsRenderResult"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
+}
+i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ContentTextComponent, decorators: [{
+ type: Component,
+ args: [{
+ selector: "content-text",
+ standalone: true,
+ imports: [
+ NgFor,
+ NgIf,
+ NgSwitch,
+ NgSwitchCase,
+ NgSwitchDefault,
+ TachTypographyComponent,
+ ContentSuggestionsRenderResultDirective,
+ ],
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ template: `
+
+
+
+
+ {{ part.text }}
+
+
+
+
+
+
+
+ {{ part.entity.displayText }}
+
+
+
+
+
+
+
+
+
+
+ {{ part.entity.text }}
+
+
+
+
+
+
+
+
+
+
+ {{ part.entity.text }}
+
+
+
+
+
+
+
+
+ …
+
+
+
+
+
+
+ `,
+ }]
+ }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { className: [{
+ type: Input
+ }], weight: [{
+ type: Input
+ }], text: [{
+ type: Input
+ }], ellipsis: [{
+ type: Input
+ }], blur: [{
+ type: Input
+ }], style: [{
+ type: Input
+ }], onView: [{
+ type: Input
+ }], renderMention: [{
+ type: Input
+ }], renderTag: [{
+ type: Input
+ }], renderLink: [{
+ type: Input
+ }], viewed: [{
+ type: Output
+ }], expandedChange: [{
+ type: Output
+ }], containerRef: [{
+ type: ViewChild,
+ args: ["container", { static: true }]
+ }] } });
+//# sourceMappingURL=content-text.component.js.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/content-text.component.js.map b/packages/content-suggestions/dist/angular/angular/content-text.component.js.map
new file mode 100644
index 0000000..9d7571a
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/content-text.component.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"content-text.component.js","sourceRoot":"","sources":["../../../src/angular/content-text.component.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/content-title-with-suggestions.component.d.ts b/packages/content-suggestions/dist/angular/angular/content-title-with-suggestions.component.d.ts
new file mode 100644
index 0000000..4c55193
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/content-title-with-suggestions.component.d.ts
@@ -0,0 +1,20 @@
+import type { AngularContentEllipsisConfig, AngularLinkRenderer, AngularMentionRenderer, AngularTagRenderer } from "./types";
+import { EventEmitter } from "@angular/core";
+import * as i0 from "@angular/core";
+export declare class ContentTitleWithSuggestionsComponent {
+ className: string | undefined;
+ text: string | null | undefined;
+ ellipsis: AngularContentEllipsisConfig | undefined;
+ blur: boolean;
+ style: Record | null | undefined;
+ onView: (() => void) | undefined;
+ renderMention: AngularMentionRenderer | undefined;
+ renderTag: AngularTagRenderer | undefined;
+ renderLink: AngularLinkRenderer | undefined;
+ readonly viewed: EventEmitter;
+ readonly expandedChange: EventEmitter;
+ get normalizedEllipsis(): AngularContentEllipsisConfig;
+ static ɵfac: i0.ɵɵFactoryDeclaration;
+ static ɵcmp: i0.ɵɵComponentDeclaration;
+}
+//# sourceMappingURL=content-title-with-suggestions.component.d.ts.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/content-title-with-suggestions.component.d.ts.map b/packages/content-suggestions/dist/angular/angular/content-title-with-suggestions.component.d.ts.map
new file mode 100644
index 0000000..270b07e
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/content-title-with-suggestions.component.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"content-title-with-suggestions.component.d.ts","sourceRoot":"","sources":["../../../src/angular/content-title-with-suggestions.component.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,4BAA4B,EAC5B,mBAAmB,EACnB,sBAAsB,EAEtB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAsC,YAAY,EAAiB,MAAM,eAAe,CAAC;;AAIhG,qBAsBa,oCAAoC;IACtC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChC,QAAQ,EAAE,4BAA4B,GAAG,SAAS,CAAC;IACnD,IAAI,UAAS;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAC1D,MAAM,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IACjC,aAAa,EAAE,sBAAsB,GAAG,SAAS,CAAC;IAClD,SAAS,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAC1C,UAAU,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAE3C,QAAQ,CAAC,MAAM,qBAA4B;IAC3C,QAAQ,CAAC,cAAc,wBAA+B;IAEhE,IAAI,kBAAkB,IAAI,4BAA4B,CAMrD;yCApBU,oCAAoC;2CAApC,oCAAoC;CAqBhD"}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/content-title-with-suggestions.component.js b/packages/content-suggestions/dist/angular/angular/content-title-with-suggestions.component.js
new file mode 100644
index 0000000..45ebca8
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/content-title-with-suggestions.component.js
@@ -0,0 +1,87 @@
+import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from "@angular/core";
+import { ContentTextWithSuggestionsComponent } from "./content-text-with-suggestions.component";
+import * as i0 from "@angular/core";
+export class ContentTitleWithSuggestionsComponent {
+ className;
+ text;
+ ellipsis;
+ blur = false;
+ style;
+ onView;
+ renderMention;
+ renderTag;
+ renderLink;
+ viewed = new EventEmitter();
+ expandedChange = new EventEmitter();
+ get normalizedEllipsis() {
+ if (this.ellipsis !== undefined) {
+ return this.ellipsis;
+ }
+ return { rows: 2 };
+ }
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ContentTitleWithSuggestionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.18", type: ContentTitleWithSuggestionsComponent, isStandalone: true, selector: "content-title-with-suggestions", inputs: { className: "className", text: "text", ellipsis: "ellipsis", blur: "blur", style: "style", onView: "onView", renderMention: "renderMention", renderTag: "renderTag", renderLink: "renderLink" }, outputs: { viewed: "viewed", expandedChange: "expandedChange" }, ngImport: i0, template: `
+
+ `, isInline: true, dependencies: [{ kind: "component", type: ContentTextWithSuggestionsComponent, selector: "content-text-with-suggestions", inputs: ["className", "weight", "text", "ellipsis", "blur", "style", "onView", "renderMention", "renderTag", "renderLink"], outputs: ["viewed", "expandedChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
+}
+i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ContentTitleWithSuggestionsComponent, decorators: [{
+ type: Component,
+ args: [{
+ selector: "content-title-with-suggestions",
+ standalone: true,
+ imports: [ContentTextWithSuggestionsComponent],
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ template: `
+
+ `,
+ }]
+ }], propDecorators: { className: [{
+ type: Input
+ }], text: [{
+ type: Input
+ }], ellipsis: [{
+ type: Input
+ }], blur: [{
+ type: Input
+ }], style: [{
+ type: Input
+ }], onView: [{
+ type: Input
+ }], renderMention: [{
+ type: Input
+ }], renderTag: [{
+ type: Input
+ }], renderLink: [{
+ type: Input
+ }], viewed: [{
+ type: Output
+ }], expandedChange: [{
+ type: Output
+ }] } });
+//# sourceMappingURL=content-title-with-suggestions.component.js.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/content-title-with-suggestions.component.js.map b/packages/content-suggestions/dist/angular/angular/content-title-with-suggestions.component.js.map
new file mode 100644
index 0000000..4b500d9
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/content-title-with-suggestions.component.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"content-title-with-suggestions.component.js","sourceRoot":"","sources":["../../../src/angular/content-title-with-suggestions.component.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEhG,OAAO,EAAE,mCAAmC,EAAE,MAAM,2CAA2C,CAAC;;AAwBhG,MAAM,OAAO,oCAAoC;IACtC,SAAS,CAAqB;IAC9B,IAAI,CAA4B;IAChC,QAAQ,CAA2C;IACnD,IAAI,GAAG,KAAK,CAAC;IACb,KAAK,CAAqD;IAC1D,MAAM,CAA2B;IACjC,aAAa,CAAqC;IAClD,SAAS,CAAiC;IAC1C,UAAU,CAAkC;IAElC,MAAM,GAAG,IAAI,YAAY,EAAQ,CAAC;IAClC,cAAc,GAAG,IAAI,YAAY,EAAW,CAAC;IAEhE,IAAI,kBAAkB;QACpB,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC,QAAQ,CAAC;QACvB,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,CAAC,EAAsC,CAAC;IACzD,CAAC;wGApBU,oCAAoC;4FAApC,oCAAoC,qWAjBrC;;;;;;;;;;;;;;;GAeT,4DAjBS,mCAAmC;;4FAmBlC,oCAAoC;kBAtBhD,SAAS;mBAAC;oBACT,QAAQ,EAAE,gCAAgC;oBAC1C,UAAU,EAAE,IAAI;oBAChB,OAAO,EAAE,CAAC,mCAAmC,CAAC;oBAC9C,eAAe,EAAE,uBAAuB,CAAC,MAAM;oBAC/C,QAAQ,EAAE;;;;;;;;;;;;;;;GAeT;iBACF;;sBAEE,KAAK;;sBACL,KAAK;;sBACL,KAAK;;sBACL,KAAK;;sBACL,KAAK;;sBACL,KAAK;;sBACL,KAAK;;sBACL,KAAK;;sBACL,KAAK;;sBAEL,MAAM;;sBACN,MAAM"}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/index.d.ts b/packages/content-suggestions/dist/angular/angular/index.d.ts
new file mode 100644
index 0000000..889e32c
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/index.d.ts
@@ -0,0 +1,18 @@
+import { ContentTextComponent } from "./content-text.component";
+import { ContentTextWithSuggestionsComponent } from "./content-text-with-suggestions.component";
+import { ContentTitleWithSuggestionsComponent } from "./content-title-with-suggestions.component";
+import { ContentSuggestionsRenderResultDirective } from "./render-result.directive";
+import * as i0 from "@angular/core";
+import * as i1 from "./content-text.component";
+import * as i2 from "./content-text-with-suggestions.component";
+import * as i3 from "./content-title-with-suggestions.component";
+import * as i4 from "./render-result.directive";
+export type { AngularContentEllipsisConfig, AngularContentSnapshot, AngularContentTextProps, AngularContentTextWithSuggestionsProps, AngularContentTitleWithSuggestionsProps, AngularContentToken, AngularCountEllipsisConfig, AngularEllipsisExpandHandler, AngularEllipsisSymbol, AngularExpandInfo, AngularLinkRenderer, AngularLinkToken, AngularMentionRenderer, AngularMentionToken, AngularRenderResult, AngularRowsEllipsisConfig, AngularTagRenderer, AngularTagToken, AngularTextToken, } from "./types";
+export { AngularContentSuggestionsAdapter, buildAngularTagHref, createAngularContentTokens, } from "./tokens";
+export { ContentTextComponent, ContentTextWithSuggestionsComponent, ContentTitleWithSuggestionsComponent, ContentSuggestionsRenderResultDirective, };
+export declare class ContentSuggestionsAngularModule {
+ static ɵfac: i0.ɵɵFactoryDeclaration;
+ static ɵmod: i0.ɵɵNgModuleDeclaration;
+ static ɵinj: i0.ɵɵInjectorDeclaration;
+}
+//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/index.d.ts.map b/packages/content-suggestions/dist/angular/angular/index.d.ts.map
new file mode 100644
index 0000000..7b6cd51
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/index.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/angular/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,mCAAmC,EAAE,MAAM,2CAA2C,CAAC;AAChG,OAAO,EAAE,oCAAoC,EAAE,MAAM,4CAA4C,CAAC;AAClG,OAAO,EAAE,uCAAuC,EAAE,MAAM,2BAA2B,CAAC;;;;;;AAEpF,YAAY,EACV,4BAA4B,EAC5B,sBAAsB,EACtB,uBAAuB,EACvB,sCAAsC,EACtC,uCAAuC,EACvC,mBAAmB,EACnB,0BAA0B,EAC1B,4BAA4B,EAC5B,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,gCAAgC,EAChC,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,oBAAoB,EACpB,mCAAmC,EACnC,oCAAoC,EACpC,uCAAuC,GACxC,CAAC;AAEF,qBAca,+BAA+B;yCAA/B,+BAA+B;0CAA/B,+BAA+B;0CAA/B,+BAA+B;CAAG"}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/index.js b/packages/content-suggestions/dist/angular/angular/index.js
new file mode 100644
index 0000000..cbc3ae9
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/index.js
@@ -0,0 +1,39 @@
+import { NgModule } from "@angular/core";
+import { ContentTextComponent } from "./content-text.component";
+import { ContentTextWithSuggestionsComponent } from "./content-text-with-suggestions.component";
+import { ContentTitleWithSuggestionsComponent } from "./content-title-with-suggestions.component";
+import { ContentSuggestionsRenderResultDirective } from "./render-result.directive";
+import * as i0 from "@angular/core";
+export { AngularContentSuggestionsAdapter, buildAngularTagHref, createAngularContentTokens, } from "./tokens";
+export { ContentTextComponent, ContentTextWithSuggestionsComponent, ContentTitleWithSuggestionsComponent, ContentSuggestionsRenderResultDirective, };
+export class ContentSuggestionsAngularModule {
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ContentSuggestionsAngularModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.18", ngImport: i0, type: ContentSuggestionsAngularModule, imports: [ContentTextComponent,
+ ContentTextWithSuggestionsComponent,
+ ContentTitleWithSuggestionsComponent,
+ ContentSuggestionsRenderResultDirective], exports: [ContentTextComponent,
+ ContentTextWithSuggestionsComponent,
+ ContentTitleWithSuggestionsComponent,
+ ContentSuggestionsRenderResultDirective] });
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ContentSuggestionsAngularModule, imports: [ContentTextComponent,
+ ContentTextWithSuggestionsComponent,
+ ContentTitleWithSuggestionsComponent] });
+}
+i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ContentSuggestionsAngularModule, decorators: [{
+ type: NgModule,
+ args: [{
+ imports: [
+ ContentTextComponent,
+ ContentTextWithSuggestionsComponent,
+ ContentTitleWithSuggestionsComponent,
+ ContentSuggestionsRenderResultDirective,
+ ],
+ exports: [
+ ContentTextComponent,
+ ContentTextWithSuggestionsComponent,
+ ContentTitleWithSuggestionsComponent,
+ ContentSuggestionsRenderResultDirective,
+ ],
+ }]
+ }] });
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/index.js.map b/packages/content-suggestions/dist/angular/angular/index.js.map
new file mode 100644
index 0000000..ea678c2
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/angular/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,mCAAmC,EAAE,MAAM,2CAA2C,CAAC;AAChG,OAAO,EAAE,oCAAoC,EAAE,MAAM,4CAA4C,CAAC;AAClG,OAAO,EAAE,uCAAuC,EAAE,MAAM,2BAA2B,CAAC;;AAwBpF,OAAO,EACL,gCAAgC,EAChC,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,oBAAoB,EACpB,mCAAmC,EACnC,oCAAoC,EACpC,uCAAuC,GACxC,CAAC;AAgBF,MAAM,OAAO,+BAA+B;wGAA/B,+BAA+B;yGAA/B,+BAA+B,YAZxC,oBAAoB;YACpB,mCAAmC;YACnC,oCAAoC;YACpC,uCAAuC,aAGvC,oBAAoB;YACpB,mCAAmC;YACnC,oCAAoC;YACpC,uCAAuC;yGAG9B,+BAA+B,YAZxC,oBAAoB;YACpB,mCAAmC;YACnC,oCAAoC;;4FAU3B,+BAA+B;kBAd3C,QAAQ;mBAAC;oBACR,OAAO,EAAE;wBACP,oBAAoB;wBACpB,mCAAmC;wBACnC,oCAAoC;wBACpC,uCAAuC;qBACxC;oBACD,OAAO,EAAE;wBACP,oBAAoB;wBACpB,mCAAmC;wBACnC,oCAAoC;wBACpC,uCAAuC;qBACxC;iBACF"}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/public-api.d.ts b/packages/content-suggestions/dist/angular/angular/public-api.d.ts
new file mode 100644
index 0000000..8948ea2
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/public-api.d.ts
@@ -0,0 +1,2 @@
+export * from "./index";
+//# sourceMappingURL=public-api.d.ts.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/public-api.d.ts.map b/packages/content-suggestions/dist/angular/angular/public-api.d.ts.map
new file mode 100644
index 0000000..ab29098
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/public-api.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../../../src/angular/public-api.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC"}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/public-api.js b/packages/content-suggestions/dist/angular/angular/public-api.js
new file mode 100644
index 0000000..1416daa
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/public-api.js
@@ -0,0 +1,2 @@
+export * from "./index";
+//# sourceMappingURL=public-api.js.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/public-api.js.map b/packages/content-suggestions/dist/angular/angular/public-api.js.map
new file mode 100644
index 0000000..b9553e5
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/public-api.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"public-api.js","sourceRoot":"","sources":["../../../src/angular/public-api.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC"}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/render-result.directive.d.ts b/packages/content-suggestions/dist/angular/angular/render-result.directive.d.ts
new file mode 100644
index 0000000..de45863
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/render-result.directive.d.ts
@@ -0,0 +1,14 @@
+import type { AngularRenderResult } from "./types";
+import { ElementRef, OnChanges, Renderer2 } from "@angular/core";
+import * as i0 from "@angular/core";
+export declare class ContentSuggestionsRenderResultDirective implements OnChanges {
+ private readonly elementRef;
+ private readonly renderer;
+ contentSuggestionsRenderResult: AngularRenderResult;
+ constructor(elementRef: ElementRef, renderer: Renderer2);
+ ngOnChanges(): void;
+ private clearHost;
+ static ɵfac: i0.ɵɵFactoryDeclaration;
+ static ɵdir: i0.ɵɵDirectiveDeclaration;
+}
+//# sourceMappingURL=render-result.directive.d.ts.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/render-result.directive.d.ts.map b/packages/content-suggestions/dist/angular/angular/render-result.directive.d.ts.map
new file mode 100644
index 0000000..7eb7737
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/render-result.directive.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"render-result.directive.d.ts","sourceRoot":"","sources":["../../../src/angular/render-result.directive.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD,OAAO,EAAa,UAAU,EAAS,SAAS,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;;AAEnF,qBAIa,uCAAwC,YAAW,SAAS;IAIrE,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAJlB,8BAA8B,EAAE,mBAAmB,CAAC;gBAG1C,UAAU,EAAE,UAAU,CAAC,WAAW,CAAC,EACnC,QAAQ,EAAE,SAAS;IAKtC,WAAW,IAAI,IAAI;IAiBnB,OAAO,CAAC,SAAS;yCA3BN,uCAAuC;2CAAvC,uCAAuC;CAkCnD"}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/render-result.directive.js b/packages/content-suggestions/dist/angular/angular/render-result.directive.js
new file mode 100644
index 0000000..e629dbe
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/render-result.directive.js
@@ -0,0 +1,43 @@
+import { Directive, Input } from "@angular/core";
+import * as i0 from "@angular/core";
+export class ContentSuggestionsRenderResultDirective {
+ elementRef;
+ renderer;
+ contentSuggestionsRenderResult;
+ constructor(elementRef, renderer) {
+ this.elementRef = elementRef;
+ this.renderer = renderer;
+ this.renderer.setStyle(this.elementRef.nativeElement, "display", "contents");
+ }
+ ngOnChanges() {
+ this.clearHost();
+ const value = this.contentSuggestionsRenderResult;
+ if (value === null || value === undefined) {
+ return;
+ }
+ if (value instanceof Node) {
+ this.renderer.appendChild(this.elementRef.nativeElement, value);
+ return;
+ }
+ const textNode = this.renderer.createText(String(value));
+ this.renderer.appendChild(this.elementRef.nativeElement, textNode);
+ }
+ clearHost() {
+ const host = this.elementRef.nativeElement;
+ while (host.firstChild) {
+ host.removeChild(host.firstChild);
+ }
+ }
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ContentSuggestionsRenderResultDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.18", type: ContentSuggestionsRenderResultDirective, isStandalone: true, selector: "[contentSuggestionsRenderResult]", inputs: { contentSuggestionsRenderResult: "contentSuggestionsRenderResult" }, usesOnChanges: true, ngImport: i0 });
+}
+i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ContentSuggestionsRenderResultDirective, decorators: [{
+ type: Directive,
+ args: [{
+ selector: "[contentSuggestionsRenderResult]",
+ standalone: true,
+ }]
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { contentSuggestionsRenderResult: [{
+ type: Input
+ }] } });
+//# sourceMappingURL=render-result.directive.js.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/render-result.directive.js.map b/packages/content-suggestions/dist/angular/angular/render-result.directive.js.map
new file mode 100644
index 0000000..e1ae716
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/render-result.directive.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"render-result.directive.js","sourceRoot":"","sources":["../../../src/angular/render-result.directive.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAc,KAAK,EAAwB,MAAM,eAAe,CAAC;;AAMnF,MAAM,OAAO,uCAAuC;IAI/B;IACA;IAJV,8BAA8B,CAAsB;IAE7D,YACmB,UAAmC,EACnC,QAAmB;QADnB,eAAU,GAAV,UAAU,CAAyB;QACnC,aAAQ,GAAR,QAAQ,CAAW;QAEpC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAC/E,CAAC;IAED,WAAW;QACT,IAAI,CAAC,SAAS,EAAE,CAAC;QAEjB,MAAM,KAAK,GAAG,IAAI,CAAC,8BAA8B,CAAC;QAClD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC1C,OAAO;QACT,CAAC;QAED,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;YAC1B,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;YAChE,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACzD,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;IACrE,CAAC;IAEO,SAAS;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;QAE3C,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;YACvB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;wGAjCU,uCAAuC;4FAAvC,uCAAuC;;4FAAvC,uCAAuC;kBAJnD,SAAS;mBAAC;oBACT,QAAQ,EAAE,kCAAkC;oBAC5C,UAAU,EAAE,IAAI;iBACjB;;sBAEE,KAAK"}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/tokens.d.ts b/packages/content-suggestions/dist/angular/angular/tokens.d.ts
new file mode 100644
index 0000000..b42354a
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/tokens.d.ts
@@ -0,0 +1,8 @@
+import type { AngularContentSnapshot, AngularContentToken } from "./types";
+import type { TagEntity } from "../core";
+export declare const createAngularContentTokens: (inputText: string | null | undefined) => AngularContentToken[];
+export declare const buildAngularTagHref: (entity: TagEntity) => string;
+export declare class AngularContentSuggestionsAdapter {
+ snapshot(inputText: string | null | undefined): AngularContentSnapshot;
+}
+//# sourceMappingURL=tokens.d.ts.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/tokens.d.ts.map b/packages/content-suggestions/dist/angular/angular/tokens.d.ts.map
new file mode 100644
index 0000000..4f8c5ed
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/tokens.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../../src/angular/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,mBAAmB,EAKpB,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,SAAS,CAAC;AAgCxD,eAAO,MAAM,0BAA0B,GACrC,WAAW,MAAM,GAAG,IAAI,GAAG,SAAS,KACnC,mBAAmB,EAqBrB,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,QAAQ,SAAS,KAAG,MAEvD,CAAC;AAEF,qBAAa,gCAAgC;IAC3C,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,sBAAsB;CAWvE"}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/tokens.js b/packages/content-suggestions/dist/angular/angular/tokens.js
new file mode 100644
index 0000000..80b8dd2
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/tokens.js
@@ -0,0 +1,58 @@
+import { findAllEntities } from "../core";
+const mapEntityToToken = (entity) => {
+ if (entity.type === "mention") {
+ return {
+ kind: "mention",
+ entity,
+ };
+ }
+ if (entity.type === "tag") {
+ return {
+ kind: "tag",
+ entity,
+ };
+ }
+ return {
+ kind: "link",
+ entity,
+ };
+};
+const createTextToken = (text, start, end) => ({
+ kind: "text",
+ text,
+ start,
+ end,
+});
+export const createAngularContentTokens = (inputText) => {
+ const text = inputText ?? "";
+ const entities = findAllEntities(text);
+ let cursor = 0;
+ const tokens = [];
+ for (const entity of entities) {
+ if (entity.start > cursor) {
+ tokens.push(createTextToken(text.slice(cursor, entity.start), cursor, entity.start));
+ }
+ tokens.push(mapEntityToToken(entity));
+ cursor = entity.end;
+ }
+ if (cursor < text.length) {
+ tokens.push(createTextToken(text.slice(cursor), cursor, text.length));
+ }
+ return tokens;
+};
+export const buildAngularTagHref = (entity) => {
+ return `/search/?query=${encodeURIComponent(entity.tag.toLowerCase())}`;
+};
+export class AngularContentSuggestionsAdapter {
+ snapshot(inputText) {
+ const text = inputText ?? "";
+ const entities = findAllEntities(text);
+ const tokens = createAngularContentTokens(text);
+ return {
+ text,
+ entities,
+ tokens,
+ };
+ }
+}
+//# sourceMappingURL=tokens.js.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/tokens.js.map b/packages/content-suggestions/dist/angular/angular/tokens.js.map
new file mode 100644
index 0000000..e7bcbcf
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/tokens.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../../src/angular/tokens.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C,MAAM,gBAAgB,GAAG,CAAC,MAAqB,EAA4D,EAAE;IAC3G,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO;YACL,IAAI,EAAE,SAAS;YACf,MAAM;SACP,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC1B,OAAO;YACL,IAAI,EAAE,KAAK;YACX,MAAM;SACP,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,MAAM;KACP,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,IAAY,EAAE,KAAa,EAAE,GAAW,EAAoB,EAAE,CAAC,CAAC;IACvF,IAAI,EAAE,MAAM;IACZ,IAAI;IACJ,KAAK;IACL,GAAG;CACJ,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CACxC,SAAoC,EACb,EAAE;IACzB,MAAM,IAAI,GAAG,SAAS,IAAI,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAEvC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,MAAM,GAA0B,EAAE,CAAC;IAEzC,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,IAAI,MAAM,CAAC,KAAK,GAAG,MAAM,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACvF,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;QACtC,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC;IACtB,CAAC;IAED,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,MAAiB,EAAU,EAAE;IAC/D,OAAO,kBAAkB,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;AAC1E,CAAC,CAAC;AAEF,MAAM,OAAO,gCAAgC;IAC3C,QAAQ,CAAC,SAAoC;QAC3C,MAAM,IAAI,GAAG,SAAS,IAAI,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,0BAA0B,CAAC,IAAI,CAAC,CAAC;QAEhD,OAAO;YACL,IAAI;YACJ,QAAQ;YACR,MAAM;SACP,CAAC;IACJ,CAAC;CACF"}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/types.d.ts b/packages/content-suggestions/dist/angular/angular/types.d.ts
new file mode 100644
index 0000000..1a82339
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/types.d.ts
@@ -0,0 +1,70 @@
+import type { ContentEntity, LinkEntity, MentionEntity, TagEntity } from "../core";
+import type { TypographyWeight } from "@hublib-web/tach-typography/core";
+export interface AngularTextToken {
+ kind: "text";
+ text: string;
+ start: number;
+ end: number;
+}
+export interface AngularMentionToken {
+ kind: "mention";
+ entity: MentionEntity;
+}
+export interface AngularTagToken {
+ kind: "tag";
+ entity: TagEntity;
+}
+export interface AngularLinkToken {
+ kind: "link";
+ entity: LinkEntity;
+}
+export type AngularContentToken = AngularTextToken | AngularMentionToken | AngularTagToken | AngularLinkToken;
+export interface AngularContentSnapshot {
+ text: string;
+ entities: ContentEntity[];
+ tokens: AngularContentToken[];
+}
+export interface AngularExpandInfo {
+ expanded: boolean;
+}
+export type AngularEllipsisSymbol = string | ((expanded: boolean) => string);
+export type AngularEllipsisExpandHandler = ((expanded: boolean) => void) | ((event: MouseEvent, info: AngularExpandInfo) => void);
+export type AngularCountEllipsisConfig = {
+ count: number;
+ rows?: never;
+ expandable?: boolean;
+ expanded?: boolean;
+ symbol?: AngularEllipsisSymbol;
+ onExpand?: AngularEllipsisExpandHandler;
+};
+export type AngularRowsEllipsisConfig = {
+ rows: number;
+ count?: never;
+ expandable?: boolean;
+ expanded?: boolean;
+ symbol?: AngularEllipsisSymbol;
+ onExpand?: AngularEllipsisExpandHandler;
+};
+export type AngularContentEllipsisConfig = AngularCountEllipsisConfig | AngularRowsEllipsisConfig | false;
+export type AngularRenderResult = Node | string | number | null | undefined;
+export type AngularMentionRenderer = (entity: MentionEntity, index: number) => AngularRenderResult;
+export type AngularTagRenderer = (entity: TagEntity, index: number) => AngularRenderResult;
+export type AngularLinkRenderer = (entity: LinkEntity, index: number) => AngularRenderResult;
+export interface AngularContentTextProps {
+ className?: string;
+ weight?: TypographyWeight;
+ text?: string | null;
+ ellipsis?: AngularContentEllipsisConfig;
+ blur?: boolean;
+ style?: Record | null;
+ onView?: () => void;
+ renderMention?: AngularMentionRenderer;
+ renderTag?: AngularTagRenderer;
+ renderLink?: AngularLinkRenderer;
+}
+export type AngularContentTextWithSuggestionsProps = Omit & {
+ renderMention?: AngularMentionRenderer;
+ renderTag?: AngularTagRenderer;
+};
+export type AngularContentTitleWithSuggestionsProps = Omit;
+//# sourceMappingURL=types.d.ts.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/types.d.ts.map b/packages/content-suggestions/dist/angular/angular/types.d.ts.map
new file mode 100644
index 0000000..b7d1257
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/types.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/angular/types.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/types.js b/packages/content-suggestions/dist/angular/angular/types.js
new file mode 100644
index 0000000..718fd38
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/types.js
@@ -0,0 +1,2 @@
+export {};
+//# sourceMappingURL=types.js.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/angular/types.js.map b/packages/content-suggestions/dist/angular/angular/types.js.map
new file mode 100644
index 0000000..5b9ef74
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/angular/types.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/angular/types.ts"],"names":[],"mappings":""}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/core/index.d.ts b/packages/content-suggestions/dist/angular/core/index.d.ts
new file mode 100644
index 0000000..0a646d2
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/core/index.d.ts
@@ -0,0 +1,3 @@
+export type { BaseEntity, ContentEntity, LinkEntity, MentionEntity, ParsedMention, ProcessedContent, TagEntity, } from "./types";
+export { findAllEntities, findLinks, findMentions, findTags, mentionLinkRegexp, parseMention, processContent, } from "./parser";
+//# sourceMappingURL=index.d.ts.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/core/index.d.ts.map b/packages/content-suggestions/dist/angular/core/index.d.ts.map
new file mode 100644
index 0000000..36e6c34
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/core/index.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,aAAa,EACb,UAAU,EACV,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,SAAS,GACV,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,eAAe,EACf,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,iBAAiB,EACjB,YAAY,EACZ,cAAc,GACf,MAAM,UAAU,CAAC"}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/core/index.js b/packages/content-suggestions/dist/angular/core/index.js
new file mode 100644
index 0000000..7cf1ff9
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/core/index.js
@@ -0,0 +1,2 @@
+export { findAllEntities, findLinks, findMentions, findTags, mentionLinkRegexp, parseMention, processContent, } from "./parser";
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/core/index.js.map b/packages/content-suggestions/dist/angular/core/index.js.map
new file mode 100644
index 0000000..edce6d4
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/core/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/index.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,eAAe,EACf,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,iBAAiB,EACjB,YAAY,EACZ,cAAc,GACf,MAAM,UAAU,CAAC"}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/core/parser.d.ts b/packages/content-suggestions/dist/angular/core/parser.d.ts
new file mode 100644
index 0000000..2b749bd
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/core/parser.d.ts
@@ -0,0 +1,9 @@
+import type { ContentEntity, LinkEntity, MentionEntity, ParsedMention, ProcessedContent, TagEntity } from "./types";
+export declare const mentionLinkRegexp: RegExp;
+export declare const parseMention: (mention: string) => ParsedMention | null;
+export declare const findMentions: (text: string) => MentionEntity[];
+export declare const findTags: (content: string) => TagEntity[];
+export declare const findLinks: (content: string) => LinkEntity[];
+export declare const findAllEntities: (content: string) => ContentEntity[];
+export declare const processContent: (content: string) => ProcessedContent;
+//# sourceMappingURL=parser.d.ts.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/core/parser.d.ts.map b/packages/content-suggestions/dist/angular/core/parser.d.ts.map
new file mode 100644
index 0000000..db327ae
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/core/parser.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/core/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,SAAS,EACV,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,iBAAiB,QACgE,CAAC;AAE/F,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,KAAG,aAAa,GAAG,IAkB9D,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,KAAG,aAAa,EAkBxD,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,SAAS,MAAM,KAAG,SAAS,EAiBnD,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,SAAS,MAAM,KAAG,UAAU,EAqBrD,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,SAAS,MAAM,KAAG,aAAa,EAM9D,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,KAAG,gBAYhD,CAAC"}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/core/parser.js b/packages/content-suggestions/dist/angular/core/parser.js
new file mode 100644
index 0000000..32f6ba6
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/core/parser.js
@@ -0,0 +1,85 @@
+export const mentionLinkRegexp = /@\[[^\]]+]\([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\)/g;
+export const parseMention = (mention) => {
+ const regex = /@\[([^\]]+)\]\(([\w-]{36})\)/;
+ const match = mention.match(regex);
+ if (!match) {
+ return null;
+ }
+ const mentionText = match[1];
+ const mentionId = match[2];
+ if (!mentionText || !mentionId) {
+ return null;
+ }
+ return {
+ mention: `@${mentionText}`,
+ id: mentionId,
+ };
+};
+export const findMentions = (text) => {
+ let match;
+ const matches = [];
+ while ((match = mentionLinkRegexp.exec(text)) !== null) {
+ const parsed = parseMention(match[0]);
+ const baseMention = {
+ start: match.index,
+ end: mentionLinkRegexp.lastIndex,
+ text: match[0],
+ type: "mention",
+ displayText: parsed?.mention ?? match[0],
+ };
+ matches.push(parsed?.id ? { ...baseMention, userId: parsed.id } : baseMention);
+ }
+ return matches;
+};
+export const findTags = (content) => {
+ const regex = /#[^\s]{1,201}/g;
+ const results = [];
+ let match;
+ while ((match = regex.exec(content)) !== null) {
+ const value = match[0];
+ results.push({
+ start: match.index,
+ end: match.index + value.length,
+ text: value,
+ type: "tag",
+ tag: value.replace("#", ""),
+ });
+ }
+ return results;
+};
+export const findLinks = (content) => {
+ const regex = /\b((https?:\/\/)?(?:[\w-]+\.)+[a-z]{2,}(\/[\w\-._~:/?#[\]@!$&'()*+,;=]*)?)/gi;
+ const results = [];
+ let match;
+ while ((match = regex.exec(content)) !== null) {
+ const rawUrl = match[0];
+ const hasProtocol = /^https?:\/\//i.test(rawUrl);
+ const fullUrl = hasProtocol ? rawUrl : `https://${rawUrl}`;
+ results.push({
+ start: match.index,
+ end: match.index + rawUrl.length,
+ text: rawUrl,
+ url: fullUrl,
+ type: "link",
+ });
+ }
+ return results;
+};
+export const findAllEntities = (content) => {
+ const mentions = findMentions(content);
+ const tags = findTags(content);
+ const links = findLinks(content);
+ return [...mentions, ...tags, ...links].sort((a, b) => a.start - b.start);
+};
+export const processContent = (content) => {
+ const processedText = content.replace(mentionLinkRegexp, match => {
+ const parsed = parseMention(match);
+ return parsed ? parsed.mention : match;
+ });
+ const tags = findTags(content).map(tag => tag.tag);
+ return {
+ processedText,
+ tags,
+ };
+};
+//# sourceMappingURL=parser.js.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/core/parser.js.map b/packages/content-suggestions/dist/angular/core/parser.js.map
new file mode 100644
index 0000000..482179c
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/core/parser.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../src/core/parser.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/core/types.d.ts b/packages/content-suggestions/dist/angular/core/types.d.ts
new file mode 100644
index 0000000..fab272c
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/core/types.d.ts
@@ -0,0 +1,28 @@
+export interface BaseEntity {
+ start: number;
+ end: number;
+ text: string;
+}
+export interface MentionEntity extends BaseEntity {
+ type: "mention";
+ displayText: string;
+ userId?: string;
+}
+export interface TagEntity extends BaseEntity {
+ type: "tag";
+ tag: string;
+}
+export interface LinkEntity extends BaseEntity {
+ type: "link";
+ url: string;
+}
+export type ContentEntity = MentionEntity | TagEntity | LinkEntity;
+export interface ParsedMention {
+ mention: string;
+ id: string;
+}
+export interface ProcessedContent {
+ processedText: string;
+ tags: string[];
+}
+//# sourceMappingURL=types.d.ts.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/core/types.d.ts.map b/packages/content-suggestions/dist/angular/core/types.d.ts.map
new file mode 100644
index 0000000..e0ced53
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/core/types.d.ts.map
@@ -0,0 +1 @@
+{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C,IAAI,EAAE,SAAS,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAU,SAAQ,UAAU;IAC3C,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,UAAW,SAAQ,UAAU;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,SAAS,GAAG,UAAU,CAAC;AAEnE,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB"}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/core/types.js b/packages/content-suggestions/dist/angular/core/types.js
new file mode 100644
index 0000000..718fd38
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/core/types.js
@@ -0,0 +1,2 @@
+export {};
+//# sourceMappingURL=types.js.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/core/types.js.map b/packages/content-suggestions/dist/angular/core/types.js.map
new file mode 100644
index 0000000..26d6a62
--- /dev/null
+++ b/packages/content-suggestions/dist/angular/core/types.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/types.ts"],"names":[],"mappings":""}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/index.cjs b/packages/content-suggestions/dist/angular/index.cjs
deleted file mode 100644
index 0ed6858..0000000
--- a/packages/content-suggestions/dist/angular/index.cjs
+++ /dev/null
@@ -1,495 +0,0 @@
-'use strict';
-
-// src/core/parser.ts
-var mentionLinkRegexp = /@\[[^\]]+]\([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\)/g;
-var parseMention = (mention) => {
- const regex = /@\[([^\]]+)\]\(([\w-]{36})\)/;
- const match = mention.match(regex);
- if (!match) {
- return null;
- }
- const mentionText = match[1];
- const mentionId = match[2];
- if (!mentionText || !mentionId) {
- return null;
- }
- return {
- mention: `@${mentionText}`,
- id: mentionId
- };
-};
-var findMentions = (text) => {
- let match;
- const matches = [];
- while ((match = mentionLinkRegexp.exec(text)) !== null) {
- const parsed = parseMention(match[0]);
- const baseMention = {
- start: match.index,
- end: mentionLinkRegexp.lastIndex,
- text: match[0],
- type: "mention",
- displayText: parsed?.mention ?? match[0]
- };
- matches.push(parsed?.id ? { ...baseMention, userId: parsed.id } : baseMention);
- }
- return matches;
-};
-var findTags = (content) => {
- const regex = /#[^\s]{1,201}/g;
- const results = [];
- let match;
- while ((match = regex.exec(content)) !== null) {
- const value = match[0];
- results.push({
- start: match.index,
- end: match.index + value.length,
- text: value,
- type: "tag",
- tag: value.replace("#", "")
- });
- }
- return results;
-};
-var findLinks = (content) => {
- const regex = /\b((https?:\/\/)?(?:[\w-]+\.)+[a-z]{2,}(\/[\w\-._~:/?#[\]@!$&'()*+,;=]*)?)/gi;
- const results = [];
- let match;
- while ((match = regex.exec(content)) !== null) {
- const rawUrl = match[0];
- const hasProtocol = /^https?:\/\//i.test(rawUrl);
- const fullUrl = hasProtocol ? rawUrl : `https://${rawUrl}`;
- results.push({
- start: match.index,
- end: match.index + rawUrl.length,
- text: rawUrl,
- url: fullUrl,
- type: "link"
- });
- }
- return results;
-};
-var findAllEntities = (content) => {
- const mentions = findMentions(content);
- const tags = findTags(content);
- const links = findLinks(content);
- return [...mentions, ...tags, ...links].sort((a, b) => a.start - b.start);
-};
-
-// src/angular/index.ts
-var LINK_COLOR = "#1677ff";
-var READ_MORE_TEXT = "\u0427\u0438\u0442\u0430\u0442\u044C \u043F\u043E\u043B\u043D\u043E\u0441\u0442\u044C\u044E";
-var toKebabCase = (value) => value.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`);
-var applyStyleObject = (element, styles) => {
- if (!styles) {
- return;
- }
- for (const [key, rawValue] of Object.entries(styles)) {
- if (rawValue === null || rawValue === void 0) {
- continue;
- }
- const styleValue = typeof rawValue === "number" ? `${rawValue}px` : String(rawValue);
- if (key.startsWith("--")) {
- element.style.setProperty(key, styleValue);
- continue;
- }
- const cssKey = key.includes("-") ? key : toKebabCase(key);
- element.style.setProperty(cssKey, styleValue);
- }
-};
-var toNode = (value) => {
- if (value === null || value === void 0) {
- return null;
- }
- if (value instanceof Node) {
- return value;
- }
- return document.createTextNode(String(value));
-};
-var resolveEllipsisSymbol = (symbol, expanded) => {
- if (typeof symbol === "function") {
- return symbol(expanded);
- }
- return symbol ?? READ_MORE_TEXT;
-};
-var buildAngularTagHref = (entity) => {
- return `/search/?query=${encodeURIComponent(entity.tag.toLowerCase())}`;
-};
-var createAngularContentTokens = (inputText) => {
- const text = inputText ?? "";
- const entities = findAllEntities(text);
- let cursor = 0;
- const tokens = [];
- for (const entity of entities) {
- if (entity.start > cursor) {
- tokens.push({
- kind: "text",
- text: text.slice(cursor, entity.start),
- start: cursor,
- end: entity.start
- });
- }
- if (entity.type === "mention") {
- tokens.push({
- kind: "mention",
- entity
- });
- } else if (entity.type === "tag") {
- tokens.push({
- kind: "tag",
- entity
- });
- } else {
- tokens.push({
- kind: "link",
- entity
- });
- }
- cursor = entity.end;
- }
- if (cursor < text.length) {
- tokens.push({
- kind: "text",
- text: text.slice(cursor),
- start: cursor,
- end: text.length
- });
- }
- return tokens;
-};
-var AngularContentSuggestionsAdapter = class {
- snapshot(inputText) {
- const text = inputText ?? "";
- const entities = findAllEntities(text);
- const tokens = createAngularContentTokens(text);
- return {
- text,
- entities,
- tokens
- };
- }
-};
-var AngularContentTextRenderer = class {
- host = null;
- props = {};
- expanded = false;
- viewed = false;
- hostInsideView = false;
- observer = null;
- attach(host, props = {}) {
- this.destroy();
- this.host = host;
- this.props = { ...props };
- this.expanded = false;
- this.viewed = false;
- this.hostInsideView = false;
- this.initObserver();
- this.render();
- return this.getState();
- }
- update(nextProps) {
- this.props = {
- ...this.props,
- ...nextProps
- };
- this.render();
- return this.getState();
- }
- destroy() {
- if (this.observer && this.host) {
- this.observer.unobserve(this.host);
- this.observer.disconnect();
- }
- this.observer = null;
- if (this.host) {
- this.host.innerHTML = "";
- }
- this.host = null;
- this.props = {};
- this.expanded = false;
- this.viewed = false;
- this.hostInsideView = false;
- }
- getState() {
- return {
- props: { ...this.props },
- snapshot: this.createSnapshot(),
- expanded: this.getMergedExpanded(this.resolveEllipsisConfig(), this.getText())
- };
- }
- getText() {
- return this.props.text ?? "";
- }
- createSnapshot() {
- const text = this.getText();
- const entities = findAllEntities(text);
- const tokens = createAngularContentTokens(text);
- return {
- text,
- entities,
- tokens
- };
- }
- resolveEllipsisConfig() {
- const ellipsis = this.props.ellipsis;
- if (!ellipsis || typeof ellipsis !== "object") {
- return null;
- }
- return ellipsis;
- }
- getMergedExpanded(ellipsisConfig, text) {
- const controlledExpanded = ellipsisConfig && typeof ellipsisConfig.expanded === "boolean" ? ellipsisConfig.expanded : void 0;
- if (controlledExpanded !== void 0) {
- return controlledExpanded;
- }
- if (ellipsisConfig && "count" in ellipsisConfig) {
- const count = ellipsisConfig.count ?? 0;
- if (count <= 0 || text.length <= count) {
- return true;
- }
- }
- return this.expanded;
- }
- createDefaultMentionNode(entity) {
- const span = document.createElement("span");
- span.style.color = LINK_COLOR;
- span.style.fontWeight = this.props.weight === "bold" ? "700" : "400";
- span.textContent = entity.displayText;
- return span;
- }
- createDefaultTagNode(entity) {
- const span = document.createElement("span");
- span.style.color = LINK_COLOR;
- span.style.fontWeight = this.props.weight === "bold" ? "700" : "400";
- span.textContent = entity.text;
- return span;
- }
- createDefaultLinkNode(entity) {
- const anchor = document.createElement("a");
- anchor.href = entity.url;
- anchor.target = "_blank";
- anchor.referrerPolicy = "no-referrer";
- anchor.style.color = LINK_COLOR;
- anchor.style.fontWeight = this.props.weight === "bold" ? "700" : "400";
- anchor.textContent = entity.text;
- return anchor;
- }
- renderEntity(entity, index) {
- if (entity.type === "mention") {
- const customNode2 = this.props.renderMention?.(entity, index);
- return toNode(customNode2) ?? this.createDefaultMentionNode(entity);
- }
- if (entity.type === "tag") {
- const customNode2 = this.props.renderTag?.(entity, index);
- return toNode(customNode2) ?? this.createDefaultTagNode(entity);
- }
- const customNode = this.props.renderLink?.(entity, index);
- return toNode(customNode) ?? this.createDefaultLinkNode(entity);
- }
- buildTextNodes(text, entities, upto = null) {
- let lastIndex = 0;
- const nodes = [];
- for (const [index, entity] of entities.entries()) {
- if (upto !== null && entity.start >= upto) {
- break;
- }
- const textEnd = upto !== null ? Math.min(entity.start, upto) : entity.start;
- if (entity.start > lastIndex && lastIndex < textEnd) {
- nodes.push(document.createTextNode(text.slice(lastIndex, textEnd)));
- }
- if (upto === null || entity.end <= upto) {
- const entityNode = this.renderEntity(entity, index);
- if (entityNode) {
- nodes.push(entityNode);
- }
- }
- lastIndex = entity.end;
- }
- if (upto === null) {
- if (lastIndex < text.length) {
- nodes.push(document.createTextNode(text.slice(lastIndex)));
- }
- } else if (lastIndex < upto) {
- nodes.push(document.createTextNode(text.slice(lastIndex, upto)));
- }
- return nodes;
- }
- applyBaseParagraphStyle(element) {
- element.style.whiteSpace = "pre-wrap";
- element.style.fontWeight = this.props.weight === "bold" ? "700" : "400";
- element.style.setProperty("-webkit-touch-callout", "default");
- element.style.setProperty("-webkit-user-select", "text");
- element.style.setProperty("-khtml-user-select", "text");
- element.style.setProperty("-moz-user-select", "text");
- element.style.setProperty("-ms-user-select", "text");
- element.style.setProperty("user-select", "text");
- if (this.props.blur) {
- element.style.filter = "blur(3px)";
- element.style.setProperty("-webkit-user-select", "none");
- element.style.setProperty("-khtml-user-select", "none");
- element.style.setProperty("-moz-user-select", "none");
- element.style.setProperty("-ms-user-select", "none");
- element.style.setProperty("user-select", "none");
- element.style.pointerEvents = "none";
- }
- applyStyleObject(element, this.props.style);
- }
- buildReadMoreButton(symbol) {
- const button = document.createElement("button");
- button.type = "button";
- button.textContent = resolveEllipsisSymbol(symbol, this.expanded);
- button.style.border = "0";
- button.style.background = "none";
- button.style.padding = "0";
- button.style.marginLeft = "6px";
- button.style.cursor = "pointer";
- button.style.color = LINK_COLOR;
- button.style.fontWeight = "700";
- button.onclick = (event) => {
- event.preventDefault();
- event.stopPropagation();
- this.handleExpand();
- };
- return button;
- }
- handleExpand() {
- const ellipsisConfig = this.resolveEllipsisConfig();
- if (!ellipsisConfig) {
- return;
- }
- this.expanded = true;
- ellipsisConfig.onExpand?.(true);
- this.render();
- }
- computeEntitySafeCutoff(count, entities) {
- let cutoff = count;
- let extended = true;
- while (extended) {
- extended = false;
- for (const entity of entities) {
- if (entity.start < cutoff && entity.end > cutoff) {
- cutoff = entity.end;
- extended = true;
- }
- }
- }
- return cutoff;
- }
- hasVerticalOverflow(element) {
- return element.scrollHeight - element.clientHeight > 1;
- }
- render() {
- if (!this.host) {
- return;
- }
- const text = this.getText();
- const entities = findAllEntities(text);
- const ellipsisConfig = this.resolveEllipsisConfig();
- const mergedExpanded = this.getMergedExpanded(ellipsisConfig, text);
- const wrapper = document.createElement("div");
- const paragraph = document.createElement("div");
- if (this.props.className) {
- paragraph.className = this.props.className;
- }
- this.applyBaseParagraphStyle(paragraph);
- if (ellipsisConfig && "count" in ellipsisConfig) {
- const count = ellipsisConfig.count ?? 0;
- const shouldTruncate = !mergedExpanded && count > 0 && text.length > count;
- if (shouldTruncate) {
- const cutoff = this.computeEntitySafeCutoff(count, entities);
- const nodes = this.buildTextNodes(text, entities, cutoff);
- paragraph.append(...nodes);
- paragraph.append(document.createTextNode("\u2026"));
- if (ellipsisConfig.expandable) {
- paragraph.append(this.buildReadMoreButton(ellipsisConfig.symbol));
- }
- } else {
- paragraph.append(...this.buildTextNodes(text, entities));
- }
- } else {
- paragraph.append(...this.buildTextNodes(text, entities));
- if (ellipsisConfig && "rows" in ellipsisConfig && !mergedExpanded) {
- paragraph.style.display = "-webkit-box";
- paragraph.style.setProperty("-webkit-box-orient", "vertical");
- paragraph.style.setProperty("-webkit-line-clamp", String(ellipsisConfig.rows));
- paragraph.style.overflow = "hidden";
- wrapper.append(paragraph);
- this.host.replaceChildren(wrapper);
- if (ellipsisConfig.expandable && this.hasVerticalOverflow(paragraph)) {
- wrapper.append(this.buildReadMoreButton(ellipsisConfig.symbol));
- }
- this.emitOnViewIfNeeded(mergedExpanded);
- return;
- }
- }
- wrapper.append(paragraph);
- this.host.replaceChildren(wrapper);
- this.emitOnViewIfNeeded(mergedExpanded);
- }
- initObserver() {
- if (!this.host) {
- return;
- }
- if (typeof IntersectionObserver === "undefined") {
- this.hostInsideView = true;
- return;
- }
- this.observer = new IntersectionObserver(
- (entries) => {
- const entry = entries[0];
- if (!entry) {
- return;
- }
- if (entry.isIntersecting && !this.hostInsideView) {
- this.hostInsideView = true;
- const ellipsisConfig = this.resolveEllipsisConfig();
- const mergedExpanded = this.getMergedExpanded(ellipsisConfig, this.getText());
- this.emitOnViewIfNeeded(mergedExpanded);
- }
- },
- { threshold: 0.5 }
- );
- this.observer.observe(this.host);
- }
- emitOnViewIfNeeded(mergedExpanded) {
- if (!mergedExpanded || this.viewed || !this.hostInsideView) {
- return;
- }
- this.viewed = true;
- this.props.onView?.();
- }
-};
-var AngularContentTextWithSuggestionsRenderer = class extends AngularContentTextRenderer {
-};
-var AngularContentTitleWithSuggestionsRenderer = class {
- renderer = new AngularContentTextWithSuggestionsRenderer();
- attach(host, props = {}) {
- return this.renderer.attach(host, this.normalizeProps(props));
- }
- update(props) {
- return this.renderer.update(this.normalizeProps(props));
- }
- destroy() {
- this.renderer.destroy();
- }
- getState() {
- return this.renderer.getState();
- }
- normalizeProps(props) {
- return {
- ...props,
- weight: "bold",
- blur: props.blur ?? false,
- ellipsis: props.ellipsis === void 0 ? { rows: 2 } : props.ellipsis
- };
- }
-};
-
-exports.AngularContentSuggestionsAdapter = AngularContentSuggestionsAdapter;
-exports.AngularContentTextRenderer = AngularContentTextRenderer;
-exports.AngularContentTextWithSuggestionsRenderer = AngularContentTextWithSuggestionsRenderer;
-exports.AngularContentTitleWithSuggestionsRenderer = AngularContentTitleWithSuggestionsRenderer;
-exports.buildAngularTagHref = buildAngularTagHref;
-exports.createAngularContentTokens = createAngularContentTokens;
-exports.toKebabCase = toKebabCase;
-//# sourceMappingURL=index.cjs.map
-//# sourceMappingURL=index.cjs.map
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/index.cjs.map b/packages/content-suggestions/dist/angular/index.cjs.map
deleted file mode 100644
index 0a872f8..0000000
--- a/packages/content-suggestions/dist/angular/index.cjs.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["../../src/core/parser.ts","../../src/angular/index.ts"],"names":["customNode"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {\n ContentEntity,\n LinkEntity,\n MentionEntity,\n ParsedMention,\n ProcessedContent,\n TagEntity,\n} from \"./types\";\n\nexport const mentionLinkRegexp =\n /@\\[[^\\]]+]\\([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\\)/g;\n\nexport const parseMention = (mention: string): ParsedMention | null => {\n const regex = /@\\[([^\\]]+)\\]\\(([\\w-]{36})\\)/;\n const match = mention.match(regex);\n\n if (!match) {\n return null;\n }\n\n const mentionText = match[1];\n const mentionId = match[2];\n if (!mentionText || !mentionId) {\n return null;\n }\n\n return {\n mention: `@${mentionText}`,\n id: mentionId,\n };\n};\n\nexport const findMentions = (text: string): MentionEntity[] => {\n let match: RegExpExecArray | null;\n const matches: MentionEntity[] = [];\n\n while ((match = mentionLinkRegexp.exec(text)) !== null) {\n const parsed = parseMention(match[0]);\n const baseMention: Omit = {\n start: match.index,\n end: mentionLinkRegexp.lastIndex,\n text: match[0],\n type: \"mention\",\n displayText: parsed?.mention ?? match[0],\n };\n\n matches.push(parsed?.id ? { ...baseMention, userId: parsed.id } : baseMention);\n }\n\n return matches;\n};\n\nexport const findTags = (content: string): TagEntity[] => {\n const regex = /#[^\\s]{1,201}/g;\n const results: TagEntity[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(content)) !== null) {\n const value = match[0];\n results.push({\n start: match.index,\n end: match.index + value.length,\n text: value,\n type: \"tag\",\n tag: value.replace(\"#\", \"\"),\n });\n }\n\n return results;\n};\n\nexport const findLinks = (content: string): LinkEntity[] => {\n const regex =\n /\\b((https?:\\/\\/)?(?:[\\w-]+\\.)+[a-z]{2,}(\\/[\\w\\-._~:/?#[\\]@!$&'()*+,;=]*)?)/gi;\n const results: LinkEntity[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(content)) !== null) {\n const rawUrl = match[0];\n const hasProtocol = /^https?:\\/\\//i.test(rawUrl);\n const fullUrl = hasProtocol ? rawUrl : `https://${rawUrl}`;\n\n results.push({\n start: match.index,\n end: match.index + rawUrl.length,\n text: rawUrl,\n url: fullUrl,\n type: \"link\",\n });\n }\n\n return results;\n};\n\nexport const findAllEntities = (content: string): ContentEntity[] => {\n const mentions = findMentions(content);\n const tags = findTags(content);\n const links = findLinks(content);\n\n return [...mentions, ...tags, ...links].sort((a, b) => a.start - b.start);\n};\n\nexport const processContent = (content: string): ProcessedContent => {\n const processedText = content.replace(mentionLinkRegexp, match => {\n const parsed = parseMention(match);\n return parsed ? parsed.mention : match;\n });\n\n const tags = findTags(content).map(tag => tag.tag);\n\n return {\n processedText,\n tags,\n };\n};\n","import type { ContentEntity, LinkEntity, MentionEntity, TagEntity } from \"../core\";\n\nimport { findAllEntities } from \"../core\";\n\nexport interface AngularTextToken {\n kind: \"text\";\n text: string;\n start: number;\n end: number;\n}\n\nexport interface AngularMentionToken {\n kind: \"mention\";\n entity: MentionEntity;\n}\n\nexport interface AngularTagToken {\n kind: \"tag\";\n entity: TagEntity;\n}\n\nexport interface AngularLinkToken {\n kind: \"link\";\n entity: LinkEntity;\n}\n\nexport type AngularContentToken =\n | AngularTextToken\n | AngularMentionToken\n | AngularTagToken\n | AngularLinkToken;\n\nexport interface AngularContentSnapshot {\n text: string;\n entities: ContentEntity[];\n tokens: AngularContentToken[];\n}\n\nexport type AngularEllipsisSymbol = string | ((expanded: boolean) => string);\n\nexport type AngularCountEllipsisConfig = {\n count: number;\n rows?: never;\n expandable?: boolean;\n expanded?: boolean;\n symbol?: AngularEllipsisSymbol;\n onExpand?: (expanded: boolean) => void;\n};\n\nexport type AngularRowsEllipsisConfig = {\n rows: number;\n count?: never;\n expandable?: boolean;\n expanded?: boolean;\n symbol?: AngularEllipsisSymbol;\n onExpand?: (expanded: boolean) => void;\n};\n\nexport type AngularContentEllipsisConfig =\n | AngularCountEllipsisConfig\n | AngularRowsEllipsisConfig\n | false;\n\nexport type AngularRenderResult = Node | string | number | null | undefined;\n\nexport type AngularMentionRenderer = (\n entity: MentionEntity,\n index: number,\n) => AngularRenderResult;\n\nexport type AngularTagRenderer = (\n entity: TagEntity,\n index: number,\n) => AngularRenderResult;\n\nexport type AngularLinkRenderer = (\n entity: LinkEntity,\n index: number,\n) => AngularRenderResult;\n\nexport interface AngularContentTextProps {\n className?: string;\n weight?: \"normal\" | \"bold\";\n text?: string | null;\n ellipsis?: AngularContentEllipsisConfig;\n blur?: boolean;\n style?: Record | null;\n onView?: () => void;\n renderMention?: AngularMentionRenderer;\n renderTag?: AngularTagRenderer;\n renderLink?: AngularLinkRenderer;\n}\n\nexport type AngularContentTextWithSuggestionsProps = Omit<\n AngularContentTextProps,\n \"renderMention\" | \"renderTag\"\n> & {\n renderMention?: AngularMentionRenderer;\n renderTag?: AngularTagRenderer;\n};\n\nexport type AngularContentTitleWithSuggestionsProps = Omit<\n AngularContentTextWithSuggestionsProps,\n \"weight\"\n>;\n\nexport interface AngularContentTextRendererState {\n props: AngularContentTextProps;\n snapshot: AngularContentSnapshot;\n expanded: boolean;\n}\n\nconst LINK_COLOR = \"#1677ff\";\nconst READ_MORE_TEXT = \"Читать полностью\";\n\nconst toKebabCase = (value: string) => value.replace(/[A-Z]/g, char => `-${char.toLowerCase()}`);\n\nconst applyStyleObject = (\n element: HTMLElement,\n styles?: Record | null,\n) => {\n if (!styles) {\n return;\n }\n\n for (const [key, rawValue] of Object.entries(styles)) {\n if (rawValue === null || rawValue === undefined) {\n continue;\n }\n\n const styleValue =\n typeof rawValue === \"number\" ? `${rawValue}px` : String(rawValue);\n\n if (key.startsWith(\"--\")) {\n element.style.setProperty(key, styleValue);\n continue;\n }\n\n const cssKey = key.includes(\"-\") ? key : toKebabCase(key);\n element.style.setProperty(cssKey, styleValue);\n }\n};\n\nconst toNode = (value: AngularRenderResult): Node | null => {\n if (value === null || value === undefined) {\n return null;\n }\n\n if (value instanceof Node) {\n return value;\n }\n\n return document.createTextNode(String(value));\n};\n\nconst resolveEllipsisSymbol = (\n symbol: AngularEllipsisSymbol | undefined,\n expanded: boolean,\n): string => {\n if (typeof symbol === \"function\") {\n return symbol(expanded);\n }\n\n return symbol ?? READ_MORE_TEXT;\n};\n\nconst buildAngularTagHref = (entity: TagEntity): string => {\n return `/search/?query=${encodeURIComponent(entity.tag.toLowerCase())}`;\n};\n\nexport { buildAngularTagHref };\n\nexport const createAngularContentTokens = (\n inputText: string | null | undefined,\n): AngularContentToken[] => {\n const text = inputText ?? \"\";\n const entities = findAllEntities(text);\n\n let cursor = 0;\n const tokens: AngularContentToken[] = [];\n\n for (const entity of entities) {\n if (entity.start > cursor) {\n tokens.push({\n kind: \"text\",\n text: text.slice(cursor, entity.start),\n start: cursor,\n end: entity.start,\n });\n }\n\n if (entity.type === \"mention\") {\n tokens.push({\n kind: \"mention\",\n entity,\n });\n } else if (entity.type === \"tag\") {\n tokens.push({\n kind: \"tag\",\n entity,\n });\n } else {\n tokens.push({\n kind: \"link\",\n entity,\n });\n }\n\n cursor = entity.end;\n }\n\n if (cursor < text.length) {\n tokens.push({\n kind: \"text\",\n text: text.slice(cursor),\n start: cursor,\n end: text.length,\n });\n }\n\n return tokens;\n};\n\nexport class AngularContentSuggestionsAdapter {\n snapshot(inputText: string | null | undefined): AngularContentSnapshot {\n const text = inputText ?? \"\";\n const entities = findAllEntities(text);\n const tokens = createAngularContentTokens(text);\n\n return {\n text,\n entities,\n tokens,\n };\n }\n}\n\nexport class AngularContentTextRenderer {\n private host: HTMLElement | null = null;\n private props: AngularContentTextProps = {};\n private expanded = false;\n private viewed = false;\n private hostInsideView = false;\n private observer: IntersectionObserver | null = null;\n\n attach(host: HTMLElement, props: AngularContentTextProps = {}): AngularContentTextRendererState {\n this.destroy();\n\n this.host = host;\n this.props = { ...props };\n this.expanded = false;\n this.viewed = false;\n this.hostInsideView = false;\n\n this.initObserver();\n this.render();\n\n return this.getState();\n }\n\n update(nextProps: AngularContentTextProps): AngularContentTextRendererState {\n this.props = {\n ...this.props,\n ...nextProps,\n };\n\n this.render();\n\n return this.getState();\n }\n\n destroy(): void {\n if (this.observer && this.host) {\n this.observer.unobserve(this.host);\n this.observer.disconnect();\n }\n\n this.observer = null;\n\n if (this.host) {\n this.host.innerHTML = \"\";\n }\n\n this.host = null;\n this.props = {};\n this.expanded = false;\n this.viewed = false;\n this.hostInsideView = false;\n }\n\n getState(): AngularContentTextRendererState {\n return {\n props: { ...this.props },\n snapshot: this.createSnapshot(),\n expanded: this.getMergedExpanded(this.resolveEllipsisConfig(), this.getText()),\n };\n }\n\n private getText(): string {\n return this.props.text ?? \"\";\n }\n\n private createSnapshot(): AngularContentSnapshot {\n const text = this.getText();\n const entities = findAllEntities(text);\n const tokens = createAngularContentTokens(text);\n\n return {\n text,\n entities,\n tokens,\n };\n }\n\n private resolveEllipsisConfig():\n | AngularCountEllipsisConfig\n | AngularRowsEllipsisConfig\n | null {\n const ellipsis = this.props.ellipsis;\n\n if (!ellipsis || typeof ellipsis !== \"object\") {\n return null;\n }\n\n return ellipsis;\n }\n\n private getMergedExpanded(\n ellipsisConfig: AngularCountEllipsisConfig | AngularRowsEllipsisConfig | null,\n text: string,\n ): boolean {\n const controlledExpanded =\n ellipsisConfig && typeof ellipsisConfig.expanded === \"boolean\"\n ? ellipsisConfig.expanded\n : undefined;\n\n if (controlledExpanded !== undefined) {\n return controlledExpanded;\n }\n\n if (ellipsisConfig && \"count\" in ellipsisConfig) {\n const count = ellipsisConfig.count ?? 0;\n if (count <= 0 || text.length <= count) {\n return true;\n }\n }\n\n return this.expanded;\n }\n\n private createDefaultMentionNode(entity: MentionEntity): Node {\n const span = document.createElement(\"span\");\n span.style.color = LINK_COLOR;\n span.style.fontWeight = this.props.weight === \"bold\" ? \"700\" : \"400\";\n span.textContent = entity.displayText;\n return span;\n }\n\n private createDefaultTagNode(entity: TagEntity): Node {\n const span = document.createElement(\"span\");\n span.style.color = LINK_COLOR;\n span.style.fontWeight = this.props.weight === \"bold\" ? \"700\" : \"400\";\n span.textContent = entity.text;\n return span;\n }\n\n private createDefaultLinkNode(entity: LinkEntity): Node {\n const anchor = document.createElement(\"a\");\n anchor.href = entity.url;\n anchor.target = \"_blank\";\n anchor.referrerPolicy = \"no-referrer\";\n anchor.style.color = LINK_COLOR;\n anchor.style.fontWeight = this.props.weight === \"bold\" ? \"700\" : \"400\";\n anchor.textContent = entity.text;\n return anchor;\n }\n\n private renderEntity(entity: ContentEntity, index: number): Node | null {\n if (entity.type === \"mention\") {\n const customNode = this.props.renderMention?.(entity, index);\n return toNode(customNode) ?? this.createDefaultMentionNode(entity);\n }\n\n if (entity.type === \"tag\") {\n const customNode = this.props.renderTag?.(entity, index);\n return toNode(customNode) ?? this.createDefaultTagNode(entity);\n }\n\n const customNode = this.props.renderLink?.(entity, index);\n return toNode(customNode) ?? this.createDefaultLinkNode(entity);\n }\n\n private buildTextNodes(\n text: string,\n entities: ContentEntity[],\n upto: number | null = null,\n ): Node[] {\n let lastIndex = 0;\n const nodes: Node[] = [];\n\n for (const [index, entity] of entities.entries()) {\n if (upto !== null && entity.start >= upto) {\n break;\n }\n\n const textEnd = upto !== null ? Math.min(entity.start, upto) : entity.start;\n if (entity.start > lastIndex && lastIndex < textEnd) {\n nodes.push(document.createTextNode(text.slice(lastIndex, textEnd)));\n }\n\n if (upto === null || entity.end <= upto) {\n const entityNode = this.renderEntity(entity, index);\n if (entityNode) {\n nodes.push(entityNode);\n }\n }\n\n lastIndex = entity.end;\n }\n\n if (upto === null) {\n if (lastIndex < text.length) {\n nodes.push(document.createTextNode(text.slice(lastIndex)));\n }\n } else if (lastIndex < upto) {\n nodes.push(document.createTextNode(text.slice(lastIndex, upto)));\n }\n\n return nodes;\n }\n\n private applyBaseParagraphStyle(element: HTMLElement): void {\n element.style.whiteSpace = \"pre-wrap\";\n element.style.fontWeight = this.props.weight === \"bold\" ? \"700\" : \"400\";\n element.style.setProperty(\"-webkit-touch-callout\", \"default\");\n element.style.setProperty(\"-webkit-user-select\", \"text\");\n element.style.setProperty(\"-khtml-user-select\", \"text\");\n element.style.setProperty(\"-moz-user-select\", \"text\");\n element.style.setProperty(\"-ms-user-select\", \"text\");\n element.style.setProperty(\"user-select\", \"text\");\n\n if (this.props.blur) {\n element.style.filter = \"blur(3px)\";\n element.style.setProperty(\"-webkit-user-select\", \"none\");\n element.style.setProperty(\"-khtml-user-select\", \"none\");\n element.style.setProperty(\"-moz-user-select\", \"none\");\n element.style.setProperty(\"-ms-user-select\", \"none\");\n element.style.setProperty(\"user-select\", \"none\");\n element.style.pointerEvents = \"none\";\n }\n\n applyStyleObject(element, this.props.style);\n }\n\n private buildReadMoreButton(symbol: AngularEllipsisSymbol | undefined): HTMLButtonElement {\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.textContent = resolveEllipsisSymbol(symbol, this.expanded);\n button.style.border = \"0\";\n button.style.background = \"none\";\n button.style.padding = \"0\";\n button.style.marginLeft = \"6px\";\n button.style.cursor = \"pointer\";\n button.style.color = LINK_COLOR;\n button.style.fontWeight = \"700\";\n button.onclick = event => {\n event.preventDefault();\n event.stopPropagation();\n this.handleExpand();\n };\n return button;\n }\n\n private handleExpand(): void {\n const ellipsisConfig = this.resolveEllipsisConfig();\n\n if (!ellipsisConfig) {\n return;\n }\n\n this.expanded = true;\n ellipsisConfig.onExpand?.(true);\n this.render();\n }\n\n private computeEntitySafeCutoff(\n count: number,\n entities: ContentEntity[],\n ): number {\n let cutoff = count;\n let extended = true;\n\n while (extended) {\n extended = false;\n\n for (const entity of entities) {\n if (entity.start < cutoff && entity.end > cutoff) {\n cutoff = entity.end;\n extended = true;\n }\n }\n }\n\n return cutoff;\n }\n\n private hasVerticalOverflow(element: HTMLElement): boolean {\n return element.scrollHeight - element.clientHeight > 1;\n }\n\n private render(): void {\n if (!this.host) {\n return;\n }\n\n const text = this.getText();\n const entities = findAllEntities(text);\n const ellipsisConfig = this.resolveEllipsisConfig();\n const mergedExpanded = this.getMergedExpanded(ellipsisConfig, text);\n\n const wrapper = document.createElement(\"div\");\n const paragraph = document.createElement(\"div\");\n\n if (this.props.className) {\n paragraph.className = this.props.className;\n }\n\n this.applyBaseParagraphStyle(paragraph);\n\n if (ellipsisConfig && \"count\" in ellipsisConfig) {\n const count = ellipsisConfig.count ?? 0;\n const shouldTruncate = !mergedExpanded && count > 0 && text.length > count;\n\n if (shouldTruncate) {\n const cutoff = this.computeEntitySafeCutoff(count, entities);\n const nodes = this.buildTextNodes(text, entities, cutoff);\n\n paragraph.append(...nodes);\n paragraph.append(document.createTextNode(\"…\"));\n\n if (ellipsisConfig.expandable) {\n paragraph.append(this.buildReadMoreButton(ellipsisConfig.symbol));\n }\n } else {\n paragraph.append(...this.buildTextNodes(text, entities));\n }\n } else {\n paragraph.append(...this.buildTextNodes(text, entities));\n\n if (ellipsisConfig && \"rows\" in ellipsisConfig && !mergedExpanded) {\n paragraph.style.display = \"-webkit-box\";\n paragraph.style.setProperty(\"-webkit-box-orient\", \"vertical\");\n paragraph.style.setProperty(\"-webkit-line-clamp\", String(ellipsisConfig.rows));\n paragraph.style.overflow = \"hidden\";\n\n // Важно: сначала рендерим paragraph в DOM, потом меряем реальный overflow.\n wrapper.append(paragraph);\n this.host.replaceChildren(wrapper);\n\n if (ellipsisConfig.expandable && this.hasVerticalOverflow(paragraph)) {\n wrapper.append(this.buildReadMoreButton(ellipsisConfig.symbol));\n }\n\n this.emitOnViewIfNeeded(mergedExpanded);\n return;\n }\n }\n\n wrapper.append(paragraph);\n this.host.replaceChildren(wrapper);\n this.emitOnViewIfNeeded(mergedExpanded);\n }\n\n private initObserver(): void {\n if (!this.host) {\n return;\n }\n\n if (typeof IntersectionObserver === \"undefined\") {\n this.hostInsideView = true;\n return;\n }\n\n this.observer = new IntersectionObserver(\n entries => {\n const entry = entries[0];\n if (!entry) {\n return;\n }\n\n if (entry.isIntersecting && !this.hostInsideView) {\n this.hostInsideView = true;\n const ellipsisConfig = this.resolveEllipsisConfig();\n const mergedExpanded = this.getMergedExpanded(ellipsisConfig, this.getText());\n this.emitOnViewIfNeeded(mergedExpanded);\n }\n },\n { threshold: 0.5 },\n );\n\n this.observer.observe(this.host);\n }\n\n private emitOnViewIfNeeded(mergedExpanded: boolean): void {\n if (!mergedExpanded || this.viewed || !this.hostInsideView) {\n return;\n }\n\n this.viewed = true;\n this.props.onView?.();\n }\n}\n\nexport class AngularContentTextWithSuggestionsRenderer extends AngularContentTextRenderer {}\n\nexport class AngularContentTitleWithSuggestionsRenderer {\n private readonly renderer = new AngularContentTextWithSuggestionsRenderer();\n\n attach(\n host: HTMLElement,\n props: AngularContentTitleWithSuggestionsProps = {},\n ): AngularContentTextRendererState {\n return this.renderer.attach(host, this.normalizeProps(props));\n }\n\n update(props: AngularContentTitleWithSuggestionsProps): AngularContentTextRendererState {\n return this.renderer.update(this.normalizeProps(props));\n }\n\n destroy(): void {\n this.renderer.destroy();\n }\n\n getState(): AngularContentTextRendererState {\n return this.renderer.getState();\n }\n\n private normalizeProps(\n props: AngularContentTitleWithSuggestionsProps,\n ): AngularContentTextWithSuggestionsProps {\n return {\n ...props,\n weight: \"bold\",\n blur: props.blur ?? false,\n ellipsis: props.ellipsis === undefined ? { rows: 2 } : props.ellipsis,\n };\n }\n}\n\nexport { toKebabCase };\n"]}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/angular/index.d.cts b/packages/content-suggestions/dist/angular/index.d.cts
deleted file mode 100644
index d256439..0000000
--- a/packages/content-suggestions/dist/angular/index.d.cts
+++ /dev/null
@@ -1,118 +0,0 @@
-import { C as ContentEntity, M as MentionEntity, T as TagEntity, L as LinkEntity } from '../types-BRt4hd7A.cjs';
-
-interface AngularTextToken {
- kind: "text";
- text: string;
- start: number;
- end: number;
-}
-interface AngularMentionToken {
- kind: "mention";
- entity: MentionEntity;
-}
-interface AngularTagToken {
- kind: "tag";
- entity: TagEntity;
-}
-interface AngularLinkToken {
- kind: "link";
- entity: LinkEntity;
-}
-type AngularContentToken = AngularTextToken | AngularMentionToken | AngularTagToken | AngularLinkToken;
-interface AngularContentSnapshot {
- text: string;
- entities: ContentEntity[];
- tokens: AngularContentToken[];
-}
-type AngularEllipsisSymbol = string | ((expanded: boolean) => string);
-type AngularCountEllipsisConfig = {
- count: number;
- rows?: never;
- expandable?: boolean;
- expanded?: boolean;
- symbol?: AngularEllipsisSymbol;
- onExpand?: (expanded: boolean) => void;
-};
-type AngularRowsEllipsisConfig = {
- rows: number;
- count?: never;
- expandable?: boolean;
- expanded?: boolean;
- symbol?: AngularEllipsisSymbol;
- onExpand?: (expanded: boolean) => void;
-};
-type AngularContentEllipsisConfig = AngularCountEllipsisConfig | AngularRowsEllipsisConfig | false;
-type AngularRenderResult = Node | string | number | null | undefined;
-type AngularMentionRenderer = (entity: MentionEntity, index: number) => AngularRenderResult;
-type AngularTagRenderer = (entity: TagEntity, index: number) => AngularRenderResult;
-type AngularLinkRenderer = (entity: LinkEntity, index: number) => AngularRenderResult;
-interface AngularContentTextProps {
- className?: string;
- weight?: "normal" | "bold";
- text?: string | null;
- ellipsis?: AngularContentEllipsisConfig;
- blur?: boolean;
- style?: Record | null;
- onView?: () => void;
- renderMention?: AngularMentionRenderer;
- renderTag?: AngularTagRenderer;
- renderLink?: AngularLinkRenderer;
-}
-type AngularContentTextWithSuggestionsProps = Omit & {
- renderMention?: AngularMentionRenderer;
- renderTag?: AngularTagRenderer;
-};
-type AngularContentTitleWithSuggestionsProps = Omit;
-interface AngularContentTextRendererState {
- props: AngularContentTextProps;
- snapshot: AngularContentSnapshot;
- expanded: boolean;
-}
-declare const toKebabCase: (value: string) => string;
-declare const buildAngularTagHref: (entity: TagEntity) => string;
-
-declare const createAngularContentTokens: (inputText: string | null | undefined) => AngularContentToken[];
-declare class AngularContentSuggestionsAdapter {
- snapshot(inputText: string | null | undefined): AngularContentSnapshot;
-}
-declare class AngularContentTextRenderer {
- private host;
- private props;
- private expanded;
- private viewed;
- private hostInsideView;
- private observer;
- attach(host: HTMLElement, props?: AngularContentTextProps): AngularContentTextRendererState;
- update(nextProps: AngularContentTextProps): AngularContentTextRendererState;
- destroy(): void;
- getState(): AngularContentTextRendererState;
- private getText;
- private createSnapshot;
- private resolveEllipsisConfig;
- private getMergedExpanded;
- private createDefaultMentionNode;
- private createDefaultTagNode;
- private createDefaultLinkNode;
- private renderEntity;
- private buildTextNodes;
- private applyBaseParagraphStyle;
- private buildReadMoreButton;
- private handleExpand;
- private computeEntitySafeCutoff;
- private hasVerticalOverflow;
- private render;
- private initObserver;
- private emitOnViewIfNeeded;
-}
-declare class AngularContentTextWithSuggestionsRenderer extends AngularContentTextRenderer {
-}
-declare class AngularContentTitleWithSuggestionsRenderer {
- private readonly renderer;
- attach(host: HTMLElement, props?: AngularContentTitleWithSuggestionsProps): AngularContentTextRendererState;
- update(props: AngularContentTitleWithSuggestionsProps): AngularContentTextRendererState;
- destroy(): void;
- getState(): AngularContentTextRendererState;
- private normalizeProps;
-}
-
-export { type AngularContentEllipsisConfig, type AngularContentSnapshot, AngularContentSuggestionsAdapter, type AngularContentTextProps, AngularContentTextRenderer, type AngularContentTextRendererState, type AngularContentTextWithSuggestionsProps, AngularContentTextWithSuggestionsRenderer, type AngularContentTitleWithSuggestionsProps, AngularContentTitleWithSuggestionsRenderer, type AngularContentToken, type AngularCountEllipsisConfig, type AngularEllipsisSymbol, type AngularLinkRenderer, type AngularLinkToken, type AngularMentionRenderer, type AngularMentionToken, type AngularRenderResult, type AngularRowsEllipsisConfig, type AngularTagRenderer, type AngularTagToken, type AngularTextToken, buildAngularTagHref, createAngularContentTokens, toKebabCase };
diff --git a/packages/content-suggestions/dist/angular/index.d.ts b/packages/content-suggestions/dist/angular/index.d.ts
index bf0a663..3672fe9 100644
--- a/packages/content-suggestions/dist/angular/index.d.ts
+++ b/packages/content-suggestions/dist/angular/index.d.ts
@@ -1,118 +1 @@
-import { C as ContentEntity, M as MentionEntity, T as TagEntity, L as LinkEntity } from '../types-BRt4hd7A.js';
-
-interface AngularTextToken {
- kind: "text";
- text: string;
- start: number;
- end: number;
-}
-interface AngularMentionToken {
- kind: "mention";
- entity: MentionEntity;
-}
-interface AngularTagToken {
- kind: "tag";
- entity: TagEntity;
-}
-interface AngularLinkToken {
- kind: "link";
- entity: LinkEntity;
-}
-type AngularContentToken = AngularTextToken | AngularMentionToken | AngularTagToken | AngularLinkToken;
-interface AngularContentSnapshot {
- text: string;
- entities: ContentEntity[];
- tokens: AngularContentToken[];
-}
-type AngularEllipsisSymbol = string | ((expanded: boolean) => string);
-type AngularCountEllipsisConfig = {
- count: number;
- rows?: never;
- expandable?: boolean;
- expanded?: boolean;
- symbol?: AngularEllipsisSymbol;
- onExpand?: (expanded: boolean) => void;
-};
-type AngularRowsEllipsisConfig = {
- rows: number;
- count?: never;
- expandable?: boolean;
- expanded?: boolean;
- symbol?: AngularEllipsisSymbol;
- onExpand?: (expanded: boolean) => void;
-};
-type AngularContentEllipsisConfig = AngularCountEllipsisConfig | AngularRowsEllipsisConfig | false;
-type AngularRenderResult = Node | string | number | null | undefined;
-type AngularMentionRenderer = (entity: MentionEntity, index: number) => AngularRenderResult;
-type AngularTagRenderer = (entity: TagEntity, index: number) => AngularRenderResult;
-type AngularLinkRenderer = (entity: LinkEntity, index: number) => AngularRenderResult;
-interface AngularContentTextProps {
- className?: string;
- weight?: "normal" | "bold";
- text?: string | null;
- ellipsis?: AngularContentEllipsisConfig;
- blur?: boolean;
- style?: Record | null;
- onView?: () => void;
- renderMention?: AngularMentionRenderer;
- renderTag?: AngularTagRenderer;
- renderLink?: AngularLinkRenderer;
-}
-type AngularContentTextWithSuggestionsProps = Omit & {
- renderMention?: AngularMentionRenderer;
- renderTag?: AngularTagRenderer;
-};
-type AngularContentTitleWithSuggestionsProps = Omit;
-interface AngularContentTextRendererState {
- props: AngularContentTextProps;
- snapshot: AngularContentSnapshot;
- expanded: boolean;
-}
-declare const toKebabCase: (value: string) => string;
-declare const buildAngularTagHref: (entity: TagEntity) => string;
-
-declare const createAngularContentTokens: (inputText: string | null | undefined) => AngularContentToken[];
-declare class AngularContentSuggestionsAdapter {
- snapshot(inputText: string | null | undefined): AngularContentSnapshot;
-}
-declare class AngularContentTextRenderer {
- private host;
- private props;
- private expanded;
- private viewed;
- private hostInsideView;
- private observer;
- attach(host: HTMLElement, props?: AngularContentTextProps): AngularContentTextRendererState;
- update(nextProps: AngularContentTextProps): AngularContentTextRendererState;
- destroy(): void;
- getState(): AngularContentTextRendererState;
- private getText;
- private createSnapshot;
- private resolveEllipsisConfig;
- private getMergedExpanded;
- private createDefaultMentionNode;
- private createDefaultTagNode;
- private createDefaultLinkNode;
- private renderEntity;
- private buildTextNodes;
- private applyBaseParagraphStyle;
- private buildReadMoreButton;
- private handleExpand;
- private computeEntitySafeCutoff;
- private hasVerticalOverflow;
- private render;
- private initObserver;
- private emitOnViewIfNeeded;
-}
-declare class AngularContentTextWithSuggestionsRenderer extends AngularContentTextRenderer {
-}
-declare class AngularContentTitleWithSuggestionsRenderer {
- private readonly renderer;
- attach(host: HTMLElement, props?: AngularContentTitleWithSuggestionsProps): AngularContentTextRendererState;
- update(props: AngularContentTitleWithSuggestionsProps): AngularContentTextRendererState;
- destroy(): void;
- getState(): AngularContentTextRendererState;
- private normalizeProps;
-}
-
-export { type AngularContentEllipsisConfig, type AngularContentSnapshot, AngularContentSuggestionsAdapter, type AngularContentTextProps, AngularContentTextRenderer, type AngularContentTextRendererState, type AngularContentTextWithSuggestionsProps, AngularContentTextWithSuggestionsRenderer, type AngularContentTitleWithSuggestionsProps, AngularContentTitleWithSuggestionsRenderer, type AngularContentToken, type AngularCountEllipsisConfig, type AngularEllipsisSymbol, type AngularLinkRenderer, type AngularLinkToken, type AngularMentionRenderer, type AngularMentionToken, type AngularRenderResult, type AngularRowsEllipsisConfig, type AngularTagRenderer, type AngularTagToken, type AngularTextToken, buildAngularTagHref, createAngularContentTokens, toKebabCase };
+export * from "./angular/index";
diff --git a/packages/content-suggestions/dist/angular/index.js b/packages/content-suggestions/dist/angular/index.js
index ae30005..2094752 100644
--- a/packages/content-suggestions/dist/angular/index.js
+++ b/packages/content-suggestions/dist/angular/index.js
@@ -1,487 +1 @@
-// src/core/parser.ts
-var mentionLinkRegexp = /@\[[^\]]+]\([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\)/g;
-var parseMention = (mention) => {
- const regex = /@\[([^\]]+)\]\(([\w-]{36})\)/;
- const match = mention.match(regex);
- if (!match) {
- return null;
- }
- const mentionText = match[1];
- const mentionId = match[2];
- if (!mentionText || !mentionId) {
- return null;
- }
- return {
- mention: `@${mentionText}`,
- id: mentionId
- };
-};
-var findMentions = (text) => {
- let match;
- const matches = [];
- while ((match = mentionLinkRegexp.exec(text)) !== null) {
- const parsed = parseMention(match[0]);
- const baseMention = {
- start: match.index,
- end: mentionLinkRegexp.lastIndex,
- text: match[0],
- type: "mention",
- displayText: parsed?.mention ?? match[0]
- };
- matches.push(parsed?.id ? { ...baseMention, userId: parsed.id } : baseMention);
- }
- return matches;
-};
-var findTags = (content) => {
- const regex = /#[^\s]{1,201}/g;
- const results = [];
- let match;
- while ((match = regex.exec(content)) !== null) {
- const value = match[0];
- results.push({
- start: match.index,
- end: match.index + value.length,
- text: value,
- type: "tag",
- tag: value.replace("#", "")
- });
- }
- return results;
-};
-var findLinks = (content) => {
- const regex = /\b((https?:\/\/)?(?:[\w-]+\.)+[a-z]{2,}(\/[\w\-._~:/?#[\]@!$&'()*+,;=]*)?)/gi;
- const results = [];
- let match;
- while ((match = regex.exec(content)) !== null) {
- const rawUrl = match[0];
- const hasProtocol = /^https?:\/\//i.test(rawUrl);
- const fullUrl = hasProtocol ? rawUrl : `https://${rawUrl}`;
- results.push({
- start: match.index,
- end: match.index + rawUrl.length,
- text: rawUrl,
- url: fullUrl,
- type: "link"
- });
- }
- return results;
-};
-var findAllEntities = (content) => {
- const mentions = findMentions(content);
- const tags = findTags(content);
- const links = findLinks(content);
- return [...mentions, ...tags, ...links].sort((a, b) => a.start - b.start);
-};
-
-// src/angular/index.ts
-var LINK_COLOR = "#1677ff";
-var READ_MORE_TEXT = "\u0427\u0438\u0442\u0430\u0442\u044C \u043F\u043E\u043B\u043D\u043E\u0441\u0442\u044C\u044E";
-var toKebabCase = (value) => value.replace(/[A-Z]/g, (char) => `-${char.toLowerCase()}`);
-var applyStyleObject = (element, styles) => {
- if (!styles) {
- return;
- }
- for (const [key, rawValue] of Object.entries(styles)) {
- if (rawValue === null || rawValue === void 0) {
- continue;
- }
- const styleValue = typeof rawValue === "number" ? `${rawValue}px` : String(rawValue);
- if (key.startsWith("--")) {
- element.style.setProperty(key, styleValue);
- continue;
- }
- const cssKey = key.includes("-") ? key : toKebabCase(key);
- element.style.setProperty(cssKey, styleValue);
- }
-};
-var toNode = (value) => {
- if (value === null || value === void 0) {
- return null;
- }
- if (value instanceof Node) {
- return value;
- }
- return document.createTextNode(String(value));
-};
-var resolveEllipsisSymbol = (symbol, expanded) => {
- if (typeof symbol === "function") {
- return symbol(expanded);
- }
- return symbol ?? READ_MORE_TEXT;
-};
-var buildAngularTagHref = (entity) => {
- return `/search/?query=${encodeURIComponent(entity.tag.toLowerCase())}`;
-};
-var createAngularContentTokens = (inputText) => {
- const text = inputText ?? "";
- const entities = findAllEntities(text);
- let cursor = 0;
- const tokens = [];
- for (const entity of entities) {
- if (entity.start > cursor) {
- tokens.push({
- kind: "text",
- text: text.slice(cursor, entity.start),
- start: cursor,
- end: entity.start
- });
- }
- if (entity.type === "mention") {
- tokens.push({
- kind: "mention",
- entity
- });
- } else if (entity.type === "tag") {
- tokens.push({
- kind: "tag",
- entity
- });
- } else {
- tokens.push({
- kind: "link",
- entity
- });
- }
- cursor = entity.end;
- }
- if (cursor < text.length) {
- tokens.push({
- kind: "text",
- text: text.slice(cursor),
- start: cursor,
- end: text.length
- });
- }
- return tokens;
-};
-var AngularContentSuggestionsAdapter = class {
- snapshot(inputText) {
- const text = inputText ?? "";
- const entities = findAllEntities(text);
- const tokens = createAngularContentTokens(text);
- return {
- text,
- entities,
- tokens
- };
- }
-};
-var AngularContentTextRenderer = class {
- host = null;
- props = {};
- expanded = false;
- viewed = false;
- hostInsideView = false;
- observer = null;
- attach(host, props = {}) {
- this.destroy();
- this.host = host;
- this.props = { ...props };
- this.expanded = false;
- this.viewed = false;
- this.hostInsideView = false;
- this.initObserver();
- this.render();
- return this.getState();
- }
- update(nextProps) {
- this.props = {
- ...this.props,
- ...nextProps
- };
- this.render();
- return this.getState();
- }
- destroy() {
- if (this.observer && this.host) {
- this.observer.unobserve(this.host);
- this.observer.disconnect();
- }
- this.observer = null;
- if (this.host) {
- this.host.innerHTML = "";
- }
- this.host = null;
- this.props = {};
- this.expanded = false;
- this.viewed = false;
- this.hostInsideView = false;
- }
- getState() {
- return {
- props: { ...this.props },
- snapshot: this.createSnapshot(),
- expanded: this.getMergedExpanded(this.resolveEllipsisConfig(), this.getText())
- };
- }
- getText() {
- return this.props.text ?? "";
- }
- createSnapshot() {
- const text = this.getText();
- const entities = findAllEntities(text);
- const tokens = createAngularContentTokens(text);
- return {
- text,
- entities,
- tokens
- };
- }
- resolveEllipsisConfig() {
- const ellipsis = this.props.ellipsis;
- if (!ellipsis || typeof ellipsis !== "object") {
- return null;
- }
- return ellipsis;
- }
- getMergedExpanded(ellipsisConfig, text) {
- const controlledExpanded = ellipsisConfig && typeof ellipsisConfig.expanded === "boolean" ? ellipsisConfig.expanded : void 0;
- if (controlledExpanded !== void 0) {
- return controlledExpanded;
- }
- if (ellipsisConfig && "count" in ellipsisConfig) {
- const count = ellipsisConfig.count ?? 0;
- if (count <= 0 || text.length <= count) {
- return true;
- }
- }
- return this.expanded;
- }
- createDefaultMentionNode(entity) {
- const span = document.createElement("span");
- span.style.color = LINK_COLOR;
- span.style.fontWeight = this.props.weight === "bold" ? "700" : "400";
- span.textContent = entity.displayText;
- return span;
- }
- createDefaultTagNode(entity) {
- const span = document.createElement("span");
- span.style.color = LINK_COLOR;
- span.style.fontWeight = this.props.weight === "bold" ? "700" : "400";
- span.textContent = entity.text;
- return span;
- }
- createDefaultLinkNode(entity) {
- const anchor = document.createElement("a");
- anchor.href = entity.url;
- anchor.target = "_blank";
- anchor.referrerPolicy = "no-referrer";
- anchor.style.color = LINK_COLOR;
- anchor.style.fontWeight = this.props.weight === "bold" ? "700" : "400";
- anchor.textContent = entity.text;
- return anchor;
- }
- renderEntity(entity, index) {
- if (entity.type === "mention") {
- const customNode2 = this.props.renderMention?.(entity, index);
- return toNode(customNode2) ?? this.createDefaultMentionNode(entity);
- }
- if (entity.type === "tag") {
- const customNode2 = this.props.renderTag?.(entity, index);
- return toNode(customNode2) ?? this.createDefaultTagNode(entity);
- }
- const customNode = this.props.renderLink?.(entity, index);
- return toNode(customNode) ?? this.createDefaultLinkNode(entity);
- }
- buildTextNodes(text, entities, upto = null) {
- let lastIndex = 0;
- const nodes = [];
- for (const [index, entity] of entities.entries()) {
- if (upto !== null && entity.start >= upto) {
- break;
- }
- const textEnd = upto !== null ? Math.min(entity.start, upto) : entity.start;
- if (entity.start > lastIndex && lastIndex < textEnd) {
- nodes.push(document.createTextNode(text.slice(lastIndex, textEnd)));
- }
- if (upto === null || entity.end <= upto) {
- const entityNode = this.renderEntity(entity, index);
- if (entityNode) {
- nodes.push(entityNode);
- }
- }
- lastIndex = entity.end;
- }
- if (upto === null) {
- if (lastIndex < text.length) {
- nodes.push(document.createTextNode(text.slice(lastIndex)));
- }
- } else if (lastIndex < upto) {
- nodes.push(document.createTextNode(text.slice(lastIndex, upto)));
- }
- return nodes;
- }
- applyBaseParagraphStyle(element) {
- element.style.whiteSpace = "pre-wrap";
- element.style.fontWeight = this.props.weight === "bold" ? "700" : "400";
- element.style.setProperty("-webkit-touch-callout", "default");
- element.style.setProperty("-webkit-user-select", "text");
- element.style.setProperty("-khtml-user-select", "text");
- element.style.setProperty("-moz-user-select", "text");
- element.style.setProperty("-ms-user-select", "text");
- element.style.setProperty("user-select", "text");
- if (this.props.blur) {
- element.style.filter = "blur(3px)";
- element.style.setProperty("-webkit-user-select", "none");
- element.style.setProperty("-khtml-user-select", "none");
- element.style.setProperty("-moz-user-select", "none");
- element.style.setProperty("-ms-user-select", "none");
- element.style.setProperty("user-select", "none");
- element.style.pointerEvents = "none";
- }
- applyStyleObject(element, this.props.style);
- }
- buildReadMoreButton(symbol) {
- const button = document.createElement("button");
- button.type = "button";
- button.textContent = resolveEllipsisSymbol(symbol, this.expanded);
- button.style.border = "0";
- button.style.background = "none";
- button.style.padding = "0";
- button.style.marginLeft = "6px";
- button.style.cursor = "pointer";
- button.style.color = LINK_COLOR;
- button.style.fontWeight = "700";
- button.onclick = (event) => {
- event.preventDefault();
- event.stopPropagation();
- this.handleExpand();
- };
- return button;
- }
- handleExpand() {
- const ellipsisConfig = this.resolveEllipsisConfig();
- if (!ellipsisConfig) {
- return;
- }
- this.expanded = true;
- ellipsisConfig.onExpand?.(true);
- this.render();
- }
- computeEntitySafeCutoff(count, entities) {
- let cutoff = count;
- let extended = true;
- while (extended) {
- extended = false;
- for (const entity of entities) {
- if (entity.start < cutoff && entity.end > cutoff) {
- cutoff = entity.end;
- extended = true;
- }
- }
- }
- return cutoff;
- }
- hasVerticalOverflow(element) {
- return element.scrollHeight - element.clientHeight > 1;
- }
- render() {
- if (!this.host) {
- return;
- }
- const text = this.getText();
- const entities = findAllEntities(text);
- const ellipsisConfig = this.resolveEllipsisConfig();
- const mergedExpanded = this.getMergedExpanded(ellipsisConfig, text);
- const wrapper = document.createElement("div");
- const paragraph = document.createElement("div");
- if (this.props.className) {
- paragraph.className = this.props.className;
- }
- this.applyBaseParagraphStyle(paragraph);
- if (ellipsisConfig && "count" in ellipsisConfig) {
- const count = ellipsisConfig.count ?? 0;
- const shouldTruncate = !mergedExpanded && count > 0 && text.length > count;
- if (shouldTruncate) {
- const cutoff = this.computeEntitySafeCutoff(count, entities);
- const nodes = this.buildTextNodes(text, entities, cutoff);
- paragraph.append(...nodes);
- paragraph.append(document.createTextNode("\u2026"));
- if (ellipsisConfig.expandable) {
- paragraph.append(this.buildReadMoreButton(ellipsisConfig.symbol));
- }
- } else {
- paragraph.append(...this.buildTextNodes(text, entities));
- }
- } else {
- paragraph.append(...this.buildTextNodes(text, entities));
- if (ellipsisConfig && "rows" in ellipsisConfig && !mergedExpanded) {
- paragraph.style.display = "-webkit-box";
- paragraph.style.setProperty("-webkit-box-orient", "vertical");
- paragraph.style.setProperty("-webkit-line-clamp", String(ellipsisConfig.rows));
- paragraph.style.overflow = "hidden";
- wrapper.append(paragraph);
- this.host.replaceChildren(wrapper);
- if (ellipsisConfig.expandable && this.hasVerticalOverflow(paragraph)) {
- wrapper.append(this.buildReadMoreButton(ellipsisConfig.symbol));
- }
- this.emitOnViewIfNeeded(mergedExpanded);
- return;
- }
- }
- wrapper.append(paragraph);
- this.host.replaceChildren(wrapper);
- this.emitOnViewIfNeeded(mergedExpanded);
- }
- initObserver() {
- if (!this.host) {
- return;
- }
- if (typeof IntersectionObserver === "undefined") {
- this.hostInsideView = true;
- return;
- }
- this.observer = new IntersectionObserver(
- (entries) => {
- const entry = entries[0];
- if (!entry) {
- return;
- }
- if (entry.isIntersecting && !this.hostInsideView) {
- this.hostInsideView = true;
- const ellipsisConfig = this.resolveEllipsisConfig();
- const mergedExpanded = this.getMergedExpanded(ellipsisConfig, this.getText());
- this.emitOnViewIfNeeded(mergedExpanded);
- }
- },
- { threshold: 0.5 }
- );
- this.observer.observe(this.host);
- }
- emitOnViewIfNeeded(mergedExpanded) {
- if (!mergedExpanded || this.viewed || !this.hostInsideView) {
- return;
- }
- this.viewed = true;
- this.props.onView?.();
- }
-};
-var AngularContentTextWithSuggestionsRenderer = class extends AngularContentTextRenderer {
-};
-var AngularContentTitleWithSuggestionsRenderer = class {
- renderer = new AngularContentTextWithSuggestionsRenderer();
- attach(host, props = {}) {
- return this.renderer.attach(host, this.normalizeProps(props));
- }
- update(props) {
- return this.renderer.update(this.normalizeProps(props));
- }
- destroy() {
- this.renderer.destroy();
- }
- getState() {
- return this.renderer.getState();
- }
- normalizeProps(props) {
- return {
- ...props,
- weight: "bold",
- blur: props.blur ?? false,
- ellipsis: props.ellipsis === void 0 ? { rows: 2 } : props.ellipsis
- };
- }
-};
-
-export { AngularContentSuggestionsAdapter, AngularContentTextRenderer, AngularContentTextWithSuggestionsRenderer, AngularContentTitleWithSuggestionsRenderer, buildAngularTagHref, createAngularContentTokens, toKebabCase };
-//# sourceMappingURL=index.js.map
-//# sourceMappingURL=index.js.map
\ No newline at end of file
+export * from "./angular/index.js";
diff --git a/packages/content-suggestions/dist/angular/index.js.map b/packages/content-suggestions/dist/angular/index.js.map
deleted file mode 100644
index 55c6caa..0000000
--- a/packages/content-suggestions/dist/angular/index.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["../../src/core/parser.ts","../../src/angular/index.ts"],"names":["customNode"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n ContentEntity,\n LinkEntity,\n MentionEntity,\n ParsedMention,\n ProcessedContent,\n TagEntity,\n} from \"./types\";\n\nexport const mentionLinkRegexp =\n /@\\[[^\\]]+]\\([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\\)/g;\n\nexport const parseMention = (mention: string): ParsedMention | null => {\n const regex = /@\\[([^\\]]+)\\]\\(([\\w-]{36})\\)/;\n const match = mention.match(regex);\n\n if (!match) {\n return null;\n }\n\n const mentionText = match[1];\n const mentionId = match[2];\n if (!mentionText || !mentionId) {\n return null;\n }\n\n return {\n mention: `@${mentionText}`,\n id: mentionId,\n };\n};\n\nexport const findMentions = (text: string): MentionEntity[] => {\n let match: RegExpExecArray | null;\n const matches: MentionEntity[] = [];\n\n while ((match = mentionLinkRegexp.exec(text)) !== null) {\n const parsed = parseMention(match[0]);\n const baseMention: Omit = {\n start: match.index,\n end: mentionLinkRegexp.lastIndex,\n text: match[0],\n type: \"mention\",\n displayText: parsed?.mention ?? match[0],\n };\n\n matches.push(parsed?.id ? { ...baseMention, userId: parsed.id } : baseMention);\n }\n\n return matches;\n};\n\nexport const findTags = (content: string): TagEntity[] => {\n const regex = /#[^\\s]{1,201}/g;\n const results: TagEntity[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(content)) !== null) {\n const value = match[0];\n results.push({\n start: match.index,\n end: match.index + value.length,\n text: value,\n type: \"tag\",\n tag: value.replace(\"#\", \"\"),\n });\n }\n\n return results;\n};\n\nexport const findLinks = (content: string): LinkEntity[] => {\n const regex =\n /\\b((https?:\\/\\/)?(?:[\\w-]+\\.)+[a-z]{2,}(\\/[\\w\\-._~:/?#[\\]@!$&'()*+,;=]*)?)/gi;\n const results: LinkEntity[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(content)) !== null) {\n const rawUrl = match[0];\n const hasProtocol = /^https?:\\/\\//i.test(rawUrl);\n const fullUrl = hasProtocol ? rawUrl : `https://${rawUrl}`;\n\n results.push({\n start: match.index,\n end: match.index + rawUrl.length,\n text: rawUrl,\n url: fullUrl,\n type: \"link\",\n });\n }\n\n return results;\n};\n\nexport const findAllEntities = (content: string): ContentEntity[] => {\n const mentions = findMentions(content);\n const tags = findTags(content);\n const links = findLinks(content);\n\n return [...mentions, ...tags, ...links].sort((a, b) => a.start - b.start);\n};\n\nexport const processContent = (content: string): ProcessedContent => {\n const processedText = content.replace(mentionLinkRegexp, match => {\n const parsed = parseMention(match);\n return parsed ? parsed.mention : match;\n });\n\n const tags = findTags(content).map(tag => tag.tag);\n\n return {\n processedText,\n tags,\n };\n};\n","import type { ContentEntity, LinkEntity, MentionEntity, TagEntity } from \"../core\";\n\nimport { findAllEntities } from \"../core\";\n\nexport interface AngularTextToken {\n kind: \"text\";\n text: string;\n start: number;\n end: number;\n}\n\nexport interface AngularMentionToken {\n kind: \"mention\";\n entity: MentionEntity;\n}\n\nexport interface AngularTagToken {\n kind: \"tag\";\n entity: TagEntity;\n}\n\nexport interface AngularLinkToken {\n kind: \"link\";\n entity: LinkEntity;\n}\n\nexport type AngularContentToken =\n | AngularTextToken\n | AngularMentionToken\n | AngularTagToken\n | AngularLinkToken;\n\nexport interface AngularContentSnapshot {\n text: string;\n entities: ContentEntity[];\n tokens: AngularContentToken[];\n}\n\nexport type AngularEllipsisSymbol = string | ((expanded: boolean) => string);\n\nexport type AngularCountEllipsisConfig = {\n count: number;\n rows?: never;\n expandable?: boolean;\n expanded?: boolean;\n symbol?: AngularEllipsisSymbol;\n onExpand?: (expanded: boolean) => void;\n};\n\nexport type AngularRowsEllipsisConfig = {\n rows: number;\n count?: never;\n expandable?: boolean;\n expanded?: boolean;\n symbol?: AngularEllipsisSymbol;\n onExpand?: (expanded: boolean) => void;\n};\n\nexport type AngularContentEllipsisConfig =\n | AngularCountEllipsisConfig\n | AngularRowsEllipsisConfig\n | false;\n\nexport type AngularRenderResult = Node | string | number | null | undefined;\n\nexport type AngularMentionRenderer = (\n entity: MentionEntity,\n index: number,\n) => AngularRenderResult;\n\nexport type AngularTagRenderer = (\n entity: TagEntity,\n index: number,\n) => AngularRenderResult;\n\nexport type AngularLinkRenderer = (\n entity: LinkEntity,\n index: number,\n) => AngularRenderResult;\n\nexport interface AngularContentTextProps {\n className?: string;\n weight?: \"normal\" | \"bold\";\n text?: string | null;\n ellipsis?: AngularContentEllipsisConfig;\n blur?: boolean;\n style?: Record | null;\n onView?: () => void;\n renderMention?: AngularMentionRenderer;\n renderTag?: AngularTagRenderer;\n renderLink?: AngularLinkRenderer;\n}\n\nexport type AngularContentTextWithSuggestionsProps = Omit<\n AngularContentTextProps,\n \"renderMention\" | \"renderTag\"\n> & {\n renderMention?: AngularMentionRenderer;\n renderTag?: AngularTagRenderer;\n};\n\nexport type AngularContentTitleWithSuggestionsProps = Omit<\n AngularContentTextWithSuggestionsProps,\n \"weight\"\n>;\n\nexport interface AngularContentTextRendererState {\n props: AngularContentTextProps;\n snapshot: AngularContentSnapshot;\n expanded: boolean;\n}\n\nconst LINK_COLOR = \"#1677ff\";\nconst READ_MORE_TEXT = \"Читать полностью\";\n\nconst toKebabCase = (value: string) => value.replace(/[A-Z]/g, char => `-${char.toLowerCase()}`);\n\nconst applyStyleObject = (\n element: HTMLElement,\n styles?: Record | null,\n) => {\n if (!styles) {\n return;\n }\n\n for (const [key, rawValue] of Object.entries(styles)) {\n if (rawValue === null || rawValue === undefined) {\n continue;\n }\n\n const styleValue =\n typeof rawValue === \"number\" ? `${rawValue}px` : String(rawValue);\n\n if (key.startsWith(\"--\")) {\n element.style.setProperty(key, styleValue);\n continue;\n }\n\n const cssKey = key.includes(\"-\") ? key : toKebabCase(key);\n element.style.setProperty(cssKey, styleValue);\n }\n};\n\nconst toNode = (value: AngularRenderResult): Node | null => {\n if (value === null || value === undefined) {\n return null;\n }\n\n if (value instanceof Node) {\n return value;\n }\n\n return document.createTextNode(String(value));\n};\n\nconst resolveEllipsisSymbol = (\n symbol: AngularEllipsisSymbol | undefined,\n expanded: boolean,\n): string => {\n if (typeof symbol === \"function\") {\n return symbol(expanded);\n }\n\n return symbol ?? READ_MORE_TEXT;\n};\n\nconst buildAngularTagHref = (entity: TagEntity): string => {\n return `/search/?query=${encodeURIComponent(entity.tag.toLowerCase())}`;\n};\n\nexport { buildAngularTagHref };\n\nexport const createAngularContentTokens = (\n inputText: string | null | undefined,\n): AngularContentToken[] => {\n const text = inputText ?? \"\";\n const entities = findAllEntities(text);\n\n let cursor = 0;\n const tokens: AngularContentToken[] = [];\n\n for (const entity of entities) {\n if (entity.start > cursor) {\n tokens.push({\n kind: \"text\",\n text: text.slice(cursor, entity.start),\n start: cursor,\n end: entity.start,\n });\n }\n\n if (entity.type === \"mention\") {\n tokens.push({\n kind: \"mention\",\n entity,\n });\n } else if (entity.type === \"tag\") {\n tokens.push({\n kind: \"tag\",\n entity,\n });\n } else {\n tokens.push({\n kind: \"link\",\n entity,\n });\n }\n\n cursor = entity.end;\n }\n\n if (cursor < text.length) {\n tokens.push({\n kind: \"text\",\n text: text.slice(cursor),\n start: cursor,\n end: text.length,\n });\n }\n\n return tokens;\n};\n\nexport class AngularContentSuggestionsAdapter {\n snapshot(inputText: string | null | undefined): AngularContentSnapshot {\n const text = inputText ?? \"\";\n const entities = findAllEntities(text);\n const tokens = createAngularContentTokens(text);\n\n return {\n text,\n entities,\n tokens,\n };\n }\n}\n\nexport class AngularContentTextRenderer {\n private host: HTMLElement | null = null;\n private props: AngularContentTextProps = {};\n private expanded = false;\n private viewed = false;\n private hostInsideView = false;\n private observer: IntersectionObserver | null = null;\n\n attach(host: HTMLElement, props: AngularContentTextProps = {}): AngularContentTextRendererState {\n this.destroy();\n\n this.host = host;\n this.props = { ...props };\n this.expanded = false;\n this.viewed = false;\n this.hostInsideView = false;\n\n this.initObserver();\n this.render();\n\n return this.getState();\n }\n\n update(nextProps: AngularContentTextProps): AngularContentTextRendererState {\n this.props = {\n ...this.props,\n ...nextProps,\n };\n\n this.render();\n\n return this.getState();\n }\n\n destroy(): void {\n if (this.observer && this.host) {\n this.observer.unobserve(this.host);\n this.observer.disconnect();\n }\n\n this.observer = null;\n\n if (this.host) {\n this.host.innerHTML = \"\";\n }\n\n this.host = null;\n this.props = {};\n this.expanded = false;\n this.viewed = false;\n this.hostInsideView = false;\n }\n\n getState(): AngularContentTextRendererState {\n return {\n props: { ...this.props },\n snapshot: this.createSnapshot(),\n expanded: this.getMergedExpanded(this.resolveEllipsisConfig(), this.getText()),\n };\n }\n\n private getText(): string {\n return this.props.text ?? \"\";\n }\n\n private createSnapshot(): AngularContentSnapshot {\n const text = this.getText();\n const entities = findAllEntities(text);\n const tokens = createAngularContentTokens(text);\n\n return {\n text,\n entities,\n tokens,\n };\n }\n\n private resolveEllipsisConfig():\n | AngularCountEllipsisConfig\n | AngularRowsEllipsisConfig\n | null {\n const ellipsis = this.props.ellipsis;\n\n if (!ellipsis || typeof ellipsis !== \"object\") {\n return null;\n }\n\n return ellipsis;\n }\n\n private getMergedExpanded(\n ellipsisConfig: AngularCountEllipsisConfig | AngularRowsEllipsisConfig | null,\n text: string,\n ): boolean {\n const controlledExpanded =\n ellipsisConfig && typeof ellipsisConfig.expanded === \"boolean\"\n ? ellipsisConfig.expanded\n : undefined;\n\n if (controlledExpanded !== undefined) {\n return controlledExpanded;\n }\n\n if (ellipsisConfig && \"count\" in ellipsisConfig) {\n const count = ellipsisConfig.count ?? 0;\n if (count <= 0 || text.length <= count) {\n return true;\n }\n }\n\n return this.expanded;\n }\n\n private createDefaultMentionNode(entity: MentionEntity): Node {\n const span = document.createElement(\"span\");\n span.style.color = LINK_COLOR;\n span.style.fontWeight = this.props.weight === \"bold\" ? \"700\" : \"400\";\n span.textContent = entity.displayText;\n return span;\n }\n\n private createDefaultTagNode(entity: TagEntity): Node {\n const span = document.createElement(\"span\");\n span.style.color = LINK_COLOR;\n span.style.fontWeight = this.props.weight === \"bold\" ? \"700\" : \"400\";\n span.textContent = entity.text;\n return span;\n }\n\n private createDefaultLinkNode(entity: LinkEntity): Node {\n const anchor = document.createElement(\"a\");\n anchor.href = entity.url;\n anchor.target = \"_blank\";\n anchor.referrerPolicy = \"no-referrer\";\n anchor.style.color = LINK_COLOR;\n anchor.style.fontWeight = this.props.weight === \"bold\" ? \"700\" : \"400\";\n anchor.textContent = entity.text;\n return anchor;\n }\n\n private renderEntity(entity: ContentEntity, index: number): Node | null {\n if (entity.type === \"mention\") {\n const customNode = this.props.renderMention?.(entity, index);\n return toNode(customNode) ?? this.createDefaultMentionNode(entity);\n }\n\n if (entity.type === \"tag\") {\n const customNode = this.props.renderTag?.(entity, index);\n return toNode(customNode) ?? this.createDefaultTagNode(entity);\n }\n\n const customNode = this.props.renderLink?.(entity, index);\n return toNode(customNode) ?? this.createDefaultLinkNode(entity);\n }\n\n private buildTextNodes(\n text: string,\n entities: ContentEntity[],\n upto: number | null = null,\n ): Node[] {\n let lastIndex = 0;\n const nodes: Node[] = [];\n\n for (const [index, entity] of entities.entries()) {\n if (upto !== null && entity.start >= upto) {\n break;\n }\n\n const textEnd = upto !== null ? Math.min(entity.start, upto) : entity.start;\n if (entity.start > lastIndex && lastIndex < textEnd) {\n nodes.push(document.createTextNode(text.slice(lastIndex, textEnd)));\n }\n\n if (upto === null || entity.end <= upto) {\n const entityNode = this.renderEntity(entity, index);\n if (entityNode) {\n nodes.push(entityNode);\n }\n }\n\n lastIndex = entity.end;\n }\n\n if (upto === null) {\n if (lastIndex < text.length) {\n nodes.push(document.createTextNode(text.slice(lastIndex)));\n }\n } else if (lastIndex < upto) {\n nodes.push(document.createTextNode(text.slice(lastIndex, upto)));\n }\n\n return nodes;\n }\n\n private applyBaseParagraphStyle(element: HTMLElement): void {\n element.style.whiteSpace = \"pre-wrap\";\n element.style.fontWeight = this.props.weight === \"bold\" ? \"700\" : \"400\";\n element.style.setProperty(\"-webkit-touch-callout\", \"default\");\n element.style.setProperty(\"-webkit-user-select\", \"text\");\n element.style.setProperty(\"-khtml-user-select\", \"text\");\n element.style.setProperty(\"-moz-user-select\", \"text\");\n element.style.setProperty(\"-ms-user-select\", \"text\");\n element.style.setProperty(\"user-select\", \"text\");\n\n if (this.props.blur) {\n element.style.filter = \"blur(3px)\";\n element.style.setProperty(\"-webkit-user-select\", \"none\");\n element.style.setProperty(\"-khtml-user-select\", \"none\");\n element.style.setProperty(\"-moz-user-select\", \"none\");\n element.style.setProperty(\"-ms-user-select\", \"none\");\n element.style.setProperty(\"user-select\", \"none\");\n element.style.pointerEvents = \"none\";\n }\n\n applyStyleObject(element, this.props.style);\n }\n\n private buildReadMoreButton(symbol: AngularEllipsisSymbol | undefined): HTMLButtonElement {\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.textContent = resolveEllipsisSymbol(symbol, this.expanded);\n button.style.border = \"0\";\n button.style.background = \"none\";\n button.style.padding = \"0\";\n button.style.marginLeft = \"6px\";\n button.style.cursor = \"pointer\";\n button.style.color = LINK_COLOR;\n button.style.fontWeight = \"700\";\n button.onclick = event => {\n event.preventDefault();\n event.stopPropagation();\n this.handleExpand();\n };\n return button;\n }\n\n private handleExpand(): void {\n const ellipsisConfig = this.resolveEllipsisConfig();\n\n if (!ellipsisConfig) {\n return;\n }\n\n this.expanded = true;\n ellipsisConfig.onExpand?.(true);\n this.render();\n }\n\n private computeEntitySafeCutoff(\n count: number,\n entities: ContentEntity[],\n ): number {\n let cutoff = count;\n let extended = true;\n\n while (extended) {\n extended = false;\n\n for (const entity of entities) {\n if (entity.start < cutoff && entity.end > cutoff) {\n cutoff = entity.end;\n extended = true;\n }\n }\n }\n\n return cutoff;\n }\n\n private hasVerticalOverflow(element: HTMLElement): boolean {\n return element.scrollHeight - element.clientHeight > 1;\n }\n\n private render(): void {\n if (!this.host) {\n return;\n }\n\n const text = this.getText();\n const entities = findAllEntities(text);\n const ellipsisConfig = this.resolveEllipsisConfig();\n const mergedExpanded = this.getMergedExpanded(ellipsisConfig, text);\n\n const wrapper = document.createElement(\"div\");\n const paragraph = document.createElement(\"div\");\n\n if (this.props.className) {\n paragraph.className = this.props.className;\n }\n\n this.applyBaseParagraphStyle(paragraph);\n\n if (ellipsisConfig && \"count\" in ellipsisConfig) {\n const count = ellipsisConfig.count ?? 0;\n const shouldTruncate = !mergedExpanded && count > 0 && text.length > count;\n\n if (shouldTruncate) {\n const cutoff = this.computeEntitySafeCutoff(count, entities);\n const nodes = this.buildTextNodes(text, entities, cutoff);\n\n paragraph.append(...nodes);\n paragraph.append(document.createTextNode(\"…\"));\n\n if (ellipsisConfig.expandable) {\n paragraph.append(this.buildReadMoreButton(ellipsisConfig.symbol));\n }\n } else {\n paragraph.append(...this.buildTextNodes(text, entities));\n }\n } else {\n paragraph.append(...this.buildTextNodes(text, entities));\n\n if (ellipsisConfig && \"rows\" in ellipsisConfig && !mergedExpanded) {\n paragraph.style.display = \"-webkit-box\";\n paragraph.style.setProperty(\"-webkit-box-orient\", \"vertical\");\n paragraph.style.setProperty(\"-webkit-line-clamp\", String(ellipsisConfig.rows));\n paragraph.style.overflow = \"hidden\";\n\n // Важно: сначала рендерим paragraph в DOM, потом меряем реальный overflow.\n wrapper.append(paragraph);\n this.host.replaceChildren(wrapper);\n\n if (ellipsisConfig.expandable && this.hasVerticalOverflow(paragraph)) {\n wrapper.append(this.buildReadMoreButton(ellipsisConfig.symbol));\n }\n\n this.emitOnViewIfNeeded(mergedExpanded);\n return;\n }\n }\n\n wrapper.append(paragraph);\n this.host.replaceChildren(wrapper);\n this.emitOnViewIfNeeded(mergedExpanded);\n }\n\n private initObserver(): void {\n if (!this.host) {\n return;\n }\n\n if (typeof IntersectionObserver === \"undefined\") {\n this.hostInsideView = true;\n return;\n }\n\n this.observer = new IntersectionObserver(\n entries => {\n const entry = entries[0];\n if (!entry) {\n return;\n }\n\n if (entry.isIntersecting && !this.hostInsideView) {\n this.hostInsideView = true;\n const ellipsisConfig = this.resolveEllipsisConfig();\n const mergedExpanded = this.getMergedExpanded(ellipsisConfig, this.getText());\n this.emitOnViewIfNeeded(mergedExpanded);\n }\n },\n { threshold: 0.5 },\n );\n\n this.observer.observe(this.host);\n }\n\n private emitOnViewIfNeeded(mergedExpanded: boolean): void {\n if (!mergedExpanded || this.viewed || !this.hostInsideView) {\n return;\n }\n\n this.viewed = true;\n this.props.onView?.();\n }\n}\n\nexport class AngularContentTextWithSuggestionsRenderer extends AngularContentTextRenderer {}\n\nexport class AngularContentTitleWithSuggestionsRenderer {\n private readonly renderer = new AngularContentTextWithSuggestionsRenderer();\n\n attach(\n host: HTMLElement,\n props: AngularContentTitleWithSuggestionsProps = {},\n ): AngularContentTextRendererState {\n return this.renderer.attach(host, this.normalizeProps(props));\n }\n\n update(props: AngularContentTitleWithSuggestionsProps): AngularContentTextRendererState {\n return this.renderer.update(this.normalizeProps(props));\n }\n\n destroy(): void {\n this.renderer.destroy();\n }\n\n getState(): AngularContentTextRendererState {\n return this.renderer.getState();\n }\n\n private normalizeProps(\n props: AngularContentTitleWithSuggestionsProps,\n ): AngularContentTextWithSuggestionsProps {\n return {\n ...props,\n weight: \"bold\",\n blur: props.blur ?? false,\n ellipsis: props.ellipsis === undefined ? { rows: 2 } : props.ellipsis,\n };\n }\n}\n\nexport { toKebabCase };\n"]}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/core/index.d.cts b/packages/content-suggestions/dist/core/index.d.cts
index d87e74f..b76e41b 100644
--- a/packages/content-suggestions/dist/core/index.d.cts
+++ b/packages/content-suggestions/dist/core/index.d.cts
@@ -1,5 +1,30 @@
-import { C as ContentEntity, L as LinkEntity, M as MentionEntity, T as TagEntity, P as ParsedMention, a as ProcessedContent } from '../types-BRt4hd7A.cjs';
-export { B as BaseEntity } from '../types-BRt4hd7A.cjs';
+interface BaseEntity {
+ start: number;
+ end: number;
+ text: string;
+}
+interface MentionEntity extends BaseEntity {
+ type: "mention";
+ displayText: string;
+ userId?: string;
+}
+interface TagEntity extends BaseEntity {
+ type: "tag";
+ tag: string;
+}
+interface LinkEntity extends BaseEntity {
+ type: "link";
+ url: string;
+}
+type ContentEntity = MentionEntity | TagEntity | LinkEntity;
+interface ParsedMention {
+ mention: string;
+ id: string;
+}
+interface ProcessedContent {
+ processedText: string;
+ tags: string[];
+}
declare const mentionLinkRegexp: RegExp;
declare const parseMention: (mention: string) => ParsedMention | null;
@@ -9,4 +34,4 @@ declare const findLinks: (content: string) => LinkEntity[];
declare const findAllEntities: (content: string) => ContentEntity[];
declare const processContent: (content: string) => ProcessedContent;
-export { ContentEntity, LinkEntity, MentionEntity, ParsedMention, ProcessedContent, TagEntity, findAllEntities, findLinks, findMentions, findTags, mentionLinkRegexp, parseMention, processContent };
+export { type BaseEntity, type ContentEntity, type LinkEntity, type MentionEntity, type ParsedMention, type ProcessedContent, type TagEntity, findAllEntities, findLinks, findMentions, findTags, mentionLinkRegexp, parseMention, processContent };
diff --git a/packages/content-suggestions/dist/core/index.d.ts b/packages/content-suggestions/dist/core/index.d.ts
index d148594..b76e41b 100644
--- a/packages/content-suggestions/dist/core/index.d.ts
+++ b/packages/content-suggestions/dist/core/index.d.ts
@@ -1,5 +1,30 @@
-import { C as ContentEntity, L as LinkEntity, M as MentionEntity, T as TagEntity, P as ParsedMention, a as ProcessedContent } from '../types-BRt4hd7A.js';
-export { B as BaseEntity } from '../types-BRt4hd7A.js';
+interface BaseEntity {
+ start: number;
+ end: number;
+ text: string;
+}
+interface MentionEntity extends BaseEntity {
+ type: "mention";
+ displayText: string;
+ userId?: string;
+}
+interface TagEntity extends BaseEntity {
+ type: "tag";
+ tag: string;
+}
+interface LinkEntity extends BaseEntity {
+ type: "link";
+ url: string;
+}
+type ContentEntity = MentionEntity | TagEntity | LinkEntity;
+interface ParsedMention {
+ mention: string;
+ id: string;
+}
+interface ProcessedContent {
+ processedText: string;
+ tags: string[];
+}
declare const mentionLinkRegexp: RegExp;
declare const parseMention: (mention: string) => ParsedMention | null;
@@ -9,4 +34,4 @@ declare const findLinks: (content: string) => LinkEntity[];
declare const findAllEntities: (content: string) => ContentEntity[];
declare const processContent: (content: string) => ProcessedContent;
-export { ContentEntity, LinkEntity, MentionEntity, ParsedMention, ProcessedContent, TagEntity, findAllEntities, findLinks, findMentions, findTags, mentionLinkRegexp, parseMention, processContent };
+export { type BaseEntity, type ContentEntity, type LinkEntity, type MentionEntity, type ParsedMention, type ProcessedContent, type TagEntity, findAllEntities, findLinks, findMentions, findTags, mentionLinkRegexp, parseMention, processContent };
diff --git a/packages/content-suggestions/dist/react/index.cjs.map b/packages/content-suggestions/dist/react/index.cjs.map
index 767f62e..9ba4d23 100644
--- a/packages/content-suggestions/dist/react/index.cjs.map
+++ b/packages/content-suggestions/dist/react/index.cjs.map
@@ -1 +1 @@
-{"version":3,"sources":["../../src/core/parser.ts","../../src/react/components/content-text.tsx","../../src/react/components/content-text-with-suggestions.tsx","../../src/react/components/content-title-with-suggestions.tsx"],"names":["jsx","React","TachTypography","useRef","useState","useMemo","useCallback","useEffect","jsxs"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {\n ContentEntity,\n LinkEntity,\n MentionEntity,\n ParsedMention,\n ProcessedContent,\n TagEntity,\n} from \"./types\";\n\nexport const mentionLinkRegexp =\n /@\\[[^\\]]+]\\([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\\)/g;\n\nexport const parseMention = (mention: string): ParsedMention | null => {\n const regex = /@\\[([^\\]]+)\\]\\(([\\w-]{36})\\)/;\n const match = mention.match(regex);\n\n if (!match) {\n return null;\n }\n\n const mentionText = match[1];\n const mentionId = match[2];\n if (!mentionText || !mentionId) {\n return null;\n }\n\n return {\n mention: `@${mentionText}`,\n id: mentionId,\n };\n};\n\nexport const findMentions = (text: string): MentionEntity[] => {\n let match: RegExpExecArray | null;\n const matches: MentionEntity[] = [];\n\n while ((match = mentionLinkRegexp.exec(text)) !== null) {\n const parsed = parseMention(match[0]);\n const baseMention: Omit = {\n start: match.index,\n end: mentionLinkRegexp.lastIndex,\n text: match[0],\n type: \"mention\",\n displayText: parsed?.mention ?? match[0],\n };\n\n matches.push(parsed?.id ? { ...baseMention, userId: parsed.id } : baseMention);\n }\n\n return matches;\n};\n\nexport const findTags = (content: string): TagEntity[] => {\n const regex = /#[^\\s]{1,201}/g;\n const results: TagEntity[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(content)) !== null) {\n const value = match[0];\n results.push({\n start: match.index,\n end: match.index + value.length,\n text: value,\n type: \"tag\",\n tag: value.replace(\"#\", \"\"),\n });\n }\n\n return results;\n};\n\nexport const findLinks = (content: string): LinkEntity[] => {\n const regex =\n /\\b((https?:\\/\\/)?(?:[\\w-]+\\.)+[a-z]{2,}(\\/[\\w\\-._~:/?#[\\]@!$&'()*+,;=]*)?)/gi;\n const results: LinkEntity[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(content)) !== null) {\n const rawUrl = match[0];\n const hasProtocol = /^https?:\\/\\//i.test(rawUrl);\n const fullUrl = hasProtocol ? rawUrl : `https://${rawUrl}`;\n\n results.push({\n start: match.index,\n end: match.index + rawUrl.length,\n text: rawUrl,\n url: fullUrl,\n type: \"link\",\n });\n }\n\n return results;\n};\n\nexport const findAllEntities = (content: string): ContentEntity[] => {\n const mentions = findMentions(content);\n const tags = findTags(content);\n const links = findLinks(content);\n\n return [...mentions, ...tags, ...links].sort((a, b) => a.start - b.start);\n};\n\nexport const processContent = (content: string): ProcessedContent => {\n const processedText = content.replace(mentionLinkRegexp, match => {\n const parsed = parseMention(match);\n return parsed ? parsed.mention : match;\n });\n\n const tags = findTags(content).map(tag => tag.tag);\n\n return {\n processedText,\n tags,\n };\n};\n","import type { ComponentProps, CSSProperties, ReactNode } from \"react\";\nimport type { EllipsisConfig } from \"antd/lib/typography/Base\";\nimport type {\n ContentEntity,\n LinkEntity,\n MentionEntity,\n TagEntity,\n} from \"../../core\";\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { TachTypography } from \"@hublib-web/tach-typography/react\";\nimport { findAllEntities } from \"../../core\";\n\ntype CustomEllipsisConfig =\n | ({\n count: number;\n rows?: never;\n expandable?: boolean;\n } & Partial)\n | ({\n rows: number;\n count?: never;\n expandable?: boolean;\n } & Partial)\n | false;\n\ntype ParagraphBodyProps = ComponentProps;\ntype TextBodyProps = ComponentProps;\ntype TitleBodyProps = ComponentProps;\n\nconst joinClassName = (...values: Array) =>\n values.filter(Boolean).join(\" \");\n\nconst baseSelectableStyle: CSSProperties = {\n whiteSpace: \"pre-wrap\",\n WebkitTouchCallout: \"default\",\n WebkitUserSelect: \"text\",\n KhtmlUserSelect: \"text\",\n MozUserSelect: \"text\",\n msUserSelect: \"text\",\n userSelect: \"text\",\n};\n\nconst blurStyle: CSSProperties = {\n filter: \"blur(3px)\",\n WebkitUserSelect: \"none\",\n KhtmlUserSelect: \"none\",\n MozUserSelect: \"none\",\n msUserSelect: \"none\",\n userSelect: \"none\",\n pointerEvents: \"none\",\n};\n\nconst ReadMoreButton: React.FC<{\n onClick: (event: React.MouseEvent) => void;\n symbol?: EllipsisConfig[\"symbol\"];\n expanded?: boolean;\n TitleComponent: React.ComponentType;\n}> = ({ onClick, symbol = \"Читать полностью\", expanded = false, TitleComponent }) => (\n {\n event.preventDefault();\n event.stopPropagation();\n onClick(event);\n }}\n weight=\"bold\"\n level={5}\n >\n {typeof symbol === \"function\" ? symbol(expanded) : symbol}\n \n);\n\nexport interface ContentTextProps {\n className?: string;\n weight?: TextBodyProps[\"weight\"];\n text?: string | null;\n ellipsis?: CustomEllipsisConfig;\n blur?: boolean;\n style?: TextBodyProps[\"style\"];\n onView?: () => void;\n renderMention?: (entity: MentionEntity, index: number) => ReactNode;\n renderTag?: (entity: TagEntity, index: number) => ReactNode;\n renderLink?: (entity: LinkEntity, index: number) => ReactNode;\n ParagraphComponent?: React.ComponentType;\n TextComponent?: React.ComponentType;\n TitleComponent?: React.ComponentType;\n}\n\nexport const ContentText: React.NamedExoticComponent = React.memo(\n ({\n text,\n className,\n ellipsis = false,\n blur = false,\n weight = \"normal\",\n style,\n onView,\n renderMention,\n renderTag,\n renderLink,\n ParagraphComponent = TachTypography.Paragraph.Body,\n TextComponent = TachTypography.Text.Body,\n TitleComponent = TachTypography.Title.Body,\n ...props\n }: ContentTextProps) => {\n const containerRef = useRef(null);\n const [expanded, setExpanded] = useState(false);\n const [containerInsideView, setContainerInsideView] = useState(false);\n const [viewed, setViewed] = useState(false);\n const content = text || \"\";\n\n const entities = useMemo(() => findAllEntities(content), [content]);\n\n const wrapWithKey = (node: ReactNode, key: React.Key) => {\n if (React.isValidElement(node)) {\n return React.cloneElement(node, { key });\n }\n\n return {node};\n };\n\n const buildMentionNode = (entity: MentionEntity, index: number) => {\n const defaultNode = (\n \n {entity.displayText}\n \n );\n const customNode = renderMention?.(entity, index) ?? defaultNode;\n return wrapWithKey(customNode, `mention-${entity.start}-${index}`);\n };\n\n const buildTagNode = (entity: TagEntity, index: number) => {\n const defaultNode = (\n \n {entity.text}\n \n );\n const customNode = renderTag?.(entity, index) ?? defaultNode;\n return wrapWithKey(customNode, `tag-${entity.start}-${index}`);\n };\n\n const buildLinkNode = (entity: LinkEntity, index: number) => {\n const defaultNode = (\n \n {entity.text}\n \n );\n const customNode = renderLink?.(entity, index) ?? defaultNode;\n return wrapWithKey(customNode, `link-${entity.start}-${index}`);\n };\n\n const buildParts = (upto: number | null = null): ReactNode[] => {\n let lastIndex = 0;\n const nodes: ReactNode[] = [];\n\n for (const [i, entity] of entities.entries()) {\n\n if (upto !== null && entity.start >= upto) {\n break;\n }\n\n const textEnd = upto !== null ? Math.min(entity.start, upto) : entity.start;\n if (entity.start > lastIndex && lastIndex < textEnd) {\n nodes.push(content.slice(lastIndex, textEnd));\n }\n\n if (upto === null || entity.end <= upto) {\n if (entity.type === \"mention\") {\n nodes.push(buildMentionNode(entity, i));\n } else if (entity.type === \"tag\") {\n nodes.push(buildTagNode(entity, i));\n } else if (entity.type === \"link\") {\n nodes.push(buildLinkNode(entity, i));\n }\n }\n\n lastIndex = entity.end;\n }\n\n if (upto === null) {\n if (lastIndex < content.length) {\n nodes.push(content.slice(lastIndex));\n }\n } else if (lastIndex < upto) {\n nodes.push(content.slice(lastIndex, upto));\n }\n\n return nodes;\n };\n\n const ellipsisConfig = ellipsis && typeof ellipsis === \"object\" ? ellipsis : null;\n const expandedFromProps =\n ellipsisConfig && typeof ellipsisConfig.expanded === \"boolean\"\n ? ellipsisConfig.expanded\n : undefined;\n const isExpandedControlled = expandedFromProps !== undefined;\n const mergedExpanded = isExpandedControlled ? expandedFromProps : expanded;\n\n const handleExpand = useCallback(\n (event: React.MouseEvent) => {\n if (!isExpandedControlled) {\n setExpanded(true);\n }\n\n ellipsisConfig?.onExpand?.(event, { expanded: true });\n },\n [ellipsisConfig, isExpandedControlled],\n );\n\n useEffect(() => {\n if (isExpandedControlled) {\n return;\n }\n\n if (ellipsisConfig && \"count\" in ellipsisConfig) {\n const count = ellipsisConfig.count ?? 0;\n if (content.length <= count && !expanded) {\n setExpanded(true);\n }\n }\n }, [content.length, ellipsisConfig, expanded, isExpandedControlled]);\n\n useEffect(() => {\n if (mergedExpanded && !viewed && containerInsideView) {\n setViewed(true);\n onView?.();\n }\n }, [mergedExpanded, viewed, containerInsideView, onView]);\n\n useEffect(() => {\n const ref = containerRef.current;\n if (!ref) {\n return;\n }\n\n const observer = new IntersectionObserver((entries) => {\n const entry = entries[0];\n if (!entry) {\n return;\n }\n\n if (entry.isIntersecting && !containerInsideView) {\n setContainerInsideView(true);\n }\n }, { threshold: 0.5 });\n\n observer.observe(ref);\n\n return () => {\n observer.unobserve(ref);\n };\n }, [containerInsideView]);\n\n const mergedStyle: CSSProperties = {\n ...baseSelectableStyle,\n ...(blur ? blurStyle : undefined),\n ...(style as CSSProperties | undefined),\n };\n\n if (ellipsisConfig && \"count\" in ellipsisConfig) {\n const { count, expandable } = ellipsisConfig;\n\n if (!mergedExpanded && count && content.length > count) {\n let cutoff = count;\n let extended = true;\n\n while (extended) {\n extended = false;\n for (const entity of entities) {\n if (entity.start < cutoff && entity.end > cutoff) {\n cutoff = entity.end;\n extended = true;\n }\n }\n }\n\n const truncatedNodes = buildParts(cutoff);\n\n return (\n \n {truncatedNodes}…\n {expandable && (\n \n )}\n \n );\n }\n }\n\n if (ellipsisConfig && \"rows\" in ellipsisConfig) {\n const paragraphEllipsis = mergedExpanded\n ? false\n : {\n ...ellipsisConfig,\n symbol: ellipsisConfig.expandable ? (\n \n ) : (\n ellipsisConfig.symbol\n ),\n };\n\n return (\n \n {buildParts()}\n \n );\n }\n\n return (\n \n {buildParts()}\n \n );\n },\n);\n\nContentText.displayName = \"ContentText\";\n","import type { ComponentProps } from \"react\";\nimport type { MentionEntity, TagEntity } from \"../../core\";\n\nimport React from \"react\";\n\nimport { TachTypography } from \"@hublib-web/tach-typography/react\";\nimport { ContentText } from \"./content-text\";\n\ntype BaseContentTextProps = Omit<\n ComponentProps,\n \"renderMention\" | \"renderTag\"\n> & {\n renderMention?: (entity: MentionEntity, index: number) => React.ReactNode;\n renderTag?: (entity: TagEntity, index: number) => React.ReactNode;\n};\n\nconst DefaultMention = ({ entity }: { entity: MentionEntity }) => (\n {entity.displayText}\n);\n\nconst DefaultTag = ({ entity }: { entity: TagEntity }) => (\n \n {entity.text}\n \n);\n\nexport const ContentTextWithSuggestions = ({\n renderMention,\n renderTag,\n ...props\n}: BaseContentTextProps) => {\n return (\n \n renderMention ? renderMention(entity, index) : \n }\n renderTag={(entity, index) =>\n renderTag ? (\n renderTag(entity, index)\n ) : (\n \n )\n }\n />\n );\n};\n","import type { ComponentProps } from \"react\";\n\nimport React from \"react\";\n\nimport { ContentTextWithSuggestions } from \"./content-text-with-suggestions\";\n\ninterface ContentTitleWithSuggestionsProps\n extends Omit, \"weight\"> {}\n\nexport const ContentTitleWithSuggestions = ({\n text,\n ellipsis,\n blur = false,\n ...rest\n}: ContentTitleWithSuggestionsProps) => {\n const normalizedEllipsis = ellipsis === undefined ? { rows: 2 } : ellipsis;\n const textProps = text === undefined ? {} : { text };\n\n return (\n \n );\n};\n"]}
\ No newline at end of file
+{"version":3,"sources":["../../src/core/parser.ts","../../src/react/components/content-text.tsx","../../src/react/components/content-text-with-suggestions.tsx","../../src/react/components/content-title-with-suggestions.tsx"],"names":["jsx","React","TachTypography","useRef","useState","useMemo","useCallback","useEffect","jsxs"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {\n ContentEntity,\n LinkEntity,\n MentionEntity,\n ParsedMention,\n ProcessedContent,\n TagEntity,\n} from \"./types\";\n\nexport const mentionLinkRegexp =\n /@\\[[^\\]]+]\\([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\\)/g;\n\nexport const parseMention = (mention: string): ParsedMention | null => {\n const regex = /@\\[([^\\]]+)\\]\\(([\\w-]{36})\\)/;\n const match = mention.match(regex);\n\n if (!match) {\n return null;\n }\n\n const mentionText = match[1];\n const mentionId = match[2];\n if (!mentionText || !mentionId) {\n return null;\n }\n\n return {\n mention: `@${mentionText}`,\n id: mentionId,\n };\n};\n\nexport const findMentions = (text: string): MentionEntity[] => {\n let match: RegExpExecArray | null;\n const matches: MentionEntity[] = [];\n\n while ((match = mentionLinkRegexp.exec(text)) !== null) {\n const parsed = parseMention(match[0]);\n const baseMention: Omit = {\n start: match.index,\n end: mentionLinkRegexp.lastIndex,\n text: match[0],\n type: \"mention\",\n displayText: parsed?.mention ?? match[0],\n };\n\n matches.push(parsed?.id ? { ...baseMention, userId: parsed.id } : baseMention);\n }\n\n return matches;\n};\n\nexport const findTags = (content: string): TagEntity[] => {\n const regex = /#[^\\s]{1,201}/g;\n const results: TagEntity[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(content)) !== null) {\n const value = match[0];\n results.push({\n start: match.index,\n end: match.index + value.length,\n text: value,\n type: \"tag\",\n tag: value.replace(\"#\", \"\"),\n });\n }\n\n return results;\n};\n\nexport const findLinks = (content: string): LinkEntity[] => {\n const regex =\n /\\b((https?:\\/\\/)?(?:[\\w-]+\\.)+[a-z]{2,}(\\/[\\w\\-._~:/?#[\\]@!$&'()*+,;=]*)?)/gi;\n const results: LinkEntity[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(content)) !== null) {\n const rawUrl = match[0];\n const hasProtocol = /^https?:\\/\\//i.test(rawUrl);\n const fullUrl = hasProtocol ? rawUrl : `https://${rawUrl}`;\n\n results.push({\n start: match.index,\n end: match.index + rawUrl.length,\n text: rawUrl,\n url: fullUrl,\n type: \"link\",\n });\n }\n\n return results;\n};\n\nexport const findAllEntities = (content: string): ContentEntity[] => {\n const mentions = findMentions(content);\n const tags = findTags(content);\n const links = findLinks(content);\n\n return [...mentions, ...tags, ...links].sort((a, b) => a.start - b.start);\n};\n\nexport const processContent = (content: string): ProcessedContent => {\n const processedText = content.replace(mentionLinkRegexp, match => {\n const parsed = parseMention(match);\n return parsed ? parsed.mention : match;\n });\n\n const tags = findTags(content).map(tag => tag.tag);\n\n return {\n processedText,\n tags,\n };\n};\n","import type { ComponentProps, CSSProperties, ReactNode } from \"react\";\nimport type { EllipsisConfig } from \"antd/lib/typography/Base\";\nimport type {\n ContentEntity,\n LinkEntity,\n MentionEntity,\n TagEntity,\n} from \"../../core\";\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { TachTypography } from \"@hublib-web/tach-typography/react\";\nimport { findAllEntities } from \"../../core\";\n\ntype CustomEllipsisConfig =\n | ({\n count: number;\n rows?: never;\n expandable?: boolean;\n } & Partial)\n | ({\n rows: number;\n count?: never;\n expandable?: boolean;\n } & Partial)\n | false;\n\ntype ParagraphBodyProps = ComponentProps;\ntype TextBodyProps = ComponentProps;\ntype TitleBodyProps = ComponentProps;\n\nconst joinClassName = (...values: Array) =>\n values.filter(Boolean).join(\" \");\n\nconst baseSelectableStyle: CSSProperties = {\n whiteSpace: \"pre-wrap\",\n WebkitTouchCallout: \"default\",\n WebkitUserSelect: \"text\",\n KhtmlUserSelect: \"text\",\n MozUserSelect: \"text\",\n msUserSelect: \"text\",\n userSelect: \"text\",\n};\n\nconst blurStyle: CSSProperties = {\n filter: \"blur(3px)\",\n WebkitUserSelect: \"none\",\n KhtmlUserSelect: \"none\",\n MozUserSelect: \"none\",\n msUserSelect: \"none\",\n userSelect: \"none\",\n pointerEvents: \"none\",\n};\n\nconst ReadMoreButton: React.FC<{\n onClick: (event: React.MouseEvent) => void;\n symbol?: EllipsisConfig[\"symbol\"];\n expanded?: boolean;\n TitleComponent: React.ComponentType;\n}> = ({ onClick, symbol = \"Читать полностью\", expanded = false, TitleComponent }) => (\n {\n event.preventDefault();\n event.stopPropagation();\n onClick(event);\n }}\n weight=\"bold\"\n level={5}\n >\n {typeof symbol === \"function\" ? symbol(expanded) : symbol}\n \n);\n\nexport interface ContentTextProps {\n className?: string;\n weight?: TextBodyProps[\"weight\"];\n text?: string | null;\n ellipsis?: CustomEllipsisConfig;\n blur?: boolean;\n style?: TextBodyProps[\"style\"];\n onView?: () => void;\n renderMention?: (entity: MentionEntity, index: number) => ReactNode;\n renderTag?: (entity: TagEntity, index: number) => ReactNode;\n renderLink?: (entity: LinkEntity, index: number) => ReactNode;\n ParagraphComponent?: React.ComponentType;\n TextComponent?: React.ComponentType;\n TitleComponent?: React.ComponentType;\n}\n\nexport const ContentText: React.NamedExoticComponent = React.memo(\n ({\n text,\n className,\n ellipsis = false,\n blur = false,\n weight = \"normal\",\n style,\n onView,\n renderMention,\n renderTag,\n renderLink,\n ParagraphComponent = TachTypography.Paragraph.Body,\n TextComponent = TachTypography.Text.Body,\n TitleComponent = TachTypography.Title.Body,\n ...props\n }: ContentTextProps) => {\n const containerRef = useRef(null);\n const [expanded, setExpanded] = useState(false);\n const [containerInsideView, setContainerInsideView] = useState(false);\n const [viewed, setViewed] = useState(false);\n const content = text || \"\";\n\n const entities = useMemo(() => findAllEntities(content), [content]);\n\n const wrapWithKey = (node: ReactNode, key: React.Key) => {\n if (React.isValidElement(node)) {\n return React.cloneElement(node, { key });\n }\n\n return {node};\n };\n\n const buildMentionNode = (entity: MentionEntity, index: number) => {\n const defaultNode = (\n \n {entity.displayText}\n \n );\n const customNode = renderMention?.(entity, index) ?? defaultNode;\n return wrapWithKey(customNode, `mention-${entity.start}-${index}`);\n };\n\n const buildTagNode = (entity: TagEntity, index: number) => {\n const defaultNode = (\n \n {entity.text}\n \n );\n const customNode = renderTag?.(entity, index) ?? defaultNode;\n return wrapWithKey(customNode, `tag-${entity.start}-${index}`);\n };\n\n const buildLinkNode = (entity: LinkEntity, index: number) => {\n const defaultNode = (\n \n {entity.text}\n \n );\n const customNode = renderLink?.(entity, index) ?? defaultNode;\n return wrapWithKey(customNode, `link-${entity.start}-${index}`);\n };\n\n const buildParts = (upto: number | null = null): ReactNode[] => {\n let lastIndex = 0;\n const nodes: ReactNode[] = [];\n\n for (const [i, entity] of entities.entries()) {\n\n if (upto !== null && entity.start >= upto) {\n break;\n }\n\n const textEnd = upto !== null ? Math.min(entity.start, upto) : entity.start;\n if (entity.start > lastIndex && lastIndex < textEnd) {\n nodes.push(content.slice(lastIndex, textEnd));\n }\n\n if (upto === null || entity.end <= upto) {\n if (entity.type === \"mention\") {\n nodes.push(buildMentionNode(entity, i));\n } else if (entity.type === \"tag\") {\n nodes.push(buildTagNode(entity, i));\n } else if (entity.type === \"link\") {\n nodes.push(buildLinkNode(entity, i));\n }\n }\n\n lastIndex = entity.end;\n }\n\n if (upto === null) {\n if (lastIndex < content.length) {\n nodes.push(content.slice(lastIndex));\n }\n } else if (lastIndex < upto) {\n nodes.push(content.slice(lastIndex, upto));\n }\n\n return nodes;\n };\n\n const ellipsisConfig = ellipsis && typeof ellipsis === \"object\" ? ellipsis : null;\n const expandedFromProps =\n ellipsisConfig && typeof ellipsisConfig.expanded === \"boolean\"\n ? ellipsisConfig.expanded\n : undefined;\n const isExpandedControlled = expandedFromProps !== undefined;\n const mergedExpanded = isExpandedControlled ? expandedFromProps : expanded;\n\n const handleExpand = useCallback(\n (event: React.MouseEvent) => {\n if (!isExpandedControlled) {\n setExpanded(true);\n }\n\n ellipsisConfig?.onExpand?.(event, { expanded: true });\n },\n [ellipsisConfig, isExpandedControlled],\n );\n\n useEffect(() => {\n if (isExpandedControlled) {\n return;\n }\n\n if (ellipsisConfig && \"count\" in ellipsisConfig) {\n const count = ellipsisConfig.count ?? 0;\n if (content.length <= count && !expanded) {\n setExpanded(true);\n }\n }\n }, [content.length, ellipsisConfig, expanded, isExpandedControlled]);\n\n useEffect(() => {\n if (mergedExpanded && !viewed && containerInsideView) {\n setViewed(true);\n onView?.();\n }\n }, [mergedExpanded, viewed, containerInsideView, onView]);\n\n useEffect(() => {\n const ref = containerRef.current;\n if (!ref) {\n return;\n }\n\n const observer = new IntersectionObserver((entries) => {\n const entry = entries[0];\n if (!entry) {\n return;\n }\n\n if (entry.isIntersecting && !containerInsideView) {\n setContainerInsideView(true);\n }\n }, { threshold: 0.5 });\n\n observer.observe(ref);\n\n return () => {\n observer.unobserve(ref);\n };\n }, [containerInsideView]);\n\n const mergedStyle: CSSProperties = {\n ...baseSelectableStyle,\n ...(blur ? blurStyle : undefined),\n ...(style as CSSProperties | undefined),\n };\n\n if (ellipsisConfig && \"count\" in ellipsisConfig) {\n const { count, expandable } = ellipsisConfig;\n\n if (!mergedExpanded && count && content.length > count) {\n let cutoff = count;\n let extended = true;\n\n while (extended) {\n extended = false;\n for (const entity of entities) {\n if (entity.start < cutoff && entity.end > cutoff) {\n cutoff = entity.end;\n extended = true;\n }\n }\n }\n\n const truncatedNodes = buildParts(cutoff);\n\n return (\n \n {truncatedNodes}…\n {expandable && (\n \n )}\n \n );\n }\n }\n\n if (ellipsisConfig && \"rows\" in ellipsisConfig) {\n const paragraphEllipsis = mergedExpanded\n ? false\n : {\n ...ellipsisConfig,\n symbol: ellipsisConfig.expandable ? (\n \n ) : (\n ellipsisConfig.symbol\n ),\n };\n\n return (\n \n {buildParts()}\n \n );\n }\n\n return (\n \n {buildParts()}\n \n );\n },\n);\n\nContentText.displayName = \"ContentText\";\n","import type { ComponentProps } from \"react\";\nimport type { MentionEntity, TagEntity } from \"../../core\";\n\nimport React from \"react\";\n\nimport { TachTypography } from \"@hublib-web/tach-typography/react\";\nimport { ContentText } from \"./content-text\";\n\ntype BaseContentTextProps = Omit<\n ComponentProps,\n \"renderMention\" | \"renderTag\"\n> & {\n renderMention?: (entity: MentionEntity, index: number) => React.ReactNode;\n renderTag?: (entity: TagEntity, index: number) => React.ReactNode;\n};\n\nconst DefaultMention = ({ entity }: { entity: MentionEntity }) => (\n {entity.displayText}\n);\n\nconst DefaultTag = ({ entity }: { entity: TagEntity }) => (\n \n {entity.text}\n \n);\n\nexport const ContentTextWithSuggestions = ({\n renderMention,\n renderTag,\n ...props\n}: BaseContentTextProps) => {\n return (\n \n renderMention ? renderMention(entity, index) : \n }\n renderTag={(entity, index) =>\n renderTag ? (\n renderTag(entity, index)\n ) : (\n \n )\n }\n />\n );\n};\n","import type { ComponentProps } from \"react\";\n\nimport React from \"react\";\n\nimport { ContentTextWithSuggestions } from \"./content-text-with-suggestions\";\n\ntype ContentTitleWithSuggestionsProps = Omit<\n ComponentProps,\n \"weight\"\n>;\n\nexport const ContentTitleWithSuggestions = ({\n text,\n ellipsis,\n blur = false,\n ...rest\n}: ContentTitleWithSuggestionsProps) => {\n const normalizedEllipsis = ellipsis === undefined ? { rows: 2 } : ellipsis;\n const textProps = text === undefined ? {} : { text };\n\n return (\n \n );\n};\n"]}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/react/index.d.cts b/packages/content-suggestions/dist/react/index.d.cts
index 776f1a4..0b577b4 100644
--- a/packages/content-suggestions/dist/react/index.d.cts
+++ b/packages/content-suggestions/dist/react/index.d.cts
@@ -1,10 +1,9 @@
import React, { ComponentProps, ReactNode } from 'react';
import { EllipsisConfig } from 'antd/lib/typography/Base';
-import { M as MentionEntity, T as TagEntity, L as LinkEntity } from '../types-BRt4hd7A.cjs';
-export { B as BaseEntity, C as ContentEntity, P as ParsedMention, a as ProcessedContent } from '../types-BRt4hd7A.cjs';
+import { MentionEntity, TagEntity, LinkEntity } from '../core/index.cjs';
+export { BaseEntity, ContentEntity, ParsedMention, ProcessedContent, findAllEntities, findLinks, findMentions, findTags, mentionLinkRegexp, parseMention, processContent } from '../core/index.cjs';
import { TachTypography } from '@hublib-web/tach-typography/react';
import * as react_jsx_runtime from 'react/jsx-runtime';
-export { findAllEntities, findLinks, findMentions, findTags, mentionLinkRegexp, parseMention, processContent } from '../core/index.cjs';
type CustomEllipsisConfig = ({
count: number;
@@ -41,8 +40,7 @@ type BaseContentTextProps = Omit, "renderMent
};
declare const ContentTextWithSuggestions: ({ renderMention, renderTag, ...props }: BaseContentTextProps) => react_jsx_runtime.JSX.Element;
-interface ContentTitleWithSuggestionsProps extends Omit, "weight"> {
-}
+type ContentTitleWithSuggestionsProps = Omit, "weight">;
declare const ContentTitleWithSuggestions: ({ text, ellipsis, blur, ...rest }: ContentTitleWithSuggestionsProps) => react_jsx_runtime.JSX.Element;
export { ContentText, type ContentTextProps, ContentTextWithSuggestions, ContentTitleWithSuggestions, LinkEntity, MentionEntity, TagEntity };
diff --git a/packages/content-suggestions/dist/react/index.d.ts b/packages/content-suggestions/dist/react/index.d.ts
index 9fa4ef3..da50594 100644
--- a/packages/content-suggestions/dist/react/index.d.ts
+++ b/packages/content-suggestions/dist/react/index.d.ts
@@ -1,10 +1,9 @@
import React, { ComponentProps, ReactNode } from 'react';
import { EllipsisConfig } from 'antd/lib/typography/Base';
-import { M as MentionEntity, T as TagEntity, L as LinkEntity } from '../types-BRt4hd7A.js';
-export { B as BaseEntity, C as ContentEntity, P as ParsedMention, a as ProcessedContent } from '../types-BRt4hd7A.js';
+import { MentionEntity, TagEntity, LinkEntity } from '../core/index.js';
+export { BaseEntity, ContentEntity, ParsedMention, ProcessedContent, findAllEntities, findLinks, findMentions, findTags, mentionLinkRegexp, parseMention, processContent } from '../core/index.js';
import { TachTypography } from '@hublib-web/tach-typography/react';
import * as react_jsx_runtime from 'react/jsx-runtime';
-export { findAllEntities, findLinks, findMentions, findTags, mentionLinkRegexp, parseMention, processContent } from '../core/index.js';
type CustomEllipsisConfig = ({
count: number;
@@ -41,8 +40,7 @@ type BaseContentTextProps = Omit, "renderMent
};
declare const ContentTextWithSuggestions: ({ renderMention, renderTag, ...props }: BaseContentTextProps) => react_jsx_runtime.JSX.Element;
-interface ContentTitleWithSuggestionsProps extends Omit, "weight"> {
-}
+type ContentTitleWithSuggestionsProps = Omit, "weight">;
declare const ContentTitleWithSuggestions: ({ text, ellipsis, blur, ...rest }: ContentTitleWithSuggestionsProps) => react_jsx_runtime.JSX.Element;
export { ContentText, type ContentTextProps, ContentTextWithSuggestions, ContentTitleWithSuggestions, LinkEntity, MentionEntity, TagEntity };
diff --git a/packages/content-suggestions/dist/react/index.js.map b/packages/content-suggestions/dist/react/index.js.map
index 1f7f0d2..cb9fec8 100644
--- a/packages/content-suggestions/dist/react/index.js.map
+++ b/packages/content-suggestions/dist/react/index.js.map
@@ -1 +1 @@
-{"version":3,"sources":["../../src/core/parser.ts","../../src/react/components/content-text.tsx","../../src/react/components/content-text-with-suggestions.tsx","../../src/react/components/content-title-with-suggestions.tsx"],"names":["jsx","TachTypography"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n ContentEntity,\n LinkEntity,\n MentionEntity,\n ParsedMention,\n ProcessedContent,\n TagEntity,\n} from \"./types\";\n\nexport const mentionLinkRegexp =\n /@\\[[^\\]]+]\\([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\\)/g;\n\nexport const parseMention = (mention: string): ParsedMention | null => {\n const regex = /@\\[([^\\]]+)\\]\\(([\\w-]{36})\\)/;\n const match = mention.match(regex);\n\n if (!match) {\n return null;\n }\n\n const mentionText = match[1];\n const mentionId = match[2];\n if (!mentionText || !mentionId) {\n return null;\n }\n\n return {\n mention: `@${mentionText}`,\n id: mentionId,\n };\n};\n\nexport const findMentions = (text: string): MentionEntity[] => {\n let match: RegExpExecArray | null;\n const matches: MentionEntity[] = [];\n\n while ((match = mentionLinkRegexp.exec(text)) !== null) {\n const parsed = parseMention(match[0]);\n const baseMention: Omit = {\n start: match.index,\n end: mentionLinkRegexp.lastIndex,\n text: match[0],\n type: \"mention\",\n displayText: parsed?.mention ?? match[0],\n };\n\n matches.push(parsed?.id ? { ...baseMention, userId: parsed.id } : baseMention);\n }\n\n return matches;\n};\n\nexport const findTags = (content: string): TagEntity[] => {\n const regex = /#[^\\s]{1,201}/g;\n const results: TagEntity[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(content)) !== null) {\n const value = match[0];\n results.push({\n start: match.index,\n end: match.index + value.length,\n text: value,\n type: \"tag\",\n tag: value.replace(\"#\", \"\"),\n });\n }\n\n return results;\n};\n\nexport const findLinks = (content: string): LinkEntity[] => {\n const regex =\n /\\b((https?:\\/\\/)?(?:[\\w-]+\\.)+[a-z]{2,}(\\/[\\w\\-._~:/?#[\\]@!$&'()*+,;=]*)?)/gi;\n const results: LinkEntity[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(content)) !== null) {\n const rawUrl = match[0];\n const hasProtocol = /^https?:\\/\\//i.test(rawUrl);\n const fullUrl = hasProtocol ? rawUrl : `https://${rawUrl}`;\n\n results.push({\n start: match.index,\n end: match.index + rawUrl.length,\n text: rawUrl,\n url: fullUrl,\n type: \"link\",\n });\n }\n\n return results;\n};\n\nexport const findAllEntities = (content: string): ContentEntity[] => {\n const mentions = findMentions(content);\n const tags = findTags(content);\n const links = findLinks(content);\n\n return [...mentions, ...tags, ...links].sort((a, b) => a.start - b.start);\n};\n\nexport const processContent = (content: string): ProcessedContent => {\n const processedText = content.replace(mentionLinkRegexp, match => {\n const parsed = parseMention(match);\n return parsed ? parsed.mention : match;\n });\n\n const tags = findTags(content).map(tag => tag.tag);\n\n return {\n processedText,\n tags,\n };\n};\n","import type { ComponentProps, CSSProperties, ReactNode } from \"react\";\nimport type { EllipsisConfig } from \"antd/lib/typography/Base\";\nimport type {\n ContentEntity,\n LinkEntity,\n MentionEntity,\n TagEntity,\n} from \"../../core\";\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { TachTypography } from \"@hublib-web/tach-typography/react\";\nimport { findAllEntities } from \"../../core\";\n\ntype CustomEllipsisConfig =\n | ({\n count: number;\n rows?: never;\n expandable?: boolean;\n } & Partial)\n | ({\n rows: number;\n count?: never;\n expandable?: boolean;\n } & Partial)\n | false;\n\ntype ParagraphBodyProps = ComponentProps;\ntype TextBodyProps = ComponentProps;\ntype TitleBodyProps = ComponentProps;\n\nconst joinClassName = (...values: Array) =>\n values.filter(Boolean).join(\" \");\n\nconst baseSelectableStyle: CSSProperties = {\n whiteSpace: \"pre-wrap\",\n WebkitTouchCallout: \"default\",\n WebkitUserSelect: \"text\",\n KhtmlUserSelect: \"text\",\n MozUserSelect: \"text\",\n msUserSelect: \"text\",\n userSelect: \"text\",\n};\n\nconst blurStyle: CSSProperties = {\n filter: \"blur(3px)\",\n WebkitUserSelect: \"none\",\n KhtmlUserSelect: \"none\",\n MozUserSelect: \"none\",\n msUserSelect: \"none\",\n userSelect: \"none\",\n pointerEvents: \"none\",\n};\n\nconst ReadMoreButton: React.FC<{\n onClick: (event: React.MouseEvent) => void;\n symbol?: EllipsisConfig[\"symbol\"];\n expanded?: boolean;\n TitleComponent: React.ComponentType;\n}> = ({ onClick, symbol = \"Читать полностью\", expanded = false, TitleComponent }) => (\n {\n event.preventDefault();\n event.stopPropagation();\n onClick(event);\n }}\n weight=\"bold\"\n level={5}\n >\n {typeof symbol === \"function\" ? symbol(expanded) : symbol}\n \n);\n\nexport interface ContentTextProps {\n className?: string;\n weight?: TextBodyProps[\"weight\"];\n text?: string | null;\n ellipsis?: CustomEllipsisConfig;\n blur?: boolean;\n style?: TextBodyProps[\"style\"];\n onView?: () => void;\n renderMention?: (entity: MentionEntity, index: number) => ReactNode;\n renderTag?: (entity: TagEntity, index: number) => ReactNode;\n renderLink?: (entity: LinkEntity, index: number) => ReactNode;\n ParagraphComponent?: React.ComponentType;\n TextComponent?: React.ComponentType;\n TitleComponent?: React.ComponentType;\n}\n\nexport const ContentText: React.NamedExoticComponent = React.memo(\n ({\n text,\n className,\n ellipsis = false,\n blur = false,\n weight = \"normal\",\n style,\n onView,\n renderMention,\n renderTag,\n renderLink,\n ParagraphComponent = TachTypography.Paragraph.Body,\n TextComponent = TachTypography.Text.Body,\n TitleComponent = TachTypography.Title.Body,\n ...props\n }: ContentTextProps) => {\n const containerRef = useRef(null);\n const [expanded, setExpanded] = useState(false);\n const [containerInsideView, setContainerInsideView] = useState(false);\n const [viewed, setViewed] = useState(false);\n const content = text || \"\";\n\n const entities = useMemo(() => findAllEntities(content), [content]);\n\n const wrapWithKey = (node: ReactNode, key: React.Key) => {\n if (React.isValidElement(node)) {\n return React.cloneElement(node, { key });\n }\n\n return {node};\n };\n\n const buildMentionNode = (entity: MentionEntity, index: number) => {\n const defaultNode = (\n \n {entity.displayText}\n \n );\n const customNode = renderMention?.(entity, index) ?? defaultNode;\n return wrapWithKey(customNode, `mention-${entity.start}-${index}`);\n };\n\n const buildTagNode = (entity: TagEntity, index: number) => {\n const defaultNode = (\n \n {entity.text}\n \n );\n const customNode = renderTag?.(entity, index) ?? defaultNode;\n return wrapWithKey(customNode, `tag-${entity.start}-${index}`);\n };\n\n const buildLinkNode = (entity: LinkEntity, index: number) => {\n const defaultNode = (\n \n {entity.text}\n \n );\n const customNode = renderLink?.(entity, index) ?? defaultNode;\n return wrapWithKey(customNode, `link-${entity.start}-${index}`);\n };\n\n const buildParts = (upto: number | null = null): ReactNode[] => {\n let lastIndex = 0;\n const nodes: ReactNode[] = [];\n\n for (const [i, entity] of entities.entries()) {\n\n if (upto !== null && entity.start >= upto) {\n break;\n }\n\n const textEnd = upto !== null ? Math.min(entity.start, upto) : entity.start;\n if (entity.start > lastIndex && lastIndex < textEnd) {\n nodes.push(content.slice(lastIndex, textEnd));\n }\n\n if (upto === null || entity.end <= upto) {\n if (entity.type === \"mention\") {\n nodes.push(buildMentionNode(entity, i));\n } else if (entity.type === \"tag\") {\n nodes.push(buildTagNode(entity, i));\n } else if (entity.type === \"link\") {\n nodes.push(buildLinkNode(entity, i));\n }\n }\n\n lastIndex = entity.end;\n }\n\n if (upto === null) {\n if (lastIndex < content.length) {\n nodes.push(content.slice(lastIndex));\n }\n } else if (lastIndex < upto) {\n nodes.push(content.slice(lastIndex, upto));\n }\n\n return nodes;\n };\n\n const ellipsisConfig = ellipsis && typeof ellipsis === \"object\" ? ellipsis : null;\n const expandedFromProps =\n ellipsisConfig && typeof ellipsisConfig.expanded === \"boolean\"\n ? ellipsisConfig.expanded\n : undefined;\n const isExpandedControlled = expandedFromProps !== undefined;\n const mergedExpanded = isExpandedControlled ? expandedFromProps : expanded;\n\n const handleExpand = useCallback(\n (event: React.MouseEvent) => {\n if (!isExpandedControlled) {\n setExpanded(true);\n }\n\n ellipsisConfig?.onExpand?.(event, { expanded: true });\n },\n [ellipsisConfig, isExpandedControlled],\n );\n\n useEffect(() => {\n if (isExpandedControlled) {\n return;\n }\n\n if (ellipsisConfig && \"count\" in ellipsisConfig) {\n const count = ellipsisConfig.count ?? 0;\n if (content.length <= count && !expanded) {\n setExpanded(true);\n }\n }\n }, [content.length, ellipsisConfig, expanded, isExpandedControlled]);\n\n useEffect(() => {\n if (mergedExpanded && !viewed && containerInsideView) {\n setViewed(true);\n onView?.();\n }\n }, [mergedExpanded, viewed, containerInsideView, onView]);\n\n useEffect(() => {\n const ref = containerRef.current;\n if (!ref) {\n return;\n }\n\n const observer = new IntersectionObserver((entries) => {\n const entry = entries[0];\n if (!entry) {\n return;\n }\n\n if (entry.isIntersecting && !containerInsideView) {\n setContainerInsideView(true);\n }\n }, { threshold: 0.5 });\n\n observer.observe(ref);\n\n return () => {\n observer.unobserve(ref);\n };\n }, [containerInsideView]);\n\n const mergedStyle: CSSProperties = {\n ...baseSelectableStyle,\n ...(blur ? blurStyle : undefined),\n ...(style as CSSProperties | undefined),\n };\n\n if (ellipsisConfig && \"count\" in ellipsisConfig) {\n const { count, expandable } = ellipsisConfig;\n\n if (!mergedExpanded && count && content.length > count) {\n let cutoff = count;\n let extended = true;\n\n while (extended) {\n extended = false;\n for (const entity of entities) {\n if (entity.start < cutoff && entity.end > cutoff) {\n cutoff = entity.end;\n extended = true;\n }\n }\n }\n\n const truncatedNodes = buildParts(cutoff);\n\n return (\n \n {truncatedNodes}…\n {expandable && (\n \n )}\n \n );\n }\n }\n\n if (ellipsisConfig && \"rows\" in ellipsisConfig) {\n const paragraphEllipsis = mergedExpanded\n ? false\n : {\n ...ellipsisConfig,\n symbol: ellipsisConfig.expandable ? (\n \n ) : (\n ellipsisConfig.symbol\n ),\n };\n\n return (\n \n {buildParts()}\n \n );\n }\n\n return (\n \n {buildParts()}\n \n );\n },\n);\n\nContentText.displayName = \"ContentText\";\n","import type { ComponentProps } from \"react\";\nimport type { MentionEntity, TagEntity } from \"../../core\";\n\nimport React from \"react\";\n\nimport { TachTypography } from \"@hublib-web/tach-typography/react\";\nimport { ContentText } from \"./content-text\";\n\ntype BaseContentTextProps = Omit<\n ComponentProps,\n \"renderMention\" | \"renderTag\"\n> & {\n renderMention?: (entity: MentionEntity, index: number) => React.ReactNode;\n renderTag?: (entity: TagEntity, index: number) => React.ReactNode;\n};\n\nconst DefaultMention = ({ entity }: { entity: MentionEntity }) => (\n {entity.displayText}\n);\n\nconst DefaultTag = ({ entity }: { entity: TagEntity }) => (\n \n {entity.text}\n \n);\n\nexport const ContentTextWithSuggestions = ({\n renderMention,\n renderTag,\n ...props\n}: BaseContentTextProps) => {\n return (\n \n renderMention ? renderMention(entity, index) : \n }\n renderTag={(entity, index) =>\n renderTag ? (\n renderTag(entity, index)\n ) : (\n \n )\n }\n />\n );\n};\n","import type { ComponentProps } from \"react\";\n\nimport React from \"react\";\n\nimport { ContentTextWithSuggestions } from \"./content-text-with-suggestions\";\n\ninterface ContentTitleWithSuggestionsProps\n extends Omit, \"weight\"> {}\n\nexport const ContentTitleWithSuggestions = ({\n text,\n ellipsis,\n blur = false,\n ...rest\n}: ContentTitleWithSuggestionsProps) => {\n const normalizedEllipsis = ellipsis === undefined ? { rows: 2 } : ellipsis;\n const textProps = text === undefined ? {} : { text };\n\n return (\n \n );\n};\n"]}
\ No newline at end of file
+{"version":3,"sources":["../../src/core/parser.ts","../../src/react/components/content-text.tsx","../../src/react/components/content-text-with-suggestions.tsx","../../src/react/components/content-title-with-suggestions.tsx"],"names":["jsx","TachTypography"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n ContentEntity,\n LinkEntity,\n MentionEntity,\n ParsedMention,\n ProcessedContent,\n TagEntity,\n} from \"./types\";\n\nexport const mentionLinkRegexp =\n /@\\[[^\\]]+]\\([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\\)/g;\n\nexport const parseMention = (mention: string): ParsedMention | null => {\n const regex = /@\\[([^\\]]+)\\]\\(([\\w-]{36})\\)/;\n const match = mention.match(regex);\n\n if (!match) {\n return null;\n }\n\n const mentionText = match[1];\n const mentionId = match[2];\n if (!mentionText || !mentionId) {\n return null;\n }\n\n return {\n mention: `@${mentionText}`,\n id: mentionId,\n };\n};\n\nexport const findMentions = (text: string): MentionEntity[] => {\n let match: RegExpExecArray | null;\n const matches: MentionEntity[] = [];\n\n while ((match = mentionLinkRegexp.exec(text)) !== null) {\n const parsed = parseMention(match[0]);\n const baseMention: Omit = {\n start: match.index,\n end: mentionLinkRegexp.lastIndex,\n text: match[0],\n type: \"mention\",\n displayText: parsed?.mention ?? match[0],\n };\n\n matches.push(parsed?.id ? { ...baseMention, userId: parsed.id } : baseMention);\n }\n\n return matches;\n};\n\nexport const findTags = (content: string): TagEntity[] => {\n const regex = /#[^\\s]{1,201}/g;\n const results: TagEntity[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(content)) !== null) {\n const value = match[0];\n results.push({\n start: match.index,\n end: match.index + value.length,\n text: value,\n type: \"tag\",\n tag: value.replace(\"#\", \"\"),\n });\n }\n\n return results;\n};\n\nexport const findLinks = (content: string): LinkEntity[] => {\n const regex =\n /\\b((https?:\\/\\/)?(?:[\\w-]+\\.)+[a-z]{2,}(\\/[\\w\\-._~:/?#[\\]@!$&'()*+,;=]*)?)/gi;\n const results: LinkEntity[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(content)) !== null) {\n const rawUrl = match[0];\n const hasProtocol = /^https?:\\/\\//i.test(rawUrl);\n const fullUrl = hasProtocol ? rawUrl : `https://${rawUrl}`;\n\n results.push({\n start: match.index,\n end: match.index + rawUrl.length,\n text: rawUrl,\n url: fullUrl,\n type: \"link\",\n });\n }\n\n return results;\n};\n\nexport const findAllEntities = (content: string): ContentEntity[] => {\n const mentions = findMentions(content);\n const tags = findTags(content);\n const links = findLinks(content);\n\n return [...mentions, ...tags, ...links].sort((a, b) => a.start - b.start);\n};\n\nexport const processContent = (content: string): ProcessedContent => {\n const processedText = content.replace(mentionLinkRegexp, match => {\n const parsed = parseMention(match);\n return parsed ? parsed.mention : match;\n });\n\n const tags = findTags(content).map(tag => tag.tag);\n\n return {\n processedText,\n tags,\n };\n};\n","import type { ComponentProps, CSSProperties, ReactNode } from \"react\";\nimport type { EllipsisConfig } from \"antd/lib/typography/Base\";\nimport type {\n ContentEntity,\n LinkEntity,\n MentionEntity,\n TagEntity,\n} from \"../../core\";\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { TachTypography } from \"@hublib-web/tach-typography/react\";\nimport { findAllEntities } from \"../../core\";\n\ntype CustomEllipsisConfig =\n | ({\n count: number;\n rows?: never;\n expandable?: boolean;\n } & Partial)\n | ({\n rows: number;\n count?: never;\n expandable?: boolean;\n } & Partial)\n | false;\n\ntype ParagraphBodyProps = ComponentProps;\ntype TextBodyProps = ComponentProps;\ntype TitleBodyProps = ComponentProps;\n\nconst joinClassName = (...values: Array) =>\n values.filter(Boolean).join(\" \");\n\nconst baseSelectableStyle: CSSProperties = {\n whiteSpace: \"pre-wrap\",\n WebkitTouchCallout: \"default\",\n WebkitUserSelect: \"text\",\n KhtmlUserSelect: \"text\",\n MozUserSelect: \"text\",\n msUserSelect: \"text\",\n userSelect: \"text\",\n};\n\nconst blurStyle: CSSProperties = {\n filter: \"blur(3px)\",\n WebkitUserSelect: \"none\",\n KhtmlUserSelect: \"none\",\n MozUserSelect: \"none\",\n msUserSelect: \"none\",\n userSelect: \"none\",\n pointerEvents: \"none\",\n};\n\nconst ReadMoreButton: React.FC<{\n onClick: (event: React.MouseEvent) => void;\n symbol?: EllipsisConfig[\"symbol\"];\n expanded?: boolean;\n TitleComponent: React.ComponentType;\n}> = ({ onClick, symbol = \"Читать полностью\", expanded = false, TitleComponent }) => (\n {\n event.preventDefault();\n event.stopPropagation();\n onClick(event);\n }}\n weight=\"bold\"\n level={5}\n >\n {typeof symbol === \"function\" ? symbol(expanded) : symbol}\n \n);\n\nexport interface ContentTextProps {\n className?: string;\n weight?: TextBodyProps[\"weight\"];\n text?: string | null;\n ellipsis?: CustomEllipsisConfig;\n blur?: boolean;\n style?: TextBodyProps[\"style\"];\n onView?: () => void;\n renderMention?: (entity: MentionEntity, index: number) => ReactNode;\n renderTag?: (entity: TagEntity, index: number) => ReactNode;\n renderLink?: (entity: LinkEntity, index: number) => ReactNode;\n ParagraphComponent?: React.ComponentType;\n TextComponent?: React.ComponentType;\n TitleComponent?: React.ComponentType;\n}\n\nexport const ContentText: React.NamedExoticComponent = React.memo(\n ({\n text,\n className,\n ellipsis = false,\n blur = false,\n weight = \"normal\",\n style,\n onView,\n renderMention,\n renderTag,\n renderLink,\n ParagraphComponent = TachTypography.Paragraph.Body,\n TextComponent = TachTypography.Text.Body,\n TitleComponent = TachTypography.Title.Body,\n ...props\n }: ContentTextProps) => {\n const containerRef = useRef(null);\n const [expanded, setExpanded] = useState(false);\n const [containerInsideView, setContainerInsideView] = useState(false);\n const [viewed, setViewed] = useState(false);\n const content = text || \"\";\n\n const entities = useMemo(() => findAllEntities(content), [content]);\n\n const wrapWithKey = (node: ReactNode, key: React.Key) => {\n if (React.isValidElement(node)) {\n return React.cloneElement(node, { key });\n }\n\n return {node};\n };\n\n const buildMentionNode = (entity: MentionEntity, index: number) => {\n const defaultNode = (\n \n {entity.displayText}\n \n );\n const customNode = renderMention?.(entity, index) ?? defaultNode;\n return wrapWithKey(customNode, `mention-${entity.start}-${index}`);\n };\n\n const buildTagNode = (entity: TagEntity, index: number) => {\n const defaultNode = (\n \n {entity.text}\n \n );\n const customNode = renderTag?.(entity, index) ?? defaultNode;\n return wrapWithKey(customNode, `tag-${entity.start}-${index}`);\n };\n\n const buildLinkNode = (entity: LinkEntity, index: number) => {\n const defaultNode = (\n \n {entity.text}\n \n );\n const customNode = renderLink?.(entity, index) ?? defaultNode;\n return wrapWithKey(customNode, `link-${entity.start}-${index}`);\n };\n\n const buildParts = (upto: number | null = null): ReactNode[] => {\n let lastIndex = 0;\n const nodes: ReactNode[] = [];\n\n for (const [i, entity] of entities.entries()) {\n\n if (upto !== null && entity.start >= upto) {\n break;\n }\n\n const textEnd = upto !== null ? Math.min(entity.start, upto) : entity.start;\n if (entity.start > lastIndex && lastIndex < textEnd) {\n nodes.push(content.slice(lastIndex, textEnd));\n }\n\n if (upto === null || entity.end <= upto) {\n if (entity.type === \"mention\") {\n nodes.push(buildMentionNode(entity, i));\n } else if (entity.type === \"tag\") {\n nodes.push(buildTagNode(entity, i));\n } else if (entity.type === \"link\") {\n nodes.push(buildLinkNode(entity, i));\n }\n }\n\n lastIndex = entity.end;\n }\n\n if (upto === null) {\n if (lastIndex < content.length) {\n nodes.push(content.slice(lastIndex));\n }\n } else if (lastIndex < upto) {\n nodes.push(content.slice(lastIndex, upto));\n }\n\n return nodes;\n };\n\n const ellipsisConfig = ellipsis && typeof ellipsis === \"object\" ? ellipsis : null;\n const expandedFromProps =\n ellipsisConfig && typeof ellipsisConfig.expanded === \"boolean\"\n ? ellipsisConfig.expanded\n : undefined;\n const isExpandedControlled = expandedFromProps !== undefined;\n const mergedExpanded = isExpandedControlled ? expandedFromProps : expanded;\n\n const handleExpand = useCallback(\n (event: React.MouseEvent) => {\n if (!isExpandedControlled) {\n setExpanded(true);\n }\n\n ellipsisConfig?.onExpand?.(event, { expanded: true });\n },\n [ellipsisConfig, isExpandedControlled],\n );\n\n useEffect(() => {\n if (isExpandedControlled) {\n return;\n }\n\n if (ellipsisConfig && \"count\" in ellipsisConfig) {\n const count = ellipsisConfig.count ?? 0;\n if (content.length <= count && !expanded) {\n setExpanded(true);\n }\n }\n }, [content.length, ellipsisConfig, expanded, isExpandedControlled]);\n\n useEffect(() => {\n if (mergedExpanded && !viewed && containerInsideView) {\n setViewed(true);\n onView?.();\n }\n }, [mergedExpanded, viewed, containerInsideView, onView]);\n\n useEffect(() => {\n const ref = containerRef.current;\n if (!ref) {\n return;\n }\n\n const observer = new IntersectionObserver((entries) => {\n const entry = entries[0];\n if (!entry) {\n return;\n }\n\n if (entry.isIntersecting && !containerInsideView) {\n setContainerInsideView(true);\n }\n }, { threshold: 0.5 });\n\n observer.observe(ref);\n\n return () => {\n observer.unobserve(ref);\n };\n }, [containerInsideView]);\n\n const mergedStyle: CSSProperties = {\n ...baseSelectableStyle,\n ...(blur ? blurStyle : undefined),\n ...(style as CSSProperties | undefined),\n };\n\n if (ellipsisConfig && \"count\" in ellipsisConfig) {\n const { count, expandable } = ellipsisConfig;\n\n if (!mergedExpanded && count && content.length > count) {\n let cutoff = count;\n let extended = true;\n\n while (extended) {\n extended = false;\n for (const entity of entities) {\n if (entity.start < cutoff && entity.end > cutoff) {\n cutoff = entity.end;\n extended = true;\n }\n }\n }\n\n const truncatedNodes = buildParts(cutoff);\n\n return (\n \n {truncatedNodes}…\n {expandable && (\n \n )}\n \n );\n }\n }\n\n if (ellipsisConfig && \"rows\" in ellipsisConfig) {\n const paragraphEllipsis = mergedExpanded\n ? false\n : {\n ...ellipsisConfig,\n symbol: ellipsisConfig.expandable ? (\n \n ) : (\n ellipsisConfig.symbol\n ),\n };\n\n return (\n \n {buildParts()}\n \n );\n }\n\n return (\n \n {buildParts()}\n \n );\n },\n);\n\nContentText.displayName = \"ContentText\";\n","import type { ComponentProps } from \"react\";\nimport type { MentionEntity, TagEntity } from \"../../core\";\n\nimport React from \"react\";\n\nimport { TachTypography } from \"@hublib-web/tach-typography/react\";\nimport { ContentText } from \"./content-text\";\n\ntype BaseContentTextProps = Omit<\n ComponentProps,\n \"renderMention\" | \"renderTag\"\n> & {\n renderMention?: (entity: MentionEntity, index: number) => React.ReactNode;\n renderTag?: (entity: TagEntity, index: number) => React.ReactNode;\n};\n\nconst DefaultMention = ({ entity }: { entity: MentionEntity }) => (\n {entity.displayText}\n);\n\nconst DefaultTag = ({ entity }: { entity: TagEntity }) => (\n \n {entity.text}\n \n);\n\nexport const ContentTextWithSuggestions = ({\n renderMention,\n renderTag,\n ...props\n}: BaseContentTextProps) => {\n return (\n \n renderMention ? renderMention(entity, index) : \n }\n renderTag={(entity, index) =>\n renderTag ? (\n renderTag(entity, index)\n ) : (\n \n )\n }\n />\n );\n};\n","import type { ComponentProps } from \"react\";\n\nimport React from \"react\";\n\nimport { ContentTextWithSuggestions } from \"./content-text-with-suggestions\";\n\ntype ContentTitleWithSuggestionsProps = Omit<\n ComponentProps,\n \"weight\"\n>;\n\nexport const ContentTitleWithSuggestions = ({\n text,\n ellipsis,\n blur = false,\n ...rest\n}: ContentTitleWithSuggestionsProps) => {\n const normalizedEllipsis = ellipsis === undefined ? { rows: 2 } : ellipsis;\n const textProps = text === undefined ? {} : { text };\n\n return (\n \n );\n};\n"]}
\ No newline at end of file
diff --git a/packages/content-suggestions/dist/types-BRt4hd7A.d.cts b/packages/content-suggestions/dist/types-BRt4hd7A.d.cts
deleted file mode 100644
index 3c40b78..0000000
--- a/packages/content-suggestions/dist/types-BRt4hd7A.d.cts
+++ /dev/null
@@ -1,29 +0,0 @@
-interface BaseEntity {
- start: number;
- end: number;
- text: string;
-}
-interface MentionEntity extends BaseEntity {
- type: "mention";
- displayText: string;
- userId?: string;
-}
-interface TagEntity extends BaseEntity {
- type: "tag";
- tag: string;
-}
-interface LinkEntity extends BaseEntity {
- type: "link";
- url: string;
-}
-type ContentEntity = MentionEntity | TagEntity | LinkEntity;
-interface ParsedMention {
- mention: string;
- id: string;
-}
-interface ProcessedContent {
- processedText: string;
- tags: string[];
-}
-
-export type { BaseEntity as B, ContentEntity as C, LinkEntity as L, MentionEntity as M, ParsedMention as P, TagEntity as T, ProcessedContent as a };
diff --git a/packages/content-suggestions/dist/types-BRt4hd7A.d.ts b/packages/content-suggestions/dist/types-BRt4hd7A.d.ts
deleted file mode 100644
index 3c40b78..0000000
--- a/packages/content-suggestions/dist/types-BRt4hd7A.d.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-interface BaseEntity {
- start: number;
- end: number;
- text: string;
-}
-interface MentionEntity extends BaseEntity {
- type: "mention";
- displayText: string;
- userId?: string;
-}
-interface TagEntity extends BaseEntity {
- type: "tag";
- tag: string;
-}
-interface LinkEntity extends BaseEntity {
- type: "link";
- url: string;
-}
-type ContentEntity = MentionEntity | TagEntity | LinkEntity;
-interface ParsedMention {
- mention: string;
- id: string;
-}
-interface ProcessedContent {
- processedText: string;
- tags: string[];
-}
-
-export type { BaseEntity as B, ContentEntity as C, LinkEntity as L, MentionEntity as M, ParsedMention as P, TagEntity as T, ProcessedContent as a };
diff --git a/packages/content-suggestions/package.json b/packages/content-suggestions/package.json
index c099884..f6a2c20 100644
--- a/packages/content-suggestions/package.json
+++ b/packages/content-suggestions/package.json
@@ -1,6 +1,6 @@
{
"name": "@hublib-web/content-suggestions",
- "version": "0.1.2",
+ "version": "0.2.0",
"description": "Content text/title with mentions, tags and links for React and Angular",
"license": "MIT",
"type": "module",
@@ -43,12 +43,12 @@
},
"./angular": {
"types": "./dist/angular/index.d.ts",
- "import": "./dist/angular/index.js",
- "require": "./dist/angular/index.cjs"
+ "import": "./dist/angular/index.js"
}
},
"scripts": {
- "build": "yarn clean && tsup",
+ "build": "yarn clean && tsup && yarn build:angular",
+ "build:angular": "ngc -p tsconfig.angular.json && node ./scripts/fix-angular-entry.mjs",
"clean": "rm -rf dist storybook-static",
"typecheck": "tsc -p tsconfig.json --noEmit",
"test": "vitest run --passWithNoTests",
@@ -59,7 +59,7 @@
"peerDependencies": {
"@angular/common": ">=17.0.0",
"@angular/core": ">=17.0.0",
- "@hublib-web/tach-typography": ">=0.1.0",
+ "@hublib-web/tach-typography": "0.3.0",
"antd": ">=5.0.0",
"react": ">=18.0.0",
"react-dom": ">=18.0.0",
@@ -87,8 +87,10 @@
},
"devDependencies": {
"@angular/common": "^20.3.17",
+ "@angular/compiler": "^20.3.17",
+ "@angular/compiler-cli": "^20.3.17",
"@angular/core": "^20.3.17",
- "@hublib-web/tach-typography": "workspace:*",
+ "@hublib-web/tach-typography": "workspace:0.3.0",
"@storybook/addon-essentials": "8.6.14",
"@storybook/react": "8.6.14",
"@storybook/react-vite": "8.6.14",
diff --git a/packages/content-suggestions/scripts/fix-angular-entry.mjs b/packages/content-suggestions/scripts/fix-angular-entry.mjs
new file mode 100644
index 0000000..1aff891
--- /dev/null
+++ b/packages/content-suggestions/scripts/fix-angular-entry.mjs
@@ -0,0 +1,12 @@
+import { access, writeFile } from "node:fs/promises";
+import path from "node:path";
+
+const distAngularDir = path.resolve("dist/angular");
+await access(path.join(distAngularDir, "angular/index.js"));
+await access(path.join(distAngularDir, "angular/index.d.ts"));
+
+await writeFile(
+ path.join(distAngularDir, "index.js"),
+ 'export * from "./angular/index.js";\n',
+);
+await writeFile(path.join(distAngularDir, "index.d.ts"), 'export * from "./angular/index";\n');
diff --git a/packages/content-suggestions/src/angular/content-text-with-suggestions.component.ts b/packages/content-suggestions/src/angular/content-text-with-suggestions.component.ts
new file mode 100644
index 0000000..5b0464f
--- /dev/null
+++ b/packages/content-suggestions/src/angular/content-text-with-suggestions.component.ts
@@ -0,0 +1,50 @@
+import type {
+ AngularContentEllipsisConfig,
+ AngularLinkRenderer,
+ AngularMentionRenderer,
+ AngularTagRenderer,
+} from "./types";
+
+import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from "@angular/core";
+
+import type { TypographyWeight } from "@hublib-web/tach-typography/core";
+
+import { ContentTextComponent } from "./content-text.component";
+
+@Component({
+ selector: "content-text-with-suggestions",
+ standalone: true,
+ imports: [ContentTextComponent],
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ template: `
+
+ `,
+})
+export class ContentTextWithSuggestionsComponent {
+ @Input() className: string | undefined;
+ @Input() weight: TypographyWeight = "normal";
+ @Input() text: string | null | undefined;
+ @Input() ellipsis: AngularContentEllipsisConfig = false;
+ @Input() blur = false;
+ @Input() style: Record | null | undefined;
+ @Input() onView: (() => void) | undefined;
+ @Input() renderMention: AngularMentionRenderer | undefined;
+ @Input() renderTag: AngularTagRenderer | undefined;
+ @Input() renderLink: AngularLinkRenderer | undefined;
+
+ @Output() readonly viewed = new EventEmitter();
+ @Output() readonly expandedChange = new EventEmitter();
+}
diff --git a/packages/content-suggestions/src/angular/content-text.component.ts b/packages/content-suggestions/src/angular/content-text.component.ts
new file mode 100644
index 0000000..39df26c
--- /dev/null
+++ b/packages/content-suggestions/src/angular/content-text.component.ts
@@ -0,0 +1,571 @@
+import type { LinkEntity, MentionEntity, TagEntity } from "../core";
+import type {
+ AngularContentEllipsisConfig,
+ AngularCountEllipsisConfig,
+ AngularLinkRenderer,
+ AngularRenderResult,
+ AngularRowsEllipsisConfig,
+ AngularTagRenderer,
+ AngularMentionRenderer,
+} from "./types";
+
+import { NgFor, NgIf, NgSwitch, NgSwitchCase, NgSwitchDefault } from "@angular/common";
+import {
+ AfterViewInit,
+ ChangeDetectionStrategy,
+ ChangeDetectorRef,
+ Component,
+ ElementRef,
+ EventEmitter,
+ Input,
+ OnChanges,
+ OnDestroy,
+ Output,
+ SimpleChanges,
+ ViewChild,
+} from "@angular/core";
+
+import {
+ TachTypographyComponent,
+ type TachTypographyHostProps,
+} from "@hublib-web/tach-typography/angular";
+import type { TypographyWeight } from "@hublib-web/tach-typography/core";
+
+import { findAllEntities } from "../core";
+import { ContentSuggestionsRenderResultDirective } from "./render-result.directive";
+
+const READ_MORE_TEXT = "Читать полностью";
+const BODY_DATA_ATTR = "data-content-suggestions-body";
+
+const BASE_SELECTABLE_STYLE: Record = {
+ whiteSpace: "pre-wrap",
+ WebkitTouchCallout: "default",
+ WebkitUserSelect: "text",
+ KhtmlUserSelect: "text",
+ MozUserSelect: "text",
+ msUserSelect: "text",
+ userSelect: "text",
+};
+
+const BLUR_STYLE: Record = {
+ filter: "blur(3px)",
+ WebkitUserSelect: "none",
+ KhtmlUserSelect: "none",
+ MozUserSelect: "none",
+ msUserSelect: "none",
+ userSelect: "none",
+ pointerEvents: "none",
+};
+
+type TextPart = {
+ kind: "text";
+ key: string;
+ text: string;
+};
+
+type MentionPart = {
+ kind: "mention";
+ key: string;
+ entity: MentionEntity;
+ index: number;
+ customRender: AngularRenderResult | null;
+};
+
+type TagPart = {
+ kind: "tag";
+ key: string;
+ entity: TagEntity;
+ index: number;
+ customRender: AngularRenderResult | null;
+};
+
+type LinkPart = {
+ kind: "link";
+ key: string;
+ entity: LinkEntity;
+ index: number;
+ customRender: AngularRenderResult | null;
+};
+
+type ContentPart = TextPart | MentionPart | TagPart | LinkPart;
+
+@Component({
+ selector: "content-text",
+ standalone: true,
+ imports: [
+ NgFor,
+ NgIf,
+ NgSwitch,
+ NgSwitchCase,
+ NgSwitchDefault,
+ TachTypographyComponent,
+ ContentSuggestionsRenderResultDirective,
+ ],
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ template: `
+
+
+
+
+ {{ part.text }}
+
+
+
+
+
+
+
+ {{ part.entity.displayText }}
+
+
+
+
+
+
+
+
+
+
+ {{ part.entity.text }}
+
+
+
+
+
+
+
+
+
+
+ {{ part.entity.text }}
+
+
+
+
+
+
+
+
+ …
+
+
+
+
+
+
+ `,
+})
+export class ContentTextComponent implements OnChanges, AfterViewInit, OnDestroy {
+ @Input() className: string | undefined;
+ @Input() weight: TypographyWeight = "normal";
+ @Input() text: string | null | undefined;
+ @Input() ellipsis: AngularContentEllipsisConfig = false;
+ @Input() blur = false;
+ @Input() style: Record | null | undefined;
+ @Input() onView: (() => void) | undefined;
+ @Input() renderMention: AngularMentionRenderer | undefined;
+ @Input() renderTag: AngularTagRenderer | undefined;
+ @Input() renderLink: AngularLinkRenderer | undefined;
+
+ @Output() readonly viewed = new EventEmitter();
+ @Output() readonly expandedChange = new EventEmitter();
+
+ @ViewChild("container", { static: true })
+ private readonly containerRef!: ElementRef;
+
+ visibleParts: ContentPart[] = [];
+ mergedStyle: Record = { ...BASE_SELECTABLE_STYLE };
+ rowsEllipsis: { rows: number } | undefined;
+ showTrailingEllipsis = false;
+ showInlineReadMore = false;
+ showBlockReadMore = false;
+ readMoreLabel = READ_MORE_TEXT;
+ paragraphHostProps: TachTypographyHostProps = { [BODY_DATA_ATTR]: "true" };
+
+ private expanded = false;
+ private mergedExpanded = false;
+ private isExpandedControlled = false;
+ private isInsideView = false;
+ private viewedFired = false;
+ private pendingRowsOverflowCheck = false;
+ private intersectionObserver: IntersectionObserver | null = null;
+
+ constructor(
+ private readonly cdr: ChangeDetectorRef,
+ ) {}
+
+ ngOnChanges(_changes: SimpleChanges): void {
+ this.recomputeContent();
+ }
+
+ ngAfterViewInit(): void {
+ this.initObserver();
+ this.scheduleRowsOverflowCheck();
+ }
+
+ ngOnDestroy(): void {
+ if (this.intersectionObserver) {
+ this.intersectionObserver.disconnect();
+ this.intersectionObserver = null;
+ }
+ }
+
+ trackByKey(_index: number, part: ContentPart): string {
+ return part.key;
+ }
+
+ buildDefaultLinkHostProps(url: string): TachTypographyHostProps {
+ return {
+ href: url,
+ target: "_blank",
+ referrerPolicy: "no-referrer",
+ };
+ }
+
+ handleExpand(event: MouseEvent): void {
+ event.preventDefault();
+ event.stopPropagation();
+
+ if (!this.isExpandedControlled) {
+ this.expanded = true;
+ }
+
+ this.notifyExpand(event, true);
+ this.recomputeContent();
+ }
+
+ private recomputeContent(): void {
+ const content = this.text ?? "";
+ const entities = findAllEntities(content);
+ const ellipsisConfig = this.resolveEllipsisConfig();
+
+ this.isExpandedControlled = Boolean(
+ ellipsisConfig && typeof ellipsisConfig.expanded === "boolean",
+ );
+
+ if (!this.isExpandedControlled && this.isCountConfig(ellipsisConfig)) {
+ const count = ellipsisConfig.count ?? 0;
+ if (content.length <= count && !this.expanded) {
+ this.expanded = true;
+ }
+ }
+
+ this.mergedExpanded = this.getMergedExpanded(ellipsisConfig, content);
+ this.readMoreLabel = this.resolveEllipsisSymbol(
+ ellipsisConfig?.symbol,
+ this.mergedExpanded,
+ );
+
+ this.mergedStyle = {
+ ...BASE_SELECTABLE_STYLE,
+ ...(this.blur ? BLUR_STYLE : {}),
+ ...(this.style ?? {}),
+ };
+
+ this.visibleParts = this.buildParts(content, entities, null);
+ this.rowsEllipsis = undefined;
+ this.showTrailingEllipsis = false;
+ this.showInlineReadMore = false;
+ this.showBlockReadMore = false;
+ this.pendingRowsOverflowCheck = false;
+
+ if (this.isCountConfig(ellipsisConfig)) {
+ const count = ellipsisConfig.count ?? 0;
+ const shouldTruncate = !this.mergedExpanded && count > 0 && content.length > count;
+
+ if (shouldTruncate) {
+ const cutoff = this.computeEntitySafeCutoff(count, entities);
+ this.visibleParts = this.buildParts(content, entities, cutoff);
+ this.showTrailingEllipsis = true;
+ this.showInlineReadMore = Boolean(ellipsisConfig.expandable);
+ }
+ } else if (this.isRowsConfig(ellipsisConfig) && !this.mergedExpanded) {
+ this.rowsEllipsis = {
+ rows: ellipsisConfig.rows,
+ };
+
+ if (ellipsisConfig.expandable) {
+ this.pendingRowsOverflowCheck = true;
+ }
+ }
+
+ this.emitViewIfNeeded();
+ this.scheduleRowsOverflowCheck();
+ this.cdr.markForCheck();
+ }
+
+ private buildParts(
+ content: string,
+ entities: ReturnType,
+ upto: number | null,
+ ): ContentPart[] {
+ const parts: ContentPart[] = [];
+ let lastIndex = 0;
+
+ for (const [index, entity] of entities.entries()) {
+ if (upto !== null && entity.start >= upto) {
+ break;
+ }
+
+ const textEnd = upto !== null ? Math.min(entity.start, upto) : entity.start;
+ if (entity.start > lastIndex && lastIndex < textEnd) {
+ parts.push({
+ kind: "text",
+ key: `text-${lastIndex}-${textEnd}`,
+ text: content.slice(lastIndex, textEnd),
+ });
+ }
+
+ if (upto === null || entity.end <= upto) {
+ if (entity.type === "mention") {
+ parts.push({
+ kind: "mention",
+ key: `mention-${entity.start}-${index}`,
+ entity,
+ index,
+ customRender: this.resolveCustomRender(this.renderMention, entity, index),
+ });
+ } else if (entity.type === "tag") {
+ parts.push({
+ kind: "tag",
+ key: `tag-${entity.start}-${index}`,
+ entity,
+ index,
+ customRender: this.resolveCustomRender(this.renderTag, entity, index),
+ });
+ } else {
+ parts.push({
+ kind: "link",
+ key: `link-${entity.start}-${index}`,
+ entity,
+ index,
+ customRender: this.resolveCustomRender(this.renderLink, entity, index),
+ });
+ }
+ }
+
+ lastIndex = entity.end;
+ }
+
+ if (upto === null) {
+ if (lastIndex < content.length) {
+ parts.push({
+ kind: "text",
+ key: `text-${lastIndex}-${content.length}`,
+ text: content.slice(lastIndex),
+ });
+ }
+ } else if (lastIndex < upto) {
+ parts.push({
+ kind: "text",
+ key: `text-${lastIndex}-${upto}`,
+ text: content.slice(lastIndex, upto),
+ });
+ }
+
+ return parts;
+ }
+
+ private resolveCustomRender(
+ rendererFn: ((entity: T, index: number) => AngularRenderResult) | undefined,
+ entity: T,
+ index: number,
+ ): AngularRenderResult | null {
+ const rendered = rendererFn?.(entity, index);
+ return rendered ?? null;
+ }
+
+ private resolveEllipsisConfig(): AngularCountEllipsisConfig | AngularRowsEllipsisConfig | null {
+ if (!this.ellipsis || typeof this.ellipsis !== "object") {
+ return null;
+ }
+
+ return this.ellipsis;
+ }
+
+ private isCountConfig(
+ config: AngularCountEllipsisConfig | AngularRowsEllipsisConfig | null,
+ ): config is AngularCountEllipsisConfig {
+ return Boolean(config && "count" in config);
+ }
+
+ private isRowsConfig(
+ config: AngularCountEllipsisConfig | AngularRowsEllipsisConfig | null,
+ ): config is AngularRowsEllipsisConfig {
+ return Boolean(config && "rows" in config);
+ }
+
+ private getMergedExpanded(
+ config: AngularCountEllipsisConfig | AngularRowsEllipsisConfig | null,
+ text: string,
+ ): boolean {
+ const controlledExpanded =
+ config && typeof config.expanded === "boolean"
+ ? config.expanded
+ : undefined;
+
+ if (controlledExpanded !== undefined) {
+ return controlledExpanded;
+ }
+
+ if (this.isCountConfig(config)) {
+ const count = config.count ?? 0;
+ if (count <= 0 || text.length <= count) {
+ return true;
+ }
+ }
+
+ return this.expanded;
+ }
+
+ private resolveEllipsisSymbol(
+ symbol: AngularCountEllipsisConfig["symbol"] | AngularRowsEllipsisConfig["symbol"],
+ expanded: boolean,
+ ): string {
+ if (typeof symbol === "function") {
+ return symbol(expanded);
+ }
+
+ return symbol ?? READ_MORE_TEXT;
+ }
+
+ private notifyExpand(event: MouseEvent, expanded: boolean): void {
+ const config = this.resolveEllipsisConfig();
+ const onExpand = config?.onExpand;
+
+ if (onExpand) {
+ if (onExpand.length >= 2) {
+ (onExpand as (e: MouseEvent, info: { expanded: boolean }) => void)(event, { expanded });
+ } else {
+ (onExpand as (nextExpanded: boolean) => void)(expanded);
+ }
+ }
+
+ this.expandedChange.emit(expanded);
+ }
+
+ private computeEntitySafeCutoff(
+ count: number,
+ entities: ReturnType,
+ ): number {
+ let cutoff = count;
+ let extended = true;
+
+ while (extended) {
+ extended = false;
+
+ for (const entity of entities) {
+ if (entity.start < cutoff && entity.end > cutoff) {
+ cutoff = entity.end;
+ extended = true;
+ }
+ }
+ }
+
+ return cutoff;
+ }
+
+ private initObserver(): void {
+ const host = this.containerRef?.nativeElement;
+ if (!host) {
+ return;
+ }
+
+ if (typeof IntersectionObserver === "undefined") {
+ this.isInsideView = true;
+ this.emitViewIfNeeded();
+ return;
+ }
+
+ this.intersectionObserver = new IntersectionObserver(
+ entries => {
+ const entry = entries[0];
+ if (!entry) {
+ return;
+ }
+
+ if (entry.isIntersecting && !this.isInsideView) {
+ this.isInsideView = true;
+ this.emitViewIfNeeded();
+ }
+ },
+ { threshold: 0.5 },
+ );
+
+ this.intersectionObserver.observe(host);
+ }
+
+ private emitViewIfNeeded(): void {
+ if (!this.mergedExpanded || this.viewedFired || !this.isInsideView) {
+ return;
+ }
+
+ this.viewedFired = true;
+ this.onView?.();
+ this.viewed.emit();
+ }
+
+ private scheduleRowsOverflowCheck(): void {
+ if (!this.pendingRowsOverflowCheck) {
+ return;
+ }
+
+ queueMicrotask(() => {
+ this.refreshRowsOverflow();
+ });
+ }
+
+ private refreshRowsOverflow(): void {
+ const paragraph = this.getParagraphElement();
+ if (!paragraph) {
+ return;
+ }
+
+ const hasOverflow = paragraph.scrollHeight - paragraph.clientHeight > 1;
+ if (this.showBlockReadMore !== hasOverflow) {
+ this.showBlockReadMore = hasOverflow;
+ this.cdr.markForCheck();
+ }
+ }
+
+ private getParagraphElement(): HTMLElement | null {
+ const host = this.containerRef?.nativeElement;
+ if (!host) {
+ return null;
+ }
+
+ return host.querySelector(`[${BODY_DATA_ATTR}="true"]`);
+ }
+}
diff --git a/packages/content-suggestions/src/angular/content-title-with-suggestions.component.ts b/packages/content-suggestions/src/angular/content-title-with-suggestions.component.ts
new file mode 100644
index 0000000..4bf3670
--- /dev/null
+++ b/packages/content-suggestions/src/angular/content-title-with-suggestions.component.ts
@@ -0,0 +1,56 @@
+import type {
+ AngularContentEllipsisConfig,
+ AngularLinkRenderer,
+ AngularMentionRenderer,
+ AngularRowsEllipsisConfig,
+ AngularTagRenderer,
+} from "./types";
+
+import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from "@angular/core";
+
+import { ContentTextWithSuggestionsComponent } from "./content-text-with-suggestions.component";
+
+@Component({
+ selector: "content-title-with-suggestions",
+ standalone: true,
+ imports: [ContentTextWithSuggestionsComponent],
+ changeDetection: ChangeDetectionStrategy.OnPush,
+ template: `
+
+ `,
+})
+export class ContentTitleWithSuggestionsComponent {
+ @Input() className: string | undefined;
+ @Input() text: string | null | undefined;
+ @Input() ellipsis: AngularContentEllipsisConfig | undefined;
+ @Input() blur = false;
+ @Input() style: Record | null | undefined;
+ @Input() onView: (() => void) | undefined;
+ @Input() renderMention: AngularMentionRenderer | undefined;
+ @Input() renderTag: AngularTagRenderer | undefined;
+ @Input() renderLink: AngularLinkRenderer | undefined;
+
+ @Output() readonly viewed = new EventEmitter();
+ @Output() readonly expandedChange = new EventEmitter();
+
+ get normalizedEllipsis(): AngularContentEllipsisConfig {
+ if (this.ellipsis !== undefined) {
+ return this.ellipsis;
+ }
+
+ return { rows: 2 } satisfies AngularRowsEllipsisConfig;
+ }
+}
diff --git a/packages/content-suggestions/src/angular/index.ts b/packages/content-suggestions/src/angular/index.ts
index 59692bb..96bf50b 100644
--- a/packages/content-suggestions/src/angular/index.ts
+++ b/packages/content-suggestions/src/angular/index.ts
@@ -1,650 +1,57 @@
-import type { ContentEntity, LinkEntity, MentionEntity, TagEntity } from "../core";
+import { NgModule } from "@angular/core";
-import { findAllEntities } from "../core";
+import { ContentTextComponent } from "./content-text.component";
+import { ContentTextWithSuggestionsComponent } from "./content-text-with-suggestions.component";
+import { ContentTitleWithSuggestionsComponent } from "./content-title-with-suggestions.component";
+import { ContentSuggestionsRenderResultDirective } from "./render-result.directive";
-export interface AngularTextToken {
- kind: "text";
- text: string;
- start: number;
- end: number;
-}
-
-export interface AngularMentionToken {
- kind: "mention";
- entity: MentionEntity;
-}
-
-export interface AngularTagToken {
- kind: "tag";
- entity: TagEntity;
-}
-
-export interface AngularLinkToken {
- kind: "link";
- entity: LinkEntity;
-}
-
-export type AngularContentToken =
- | AngularTextToken
- | AngularMentionToken
- | AngularTagToken
- | AngularLinkToken;
-
-export interface AngularContentSnapshot {
- text: string;
- entities: ContentEntity[];
- tokens: AngularContentToken[];
-}
-
-export type AngularEllipsisSymbol = string | ((expanded: boolean) => string);
-
-export type AngularCountEllipsisConfig = {
- count: number;
- rows?: never;
- expandable?: boolean;
- expanded?: boolean;
- symbol?: AngularEllipsisSymbol;
- onExpand?: (expanded: boolean) => void;
-};
-
-export type AngularRowsEllipsisConfig = {
- rows: number;
- count?: never;
- expandable?: boolean;
- expanded?: boolean;
- symbol?: AngularEllipsisSymbol;
- onExpand?: (expanded: boolean) => void;
-};
-
-export type AngularContentEllipsisConfig =
- | AngularCountEllipsisConfig
- | AngularRowsEllipsisConfig
- | false;
-
-export type AngularRenderResult = Node | string | number | null | undefined;
-
-export type AngularMentionRenderer = (
- entity: MentionEntity,
- index: number,
-) => AngularRenderResult;
-
-export type AngularTagRenderer = (
- entity: TagEntity,
- index: number,
-) => AngularRenderResult;
-
-export type AngularLinkRenderer = (
- entity: LinkEntity,
- index: number,
-) => AngularRenderResult;
-
-export interface AngularContentTextProps {
- className?: string;
- weight?: "normal" | "bold";
- text?: string | null;
- ellipsis?: AngularContentEllipsisConfig;
- blur?: boolean;
- style?: Record | null;
- onView?: () => void;
- renderMention?: AngularMentionRenderer;
- renderTag?: AngularTagRenderer;
- renderLink?: AngularLinkRenderer;
-}
-
-export type AngularContentTextWithSuggestionsProps = Omit<
+export type {
+ AngularContentEllipsisConfig,
+ AngularContentSnapshot,
AngularContentTextProps,
- "renderMention" | "renderTag"
-> & {
- renderMention?: AngularMentionRenderer;
- renderTag?: AngularTagRenderer;
-};
-
-export type AngularContentTitleWithSuggestionsProps = Omit<
AngularContentTextWithSuggestionsProps,
- "weight"
->;
+ AngularContentTitleWithSuggestionsProps,
+ AngularContentToken,
+ AngularCountEllipsisConfig,
+ AngularEllipsisExpandHandler,
+ AngularEllipsisSymbol,
+ AngularExpandInfo,
+ AngularLinkRenderer,
+ AngularLinkToken,
+ AngularMentionRenderer,
+ AngularMentionToken,
+ AngularRenderResult,
+ AngularRowsEllipsisConfig,
+ AngularTagRenderer,
+ AngularTagToken,
+ AngularTextToken,
+} from "./types";
-export interface AngularContentTextRendererState {
- props: AngularContentTextProps;
- snapshot: AngularContentSnapshot;
- expanded: boolean;
-}
+export {
+ AngularContentSuggestionsAdapter,
+ buildAngularTagHref,
+ createAngularContentTokens,
+} from "./tokens";
-const LINK_COLOR = "#1677ff";
-const READ_MORE_TEXT = "Читать полностью";
-
-const toKebabCase = (value: string) => value.replace(/[A-Z]/g, char => `-${char.toLowerCase()}`);
-
-const applyStyleObject = (
- element: HTMLElement,
- styles?: Record | null,
-) => {
- if (!styles) {
- return;
- }
-
- for (const [key, rawValue] of Object.entries(styles)) {
- if (rawValue === null || rawValue === undefined) {
- continue;
- }
-
- const styleValue =
- typeof rawValue === "number" ? `${rawValue}px` : String(rawValue);
-
- if (key.startsWith("--")) {
- element.style.setProperty(key, styleValue);
- continue;
- }
-
- const cssKey = key.includes("-") ? key : toKebabCase(key);
- element.style.setProperty(cssKey, styleValue);
- }
+export {
+ ContentTextComponent,
+ ContentTextWithSuggestionsComponent,
+ ContentTitleWithSuggestionsComponent,
+ ContentSuggestionsRenderResultDirective,
};
-const toNode = (value: AngularRenderResult): Node | null => {
- if (value === null || value === undefined) {
- return null;
- }
-
- if (value instanceof Node) {
- return value;
- }
-
- return document.createTextNode(String(value));
-};
-
-const resolveEllipsisSymbol = (
- symbol: AngularEllipsisSymbol | undefined,
- expanded: boolean,
-): string => {
- if (typeof symbol === "function") {
- return symbol(expanded);
- }
-
- return symbol ?? READ_MORE_TEXT;
-};
-
-const buildAngularTagHref = (entity: TagEntity): string => {
- return `/search/?query=${encodeURIComponent(entity.tag.toLowerCase())}`;
-};
-
-export { buildAngularTagHref };
-
-export const createAngularContentTokens = (
- inputText: string | null | undefined,
-): AngularContentToken[] => {
- const text = inputText ?? "";
- const entities = findAllEntities(text);
-
- let cursor = 0;
- const tokens: AngularContentToken[] = [];
-
- for (const entity of entities) {
- if (entity.start > cursor) {
- tokens.push({
- kind: "text",
- text: text.slice(cursor, entity.start),
- start: cursor,
- end: entity.start,
- });
- }
-
- if (entity.type === "mention") {
- tokens.push({
- kind: "mention",
- entity,
- });
- } else if (entity.type === "tag") {
- tokens.push({
- kind: "tag",
- entity,
- });
- } else {
- tokens.push({
- kind: "link",
- entity,
- });
- }
-
- cursor = entity.end;
- }
-
- if (cursor < text.length) {
- tokens.push({
- kind: "text",
- text: text.slice(cursor),
- start: cursor,
- end: text.length,
- });
- }
-
- return tokens;
-};
-
-export class AngularContentSuggestionsAdapter {
- snapshot(inputText: string | null | undefined): AngularContentSnapshot {
- const text = inputText ?? "";
- const entities = findAllEntities(text);
- const tokens = createAngularContentTokens(text);
-
- return {
- text,
- entities,
- tokens,
- };
- }
-}
-
-export class AngularContentTextRenderer {
- private host: HTMLElement | null = null;
- private props: AngularContentTextProps = {};
- private expanded = false;
- private viewed = false;
- private hostInsideView = false;
- private observer: IntersectionObserver | null = null;
-
- attach(host: HTMLElement, props: AngularContentTextProps = {}): AngularContentTextRendererState {
- this.destroy();
-
- this.host = host;
- this.props = { ...props };
- this.expanded = false;
- this.viewed = false;
- this.hostInsideView = false;
-
- this.initObserver();
- this.render();
-
- return this.getState();
- }
-
- update(nextProps: AngularContentTextProps): AngularContentTextRendererState {
- this.props = {
- ...this.props,
- ...nextProps,
- };
-
- this.render();
-
- return this.getState();
- }
-
- destroy(): void {
- if (this.observer && this.host) {
- this.observer.unobserve(this.host);
- this.observer.disconnect();
- }
-
- this.observer = null;
-
- if (this.host) {
- this.host.innerHTML = "";
- }
-
- this.host = null;
- this.props = {};
- this.expanded = false;
- this.viewed = false;
- this.hostInsideView = false;
- }
-
- getState(): AngularContentTextRendererState {
- return {
- props: { ...this.props },
- snapshot: this.createSnapshot(),
- expanded: this.getMergedExpanded(this.resolveEllipsisConfig(), this.getText()),
- };
- }
-
- private getText(): string {
- return this.props.text ?? "";
- }
-
- private createSnapshot(): AngularContentSnapshot {
- const text = this.getText();
- const entities = findAllEntities(text);
- const tokens = createAngularContentTokens(text);
-
- return {
- text,
- entities,
- tokens,
- };
- }
-
- private resolveEllipsisConfig():
- | AngularCountEllipsisConfig
- | AngularRowsEllipsisConfig
- | null {
- const ellipsis = this.props.ellipsis;
-
- if (!ellipsis || typeof ellipsis !== "object") {
- return null;
- }
-
- return ellipsis;
- }
-
- private getMergedExpanded(
- ellipsisConfig: AngularCountEllipsisConfig | AngularRowsEllipsisConfig | null,
- text: string,
- ): boolean {
- const controlledExpanded =
- ellipsisConfig && typeof ellipsisConfig.expanded === "boolean"
- ? ellipsisConfig.expanded
- : undefined;
-
- if (controlledExpanded !== undefined) {
- return controlledExpanded;
- }
-
- if (ellipsisConfig && "count" in ellipsisConfig) {
- const count = ellipsisConfig.count ?? 0;
- if (count <= 0 || text.length <= count) {
- return true;
- }
- }
-
- return this.expanded;
- }
-
- private createDefaultMentionNode(entity: MentionEntity): Node {
- const span = document.createElement("span");
- span.style.color = LINK_COLOR;
- span.style.fontWeight = this.props.weight === "bold" ? "700" : "400";
- span.textContent = entity.displayText;
- return span;
- }
-
- private createDefaultTagNode(entity: TagEntity): Node {
- const span = document.createElement("span");
- span.style.color = LINK_COLOR;
- span.style.fontWeight = this.props.weight === "bold" ? "700" : "400";
- span.textContent = entity.text;
- return span;
- }
-
- private createDefaultLinkNode(entity: LinkEntity): Node {
- const anchor = document.createElement("a");
- anchor.href = entity.url;
- anchor.target = "_blank";
- anchor.referrerPolicy = "no-referrer";
- anchor.style.color = LINK_COLOR;
- anchor.style.fontWeight = this.props.weight === "bold" ? "700" : "400";
- anchor.textContent = entity.text;
- return anchor;
- }
-
- private renderEntity(entity: ContentEntity, index: number): Node | null {
- if (entity.type === "mention") {
- const customNode = this.props.renderMention?.(entity, index);
- return toNode(customNode) ?? this.createDefaultMentionNode(entity);
- }
-
- if (entity.type === "tag") {
- const customNode = this.props.renderTag?.(entity, index);
- return toNode(customNode) ?? this.createDefaultTagNode(entity);
- }
-
- const customNode = this.props.renderLink?.(entity, index);
- return toNode(customNode) ?? this.createDefaultLinkNode(entity);
- }
-
- private buildTextNodes(
- text: string,
- entities: ContentEntity[],
- upto: number | null = null,
- ): Node[] {
- let lastIndex = 0;
- const nodes: Node[] = [];
-
- for (const [index, entity] of entities.entries()) {
- if (upto !== null && entity.start >= upto) {
- break;
- }
-
- const textEnd = upto !== null ? Math.min(entity.start, upto) : entity.start;
- if (entity.start > lastIndex && lastIndex < textEnd) {
- nodes.push(document.createTextNode(text.slice(lastIndex, textEnd)));
- }
-
- if (upto === null || entity.end <= upto) {
- const entityNode = this.renderEntity(entity, index);
- if (entityNode) {
- nodes.push(entityNode);
- }
- }
-
- lastIndex = entity.end;
- }
-
- if (upto === null) {
- if (lastIndex < text.length) {
- nodes.push(document.createTextNode(text.slice(lastIndex)));
- }
- } else if (lastIndex < upto) {
- nodes.push(document.createTextNode(text.slice(lastIndex, upto)));
- }
-
- return nodes;
- }
-
- private applyBaseParagraphStyle(element: HTMLElement): void {
- element.style.whiteSpace = "pre-wrap";
- element.style.fontWeight = this.props.weight === "bold" ? "700" : "400";
- element.style.setProperty("-webkit-touch-callout", "default");
- element.style.setProperty("-webkit-user-select", "text");
- element.style.setProperty("-khtml-user-select", "text");
- element.style.setProperty("-moz-user-select", "text");
- element.style.setProperty("-ms-user-select", "text");
- element.style.setProperty("user-select", "text");
-
- if (this.props.blur) {
- element.style.filter = "blur(3px)";
- element.style.setProperty("-webkit-user-select", "none");
- element.style.setProperty("-khtml-user-select", "none");
- element.style.setProperty("-moz-user-select", "none");
- element.style.setProperty("-ms-user-select", "none");
- element.style.setProperty("user-select", "none");
- element.style.pointerEvents = "none";
- }
-
- applyStyleObject(element, this.props.style);
- }
-
- private buildReadMoreButton(symbol: AngularEllipsisSymbol | undefined): HTMLButtonElement {
- const button = document.createElement("button");
- button.type = "button";
- button.textContent = resolveEllipsisSymbol(symbol, this.expanded);
- button.style.border = "0";
- button.style.background = "none";
- button.style.padding = "0";
- button.style.marginLeft = "6px";
- button.style.cursor = "pointer";
- button.style.color = LINK_COLOR;
- button.style.fontWeight = "700";
- button.onclick = event => {
- event.preventDefault();
- event.stopPropagation();
- this.handleExpand();
- };
- return button;
- }
-
- private handleExpand(): void {
- const ellipsisConfig = this.resolveEllipsisConfig();
-
- if (!ellipsisConfig) {
- return;
- }
-
- this.expanded = true;
- ellipsisConfig.onExpand?.(true);
- this.render();
- }
-
- private computeEntitySafeCutoff(
- count: number,
- entities: ContentEntity[],
- ): number {
- let cutoff = count;
- let extended = true;
-
- while (extended) {
- extended = false;
-
- for (const entity of entities) {
- if (entity.start < cutoff && entity.end > cutoff) {
- cutoff = entity.end;
- extended = true;
- }
- }
- }
-
- return cutoff;
- }
-
- private hasVerticalOverflow(element: HTMLElement): boolean {
- return element.scrollHeight - element.clientHeight > 1;
- }
-
- private render(): void {
- if (!this.host) {
- return;
- }
-
- const text = this.getText();
- const entities = findAllEntities(text);
- const ellipsisConfig = this.resolveEllipsisConfig();
- const mergedExpanded = this.getMergedExpanded(ellipsisConfig, text);
-
- const wrapper = document.createElement("div");
- const paragraph = document.createElement("div");
-
- if (this.props.className) {
- paragraph.className = this.props.className;
- }
-
- this.applyBaseParagraphStyle(paragraph);
-
- if (ellipsisConfig && "count" in ellipsisConfig) {
- const count = ellipsisConfig.count ?? 0;
- const shouldTruncate = !mergedExpanded && count > 0 && text.length > count;
-
- if (shouldTruncate) {
- const cutoff = this.computeEntitySafeCutoff(count, entities);
- const nodes = this.buildTextNodes(text, entities, cutoff);
-
- paragraph.append(...nodes);
- paragraph.append(document.createTextNode("…"));
-
- if (ellipsisConfig.expandable) {
- paragraph.append(this.buildReadMoreButton(ellipsisConfig.symbol));
- }
- } else {
- paragraph.append(...this.buildTextNodes(text, entities));
- }
- } else {
- paragraph.append(...this.buildTextNodes(text, entities));
-
- if (ellipsisConfig && "rows" in ellipsisConfig && !mergedExpanded) {
- paragraph.style.display = "-webkit-box";
- paragraph.style.setProperty("-webkit-box-orient", "vertical");
- paragraph.style.setProperty("-webkit-line-clamp", String(ellipsisConfig.rows));
- paragraph.style.overflow = "hidden";
-
- // Важно: сначала рендерим paragraph в DOM, потом меряем реальный overflow.
- wrapper.append(paragraph);
- this.host.replaceChildren(wrapper);
-
- if (ellipsisConfig.expandable && this.hasVerticalOverflow(paragraph)) {
- wrapper.append(this.buildReadMoreButton(ellipsisConfig.symbol));
- }
-
- this.emitOnViewIfNeeded(mergedExpanded);
- return;
- }
- }
-
- wrapper.append(paragraph);
- this.host.replaceChildren(wrapper);
- this.emitOnViewIfNeeded(mergedExpanded);
- }
-
- private initObserver(): void {
- if (!this.host) {
- return;
- }
-
- if (typeof IntersectionObserver === "undefined") {
- this.hostInsideView = true;
- return;
- }
-
- this.observer = new IntersectionObserver(
- entries => {
- const entry = entries[0];
- if (!entry) {
- return;
- }
-
- if (entry.isIntersecting && !this.hostInsideView) {
- this.hostInsideView = true;
- const ellipsisConfig = this.resolveEllipsisConfig();
- const mergedExpanded = this.getMergedExpanded(ellipsisConfig, this.getText());
- this.emitOnViewIfNeeded(mergedExpanded);
- }
- },
- { threshold: 0.5 },
- );
-
- this.observer.observe(this.host);
- }
-
- private emitOnViewIfNeeded(mergedExpanded: boolean): void {
- if (!mergedExpanded || this.viewed || !this.hostInsideView) {
- return;
- }
-
- this.viewed = true;
- this.props.onView?.();
- }
-}
-
-export class AngularContentTextWithSuggestionsRenderer extends AngularContentTextRenderer {}
-
-export class AngularContentTitleWithSuggestionsRenderer {
- private readonly renderer = new AngularContentTextWithSuggestionsRenderer();
-
- attach(
- host: HTMLElement,
- props: AngularContentTitleWithSuggestionsProps = {},
- ): AngularContentTextRendererState {
- return this.renderer.attach(host, this.normalizeProps(props));
- }
-
- update(props: AngularContentTitleWithSuggestionsProps): AngularContentTextRendererState {
- return this.renderer.update(this.normalizeProps(props));
- }
-
- destroy(): void {
- this.renderer.destroy();
- }
-
- getState(): AngularContentTextRendererState {
- return this.renderer.getState();
- }
-
- private normalizeProps(
- props: AngularContentTitleWithSuggestionsProps,
- ): AngularContentTextWithSuggestionsProps {
- return {
- ...props,
- weight: "bold",
- blur: props.blur ?? false,
- ellipsis: props.ellipsis === undefined ? { rows: 2 } : props.ellipsis,
- };
- }
-}
-
-export { toKebabCase };
+@NgModule({
+ imports: [
+ ContentTextComponent,
+ ContentTextWithSuggestionsComponent,
+ ContentTitleWithSuggestionsComponent,
+ ContentSuggestionsRenderResultDirective,
+ ],
+ exports: [
+ ContentTextComponent,
+ ContentTextWithSuggestionsComponent,
+ ContentTitleWithSuggestionsComponent,
+ ContentSuggestionsRenderResultDirective,
+ ],
+})
+export class ContentSuggestionsAngularModule {}
diff --git a/packages/content-suggestions/src/angular/public-api.ts b/packages/content-suggestions/src/angular/public-api.ts
new file mode 100644
index 0000000..6d1e0ee
--- /dev/null
+++ b/packages/content-suggestions/src/angular/public-api.ts
@@ -0,0 +1 @@
+export * from "./index";
diff --git a/packages/content-suggestions/src/angular/render-result.directive.ts b/packages/content-suggestions/src/angular/render-result.directive.ts
new file mode 100644
index 0000000..adba262
--- /dev/null
+++ b/packages/content-suggestions/src/angular/render-result.directive.ts
@@ -0,0 +1,43 @@
+import type { AngularRenderResult } from "./types";
+
+import { Directive, ElementRef, Input, OnChanges, Renderer2 } from "@angular/core";
+
+@Directive({
+ selector: "[contentSuggestionsRenderResult]",
+ standalone: true,
+})
+export class ContentSuggestionsRenderResultDirective implements OnChanges {
+ @Input() contentSuggestionsRenderResult: AngularRenderResult;
+
+ constructor(
+ private readonly elementRef: ElementRef,
+ private readonly renderer: Renderer2,
+ ) {
+ this.renderer.setStyle(this.elementRef.nativeElement, "display", "contents");
+ }
+
+ ngOnChanges(): void {
+ this.clearHost();
+
+ const value = this.contentSuggestionsRenderResult;
+ if (value === null || value === undefined) {
+ return;
+ }
+
+ if (value instanceof Node) {
+ this.renderer.appendChild(this.elementRef.nativeElement, value);
+ return;
+ }
+
+ const textNode = this.renderer.createText(String(value));
+ this.renderer.appendChild(this.elementRef.nativeElement, textNode);
+ }
+
+ private clearHost(): void {
+ const host = this.elementRef.nativeElement;
+
+ while (host.firstChild) {
+ host.removeChild(host.firstChild);
+ }
+ }
+}
diff --git a/packages/content-suggestions/src/angular/tokens.ts b/packages/content-suggestions/src/angular/tokens.ts
new file mode 100644
index 0000000..0e0607e
--- /dev/null
+++ b/packages/content-suggestions/src/angular/tokens.ts
@@ -0,0 +1,83 @@
+import type {
+ AngularContentSnapshot,
+ AngularContentToken,
+ AngularLinkToken,
+ AngularMentionToken,
+ AngularTagToken,
+ AngularTextToken,
+} from "./types";
+
+import type { ContentEntity, TagEntity } from "../core";
+
+import { findAllEntities } from "../core";
+
+const mapEntityToToken = (entity: ContentEntity): AngularMentionToken | AngularTagToken | AngularLinkToken => {
+ if (entity.type === "mention") {
+ return {
+ kind: "mention",
+ entity,
+ };
+ }
+
+ if (entity.type === "tag") {
+ return {
+ kind: "tag",
+ entity,
+ };
+ }
+
+ return {
+ kind: "link",
+ entity,
+ };
+};
+
+const createTextToken = (text: string, start: number, end: number): AngularTextToken => ({
+ kind: "text",
+ text,
+ start,
+ end,
+});
+
+export const createAngularContentTokens = (
+ inputText: string | null | undefined,
+): AngularContentToken[] => {
+ const text = inputText ?? "";
+ const entities = findAllEntities(text);
+
+ let cursor = 0;
+ const tokens: AngularContentToken[] = [];
+
+ for (const entity of entities) {
+ if (entity.start > cursor) {
+ tokens.push(createTextToken(text.slice(cursor, entity.start), cursor, entity.start));
+ }
+
+ tokens.push(mapEntityToToken(entity));
+ cursor = entity.end;
+ }
+
+ if (cursor < text.length) {
+ tokens.push(createTextToken(text.slice(cursor), cursor, text.length));
+ }
+
+ return tokens;
+};
+
+export const buildAngularTagHref = (entity: TagEntity): string => {
+ return `/search/?query=${encodeURIComponent(entity.tag.toLowerCase())}`;
+};
+
+export class AngularContentSuggestionsAdapter {
+ snapshot(inputText: string | null | undefined): AngularContentSnapshot {
+ const text = inputText ?? "";
+ const entities = findAllEntities(text);
+ const tokens = createAngularContentTokens(text);
+
+ return {
+ text,
+ entities,
+ tokens,
+ };
+ }
+}
diff --git a/packages/content-suggestions/src/angular/types.ts b/packages/content-suggestions/src/angular/types.ts
new file mode 100644
index 0000000..52b7d47
--- /dev/null
+++ b/packages/content-suggestions/src/angular/types.ts
@@ -0,0 +1,113 @@
+import type { ContentEntity, LinkEntity, MentionEntity, TagEntity } from "../core";
+
+import type { TypographyWeight } from "@hublib-web/tach-typography/core";
+
+export interface AngularTextToken {
+ kind: "text";
+ text: string;
+ start: number;
+ end: number;
+}
+
+export interface AngularMentionToken {
+ kind: "mention";
+ entity: MentionEntity;
+}
+
+export interface AngularTagToken {
+ kind: "tag";
+ entity: TagEntity;
+}
+
+export interface AngularLinkToken {
+ kind: "link";
+ entity: LinkEntity;
+}
+
+export type AngularContentToken =
+ | AngularTextToken
+ | AngularMentionToken
+ | AngularTagToken
+ | AngularLinkToken;
+
+export interface AngularContentSnapshot {
+ text: string;
+ entities: ContentEntity[];
+ tokens: AngularContentToken[];
+}
+
+export interface AngularExpandInfo {
+ expanded: boolean;
+}
+
+export type AngularEllipsisSymbol = string | ((expanded: boolean) => string);
+
+export type AngularEllipsisExpandHandler =
+ | ((expanded: boolean) => void)
+ | ((event: MouseEvent, info: AngularExpandInfo) => void);
+
+export type AngularCountEllipsisConfig = {
+ count: number;
+ rows?: never;
+ expandable?: boolean;
+ expanded?: boolean;
+ symbol?: AngularEllipsisSymbol;
+ onExpand?: AngularEllipsisExpandHandler;
+};
+
+export type AngularRowsEllipsisConfig = {
+ rows: number;
+ count?: never;
+ expandable?: boolean;
+ expanded?: boolean;
+ symbol?: AngularEllipsisSymbol;
+ onExpand?: AngularEllipsisExpandHandler;
+};
+
+export type AngularContentEllipsisConfig =
+ | AngularCountEllipsisConfig
+ | AngularRowsEllipsisConfig
+ | false;
+
+export type AngularRenderResult = Node | string | number | null | undefined;
+
+export type AngularMentionRenderer = (
+ entity: MentionEntity,
+ index: number,
+) => AngularRenderResult;
+
+export type AngularTagRenderer = (
+ entity: TagEntity,
+ index: number,
+) => AngularRenderResult;
+
+export type AngularLinkRenderer = (
+ entity: LinkEntity,
+ index: number,
+) => AngularRenderResult;
+
+export interface AngularContentTextProps {
+ className?: string;
+ weight?: TypographyWeight;
+ text?: string | null;
+ ellipsis?: AngularContentEllipsisConfig;
+ blur?: boolean;
+ style?: Record | null;
+ onView?: () => void;
+ renderMention?: AngularMentionRenderer;
+ renderTag?: AngularTagRenderer;
+ renderLink?: AngularLinkRenderer;
+}
+
+export type AngularContentTextWithSuggestionsProps = Omit<
+ AngularContentTextProps,
+ "renderMention" | "renderTag"
+> & {
+ renderMention?: AngularMentionRenderer;
+ renderTag?: AngularTagRenderer;
+};
+
+export type AngularContentTitleWithSuggestionsProps = Omit<
+ AngularContentTextWithSuggestionsProps,
+ "weight"
+>;
diff --git a/packages/content-suggestions/src/react/components/content-title-with-suggestions.tsx b/packages/content-suggestions/src/react/components/content-title-with-suggestions.tsx
index 871d6a5..79411df 100644
--- a/packages/content-suggestions/src/react/components/content-title-with-suggestions.tsx
+++ b/packages/content-suggestions/src/react/components/content-title-with-suggestions.tsx
@@ -4,8 +4,10 @@ import React from "react";
import { ContentTextWithSuggestions } from "./content-text-with-suggestions";
-interface ContentTitleWithSuggestionsProps
- extends Omit, "weight"> {}
+type ContentTitleWithSuggestionsProps = Omit<
+ ComponentProps,
+ "weight"
+>;
export const ContentTitleWithSuggestions = ({
text,
diff --git a/packages/content-suggestions/tsconfig.angular.json b/packages/content-suggestions/tsconfig.angular.json
new file mode 100644
index 0000000..364197d
--- /dev/null
+++ b/packages/content-suggestions/tsconfig.angular.json
@@ -0,0 +1,20 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "rootDir": "src",
+ "outDir": "dist/angular",
+ "types": ["node"],
+ "module": "ES2022",
+ "target": "ES2022",
+ "declaration": true,
+ "declarationMap": true,
+ "sourceMap": true,
+ "importHelpers": true
+ },
+ "angularCompilerOptions": {
+ "compilationMode": "partial"
+ },
+ "files": ["src/angular/public-api.ts"],
+ "include": ["src/angular/**/*.ts", "src/core/**/*.ts"],
+ "exclude": ["dist", "src/**/*.test.ts", "src/react", "src/stories"]
+}
diff --git a/packages/content-suggestions/tsup.config.ts b/packages/content-suggestions/tsup.config.ts
index 8d92af3..bfa65b0 100644
--- a/packages/content-suggestions/tsup.config.ts
+++ b/packages/content-suggestions/tsup.config.ts
@@ -4,7 +4,6 @@ export default defineConfig({
entry: {
"core/index": "src/core/index.ts",
"react/index": "src/react/index.tsx",
- "angular/index": "src/angular/index.ts",
},
format: ["esm", "cjs"],
dts: true,
@@ -21,5 +20,6 @@ export default defineConfig({
"@angular/core",
"@angular/common",
"@hublib-web/tach-typography/react",
+ "@hublib-web/tach-typography/angular",
],
});
diff --git a/yarn.lock b/yarn.lock
index 74569f7..420a94b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -987,8 +987,10 @@ __metadata:
resolution: "@hublib-web/content-suggestions@workspace:packages/content-suggestions"
dependencies:
"@angular/common": "npm:^20.3.17"
+ "@angular/compiler": "npm:^20.3.17"
+ "@angular/compiler-cli": "npm:^20.3.17"
"@angular/core": "npm:^20.3.17"
- "@hublib-web/tach-typography": "workspace:*"
+ "@hublib-web/tach-typography": "workspace:0.3.0"
"@storybook/addon-essentials": "npm:8.6.14"
"@storybook/react": "npm:8.6.14"
"@storybook/react-vite": "npm:8.6.14"
@@ -1004,7 +1006,7 @@ __metadata:
peerDependencies:
"@angular/common": ">=17.0.0"
"@angular/core": ">=17.0.0"
- "@hublib-web/tach-typography": ">=0.1.0"
+ "@hublib-web/tach-typography": 0.3.0
antd: ">=5.0.0"
react: ">=18.0.0"
react-dom: ">=18.0.0"
@@ -1042,7 +1044,7 @@ __metadata:
languageName: unknown
linkType: soft
-"@hublib-web/tach-typography@workspace:*, @hublib-web/tach-typography@workspace:packages/tach-typography":
+"@hublib-web/tach-typography@workspace:0.3.0, @hublib-web/tach-typography@workspace:packages/tach-typography":
version: 0.0.0-use.local
resolution: "@hublib-web/tach-typography@workspace:packages/tach-typography"
dependencies: