3 Commits

Author SHA1 Message Date
2bb8f9c697 release(content-suggestions): v0.2.1 2026-04-10 18:01:53 +03:00
74f11aefbc release(tach-typography): v0.3.1 2026-04-10 18:00:53 +03:00
28b91cd9eb video-player: release v0.1.4 2026-04-08 12:42:17 +03:00
19 changed files with 666 additions and 150 deletions

View File

@@ -29,7 +29,7 @@ export class ContentTextWithSuggestionsComponent {
[renderLink]="renderLink" [renderLink]="renderLink"
(viewed)="viewed.emit()" (viewed)="viewed.emit()"
(expandedChange)="expandedChange.emit($event)" (expandedChange)="expandedChange.emit($event)"
/> ></content-text>
`, isInline: true, dependencies: [{ kind: "component", type: ContentTextComponent, selector: "content-text", inputs: ["className", "weight", "text", "ellipsis", "blur", "style", "onView", "renderMention", "renderTag", "renderLink"], outputs: ["viewed", "expandedChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); `, isInline: true, dependencies: [{ kind: "component", type: ContentTextComponent, selector: "content-text", 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: ContentTextWithSuggestionsComponent, decorators: [{ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ContentTextWithSuggestionsComponent, decorators: [{
@@ -53,7 +53,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
[renderLink]="renderLink" [renderLink]="renderLink"
(viewed)="viewed.emit()" (viewed)="viewed.emit()"
(expandedChange)="expandedChange.emit($event)" (expandedChange)="expandedChange.emit($event)"
/> ></content-text>
`, `,
}] }]
}], propDecorators: { className: [{ }], propDecorators: { className: [{

View File

@@ -34,7 +34,7 @@ export class ContentTitleWithSuggestionsComponent {
[renderLink]="renderLink" [renderLink]="renderLink"
(viewed)="viewed.emit()" (viewed)="viewed.emit()"
(expandedChange)="expandedChange.emit($event)" (expandedChange)="expandedChange.emit($event)"
/> ></content-text-with-suggestions>
`, 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 }); `, 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: [{ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: ContentTitleWithSuggestionsComponent, decorators: [{
@@ -58,7 +58,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
[renderLink]="renderLink" [renderLink]="renderLink"
(viewed)="viewed.emit()" (viewed)="viewed.emit()"
(expandedChange)="expandedChange.emit($event)" (expandedChange)="expandedChange.emit($event)"
/> ></content-text-with-suggestions>
`, `,
}] }]
}], propDecorators: { className: [{ }], propDecorators: { className: [{

View File

@@ -1,6 +1,6 @@
{ {
"name": "@hublib-web/content-suggestions", "name": "@hublib-web/content-suggestions",
"version": "0.2.0", "version": "0.2.1",
"description": "Content text/title with mentions, tags and links for React and Angular", "description": "Content text/title with mentions, tags and links for React and Angular",
"license": "MIT", "license": "MIT",
"type": "module", "type": "module",
@@ -51,7 +51,7 @@
"build:angular": "ngc -p tsconfig.angular.json && node ./scripts/fix-angular-entry.mjs", "build:angular": "ngc -p tsconfig.angular.json && node ./scripts/fix-angular-entry.mjs",
"clean": "rm -rf dist storybook-static", "clean": "rm -rf dist storybook-static",
"typecheck": "tsc -p tsconfig.json --noEmit", "typecheck": "tsc -p tsconfig.json --noEmit",
"test": "vitest run --passWithNoTests", "test": "yarn run -T vitest run --passWithNoTests",
"lint": "eslint src --ext .ts,.tsx", "lint": "eslint src --ext .ts,.tsx",
"storybook": "storybook dev -p 6006", "storybook": "storybook dev -p 6006",
"storybook:build": "storybook build" "storybook:build": "storybook build"
@@ -59,7 +59,7 @@
"peerDependencies": { "peerDependencies": {
"@angular/common": ">=17.0.0", "@angular/common": ">=17.0.0",
"@angular/core": ">=17.0.0", "@angular/core": ">=17.0.0",
"@hublib-web/tach-typography": "0.3.0", "@hublib-web/tach-typography": "0.3.1",
"antd": ">=5.0.0", "antd": ">=5.0.0",
"react": ">=18.0.0", "react": ">=18.0.0",
"react-dom": ">=18.0.0", "react-dom": ">=18.0.0",
@@ -90,7 +90,7 @@
"@angular/compiler": "^20.3.17", "@angular/compiler": "^20.3.17",
"@angular/compiler-cli": "^20.3.17", "@angular/compiler-cli": "^20.3.17",
"@angular/core": "^20.3.17", "@angular/core": "^20.3.17",
"@hublib-web/tach-typography": "workspace:0.3.0", "@hublib-web/tach-typography": "workspace:0.3.1",
"@storybook/addon-essentials": "8.6.14", "@storybook/addon-essentials": "8.6.14",
"@storybook/react": "8.6.14", "@storybook/react": "8.6.14",
"@storybook/react-vite": "8.6.14", "@storybook/react-vite": "8.6.14",

View File

@@ -30,7 +30,7 @@ import { ContentTextComponent } from "./content-text.component";
[renderLink]="renderLink" [renderLink]="renderLink"
(viewed)="viewed.emit()" (viewed)="viewed.emit()"
(expandedChange)="expandedChange.emit($event)" (expandedChange)="expandedChange.emit($event)"
/> ></content-text>
`, `,
}) })
export class ContentTextWithSuggestionsComponent { export class ContentTextWithSuggestionsComponent {

View File

@@ -29,7 +29,7 @@ import { ContentTextWithSuggestionsComponent } from "./content-text-with-suggest
[renderLink]="renderLink" [renderLink]="renderLink"
(viewed)="viewed.emit()" (viewed)="viewed.emit()"
(expandedChange)="expandedChange.emit($event)" (expandedChange)="expandedChange.emit($event)"
/> ></content-text-with-suggestions>
`, `,
}) })
export class ContentTitleWithSuggestionsComponent { export class ContentTitleWithSuggestionsComponent {

View File

@@ -0,0 +1,97 @@
// @vitest-environment jsdom
import "@angular/compiler";
import { Component, provideZonelessChangeDetection } from "@angular/core";
import { TestBed, getTestBed } from "@angular/core/testing";
import { BrowserTestingModule, platformBrowserTesting } from "@angular/platform-browser/testing";
import { afterEach, describe, expect, it } from "vitest";
import {
ContentTextWithSuggestionsComponent,
ContentTitleWithSuggestionsComponent,
} from "../../dist/angular/index.js";
const ensureAngularTestEnvironment = (): void => {
try {
getTestBed().initTestEnvironment(BrowserTestingModule, platformBrowserTesting());
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
if (!message.includes("Cannot set base providers")) {
throw error;
}
}
};
ensureAngularTestEnvironment();
@Component({
standalone: true,
imports: [ContentTextWithSuggestionsComponent, ContentTitleWithSuggestionsComponent],
template: `
<content-text-with-suggestions [text]="text"></content-text-with-suggestions>
<content-title-with-suggestions [text]="title"></content-title-with-suggestions>
`,
})
class ContentSuggestionsHostComponent {
text =
"Привет @[John Doe](d290f1ee-6c54-4b01-90e6-d701748f0851) #frontend смотри example.com";
title = "Заголовок @[Jane Roe](123e4567-e89b-12d3-a456-426614174000) #news docs.example.com";
}
describe("content-suggestions (angular)", () => {
afterEach(() => {
TestBed.resetTestingModule();
});
it("renders text with mention, tag and link tokens", async () => {
TestBed.configureTestingModule({
providers: [provideZonelessChangeDetection()],
});
const fixture = TestBed.createComponent(ContentSuggestionsHostComponent);
fixture.detectChanges();
await fixture.whenStable();
const host: HTMLElement = fixture.nativeElement;
const content = host.querySelector("content-text-with-suggestions");
expect(content).not.toBeNull();
const text = content?.textContent ?? "";
expect(text).toContain("Привет");
expect(text).toContain("@John Doe");
expect(text).toContain("#frontend");
expect(text).toContain("example.com");
const link = content?.querySelector('a.tach-typography[href="https://example.com"]');
expect(link).not.toBeNull();
expect(link?.textContent).toContain("example.com");
});
it("renders title variant and keeps entities visible", async () => {
TestBed.configureTestingModule({
providers: [provideZonelessChangeDetection()],
});
const fixture = TestBed.createComponent(ContentSuggestionsHostComponent);
fixture.detectChanges();
await fixture.whenStable();
const host: HTMLElement = fixture.nativeElement;
const title = host.querySelector("content-title-with-suggestions");
expect(title).not.toBeNull();
const text = title?.textContent ?? "";
expect(text).toContain("Заголовок");
expect(text).toContain("@Jane Roe");
expect(text).toContain("#news");
expect(text).toContain("docs.example.com");
const boldNode = title?.querySelector(".tach-typography--bold");
expect(boldNode).not.toBeNull();
const link = title?.querySelector('a.tach-typography[href="https://docs.example.com"]');
expect(link).not.toBeNull();
expect(link?.textContent).toContain("docs.example.com");
});
});

View File

@@ -0,0 +1,177 @@
import "@angular/compiler";
import React, { useEffect, useRef, useState } from "react";
import { createComponent, provideZonelessChangeDetection, type ApplicationRef } from "@angular/core";
import { createApplication } from "@angular/platform-browser";
import type { Meta, StoryObj } from "@storybook/react";
import { expect, waitFor, within } from "@storybook/test";
import {
ContentTextWithSuggestionsComponent,
ContentTitleWithSuggestionsComponent,
} from "../../dist/angular/index.js";
const meta = {
title: "Angular/ContentSuggestions DOM",
tags: ["autodocs"],
parameters: {
docs: {
description: {
component:
"Angular runtime verification in Storybook: text and title components with mention/tag/link rendered into real DOM.",
},
},
},
} satisfies Meta;
export default meta;
type Story = StoryObj<typeof meta>;
type MountedTextComponent = ReturnType<typeof createComponent<ContentTextWithSuggestionsComponent>>;
type MountedTitleComponent = ReturnType<typeof createComponent<ContentTitleWithSuggestionsComponent>>;
const TEXT_SAMPLE =
"Angular text: @[Иван](123e4567-e89b-12d3-a456-426614174000) #frontend docs.example.com";
const TITLE_SAMPLE =
"Angular title: @[Мария](123e4567-e89b-12d3-a456-426614174001) #release github.com";
const createSection = (title: string): HTMLDivElement => {
const section = document.createElement("div");
section.style.display = "grid";
section.style.gap = "8px";
section.style.padding = "10px 12px";
section.style.border = "1px solid #e2e8f0";
section.style.borderRadius = "10px";
const heading = document.createElement("div");
heading.style.fontFamily =
'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Courier New", monospace';
heading.style.fontSize = "12px";
heading.style.color = "#475569";
heading.textContent = title;
const body = document.createElement("div");
section.append(heading, body);
body.dataset.slot = "body";
return section;
};
const AngularContentDomHarness: React.FC = () => {
const hostRef = useRef<HTMLDivElement | null>(null);
const [status, setStatus] = useState("mounting");
useEffect(() => {
const host = hostRef.current;
if (!host) {
return;
}
let cancelled = false;
let appRef: ApplicationRef | null = null;
let textRef: MountedTextComponent | null = null;
let titleRef: MountedTitleComponent | null = null;
host.innerHTML = "";
setStatus("mounting");
void createApplication({
providers: [provideZonelessChangeDetection()],
})
.then(app => {
if (cancelled) {
app.destroy();
return;
}
appRef = app;
const textSection = createSection("ContentTextWithSuggestionsComponent");
const titleSection = createSection("ContentTitleWithSuggestionsComponent");
textSection.dataset.testid = "angular-content-text";
titleSection.dataset.testid = "angular-content-title";
host.append(textSection, titleSection);
const textHost = textSection.querySelector('[data-slot="body"]') as HTMLElement;
const titleHost = titleSection.querySelector('[data-slot="body"]') as HTMLElement;
textRef = createComponent(ContentTextWithSuggestionsComponent, {
environmentInjector: app.injector,
hostElement: textHost,
});
app.attachView(textRef.hostView);
textRef.setInput("text", TEXT_SAMPLE);
textRef.setInput("ellipsis", false);
textRef.changeDetectorRef.detectChanges();
titleRef = createComponent(ContentTitleWithSuggestionsComponent, {
environmentInjector: app.injector,
hostElement: titleHost,
});
app.attachView(titleRef.hostView);
titleRef.setInput("text", TITLE_SAMPLE);
titleRef.setInput("ellipsis", false);
titleRef.changeDetectorRef.detectChanges();
setStatus("ready");
})
.catch(error => {
setStatus(`error: ${String(error)}`);
});
return () => {
cancelled = true;
textRef?.destroy();
titleRef?.destroy();
appRef?.destroy();
};
}, []);
return (
<div
style={{ maxWidth: 960, width: "100%", display: "grid", gap: 12 }}
data-testid="angular-content-dom-story"
>
<div
style={{
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
fontSize: 12,
color: "#475569",
}}
>
status={status}
</div>
<div ref={hostRef} style={{ display: "grid", gap: 12 }} />
</div>
);
};
export const TextAndTitleRenderCheck: Story = {
render: () => <AngularContentDomHarness />,
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await waitFor(() => {
expect(canvas.getByText("status=ready")).toBeTruthy();
});
await waitFor(() => {
expect(canvas.getByText("Angular text:")).toBeTruthy();
expect(canvas.getByText("@Иван")).toBeTruthy();
expect(canvas.getByText("#frontend")).toBeTruthy();
expect(canvas.getByText("docs.example.com")).toBeTruthy();
expect(canvas.getByText("Angular title:")).toBeTruthy();
expect(canvas.getByText("@Мария")).toBeTruthy();
expect(canvas.getByText("#release")).toBeTruthy();
expect(canvas.getByText("github.com")).toBeTruthy();
});
const docsLink = canvas.getByRole("link", { name: "docs.example.com" });
expect(docsLink.getAttribute("href")).toBe("https://docs.example.com");
const githubLink = canvas.getByRole("link", { name: "github.com" });
expect(githubLink.getAttribute("href")).toBe("https://github.com");
},
};

View File

@@ -74,7 +74,7 @@ export declare class TachTypographyComponent implements OnChanges {
ngOnChanges(_changes: SimpleChanges): void; ngOnChanges(_changes: SimpleChanges): void;
handleClick(event: MouseEvent): void; handleClick(event: MouseEvent): void;
static ɵfac: i0.ɵɵFactoryDeclaration<TachTypographyComponent, never>; static ɵfac: i0.ɵɵFactoryDeclaration<TachTypographyComponent, never>;
static ɵcmp: i0.ɵɵComponentDeclaration<TachTypographyComponent, "tach-typography", never, { "hostTag": { "alias": "as"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; "color": { "alias": "color"; "required": false; }; "weight": { "alias": "weight"; "required": false; }; "clickable": { "alias": "clickable"; "required": false; }; "markdownEnabled": { "alias": "markdownEnabled"; "required": false; }; "markdown": { "alias": "markdown"; "required": false; }; "className": { "alias": "className"; "required": false; }; "ellipsis": { "alias": "ellipsis"; "required": false; }; "nzProps": { "alias": "nzProps"; "required": false; }; "hostProps": { "alias": "hostProps"; "required": false; }; "preserveStyle": { "alias": "preserveStyle"; "required": false; }; }, { "tachClick": "tachClick"; }, never, ["*", "*", "*", "*", "*", "*", "*"], true, never>; static ɵcmp: i0.ɵɵComponentDeclaration<TachTypographyComponent, "tach-typography", never, { "hostTag": { "alias": "as"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; "color": { "alias": "color"; "required": false; }; "weight": { "alias": "weight"; "required": false; }; "clickable": { "alias": "clickable"; "required": false; }; "markdownEnabled": { "alias": "markdownEnabled"; "required": false; }; "markdown": { "alias": "markdown"; "required": false; }; "className": { "alias": "className"; "required": false; }; "ellipsis": { "alias": "ellipsis"; "required": false; }; "nzProps": { "alias": "nzProps"; "required": false; }; "hostProps": { "alias": "hostProps"; "required": false; }; "preserveStyle": { "alias": "preserveStyle"; "required": false; }; }, { "tachClick": "tachClick"; }, never, ["*"], true, never>;
} }
export declare class TachTypographyNzModule { export declare class TachTypographyNzModule {
static ɵfac: i0.ɵɵFactoryDeclaration<TachTypographyNzModule, never>; static ɵfac: i0.ɵɵFactoryDeclaration<TachTypographyNzModule, never>;

View File

@@ -1 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/angular/index.ts"],"names":[],"mappings":"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"} {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/angular/index.ts"],"names":[],"mappings":"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"}

View File

@@ -1,4 +1,4 @@
import { NgIf, NgStyle, NgSwitch, NgSwitchCase, NgSwitchDefault } from "@angular/common"; import { NgStyle, NgSwitch, NgSwitchCase, NgSwitchDefault, NgTemplateOutlet } from "@angular/common";
import { ChangeDetectionStrategy, Component, Directive, EventEmitter, inject, Input, NgModule, Output, } from "@angular/core"; import { ChangeDetectionStrategy, Component, Directive, EventEmitter, inject, Input, NgModule, Output, } from "@angular/core";
import { NzTypographyComponent, NzTypographyModule } from "ng-zorro-antd/typography"; import { NzTypographyComponent, NzTypographyModule } from "ng-zorro-antd/typography";
import { tachTypographyClassList, tachTypographyClassName, tachTypographyEllipsisStyle, tachTypographyMarkdownToHtml, } from "../core"; import { tachTypographyClassList, tachTypographyClassName, tachTypographyEllipsisStyle, tachTypographyMarkdownToHtml, } from "../core";
@@ -252,6 +252,13 @@ export class TachTypographyComponent {
} }
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: TachTypographyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: TachTypographyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.18", type: TachTypographyComponent, isStandalone: true, selector: "tach-typography", inputs: { hostTag: ["as", "hostTag"], variant: "variant", color: "color", weight: "weight", clickable: "clickable", markdownEnabled: "markdownEnabled", markdown: "markdown", className: "className", ellipsis: "ellipsis", nzProps: "nzProps", hostProps: "hostProps", preserveStyle: "preserveStyle" }, outputs: { tachClick: "tachClick" }, usesOnChanges: true, ngImport: i0, template: ` static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.18", type: TachTypographyComponent, isStandalone: true, selector: "tach-typography", inputs: { hostTag: ["as", "hostTag"], variant: "variant", color: "color", weight: "weight", clickable: "clickable", markdownEnabled: "markdownEnabled", markdown: "markdown", className: "className", ellipsis: "ellipsis", nzProps: "nzProps", hostProps: "hostProps", preserveStyle: "preserveStyle" }, outputs: { tachClick: "tachClick" }, usesOnChanges: true, ngImport: i0, template: `
<ng-template #tachTypographyProjectedContent>
<ng-content></ng-content>
</ng-template>
<ng-template #tachTypographyMarkdownContent>
<span [innerHTML]="renderedMarkdown"></span>
</ng-template>
<ng-container [ngSwitch]="hostTag"> <ng-container [ngSwitch]="hostTag">
<p <p
*ngSwitchCase="'p'" *ngSwitchCase="'p'"
@@ -267,12 +274,9 @@ export class TachTypographyComponent {
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentP"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentP>
<ng-content />
</ng-template>
</p> </p>
<a <a
*ngSwitchCase="'a'" *ngSwitchCase="'a'"
@@ -288,12 +292,9 @@ export class TachTypographyComponent {
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentA"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentA>
<ng-content />
</ng-template>
</a> </a>
<h1 <h1
*ngSwitchCase="'h1'" *ngSwitchCase="'h1'"
@@ -309,12 +310,9 @@ export class TachTypographyComponent {
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentH1"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentH1>
<ng-content />
</ng-template>
</h1> </h1>
<h2 <h2
*ngSwitchCase="'h2'" *ngSwitchCase="'h2'"
@@ -330,12 +328,9 @@ export class TachTypographyComponent {
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentH2"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentH2>
<ng-content />
</ng-template>
</h2> </h2>
<h3 <h3
*ngSwitchCase="'h3'" *ngSwitchCase="'h3'"
@@ -351,12 +346,9 @@ export class TachTypographyComponent {
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentH3"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentH3>
<ng-content />
</ng-template>
</h3> </h3>
<h4 <h4
*ngSwitchCase="'h4'" *ngSwitchCase="'h4'"
@@ -372,12 +364,9 @@ export class TachTypographyComponent {
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentH4"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentH4>
<ng-content />
</ng-template>
</h4> </h4>
<span <span
*ngSwitchDefault *ngSwitchDefault
@@ -393,15 +382,12 @@ export class TachTypographyComponent {
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentSpan"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentSpan>
<ng-content />
</ng-template>
</span> </span>
</ng-container> </ng-container>
`, isInline: true, dependencies: [{ kind: "ngmodule", type: NzTypographyModule }, { kind: "component", type: i1.NzTypographyComponent, selector: " nz-typography, [nz-typography], p[nz-paragraph], span[nz-text], h1[nz-title], h2[nz-title], h3[nz-title], h4[nz-title] ", inputs: ["nzCopyable", "nzEditable", "nzDisabled", "nzExpandable", "nzEllipsis", "nzCopyTooltips", "nzCopyIcons", "nzEditTooltip", "nzEditIcon", "nzContent", "nzEllipsisRows", "nzType", "nzCopyText", "nzSuffix"], outputs: ["nzContentChange", "nzCopy", "nzExpandChange", "nzOnEllipsis"], exportAs: ["nzTypography"] }, { kind: "directive", type: TachTypographyDirective, selector: "[tachTypography]", inputs: ["tachTypography", "tachTypographyVariant", "tachTypographyColor", "tachTypographyWeight", "tachTypographyClickable", "tachTypographyClassName", "tachTypographyEllipsis"] }, { kind: "directive", type: TachTypographyNzPropsDirective, selector: "[tachTypographyNzProps]", inputs: ["tachTypographyNzProps"] }, { kind: "directive", type: TachTypographyHostPropsDirective, selector: "[tachTypographyHostProps]", inputs: ["tachTypographyHostProps"] }, { kind: "directive", type: NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); `, isInline: true, dependencies: [{ kind: "ngmodule", type: NzTypographyModule }, { kind: "component", type: i1.NzTypographyComponent, selector: " nz-typography, [nz-typography], p[nz-paragraph], span[nz-text], h1[nz-title], h2[nz-title], h3[nz-title], h4[nz-title] ", inputs: ["nzCopyable", "nzEditable", "nzDisabled", "nzExpandable", "nzEllipsis", "nzCopyTooltips", "nzCopyIcons", "nzEditTooltip", "nzEditIcon", "nzContent", "nzEllipsisRows", "nzType", "nzCopyText", "nzSuffix"], outputs: ["nzContentChange", "nzCopy", "nzExpandChange", "nzOnEllipsis"], exportAs: ["nzTypography"] }, { kind: "directive", type: TachTypographyDirective, selector: "[tachTypography]", inputs: ["tachTypography", "tachTypographyVariant", "tachTypographyColor", "tachTypographyWeight", "tachTypographyClickable", "tachTypographyClassName", "tachTypographyEllipsis"] }, { kind: "directive", type: TachTypographyNzPropsDirective, selector: "[tachTypographyNzProps]", inputs: ["tachTypographyNzProps"] }, { kind: "directive", type: TachTypographyHostPropsDirective, selector: "[tachTypographyHostProps]", inputs: ["tachTypographyHostProps"] }, { kind: "directive", type: NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
} }
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: TachTypographyComponent, decorators: [{ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImport: i0, type: TachTypographyComponent, decorators: [{
type: Component, type: Component,
@@ -416,11 +402,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
NgSwitch, NgSwitch,
NgSwitchCase, NgSwitchCase,
NgSwitchDefault, NgSwitchDefault,
NgIf,
NgStyle, NgStyle,
NgTemplateOutlet,
], ],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
template: ` template: `
<ng-template #tachTypographyProjectedContent>
<ng-content></ng-content>
</ng-template>
<ng-template #tachTypographyMarkdownContent>
<span [innerHTML]="renderedMarkdown"></span>
</ng-template>
<ng-container [ngSwitch]="hostTag"> <ng-container [ngSwitch]="hostTag">
<p <p
*ngSwitchCase="'p'" *ngSwitchCase="'p'"
@@ -436,12 +429,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentP"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentP>
<ng-content />
</ng-template>
</p> </p>
<a <a
*ngSwitchCase="'a'" *ngSwitchCase="'a'"
@@ -457,12 +447,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentA"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentA>
<ng-content />
</ng-template>
</a> </a>
<h1 <h1
*ngSwitchCase="'h1'" *ngSwitchCase="'h1'"
@@ -478,12 +465,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentH1"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentH1>
<ng-content />
</ng-template>
</h1> </h1>
<h2 <h2
*ngSwitchCase="'h2'" *ngSwitchCase="'h2'"
@@ -499,12 +483,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentH2"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentH2>
<ng-content />
</ng-template>
</h2> </h2>
<h3 <h3
*ngSwitchCase="'h3'" *ngSwitchCase="'h3'"
@@ -520,12 +501,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentH3"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentH3>
<ng-content />
</ng-template>
</h3> </h3>
<h4 <h4
*ngSwitchCase="'h4'" *ngSwitchCase="'h4'"
@@ -541,12 +519,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentH4"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentH4>
<ng-content />
</ng-template>
</h4> </h4>
<span <span
*ngSwitchDefault *ngSwitchDefault
@@ -562,12 +537,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.18", ngImpo
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentSpan"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentSpan>
<ng-content />
</ng-template>
</span> </span>
</ng-container> </ng-container>
`, `,

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
{ {
"name": "@hublib-web/tach-typography", "name": "@hublib-web/tach-typography",
"version": "0.3.0", "version": "0.3.1",
"description": "Cross-framework typography package for React and Angular", "description": "Cross-framework typography package for React and Angular",
"license": "MIT", "license": "MIT",
"type": "module", "type": "module",
@@ -56,7 +56,7 @@
"build:angular": "ngc -p tsconfig.angular.json && node ./scripts/fix-angular-entry.mjs", "build:angular": "ngc -p tsconfig.angular.json && node ./scripts/fix-angular-entry.mjs",
"clean": "rm -rf dist", "clean": "rm -rf dist",
"typecheck": "tsc -p tsconfig.json --noEmit", "typecheck": "tsc -p tsconfig.json --noEmit",
"test": "vitest run", "test": "yarn run -T vitest run",
"lint": "eslint src --ext .ts,.tsx", "lint": "eslint src --ext .ts,.tsx",
"storybook": "storybook dev -p 6006", "storybook": "storybook dev -p 6006",
"storybook:build": "storybook build" "storybook:build": "storybook build"

View File

@@ -0,0 +1,90 @@
// @vitest-environment jsdom
import "@angular/compiler";
import { NgFor } from "@angular/common";
import { Component, provideZonelessChangeDetection } from "@angular/core";
import { TestBed, getTestBed } from "@angular/core/testing";
import { BrowserTestingModule, platformBrowserTesting } from "@angular/platform-browser/testing";
import { afterEach, describe, expect, it } from "vitest";
import { TYPOGRAPHY_VARIANTS, type TypographyVariant } from "../core";
import {
TachTypographyComponent,
type TachTypographyHostTag,
} from "../../dist/angular/index.js";
const ensureAngularTestEnvironment = (): void => {
try {
getTestBed().initTestEnvironment(BrowserTestingModule, platformBrowserTesting());
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
if (!message.includes("Cannot set base providers")) {
throw error;
}
}
};
ensureAngularTestEnvironment();
@Component({
standalone: true,
imports: [NgFor, TachTypographyComponent],
template: `
<ng-container *ngFor="let variant of variants; let i = index">
<tach-typography [as]="tags[i % tags.length]" [variant]="variant">
variant-{{ variant }}
</tach-typography>
</ng-container>
`,
})
class TypographyMatrixHostComponent {
readonly variants: readonly TypographyVariant[] = TYPOGRAPHY_VARIANTS;
readonly tags: readonly TachTypographyHostTag[] = ["span", "p", "a", "h1", "h2", "h3", "h4"];
}
describe("TachTypographyComponent (angular)", () => {
afterEach(() => {
TestBed.resetTestingModule();
});
it("renders projected text for every typography variant", async () => {
TestBed.configureTestingModule({
providers: [provideZonelessChangeDetection()],
});
const fixture = TestBed.createComponent(TypographyMatrixHostComponent);
fixture.detectChanges();
await fixture.whenStable();
const host: HTMLElement = fixture.nativeElement;
for (const variant of TYPOGRAPHY_VARIANTS) {
const selector = `.tach-typography--${variant}`;
const node = host.querySelector(selector);
expect(node, `missing ${selector}`).not.toBeNull();
expect(node?.textContent).toContain(`variant-${variant}`);
}
});
it("projects text when using all supported host tags", async () => {
TestBed.configureTestingModule({
providers: [provideZonelessChangeDetection()],
});
const fixture = TestBed.createComponent(TypographyMatrixHostComponent);
fixture.detectChanges();
await fixture.whenStable();
const host: HTMLElement = fixture.nativeElement;
const tags: readonly TachTypographyHostTag[] = ["span", "p", "a", "h1", "h2", "h3", "h4"];
for (const tag of tags) {
const nodes = host.querySelectorAll(`${tag}.tach-typography`);
expect(nodes.length, `missing rendered <${tag}>`).toBeGreaterThan(0);
const firstText = nodes[0]?.textContent?.trim() ?? "";
expect(firstText.length, `<${tag}> should contain projected text`).toBeGreaterThan(0);
}
});
});

View File

@@ -1,4 +1,4 @@
import { NgIf, NgStyle, NgSwitch, NgSwitchCase, NgSwitchDefault } from "@angular/common"; import { NgStyle, NgSwitch, NgSwitchCase, NgSwitchDefault, NgTemplateOutlet } from "@angular/common";
import { import {
ChangeDetectionStrategy, ChangeDetectionStrategy,
Component, Component,
@@ -292,11 +292,18 @@ export class TachTypographyHostPropsDirective implements OnChanges {
NgSwitch, NgSwitch,
NgSwitchCase, NgSwitchCase,
NgSwitchDefault, NgSwitchDefault,
NgIf,
NgStyle, NgStyle,
NgTemplateOutlet,
], ],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
template: ` template: `
<ng-template #tachTypographyProjectedContent>
<ng-content></ng-content>
</ng-template>
<ng-template #tachTypographyMarkdownContent>
<span [innerHTML]="renderedMarkdown"></span>
</ng-template>
<ng-container [ngSwitch]="hostTag"> <ng-container [ngSwitch]="hostTag">
<p <p
*ngSwitchCase="'p'" *ngSwitchCase="'p'"
@@ -312,12 +319,9 @@ export class TachTypographyHostPropsDirective implements OnChanges {
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentP"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentP>
<ng-content />
</ng-template>
</p> </p>
<a <a
*ngSwitchCase="'a'" *ngSwitchCase="'a'"
@@ -333,12 +337,9 @@ export class TachTypographyHostPropsDirective implements OnChanges {
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentA"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentA>
<ng-content />
</ng-template>
</a> </a>
<h1 <h1
*ngSwitchCase="'h1'" *ngSwitchCase="'h1'"
@@ -354,12 +355,9 @@ export class TachTypographyHostPropsDirective implements OnChanges {
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentH1"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentH1>
<ng-content />
</ng-template>
</h1> </h1>
<h2 <h2
*ngSwitchCase="'h2'" *ngSwitchCase="'h2'"
@@ -375,12 +373,9 @@ export class TachTypographyHostPropsDirective implements OnChanges {
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentH2"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentH2>
<ng-content />
</ng-template>
</h2> </h2>
<h3 <h3
*ngSwitchCase="'h3'" *ngSwitchCase="'h3'"
@@ -396,12 +391,9 @@ export class TachTypographyHostPropsDirective implements OnChanges {
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentH3"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentH3>
<ng-content />
</ng-template>
</h3> </h3>
<h4 <h4
*ngSwitchCase="'h4'" *ngSwitchCase="'h4'"
@@ -417,12 +409,9 @@ export class TachTypographyHostPropsDirective implements OnChanges {
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentH4"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentH4>
<ng-content />
</ng-template>
</h4> </h4>
<span <span
*ngSwitchDefault *ngSwitchDefault
@@ -438,12 +427,9 @@ export class TachTypographyHostPropsDirective implements OnChanges {
[ngStyle]="preserveStyle" [ngStyle]="preserveStyle"
(click)="handleClick($event)" (click)="handleClick($event)"
> >
<ng-container *ngIf="markdownEnabled; else tachTypographyContentSpan"> <ng-container
<span [innerHTML]="renderedMarkdown"></span> [ngTemplateOutlet]="markdownEnabled ? tachTypographyMarkdownContent : tachTypographyProjectedContent"
</ng-container> ></ng-container>
<ng-template #tachTypographyContentSpan>
<ng-content />
</ng-template>
</span> </span>
</ng-container> </ng-container>
`, `,

View File

@@ -0,0 +1,194 @@
import "@angular/compiler";
import React, { useEffect, useRef, useState } from "react";
import { createComponent, provideZonelessChangeDetection, type ApplicationRef } from "@angular/core";
import { createApplication } from "@angular/platform-browser";
import type { Meta, StoryObj } from "@storybook/react";
import { expect, waitFor, within } from "@storybook/test";
import { TYPOGRAPHY_VARIANTS, type TypographyVariant } from "../core";
import {
TachTypographyComponent,
type TachTypographyHostTag,
} from "../../dist/angular/index.js";
const meta = {
title: "Angular/TachTypography DOM",
tags: ["autodocs"],
parameters: {
docs: {
description: {
component:
"Angular runtime verification in Storybook: renders TachTypography Angular component and verifies text in real DOM.",
},
},
},
} satisfies Meta;
export default meta;
type Story = StoryObj<typeof meta>;
type MountedComponent = ReturnType<typeof createComponent<TachTypographyComponent>>;
const createRow = (label: string): { row: HTMLDivElement; value: HTMLDivElement } => {
const row = document.createElement("div");
row.className = "tach-story-row";
const title = document.createElement("span");
title.className = "tach-story-label";
title.textContent = label;
const value = document.createElement("div");
row.append(title, value);
return { row, value };
};
const mountTypography = (
app: ApplicationRef,
host: HTMLElement,
options: {
label: string;
text: string;
variant: TypographyVariant;
as?: TachTypographyHostTag;
color?: "primary" | "link";
hostProps?: Record<string, unknown>;
},
): MountedComponent => {
const { row, value } = createRow(options.label);
host.appendChild(row);
const componentRef = createComponent(TachTypographyComponent, {
environmentInjector: app.injector,
hostElement: value,
projectableNodes: [[document.createTextNode(options.text)]],
});
app.attachView(componentRef.hostView);
componentRef.setInput("as", options.as ?? "span");
componentRef.setInput("variant", options.variant);
componentRef.setInput("color", options.color ?? "primary");
if (options.hostProps) {
componentRef.setInput("hostProps", options.hostProps);
}
componentRef.changeDetectorRef.detectChanges();
return componentRef;
};
const AngularTypographyDomHarness: React.FC = () => {
const hostRef = useRef<HTMLDivElement | null>(null);
const [status, setStatus] = useState("mounting");
useEffect(() => {
const host = hostRef.current;
if (!host) {
return;
}
let cancelled = false;
let appRef: ApplicationRef | null = null;
const mounted: MountedComponent[] = [];
host.innerHTML = "";
setStatus("mounting");
void createApplication({
providers: [provideZonelessChangeDetection()],
})
.then(app => {
if (cancelled) {
app.destroy();
return;
}
appRef = app;
for (const variant of TYPOGRAPHY_VARIANTS) {
mounted.push(
mountTypography(app, host, {
label: variant,
text: `Angular variant text: ${variant}`,
variant,
as: "span",
}),
);
}
mounted.push(
mountTypography(app, host, {
label: "Tag p",
text: "Angular paragraph text",
variant: "Body",
as: "p",
}),
);
mounted.push(
mountTypography(app, host, {
label: "Tag a",
text: "Angular link text",
variant: "Body",
as: "a",
color: "link",
hostProps: {
href: "https://example.com/angular-dom-verify",
target: "_blank",
rel: "noopener noreferrer",
},
}),
);
setStatus("ready");
})
.catch(error => {
setStatus(`error: ${String(error)}`);
});
return () => {
cancelled = true;
for (const ref of mounted) {
ref.destroy();
}
appRef?.destroy();
};
}, []);
return (
<div className="tach-story-surface tach-story-stack" data-testid="angular-typography-dom-story">
<div
style={{
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
fontSize: 12,
color: "#475569",
}}
>
status={status}
</div>
<div ref={hostRef} className="tach-story-grid" />
</div>
);
};
export const FullRenderCheck: Story = {
render: () => <AngularTypographyDomHarness />,
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await waitFor(() => {
expect(canvas.getByText("status=ready")).toBeTruthy();
});
await waitFor(() => {
for (const variant of TYPOGRAPHY_VARIANTS) {
expect(canvas.getByText(`Angular variant text: ${variant}`)).toBeTruthy();
}
});
const link = canvas.getByRole("link", { name: "Angular link text" });
expect(link.getAttribute("href")).toBe("https://example.com/angular-dom-verify");
},
};

View File

@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import cn from "classnames"; import cn from "classnames";
import styles from "./video-processing.module.scss"; import styles from "./video-processing.module.scss";
const VideoProcessing = ({ className }) => { const VideoProcessing = ({ className }) => {
return (_jsxs("div", { className: cn(styles.container, className), children: [_jsxs("div", { className: styles.spinner, children: [_jsx("div", { className: styles.spinnerBar }), _jsx("div", { className: styles.spinnerBar }), _jsx("div", { className: styles.spinnerBar }), _jsx("div", { className: styles.spinnerBar }), _jsx("div", { className: styles.spinnerBar }), _jsx("div", { className: styles.spinnerBar }), _jsx("div", { className: styles.spinnerBar }), _jsx("div", { className: styles.spinnerBar })] }), _jsx("p", { children: "\u0412\u0438\u0434\u0435\u043E \u043E\u0431\u0440\u0430\u0431\u0430\u0442\u044B\u0432\u0430\u0435\u0442\u0441\u044F, \u043F\u043E\u0434\u043E\u0436\u0434\u0438\u0442\u0435" })] })); return (_jsxs("div", { className: cn(styles.container, className), children: [_jsxs("div", { className: styles.spinner, children: [_jsx("div", { className: styles.spinnerBar }), _jsx("div", { className: styles.spinnerBar }), _jsx("div", { className: styles.spinnerBar }), _jsx("div", { className: styles.spinnerBar }), _jsx("div", { className: styles.spinnerBar }), _jsx("div", { className: styles.spinnerBar }), _jsx("div", { className: styles.spinnerBar }), _jsx("div", { className: styles.spinnerBar })] }), _jsx("p", { className: styles.text, children: "\u0412\u0438\u0434\u0435\u043E \u043E\u0431\u0440\u0430\u0431\u0430\u0442\u044B\u0432\u0430\u0435\u0442\u0441\u044F, \u043F\u043E\u0434\u043E\u0436\u0434\u0438\u0442\u0435" })] }));
}; };
export default VideoProcessing; export default VideoProcessing;
//# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map

View File

@@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/react/video-player/components/with-processing/video-processing/index.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B,OAAO,MAAM,MAAM,gCAAgC,CAAC;AAIpD,MAAM,eAAe,GAAG,CAAC,EAAE,SAAS,EAAoB,EAAE,EAAE;IAC3D,OAAO,CACN,eAAK,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,aAC9C,eAAK,SAAS,EAAE,MAAM,CAAC,OAAO,aAC7B,cAAK,SAAS,EAAE,MAAM,CAAC,UAAU,GAAQ,EACzC,cAAK,SAAS,EAAE,MAAM,CAAC,UAAU,GAAQ,EACzC,cAAK,SAAS,EAAE,MAAM,CAAC,UAAU,GAAQ,EACzC,cAAK,SAAS,EAAE,MAAM,CAAC,UAAU,GAAQ,EACzC,cAAK,SAAS,EAAE,MAAM,CAAC,UAAU,GAAQ,EACzC,cAAK,SAAS,EAAE,MAAM,CAAC,UAAU,GAAQ,EACzC,cAAK,SAAS,EAAE,MAAM,CAAC,UAAU,GAAQ,EACzC,cAAK,SAAS,EAAE,MAAM,CAAC,UAAU,GAAQ,IACpC,EAEN,sMAAsC,IACjC,CACN,CAAC;AACH,CAAC,CAAC;AAEF,eAAe,eAAe,CAAC"} {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/react/video-player/components/with-processing/video-processing/index.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B,OAAO,MAAM,MAAM,gCAAgC,CAAC;AAIpD,MAAM,eAAe,GAAG,CAAC,EAAE,SAAS,EAAoB,EAAE,EAAE;IAC3D,OAAO,CACN,eAAK,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,aAC9C,eAAK,SAAS,EAAE,MAAM,CAAC,OAAO,aAC7B,cAAK,SAAS,EAAE,MAAM,CAAC,UAAU,GAAQ,EACzC,cAAK,SAAS,EAAE,MAAM,CAAC,UAAU,GAAQ,EACzC,cAAK,SAAS,EAAE,MAAM,CAAC,UAAU,GAAQ,EACzC,cAAK,SAAS,EAAE,MAAM,CAAC,UAAU,GAAQ,EACzC,cAAK,SAAS,EAAE,MAAM,CAAC,UAAU,GAAQ,EACzC,cAAK,SAAS,EAAE,MAAM,CAAC,UAAU,GAAQ,EACzC,cAAK,SAAS,EAAE,MAAM,CAAC,UAAU,GAAQ,EACzC,cAAK,SAAS,EAAE,MAAM,CAAC,UAAU,GAAQ,IACpC,EAEN,YAAG,SAAS,EAAE,MAAM,CAAC,IAAI,4LAAqC,IACzD,CACN,CAAC;AACH,CAAC,CAAC;AAEF,eAAe,eAAe,CAAC"}

View File

@@ -1,6 +1,6 @@
{ {
"name": "@hublib-web/video-player", "name": "@hublib-web/video-player",
"version": "0.1.3", "version": "0.1.4",
"description": "Cross-framework video player package for React and Angular", "description": "Cross-framework video player package for React and Angular",
"license": "MIT", "license": "MIT",
"type": "module", "type": "module",

View File

@@ -21,7 +21,7 @@ const VideoProcessing = ({ className }: IVideoErrorProps) => {
<div className={styles.spinnerBar}></div> <div className={styles.spinnerBar}></div>
</div> </div>
<p>Видео обрабатывается, подождите</p> <p className={styles.text}>Видео обрабатывается, подождите</p>
</div> </div>
); );
}; };