@forgeroute/ui 0.3.7 → 0.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgeroute/ui",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@angular/common": ">=22.0.0",
|
|
6
6
|
"@angular/core": ">=22.0.0",
|
|
7
7
|
"@angular/forms": ">=22.0.0",
|
|
8
8
|
"@angular/router": ">=22.0.0",
|
|
9
9
|
"@angular/platform-browser": ">=22.0.0",
|
|
10
|
-
"chart.js": ">=4.0.0"
|
|
10
|
+
"chart.js": ">=4.0.0",
|
|
11
|
+
"pdfjs-dist": ">=5.0.0"
|
|
11
12
|
},
|
|
12
13
|
"peerDependenciesMeta": {
|
|
13
14
|
"@angular/forms": {
|
|
@@ -15,6 +16,9 @@
|
|
|
15
16
|
},
|
|
16
17
|
"chart.js": {
|
|
17
18
|
"optional": true
|
|
19
|
+
},
|
|
20
|
+
"pdfjs-dist": {
|
|
21
|
+
"optional": true
|
|
18
22
|
}
|
|
19
23
|
},
|
|
20
24
|
"publishConfig": {
|
|
@@ -40,6 +44,10 @@
|
|
|
40
44
|
"./charts": {
|
|
41
45
|
"types": "./types/forgeroute-ui-charts.d.ts",
|
|
42
46
|
"default": "./fesm2022/forgeroute-ui-charts.mjs"
|
|
47
|
+
},
|
|
48
|
+
"./pdf": {
|
|
49
|
+
"types": "./types/forgeroute-ui-pdf.d.ts",
|
|
50
|
+
"default": "./fesm2022/forgeroute-ui-pdf.mjs"
|
|
43
51
|
}
|
|
44
52
|
},
|
|
45
53
|
"sideEffects": false,
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { InjectionToken } from "@angular/core";
|
|
3
|
+
import { PDFDocumentProxy } from "pdfjs-dist";
|
|
4
|
+
/** Where pdf.js finds its worker script. Provide it once in the app (`{ provide: PDF_VIEWER_WORKER_SRC, useValue: '/assets/pdf.worker.min.mjs' }`). */
|
|
5
|
+
export declare const PDF_VIEWER_WORKER_SRC: InjectionToken<string>;
|
|
6
|
+
/** Colour of an overlay badge. */
|
|
7
|
+
export type PdfViewerTone = 'blue' | 'green' | 'amber' | 'red' | 'slate';
|
|
8
|
+
/** A labelled box drawn over a page. Positions are PDF points with the origin at the page's bottom-left corner. */
|
|
9
|
+
export interface PdfViewerField {
|
|
10
|
+
id: string;
|
|
11
|
+
/** 1-based page number; a field on a page that does not exist is ignored. */
|
|
12
|
+
page: number;
|
|
13
|
+
/** Bottom-left corner of the box, in PDF points. */
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
/** Size in PDF points. Without a width the box fits its label; the default height is 14. */
|
|
17
|
+
width?: number;
|
|
18
|
+
height?: number;
|
|
19
|
+
label: string;
|
|
20
|
+
tone?: PdfViewerTone;
|
|
21
|
+
}
|
|
22
|
+
export interface PdfViewerLoadedEvent {
|
|
23
|
+
pageCount: number;
|
|
24
|
+
/** Every page's size in PDF points at scale 1. */
|
|
25
|
+
pages: {
|
|
26
|
+
width: number;
|
|
27
|
+
height: number;
|
|
28
|
+
}[];
|
|
29
|
+
/** The loaded pdf.js document, so the host can read text content. The viewer destroys it when it is replaced or the viewer goes away. */
|
|
30
|
+
document: PDFDocumentProxy;
|
|
31
|
+
}
|
|
32
|
+
export interface PdfViewerRenderedEvent {
|
|
33
|
+
pageCount: number;
|
|
34
|
+
/** CSS px per PDF point of the first page. */
|
|
35
|
+
scale: number;
|
|
36
|
+
/** Displayed (CSS px) width of every page. */
|
|
37
|
+
pageWidths: number[];
|
|
38
|
+
}
|
|
39
|
+
type PdfJsModule = typeof import('pdfjs-dist');
|
|
40
|
+
type Status = 'idle' | 'loading' | 'ready' | 'error';
|
|
41
|
+
interface PageView {
|
|
42
|
+
number: number;
|
|
43
|
+
cssWidth: number;
|
|
44
|
+
cssHeight: number;
|
|
45
|
+
canvasWidth: number;
|
|
46
|
+
canvasHeight: number;
|
|
47
|
+
fields: FieldView[];
|
|
48
|
+
}
|
|
49
|
+
interface FieldView {
|
|
50
|
+
id: string;
|
|
51
|
+
label: string;
|
|
52
|
+
tone: PdfViewerTone;
|
|
53
|
+
left: number;
|
|
54
|
+
top: number;
|
|
55
|
+
width: number | null;
|
|
56
|
+
maxWidth: number;
|
|
57
|
+
height: number;
|
|
58
|
+
fontPx: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Renders every page of a PDF into a canvas (crisp on high-density screens), with optional labelled boxes overlaid in PDF coordinates.
|
|
62
|
+
* Needs `pdfjs-dist` (loaded on first use, so it stays out of bundles that never show a PDF).
|
|
63
|
+
*
|
|
64
|
+
* <ui-pdf-viewer [data]="buffer()" [fields]="badges()" ariaLabel="Contract preview" (loaded)="onLoaded($event)" />
|
|
65
|
+
* <ui-pdf-viewer src="/files/contract.pdf" [httpHeaders]="{ Authorization: 'Bearer ' + token }" />
|
|
66
|
+
*
|
|
67
|
+
* - `src` / `data`: a URL, or the bytes (`data` wins). The bytes are copied, so your buffer stays usable.
|
|
68
|
+
* - `workerSrc` or the `PDF_VIEWER_WORKER_SRC` token: the pdf.js worker URL. Without either the viewer shows "PDF worker is not configured."
|
|
69
|
+
* - `maxPageWidth` (default 700): pages are drawn this wide, or the container's width when narrower; never larger.
|
|
70
|
+
* - `pixelRatio`: canvas pixels per CSS pixel; default is the screen's ratio between 1 and 3.
|
|
71
|
+
* - `fields`: badges positioned in PDF points (origin bottom-left); they scale with the page.
|
|
72
|
+
* - `loaded` / `pagesRendered` / `loadFailed`: see the event types. A new `src` / `data` replaces the document; a slow older load never paints.
|
|
73
|
+
* A page that fails to draw after `loaded` also emits `loadFailed`, shows the error state and destroys the document that `loaded` handed to the host.
|
|
74
|
+
* - A page's canvas never exceeds 16,000,000 pixels (Safari limit); the pixel ratio is lowered for such a page, its CSS size is unchanged.
|
|
75
|
+
* - All canvases together never exceed 48,000,000 pixels (iOS Safari limits total canvas memory): a long document is drawn at a lower
|
|
76
|
+
* density, the same for every page and never below 1 pixel per CSS pixel. CSS sizes are unchanged.
|
|
77
|
+
* - `httpHeaders` and `withCredentials` apply to `src` only; they are not used when `data` is given.
|
|
78
|
+
* - `fields[].id` is only a display / test hook; duplicates are tolerated. `httpHeaders` is compared by content, but a stable reference is still preferred.
|
|
79
|
+
* - The worker-missing message is fixed text and ignores `errorText`, because it is a setup problem for the developer.
|
|
80
|
+
* - Needs pdf.js 5 (`pdfjs-dist` >= 5), which needs Safari 17.4+; the legacy pdf.js build is not supported by this component.
|
|
81
|
+
* - The public typings reference `pdfjs-dist` types: apps that type-check the library without `pdfjs-dist` installed need `skipLibCheck` or the
|
|
82
|
+
* package (the same trade-off as `@forgeroute/ui/charts` and chart.js).
|
|
83
|
+
*/
|
|
84
|
+
export declare class PdfViewerComponent {
|
|
85
|
+
/** PDF URL. Ignored while `data` is set. */
|
|
86
|
+
readonly src: import("@angular/core").InputSignal<string | null>;
|
|
87
|
+
/** PDF bytes. Wins over `src`. */
|
|
88
|
+
readonly data: import("@angular/core").InputSignal<ArrayBuffer | Uint8Array<ArrayBufferLike> | null>;
|
|
89
|
+
/** Request headers for `src`. Changes are detected by content, but pass a stable reference when you can. */
|
|
90
|
+
readonly httpHeaders: import("@angular/core").InputSignal<Record<string, string>>;
|
|
91
|
+
readonly withCredentials: import("@angular/core").InputSignal<boolean>;
|
|
92
|
+
/** pdf.js worker URL; falls back to the `PDF_VIEWER_WORKER_SRC` token. */
|
|
93
|
+
readonly workerSrc: import("@angular/core").InputSignal<string>;
|
|
94
|
+
/** Widest a page is drawn, in CSS px. */
|
|
95
|
+
readonly maxPageWidth: import("@angular/core").InputSignal<number>;
|
|
96
|
+
/** Canvas pixels per CSS pixel; null = the screen's ratio, limited to 1..3. */
|
|
97
|
+
readonly pixelRatio: import("@angular/core").InputSignal<number | null>;
|
|
98
|
+
readonly fields: import("@angular/core").InputSignal<PdfViewerField[]>;
|
|
99
|
+
/** Accessible name of the viewer. */
|
|
100
|
+
readonly ariaLabel: import("@angular/core").InputSignal<string>;
|
|
101
|
+
readonly loadingText: import("@angular/core").InputSignal<string>;
|
|
102
|
+
readonly errorText: import("@angular/core").InputSignal<string>;
|
|
103
|
+
readonly loaded: import("@angular/core").OutputEmitterRef<PdfViewerLoadedEvent>;
|
|
104
|
+
readonly loadFailed: import("@angular/core").OutputEmitterRef<unknown>;
|
|
105
|
+
readonly pagesRendered: import("@angular/core").OutputEmitterRef<PdfViewerRenderedEvent>;
|
|
106
|
+
protected readonly status: import("@angular/core").WritableSignal<Status>;
|
|
107
|
+
private readonly pageSizes;
|
|
108
|
+
private readonly containerWidth;
|
|
109
|
+
private readonly customError;
|
|
110
|
+
protected readonly errorMessage: import("@angular/core").Signal<string>;
|
|
111
|
+
/** Changes exactly when some canvas bitmap changes size (and so is cleared). */
|
|
112
|
+
private readonly drawKey;
|
|
113
|
+
private readonly effectiveWidth;
|
|
114
|
+
protected readonly views: import("@angular/core").Signal<PageView[]>;
|
|
115
|
+
private readonly host;
|
|
116
|
+
private readonly injector;
|
|
117
|
+
private readonly tokenWorkerSrc;
|
|
118
|
+
private readonly isBrowser;
|
|
119
|
+
private readonly headersKey;
|
|
120
|
+
/** Bumped by every new load, replacement and destroy; an async step whose token no longer matches stops. */
|
|
121
|
+
private loadToken;
|
|
122
|
+
/** Bumped by every (re)draw so only the newest draw paints. */
|
|
123
|
+
private drawToken;
|
|
124
|
+
private doc;
|
|
125
|
+
private loadingTask;
|
|
126
|
+
private pageProxies;
|
|
127
|
+
private renderTasks;
|
|
128
|
+
private observer;
|
|
129
|
+
private frame;
|
|
130
|
+
private lastDrawKey;
|
|
131
|
+
constructor();
|
|
132
|
+
/** Test seam: loads pdf.js on first use so apps that never show a PDF do not bundle or fetch it. */
|
|
133
|
+
protected loadPdfJs(): Promise<PdfJsModule>;
|
|
134
|
+
private resolvedRatio;
|
|
135
|
+
private widthFor;
|
|
136
|
+
private startLoad;
|
|
137
|
+
private fail;
|
|
138
|
+
private scheduleDraw;
|
|
139
|
+
private draw;
|
|
140
|
+
private onResize;
|
|
141
|
+
private cancelRenders;
|
|
142
|
+
private teardown;
|
|
143
|
+
private destroyDoc;
|
|
144
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PdfViewerComponent, never>;
|
|
145
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<PdfViewerComponent, "ui-pdf-viewer", never, {
|
|
146
|
+
"src": {
|
|
147
|
+
"alias": "src";
|
|
148
|
+
"required": false;
|
|
149
|
+
"isSignal": true;
|
|
150
|
+
};
|
|
151
|
+
"data": {
|
|
152
|
+
"alias": "data";
|
|
153
|
+
"required": false;
|
|
154
|
+
"isSignal": true;
|
|
155
|
+
};
|
|
156
|
+
"httpHeaders": {
|
|
157
|
+
"alias": "httpHeaders";
|
|
158
|
+
"required": false;
|
|
159
|
+
"isSignal": true;
|
|
160
|
+
};
|
|
161
|
+
"withCredentials": {
|
|
162
|
+
"alias": "withCredentials";
|
|
163
|
+
"required": false;
|
|
164
|
+
"isSignal": true;
|
|
165
|
+
};
|
|
166
|
+
"workerSrc": {
|
|
167
|
+
"alias": "workerSrc";
|
|
168
|
+
"required": false;
|
|
169
|
+
"isSignal": true;
|
|
170
|
+
};
|
|
171
|
+
"maxPageWidth": {
|
|
172
|
+
"alias": "maxPageWidth";
|
|
173
|
+
"required": false;
|
|
174
|
+
"isSignal": true;
|
|
175
|
+
};
|
|
176
|
+
"pixelRatio": {
|
|
177
|
+
"alias": "pixelRatio";
|
|
178
|
+
"required": false;
|
|
179
|
+
"isSignal": true;
|
|
180
|
+
};
|
|
181
|
+
"fields": {
|
|
182
|
+
"alias": "fields";
|
|
183
|
+
"required": false;
|
|
184
|
+
"isSignal": true;
|
|
185
|
+
};
|
|
186
|
+
"ariaLabel": {
|
|
187
|
+
"alias": "ariaLabel";
|
|
188
|
+
"required": false;
|
|
189
|
+
"isSignal": true;
|
|
190
|
+
};
|
|
191
|
+
"loadingText": {
|
|
192
|
+
"alias": "loadingText";
|
|
193
|
+
"required": false;
|
|
194
|
+
"isSignal": true;
|
|
195
|
+
};
|
|
196
|
+
"errorText": {
|
|
197
|
+
"alias": "errorText";
|
|
198
|
+
"required": false;
|
|
199
|
+
"isSignal": true;
|
|
200
|
+
};
|
|
201
|
+
}, {
|
|
202
|
+
"loaded": "loaded";
|
|
203
|
+
"loadFailed": "loadFailed";
|
|
204
|
+
"pagesRendered": "pagesRendered";
|
|
205
|
+
}, never, never, true, never>;
|
|
206
|
+
}
|
package/types/forgeroute-ui.d.ts
CHANGED
|
@@ -834,7 +834,7 @@ export declare class SelectComponent implements ControlValueAccessor, Validator,
|
|
|
834
834
|
readonly error: import("@angular/core").InputSignal<string>;
|
|
835
835
|
/** Reveal the built-in error messages now (e.g. after a failed Save click), without waiting for blur. */
|
|
836
836
|
readonly showErrors: import("@angular/core").InputSignal<boolean>;
|
|
837
|
-
readonly size: import("@angular/core").InputSignal<"
|
|
837
|
+
readonly size: import("@angular/core").InputSignal<"sm" | "default">;
|
|
838
838
|
readonly _disabledInput: import("@angular/core").InputSignal<boolean>;
|
|
839
839
|
private readonly _cvaDisabled;
|
|
840
840
|
protected readonly disabled: import("@angular/core").Signal<boolean>;
|
|
@@ -1685,7 +1685,7 @@ export declare class ModalComponent implements OnInit, OnDestroy {
|
|
|
1685
1685
|
readonly title: import("@angular/core").InputSignal<string>;
|
|
1686
1686
|
readonly description: import("@angular/core").InputSignal<string>;
|
|
1687
1687
|
readonly maxWidth: import("@angular/core").InputSignal<string>;
|
|
1688
|
-
readonly bodyOverflow: import("@angular/core").InputSignal<"auto" | "
|
|
1688
|
+
readonly bodyOverflow: import("@angular/core").InputSignal<"auto" | "visible" | "hidden">;
|
|
1689
1689
|
readonly close: import("@angular/core").OutputEmitterRef<void>;
|
|
1690
1690
|
protected readonly titleId: string;
|
|
1691
1691
|
private readonly el;
|
|
@@ -1843,7 +1843,7 @@ export declare class AudioPlayerComponent {
|
|
|
1843
1843
|
/** Accessible name of the player. */
|
|
1844
1844
|
readonly ariaLabel: import("@angular/core").InputSignal<string>;
|
|
1845
1845
|
/** How much to load before play: 'metadata' (default), 'auto' or 'none'. */
|
|
1846
|
-
readonly preload: import("@angular/core").InputSignal<"
|
|
1846
|
+
readonly preload: import("@angular/core").InputSignal<"auto" | "none" | "metadata">;
|
|
1847
1847
|
/** Fires when the browser can't load or decode the source. */
|
|
1848
1848
|
readonly playbackError: import("@angular/core").OutputEmitterRef<void>;
|
|
1849
1849
|
protected readonly failed: import("@angular/core").WritableSignal<boolean>;
|
|
@@ -2111,7 +2111,7 @@ export declare class ButtonComponent {
|
|
|
2111
2111
|
readonly color: import("@angular/core").InputSignal<string | undefined>;
|
|
2112
2112
|
readonly active: import("@angular/core").InputSignal<boolean>;
|
|
2113
2113
|
readonly size: import("@angular/core").InputSignal<"sm" | "md" | "xs" | "lg">;
|
|
2114
|
-
readonly type: import("@angular/core").InputSignal<"
|
|
2114
|
+
readonly type: import("@angular/core").InputSignal<"button" | "reset" | "submit">;
|
|
2115
2115
|
readonly disabled: import("@angular/core").InputSignal<boolean>;
|
|
2116
2116
|
readonly loading: import("@angular/core").InputSignal<boolean>;
|
|
2117
2117
|
readonly fullWidth: import("@angular/core").InputSignal<boolean>;
|
|
@@ -4816,7 +4816,7 @@ export declare class FormSectionComponent {
|
|
|
4816
4816
|
}, {}, never, ["*"], true, never>;
|
|
4817
4817
|
}
|
|
4818
4818
|
export declare class FormRowComponent {
|
|
4819
|
-
readonly cols: import("@angular/core").InputSignal<
|
|
4819
|
+
readonly cols: import("@angular/core").InputSignal<2 | 1 | 3>;
|
|
4820
4820
|
static ɵfac: i0.ɵɵFactoryDeclaration<FormRowComponent, never>;
|
|
4821
4821
|
static ɵcmp: i0.ɵɵComponentDeclaration<FormRowComponent, "ui-form-row", never, {
|
|
4822
4822
|
"cols": {
|
|
@@ -6146,7 +6146,7 @@ export declare class DetailCardComponent {
|
|
|
6146
6146
|
/** Bold uppercase title. Empty = no title text. */
|
|
6147
6147
|
readonly title: import("@angular/core").InputSignal<string>;
|
|
6148
6148
|
/** 1-6 makes the title a real heading for screen readers (role=heading, aria-level); null keeps it plain text. */
|
|
6149
|
-
readonly headingLevel: import("@angular/core").InputSignal<
|
|
6149
|
+
readonly headingLevel: import("@angular/core").InputSignal<2 | 1 | 5 | 3 | 6 | 4 | null>;
|
|
6150
6150
|
/** Optional id for the title text; the card is then labelled by it. Without it the title is the card's aria-label. */
|
|
6151
6151
|
readonly titleId: import("@angular/core").InputSignal<string>;
|
|
6152
6152
|
/** Grey line under the title. */
|