@rt-tools/ui-kit-v2 0.25.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,677 @@
1
+ import { CdkTrapFocus } from "@angular/cdk/a11y";
2
+ import { DOCUMENT } from "@angular/common";
3
+ import * as i0 from "@angular/core";
4
+ import { ChangeDetectionStrategy, Component, DestroyRef, ElementRef, InjectionToken, Injector, ViewEncapsulation, afterNextRender, computed, inject, signal, viewChild, viewChildren } from "@angular/core";
5
+ import { BlockDirective, ElemDirective, WINDOW } from "@rt-tools/core";
6
+ import { RT_KIT_LABELS, rtKitLabel } from "@rt-tools/ui-kit-v2/core";
7
+ import { RtButtonDirective } from "@rt-tools/ui-kit-v2/button";
8
+ import { RT_DIALOG_DATA, RtDialogRef } from "@rt-tools/ui-kit-v2/dialog";
9
+ import { RtEmptyStateComponent } from "@rt-tools/ui-kit-v2/empty-state";
10
+ import { RtIconComponent } from "@rt-tools/ui-kit-v2/icon";
11
+ import { RtIconButtonComponent } from "@rt-tools/ui-kit-v2/icon-button";
12
+ import { RtSpinnerComponent } from "@rt-tools/ui-kit-v2/spinner";
13
+ const RT_PDF_ZOOM_STEPS = [
14
+ 50,
15
+ 75,
16
+ 100,
17
+ 125,
18
+ 150,
19
+ 200,
20
+ 300
21
+ ];
22
+ const RT_PDF_ZOOM_MIN = RT_PDF_ZOOM_STEPS[0];
23
+ const RT_PDF_ZOOM_MAX = RT_PDF_ZOOM_STEPS[RT_PDF_ZOOM_STEPS.length - 1];
24
+ const RT_PDF_CSS_UNITS = 96 / 72;
25
+ const RT_PDF_NARROW_WIDTH = 768;
26
+ const EPSILON = .01;
27
+ function nextZoomStep(current, direction) {
28
+ if (direction > 0) return RT_PDF_ZOOM_STEPS.find((step) => step > current + EPSILON) ?? RT_PDF_ZOOM_MAX;
29
+ return [...RT_PDF_ZOOM_STEPS].reverse().find((step) => step < current - EPSILON) ?? RT_PDF_ZOOM_MIN;
30
+ }
31
+ function canZoomIn(current) {
32
+ return current < RT_PDF_ZOOM_MAX - EPSILON;
33
+ }
34
+ function canZoomOut(current) {
35
+ return current > RT_PDF_ZOOM_MIN + EPSILON;
36
+ }
37
+ function fitWidthPercent(availableWidth, pages) {
38
+ const widest = Math.max(0, ...pages.map((page) => page.width));
39
+ if (widest <= 0 || availableWidth <= 0) return 100;
40
+ return availableWidth / (widest * RT_PDF_CSS_UNITS) * 100;
41
+ }
42
+ function initialZoom(viewportWidth, availableWidth, pages) {
43
+ const widest = Math.max(0, ...pages.map((page) => page.width));
44
+ if (viewportWidth <= 768 || widest * 1.3333333333333333 > availableWidth) return { kind: "fit" };
45
+ return {
46
+ kind: "percent",
47
+ percent: 100
48
+ };
49
+ }
50
+ function pageBoxes(pages, percent) {
51
+ const scale = percent / 100 * RT_PDF_CSS_UNITS;
52
+ return pages.map((page, index) => ({
53
+ index,
54
+ width: Math.floor(page.width * scale),
55
+ height: Math.floor(page.height * scale)
56
+ }));
57
+ }
58
+ function visiblePageIndex(tops, heights, scrollTop, viewportHeight) {
59
+ const total = Math.min(tops.length, heights.length);
60
+ if (total === 0) return 0;
61
+ const contentBottom = tops[total - 1] + heights[total - 1];
62
+ if (scrollTop > 0 && scrollTop + viewportHeight >= contentBottom - 1) return total - 1;
63
+ let best = 0;
64
+ let bestArea = -1;
65
+ for (let index = 0; index < total; index++) {
66
+ const visible = Math.min(tops[index] + heights[index], scrollTop + viewportHeight) - Math.max(tops[index], scrollTop);
67
+ if (visible > bestArea) {
68
+ best = index;
69
+ bestArea = visible;
70
+ }
71
+ }
72
+ return best;
73
+ }
74
+ function pagesToRender(tops, heights, scrollTop, viewportHeight, overscan = 1) {
75
+ const total = Math.min(tops.length, heights.length);
76
+ const visible = [];
77
+ for (let index = 0; index < total; index++) if (tops[index] < scrollTop + viewportHeight && tops[index] + heights[index] > scrollTop) visible.push(index);
78
+ if (visible.length === 0) return [];
79
+ const first = Math.max(0, visible[0] - overscan);
80
+ const last = Math.min(total - 1, visible[visible.length - 1] + overscan);
81
+ return Array.from({ length: last - first + 1 }, (_, offset) => first + offset);
82
+ }
83
+ function anchoredScrollTop(oldTop, oldHeight, oldScrollTop, newTop, newHeight) {
84
+ if (oldHeight <= 0) return newTop;
85
+ const ratio = (oldScrollTop - oldTop) / oldHeight;
86
+ return Math.max(0, newTop + ratio * newHeight);
87
+ }
88
+ function zoomPercentLabel(percent) {
89
+ return `${Math.round(percent)}%`;
90
+ }
91
+ const RT_PDF_PRINT_BLOCK = "rt-pdf-viewer-print";
92
+ const RT_PDF_PRINTING_FLAG = "rt-pdf-viewer-printing";
93
+ const PRINT_DPI = 150;
94
+ function blobOf(bytes) {
95
+ const copy = bytes instanceof ArrayBuffer ? new Uint8Array(bytes.slice(0)) : new Uint8Array(bytes);
96
+ return new Blob([copy], { type: "application/pdf" });
97
+ }
98
+ function downloadPdf(doc, win, file, fileName) {
99
+ const anchor = doc.createElement("a");
100
+ const ownUrl = typeof file === "string" ? null : win.URL.createObjectURL(blobOf(file));
101
+ anchor.href = ownUrl ?? (typeof file === "string" ? file : "");
102
+ anchor.download = fileName;
103
+ anchor.rel = "noopener";
104
+ anchor.style.display = "none";
105
+ doc.body.append(anchor);
106
+ anchor.click();
107
+ anchor.remove();
108
+ if (ownUrl) win.setTimeout(() => win.URL.revokeObjectURL(ownUrl), 0);
109
+ }
110
+ function canvasBlob(canvas) {
111
+ return new Promise((resolve, reject) => {
112
+ canvas.toBlob((blob) => blob ? resolve(blob) : reject(/* @__PURE__ */ new Error("canvas is empty")), "image/png");
113
+ });
114
+ }
115
+ async function preparePrintSheet(pdf, doc, win) {
116
+ const sheet = doc.createElement("div");
117
+ const urls = [];
118
+ const images = [];
119
+ sheet.classList.add(RT_PDF_PRINT_BLOCK);
120
+ const dispose = () => {
121
+ doc.documentElement.classList.remove(RT_PDF_PRINTING_FLAG);
122
+ sheet.remove();
123
+ for (const url of urls) win.URL.revokeObjectURL(url);
124
+ };
125
+ try {
126
+ for (let pageNumber = 1; pageNumber <= pdf.numPages; pageNumber++) {
127
+ const page = await pdf.getPage(pageNumber);
128
+ const viewport = page.getViewport({ scale: PRINT_DPI / 72 });
129
+ const canvas = doc.createElement("canvas");
130
+ canvas.width = Math.floor(viewport.width);
131
+ canvas.height = Math.floor(viewport.height);
132
+ await page.render({
133
+ canvas,
134
+ viewport,
135
+ intent: "print"
136
+ }).promise;
137
+ const url = win.URL.createObjectURL(await canvasBlob(canvas));
138
+ urls.push(url);
139
+ canvas.width = 0;
140
+ canvas.height = 0;
141
+ const image = doc.createElement("img");
142
+ image.classList.add(`${RT_PDF_PRINT_BLOCK}__page`);
143
+ image.alt = "";
144
+ image.src = url;
145
+ images.push(image);
146
+ sheet.append(image);
147
+ }
148
+ doc.body.append(sheet);
149
+ await Promise.all(images.map((image) => image.decode().catch(() => void 0)));
150
+ doc.documentElement.classList.add(RT_PDF_PRINTING_FLAG);
151
+ } catch (error) {
152
+ dispose();
153
+ throw error;
154
+ }
155
+ return { dispose };
156
+ }
157
+ const RT_PDF_VIEWER_WORKER_SRC = "assets/pdfjs/pdf.worker.min.mjs";
158
+ function loadPdfJs() {
159
+ return import("pdfjs-dist");
160
+ }
161
+ const RT_PDF_VIEWER_CONFIG = new InjectionToken("RT_PDF_VIEWER_CONFIG", {
162
+ providedIn: "root",
163
+ factory: () => ({
164
+ workerSrc: RT_PDF_VIEWER_WORKER_SRC,
165
+ load: loadPdfJs
166
+ })
167
+ });
168
+ function provideRtPdfViewer(config) {
169
+ return {
170
+ provide: RT_PDF_VIEWER_CONFIG,
171
+ useValue: {
172
+ workerSrc: RT_PDF_VIEWER_WORKER_SRC,
173
+ load: loadPdfJs,
174
+ ...config
175
+ }
176
+ };
177
+ }
178
+ const BEM_BLOCK = "rt-pdf-viewer";
179
+ const KEEP_OVERSCAN = 3;
180
+ var RtPdfViewerComponent = class RtPdfViewerComponent {
181
+ #data;
182
+ #dialogRef;
183
+ #config;
184
+ #host;
185
+ #document;
186
+ #window;
187
+ #injector;
188
+ #opener;
189
+ #availableWidth;
190
+ #pageSizes;
191
+ #pageOfParams;
192
+ #loadingTask;
193
+ #pdf;
194
+ #pages;
195
+ #rendered;
196
+ #printSheet;
197
+ #destroyed;
198
+ constructor() {
199
+ this.#data = inject(RT_DIALOG_DATA);
200
+ this.#dialogRef = inject(RtDialogRef);
201
+ this.#config = inject(RT_PDF_VIEWER_CONFIG);
202
+ this.#host = inject(ElementRef);
203
+ this.#document = inject(DOCUMENT);
204
+ this.#window = inject(WINDOW);
205
+ this.#injector = inject(Injector);
206
+ this.#opener = this.#focusedElement();
207
+ this.#availableWidth = signal(0, ...ngDevMode ? [{ debugName: "#availableWidth" }] : /* istanbul ignore next */ []);
208
+ this.#pageSizes = signal([], ...ngDevMode ? [{ debugName: "#pageSizes" }] : /* istanbul ignore next */ []);
209
+ this.#pageOfParams = computed(() => ({
210
+ page: this.currentPage() + 1,
211
+ total: this.#pageSizes().length
212
+ }), ...ngDevMode ? [{ debugName: "#pageOfParams" }] : /* istanbul ignore next */ []);
213
+ this.#loadingTask = null;
214
+ this.#pdf = null;
215
+ this.#pages = /* @__PURE__ */ new Map();
216
+ this.#rendered = /* @__PURE__ */ new Map();
217
+ this.#printSheet = null;
218
+ this.#destroyed = false;
219
+ this.t = inject(RT_KIT_LABELS);
220
+ this.scroller = viewChild("scroller", ...ngDevMode ? [{ debugName: "scroller" }] : /* istanbul ignore next */ []);
221
+ this.column = viewChild("column", ...ngDevMode ? [{ debugName: "column" }] : /* istanbul ignore next */ []);
222
+ this.pageNodes = viewChildren("page", ...ngDevMode ? [{ debugName: "pageNodes" }] : /* istanbul ignore next */ []);
223
+ this.canvases = viewChildren("canvas", ...ngDevMode ? [{ debugName: "canvases" }] : /* istanbul ignore next */ []);
224
+ this.fileName = this.#data.fileName;
225
+ this.status = signal("loading", ...ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []);
226
+ this.printing = signal(false, ...ngDevMode ? [{ debugName: "printing" }] : /* istanbul ignore next */ []);
227
+ this.zoom = signal({
228
+ kind: "percent",
229
+ percent: 100
230
+ }, ...ngDevMode ? [{ debugName: "zoom" }] : /* istanbul ignore next */ []);
231
+ this.percent = computed(() => {
232
+ const zoom = this.zoom();
233
+ return zoom.kind === "fit" ? fitWidthPercent(this.#availableWidth(), this.#pageSizes()) : zoom.percent;
234
+ }, ...ngDevMode ? [{ debugName: "percent" }] : /* istanbul ignore next */ []);
235
+ this.isFit = computed(() => this.zoom().kind === "fit", ...ngDevMode ? [{ debugName: "isFit" }] : /* istanbul ignore next */ []);
236
+ this.zoomLabel = computed(() => this.isFit() ? this.t().pdfViewerFitWidth : zoomPercentLabel(this.percent()), ...ngDevMode ? [{ debugName: "zoomLabel" }] : /* istanbul ignore next */ []);
237
+ this.canZoomIn = computed(() => canZoomIn(this.percent()), ...ngDevMode ? [{ debugName: "canZoomIn" }] : /* istanbul ignore next */ []);
238
+ this.canZoomOut = computed(() => canZoomOut(this.percent()), ...ngDevMode ? [{ debugName: "canZoomOut" }] : /* istanbul ignore next */ []);
239
+ this.boxes = computed(() => pageBoxes(this.#pageSizes(), this.percent()), ...ngDevMode ? [{ debugName: "boxes" }] : /* istanbul ignore next */ []);
240
+ this.currentPage = signal(0, ...ngDevMode ? [{ debugName: "currentPage" }] : /* istanbul ignore next */ []);
241
+ this.counter = computed(() => `${this.currentPage() + 1} / ${this.#pageSizes().length}`, ...ngDevMode ? [{ debugName: "counter" }] : /* istanbul ignore next */ []);
242
+ this.pageOfLabel = rtKitLabel("pdfViewerPageOf", this.#pageOfParams);
243
+ inject(DestroyRef).onDestroy(() => this.#teardown());
244
+ afterNextRender(() => {
245
+ this.#host.nativeElement.focus();
246
+ this.#open();
247
+ });
248
+ }
249
+ close() {
250
+ this.#dialogRef.close();
251
+ }
252
+ onEscape(event) {
253
+ event.stopPropagation();
254
+ this.close();
255
+ }
256
+ zoomIn() {
257
+ this.#setZoom({
258
+ kind: "percent",
259
+ percent: nextZoomStep(this.percent(), 1)
260
+ });
261
+ }
262
+ zoomOut() {
263
+ this.#setZoom({
264
+ kind: "percent",
265
+ percent: nextZoomStep(this.percent(), -1)
266
+ });
267
+ }
268
+ fitWidth() {
269
+ this.#measure();
270
+ this.#setZoom({ kind: "fit" });
271
+ }
272
+ onScroll() {
273
+ this.#renderVisible();
274
+ }
275
+ onResize() {
276
+ if (this.status() !== "ready") return;
277
+ this.#measure();
278
+ if (this.isFit()) this.#afterLayout(() => this.#renderVisible());
279
+ }
280
+ async download() {
281
+ const source = this.#data.source;
282
+ if (typeof source !== "string") {
283
+ downloadPdf(this.#document, this.#window, source, this.fileName);
284
+ return;
285
+ }
286
+ const bytes = this.#pdf ? await this.#pdf.getData().catch(() => null) : null;
287
+ downloadPdf(this.#document, this.#window, bytes ?? source, this.fileName);
288
+ }
289
+ async print() {
290
+ const pdf = this.#pdf;
291
+ if (!pdf || this.printing()) return;
292
+ this.printing.set(true);
293
+ try {
294
+ this.#printSheet?.dispose();
295
+ const sheet = await preparePrintSheet(pdf, this.#document, this.#window);
296
+ if (this.#destroyed) {
297
+ sheet.dispose();
298
+ return;
299
+ }
300
+ this.#printSheet = sheet;
301
+ this.#window.addEventListener("afterprint", () => {
302
+ sheet.dispose();
303
+ if (this.#printSheet === sheet) this.#printSheet = null;
304
+ }, { once: true });
305
+ this.#window.print();
306
+ } catch {
307
+ this.#printSheet?.dispose();
308
+ this.#printSheet = null;
309
+ } finally {
310
+ this.printing.set(false);
311
+ }
312
+ }
313
+ async #open() {
314
+ try {
315
+ const pdfjs = await this.#config.load();
316
+ if (this.#destroyed) return;
317
+ pdfjs.GlobalWorkerOptions.workerSrc = this.#config.workerSrc;
318
+ this.#loadingTask = pdfjs.getDocument(this.#documentParams());
319
+ const pdf = await this.#loadingTask.promise;
320
+ if (this.#destroyed) return;
321
+ this.#pdf = pdf;
322
+ const sizes = await Promise.all(Array.from({ length: pdf.numPages }, async (_, index) => {
323
+ const viewport = (await this.#page(index)).getViewport({ scale: 1 });
324
+ return {
325
+ width: viewport.width,
326
+ height: viewport.height
327
+ };
328
+ }));
329
+ if (this.#destroyed) return;
330
+ this.#measure();
331
+ this.zoom.set(initialZoom(this.#host.nativeElement.clientWidth, this.#availableWidth(), sizes));
332
+ this.#pageSizes.set(sizes);
333
+ this.status.set("ready");
334
+ this.#afterLayout(() => this.#renderVisible());
335
+ } catch {
336
+ if (!this.#destroyed) this.status.set("error");
337
+ }
338
+ }
339
+ #documentParams() {
340
+ const source = this.#data.source;
341
+ return {
342
+ ...typeof source === "string" ? { url: source } : { data: source instanceof ArrayBuffer ? new Uint8Array(source.slice(0)) : source.slice() },
343
+ ...this.#config.cMapUrl ? {
344
+ cMapUrl: this.#config.cMapUrl,
345
+ cMapPacked: true
346
+ } : {},
347
+ ...this.#config.standardFontDataUrl ? { standardFontDataUrl: this.#config.standardFontDataUrl } : {},
348
+ ...this.#config.wasmUrl ? { wasmUrl: this.#config.wasmUrl } : {}
349
+ };
350
+ }
351
+ #page(index) {
352
+ const pdf = this.#pdf;
353
+ if (!pdf) return Promise.reject(/* @__PURE__ */ new Error("document is not loaded"));
354
+ let page = this.#pages.get(index);
355
+ if (!page) {
356
+ page = pdf.getPage(index + 1);
357
+ this.#pages.set(index, page);
358
+ }
359
+ return page;
360
+ }
361
+ #measure() {
362
+ const scroller = this.scroller()?.nativeElement;
363
+ const column = this.column()?.nativeElement;
364
+ if (!scroller || !column) return;
365
+ const style = this.#window.getComputedStyle(column);
366
+ const padding = (parseFloat(style.paddingLeft) || 0) + (parseFloat(style.paddingRight) || 0);
367
+ this.#availableWidth.set(Math.max(0, scroller.clientWidth - padding));
368
+ }
369
+ #setZoom(zoom) {
370
+ const scroller = this.scroller()?.nativeElement;
371
+ const current = this.currentPage();
372
+ const node = this.pageNodes()[current]?.nativeElement;
373
+ const before = scroller && node ? {
374
+ top: node.offsetTop,
375
+ height: node.offsetHeight,
376
+ scrollTop: scroller.scrollTop
377
+ } : null;
378
+ this.zoom.set(zoom);
379
+ this.#afterLayout(() => {
380
+ const after = this.pageNodes()[current]?.nativeElement;
381
+ if (scroller && after && before) scroller.scrollTop = anchoredScrollTop(before.top, before.height, before.scrollTop, after.offsetTop, after.offsetHeight);
382
+ this.#renderVisible();
383
+ });
384
+ }
385
+ #afterLayout(callback) {
386
+ afterNextRender(callback, { injector: this.#injector });
387
+ }
388
+ #renderVisible() {
389
+ const scroller = this.scroller()?.nativeElement;
390
+ const nodes = this.pageNodes();
391
+ if (!scroller || nodes.length === 0 || this.#destroyed) return;
392
+ const tops = nodes.map((node) => node.nativeElement.offsetTop);
393
+ const heights = nodes.map((node) => node.nativeElement.offsetHeight);
394
+ const { scrollTop, clientHeight } = scroller;
395
+ this.currentPage.set(visiblePageIndex(tops, heights, scrollTop, clientHeight));
396
+ const keep = new Set(pagesToRender(tops, heights, scrollTop, clientHeight, KEEP_OVERSCAN));
397
+ for (const index of [...this.#rendered.keys()]) if (!keep.has(index)) this.#clearPage(index);
398
+ for (const index of pagesToRender(tops, heights, scrollTop, clientHeight)) this.#renderPage(index);
399
+ }
400
+ async #renderPage(index) {
401
+ const percent = this.percent();
402
+ const existing = this.#rendered.get(index);
403
+ if (existing?.percent === percent) return;
404
+ existing?.task.cancel();
405
+ this.#rendered.delete(index);
406
+ const canvas = this.canvases()[index]?.nativeElement;
407
+ const box = this.boxes()[index];
408
+ if (!canvas || !box) return;
409
+ try {
410
+ const page = await this.#page(index);
411
+ if (this.#destroyed || this.percent() !== percent || this.#rendered.has(index)) return;
412
+ const ratio = this.#window.devicePixelRatio || 1;
413
+ const viewport = page.getViewport({ scale: box.width / page.getViewport({ scale: 1 }).width * ratio });
414
+ canvas.width = Math.floor(viewport.width);
415
+ canvas.height = Math.floor(viewport.height);
416
+ const task = page.render({
417
+ canvas,
418
+ viewport
419
+ });
420
+ this.#rendered.set(index, {
421
+ percent,
422
+ task
423
+ });
424
+ await task.promise;
425
+ } catch {
426
+ if (this.#rendered.get(index)?.percent === percent) this.#rendered.delete(index);
427
+ }
428
+ }
429
+ #clearPage(index) {
430
+ this.#rendered.get(index)?.task.cancel();
431
+ this.#rendered.delete(index);
432
+ const canvas = this.canvases()[index]?.nativeElement;
433
+ if (canvas) {
434
+ canvas.width = 0;
435
+ canvas.height = 0;
436
+ }
437
+ }
438
+ #teardown() {
439
+ this.#destroyed = true;
440
+ for (const rendered of this.#rendered.values()) rendered.task.cancel();
441
+ this.#rendered.clear();
442
+ this.#printSheet?.dispose();
443
+ this.#printSheet = null;
444
+ this.#loadingTask?.destroy().catch(() => void 0);
445
+ this.#pdf = null;
446
+ if (this.#opener?.isConnected) this.#opener.focus();
447
+ }
448
+ #focusedElement() {
449
+ const active = this.#document.activeElement;
450
+ return active instanceof HTMLElement && active !== this.#document.body ? active : null;
451
+ }
452
+ static {
453
+ this.ɵfac = i0.ɵɵngDeclareFactory({
454
+ minVersion: "12.0.0",
455
+ version: "22.2.2",
456
+ ngImport: i0,
457
+ type: RtPdfViewerComponent,
458
+ deps: [],
459
+ target: i0.ɵɵFactoryTarget.Component
460
+ });
461
+ }
462
+ static {
463
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
464
+ minVersion: "17.0.0",
465
+ version: "22.2.2",
466
+ type: RtPdfViewerComponent,
467
+ isStandalone: true,
468
+ selector: "rt-pdf-viewer",
469
+ host: {
470
+ attributes: {
471
+ "role": "dialog",
472
+ "aria-modal": "true",
473
+ "tabindex": "-1"
474
+ },
475
+ listeners: {
476
+ "keydown.escape": "onEscape($event)",
477
+ "window:resize": "onResize()"
478
+ },
479
+ properties: { "attr.aria-label": "fileName" },
480
+ classAttribute: "rt-pdf-viewer"
481
+ },
482
+ viewQueries: [
483
+ {
484
+ propertyName: "scroller",
485
+ first: true,
486
+ predicate: ["scroller"],
487
+ descendants: true,
488
+ isSignal: true
489
+ },
490
+ {
491
+ propertyName: "column",
492
+ first: true,
493
+ predicate: ["column"],
494
+ descendants: true,
495
+ isSignal: true
496
+ },
497
+ {
498
+ propertyName: "pageNodes",
499
+ predicate: ["page"],
500
+ descendants: true,
501
+ isSignal: true
502
+ },
503
+ {
504
+ propertyName: "canvases",
505
+ predicate: ["canvas"],
506
+ descendants: true,
507
+ isSignal: true
508
+ }
509
+ ],
510
+ ngImport: i0,
511
+ template: "<ng-container rtBlock=\"rt-pdf-viewer\">\n <!-- Ловушка держит Tab внутри; фокус ставит сам компонент, поэтому авто-захвата здесь нет -->\n <div rtElem=\"surface\" cdkTrapFocus>\n <!-- Полоса видна сразу, ещё до загрузки документа: человек видит, что открыл, и может закрыть -->\n <header rtElem=\"bar\">\n <div rtElem=\"title\">\n <rt-icon rtElem=\"file-icon\" name=\"attach-pdf\" size=\"md\" />\n <span rtElem=\"file-name\" qa-dataid=\"pdf-viewer-file-name\" [attr.title]=\"fileName\">{{ fileName }}</span>\n </div>\n\n <div rtElem=\"actions\">\n <rt-icon-button\n qa-dataid=\"pdf-viewer-print\"\n icon=\"print\"\n variant=\"ghost\"\n [ariaLabel]=\"t().pdfViewerPrint\"\n [tooltip]=\"t().pdfViewerPrint\"\n [disabled]=\"status() !== 'ready'\"\n [loading]=\"printing()\"\n (clicked)=\"print()\" />\n <rt-icon-button\n qa-dataid=\"pdf-viewer-download\"\n icon=\"ico-download\"\n variant=\"ghost\"\n [ariaLabel]=\"t().pdfViewerDownload\"\n [tooltip]=\"t().pdfViewerDownload\"\n (clicked)=\"download()\" />\n <rt-icon-button\n qa-dataid=\"pdf-viewer-close\"\n icon=\"close\"\n variant=\"ghost\"\n [ariaLabel]=\"t().pdfViewerClose\"\n [tooltip]=\"t().pdfViewerClose\"\n (clicked)=\"close()\" />\n </div>\n </header>\n\n <div rtElem=\"scroller\" qa-dataid=\"pdf-viewer-pages\" #scroller (scroll)=\"onScroll()\">\n <!-- Столбец стоит и до загрузки: по его ширине выбирается начальный масштаб -->\n <div rtElem=\"column\" #column>\n @if (status() === 'ready') {\n @for (box of boxes(); track box.index) {\n <div\n rtElem=\"page\"\n qa-dataid=\"pdf-viewer-page\"\n #page\n [attr.data-page-index]=\"box.index\"\n [style.width.px]=\"box.width\"\n [style.height.px]=\"box.height\">\n <canvas rtElem=\"canvas\" #canvas></canvas>\n </div>\n }\n }\n </div>\n </div>\n\n @switch (status()) {\n @case ('loading') {\n <div rtElem=\"center\">\n <rt-spinner qa-dataid=\"pdf-viewer-spinner\" color=\"on-primary\" [diameter]=\"40\" />\n </div>\n }\n\n @case ('error') {\n <div rtElem=\"center\">\n <rt-empty-state\n rtElem=\"error\"\n qa-dataid=\"pdf-viewer-error\"\n [title]=\"t().pdfViewerErrorTitle\"\n [description]=\"t().pdfViewerErrorText\">\n <button\n rtButton\n rtElem=\"error-download\"\n qa-dataid=\"pdf-viewer-error-download\"\n type=\"button\"\n icon=\"ico-download\"\n [label]=\"t().pdfViewerDownload\"\n [attr.aria-label]=\"t().pdfViewerDownload\"\n (click)=\"download()\"></button>\n </rt-empty-state>\n </div>\n }\n\n @case ('ready') {\n <div rtElem=\"toolbar\" qa-dataid=\"pdf-viewer-toolbar\">\n <span rtElem=\"counter\" qa-dataid=\"pdf-viewer-counter\" role=\"status\" aria-live=\"off\" [attr.aria-label]=\"pageOfLabel()\">\n {{ counter() }}\n </span>\n <span rtElem=\"divider\" aria-hidden=\"true\"></span>\n <rt-icon-button\n qa-dataid=\"pdf-viewer-zoom-out\"\n icon=\"minus\"\n variant=\"ghost\"\n size=\"sm\"\n [ariaLabel]=\"t().pdfViewerZoomOut\"\n [disabled]=\"!canZoomOut()\"\n (clicked)=\"zoomOut()\" />\n <span rtElem=\"zoom\" qa-dataid=\"pdf-viewer-zoom\">{{ zoomLabel() }}</span>\n <rt-icon-button\n qa-dataid=\"pdf-viewer-zoom-in\"\n icon=\"ico-plus\"\n variant=\"ghost\"\n size=\"sm\"\n [ariaLabel]=\"t().pdfViewerZoomIn\"\n [disabled]=\"!canZoomIn()\"\n (clicked)=\"zoomIn()\" />\n <span rtElem=\"fit-divider\" aria-hidden=\"true\"></span>\n <button\n rtButton\n rtElem=\"fit\"\n qa-dataid=\"pdf-viewer-fit\"\n type=\"button\"\n appearance=\"text\"\n size=\"sm\"\n [label]=\"t().pdfViewerFitWidth\"\n [attr.aria-label]=\"t().pdfViewerFitWidth\"\n [pressed]=\"isFit()\"\n (click)=\"fitWidth()\"></button>\n </div>\n }\n }\n </div>\n</ng-container>\n",
512
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-pdf-viewer{--rt-pdf-viewer-bg: var(--rt-neutral-900);--rt-pdf-viewer-bar-bg: color-mix(in srgb, var(--rt-neutral-900) 35%, var(--rt-neutral-950));--rt-pdf-viewer-bar-height: var(--rt-control-height-2xl);--rt-pdf-viewer-text-color: var(--rt-neutral-0);--rt-pdf-viewer-muted-color: var(--rt-neutral-200);--rt-pdf-viewer-page-bg: var(--rt-neutral-0);--rt-pdf-viewer-page-shadow: var(--rt-shadow-md);--rt-pdf-viewer-page-gap: var(--rt-space-4);--rt-pdf-viewer-toolbar-bg: var(--rt-neutral-800);--rt-pdf-viewer-toolbar-radius: var(--rt-radius-full);--rt-pdf-viewer-divider-width: var(--rt-border-width-thin);--rt-pdf-viewer-divider-color: color-mix(in srgb, var(--rt-neutral-0) 20%, transparent);--rt-pdf-viewer-control-radius: var(--rt-radius-md);--rt-pdf-viewer-control-bg: color-mix(in srgb, var(--rt-neutral-0) 10%, transparent);--rt-pdf-viewer-control-bg-hover: color-mix(in srgb, var(--rt-neutral-0) 24%, transparent);display:block;width:100vw;height:100vh;height:100dvh;background:var(--rt-pdf-viewer-bg);color:var(--rt-pdf-viewer-text-color)}.rt-pdf-viewer__surface{position:absolute;display:flex;flex-direction:column;inset:0}.rt-pdf-viewer__bar{display:flex;height:var(--rt-pdf-viewer-bar-height);flex:none;align-items:center;justify-content:space-between;padding:0 var(--rt-space-4);background:var(--rt-pdf-viewer-bar-bg);gap:var(--rt-space-4)}.rt-pdf-viewer__title{display:flex;min-width:0;align-items:center;gap:var(--rt-space-2)}.rt-pdf-viewer__file-icon{flex:none;color:var(--rt-pdf-viewer-text-color)}.rt-pdf-viewer__file-name{overflow:hidden;min-width:0;font-size:var(--rt-text-sm);text-overflow:ellipsis;white-space:nowrap}.rt-pdf-viewer__actions{display:flex;flex:none;align-items:center;gap:var(--rt-space-2)}.rt-pdf-viewer__actions rt-icon-button{--rt-icon-button-color: var(--rt-pdf-viewer-text-color);--rt-icon-button-color-bg-hover: var(--rt-pdf-viewer-control-bg-hover);border-radius:var(--rt-pdf-viewer-control-radius);background:var(--rt-pdf-viewer-control-bg)}.rt-pdf-viewer__scroller{position:relative;overflow:auto;flex:1 1 auto;overscroll-behavior:contain;scrollbar-gutter:stable}.rt-pdf-viewer__column{display:flex;width:max-content;min-width:100%;box-sizing:border-box;flex-direction:column;align-items:center;padding:var(--rt-space-4) var(--rt-space-4) var(--rt-space-24);gap:var(--rt-pdf-viewer-page-gap)}.rt-pdf-viewer__page{flex:none;background:var(--rt-pdf-viewer-page-bg);box-shadow:var(--rt-pdf-viewer-page-shadow)}.rt-pdf-viewer__canvas{display:block;width:100%;height:100%}.rt-pdf-viewer__center{position:absolute;display:flex;align-items:center;justify-content:center;padding:var(--rt-space-4);inset:var(--rt-pdf-viewer-bar-height) 0 0}.rt-pdf-viewer .rt-pdf-viewer__error{--rt-empty-state-title-color: var(--rt-pdf-viewer-text-color)}.rt-pdf-viewer .rt-pdf-viewer__error .rt-empty-state__description{color:var(--rt-pdf-viewer-muted-color)}.rt-pdf-viewer .rt-pdf-viewer__error-download{--rt-btn-bg: var(--rt-pdf-viewer-page-bg);--rt-btn-bg-hover: var(--rt-neutral-100);--rt-btn-bg-active: var(--rt-neutral-200);--rt-btn-color: var(--rt-neutral-900)}.rt-pdf-viewer__toolbar{position:absolute;bottom:var(--rt-space-6);left:50%;display:flex;align-items:center;padding:var(--rt-space-1) var(--rt-space-2);border-radius:var(--rt-pdf-viewer-toolbar-radius);background:var(--rt-pdf-viewer-toolbar-bg);gap:var(--rt-space-1);transform:translate(-50%);white-space:nowrap}.rt-pdf-viewer__toolbar rt-icon-button{--rt-icon-button-color: var(--rt-pdf-viewer-text-color);--rt-icon-button-color-bg-hover: var(--rt-pdf-viewer-control-bg-hover)}.rt-pdf-viewer__counter,.rt-pdf-viewer__zoom{padding:0 var(--rt-space-2);font-size:var(--rt-text-sm);font-variant-numeric:tabular-nums}.rt-pdf-viewer__zoom{min-width:var(--rt-size-12);text-align:center}.rt-pdf-viewer__divider,.rt-pdf-viewer__fit-divider{width:var(--rt-pdf-viewer-divider-width);height:var(--rt-size-5);margin:0 var(--rt-space-1);background:var(--rt-pdf-viewer-divider-color)}.rt-pdf-viewer .rt-pdf-viewer__fit{--rt-btn-color: var(--rt-pdf-viewer-text-color);--rt-btn-bg-hover: var(--rt-pdf-viewer-control-bg-hover)}@media(width<=480px){.rt-pdf-viewer{--rt-pdf-viewer-bar-height: var(--rt-control-height-xl)}.rt-pdf-viewer__fit,.rt-pdf-viewer__fit-divider{display:none}}.rt-pdf-viewer-print{display:none}.rt-pdf-viewer-print__page{display:block;width:100%;break-after:page;break-inside:avoid}@media print{.rt-pdf-viewer-printing body>:not(.rt-pdf-viewer-print){display:none}.rt-pdf-viewer-printing .rt-pdf-viewer-print{display:block}}}\n"],
513
+ dependencies: [
514
+ {
515
+ kind: "directive",
516
+ type: CdkTrapFocus,
517
+ selector: "[cdkTrapFocus]",
518
+ inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"],
519
+ exportAs: ["cdkTrapFocus"]
520
+ },
521
+ {
522
+ kind: "directive",
523
+ type: BlockDirective,
524
+ selector: "[rtBlock]",
525
+ inputs: ["rtMod"]
526
+ },
527
+ {
528
+ kind: "directive",
529
+ type: ElemDirective,
530
+ selector: "[rtElem]",
531
+ inputs: ["rtMod"]
532
+ },
533
+ {
534
+ kind: "directive",
535
+ type: RtButtonDirective,
536
+ selector: "button[rtButton], a[rtButton]",
537
+ inputs: [
538
+ "label",
539
+ "icon",
540
+ "iconPos",
541
+ "theme",
542
+ "appearance",
543
+ "size",
544
+ "loading",
545
+ "loadingIcon",
546
+ "loadingLabel",
547
+ "pressed"
548
+ ]
549
+ },
550
+ {
551
+ kind: "component",
552
+ type: RtEmptyStateComponent,
553
+ selector: "rt-empty-state",
554
+ inputs: [
555
+ "icon",
556
+ "glyph",
557
+ "title",
558
+ "description",
559
+ "framed"
560
+ ]
561
+ },
562
+ {
563
+ kind: "component",
564
+ type: RtIconButtonComponent,
565
+ selector: "rt-icon-button",
566
+ inputs: [
567
+ "icon",
568
+ "glyph",
569
+ "ariaLabel",
570
+ "variant",
571
+ "iconColor",
572
+ "iconFill",
573
+ "size",
574
+ "iconSize",
575
+ "type",
576
+ "tooltip",
577
+ "tooltipHideOnClick",
578
+ "tabIndex",
579
+ "loading",
580
+ "disabled",
581
+ "active",
582
+ "expanded",
583
+ "indicator"
584
+ ],
585
+ outputs: ["clicked"]
586
+ },
587
+ {
588
+ kind: "component",
589
+ type: RtIconComponent,
590
+ selector: "rt-icon",
591
+ inputs: [
592
+ "name",
593
+ "glyph",
594
+ "glyphStrategy",
595
+ "size",
596
+ "color",
597
+ "fill",
598
+ "spin",
599
+ "rotate"
600
+ ]
601
+ },
602
+ {
603
+ kind: "component",
604
+ type: RtSpinnerComponent,
605
+ selector: "rt-spinner",
606
+ inputs: [
607
+ "diameter",
608
+ "color",
609
+ "appearance",
610
+ "overlay",
611
+ "backdrop",
612
+ "plate"
613
+ ]
614
+ }
615
+ ],
616
+ changeDetection: i0.ChangeDetectionStrategy.OnPush,
617
+ encapsulation: i0.ViewEncapsulation.None
618
+ });
619
+ }
620
+ };
621
+ i0.ɵɵngDeclareClassMetadata({
622
+ minVersion: "12.0.0",
623
+ version: "22.2.2",
624
+ ngImport: i0,
625
+ type: RtPdfViewerComponent,
626
+ decorators: [{
627
+ type: Component,
628
+ args: [{
629
+ selector: "rt-pdf-viewer",
630
+ changeDetection: ChangeDetectionStrategy.OnPush,
631
+ encapsulation: ViewEncapsulation.None,
632
+ imports: [
633
+ CdkTrapFocus,
634
+ BlockDirective,
635
+ ElemDirective,
636
+ RtButtonDirective,
637
+ RtEmptyStateComponent,
638
+ RtIconButtonComponent,
639
+ RtIconComponent,
640
+ RtSpinnerComponent
641
+ ],
642
+ host: {
643
+ class: BEM_BLOCK,
644
+ role: "dialog",
645
+ "aria-modal": "true",
646
+ "[attr.aria-label]": "fileName",
647
+ tabindex: "-1",
648
+ "(keydown.escape)": "onEscape($event)",
649
+ "(window:resize)": "onResize()"
650
+ },
651
+ template: "<ng-container rtBlock=\"rt-pdf-viewer\">\n <!-- Ловушка держит Tab внутри; фокус ставит сам компонент, поэтому авто-захвата здесь нет -->\n <div rtElem=\"surface\" cdkTrapFocus>\n <!-- Полоса видна сразу, ещё до загрузки документа: человек видит, что открыл, и может закрыть -->\n <header rtElem=\"bar\">\n <div rtElem=\"title\">\n <rt-icon rtElem=\"file-icon\" name=\"attach-pdf\" size=\"md\" />\n <span rtElem=\"file-name\" qa-dataid=\"pdf-viewer-file-name\" [attr.title]=\"fileName\">{{ fileName }}</span>\n </div>\n\n <div rtElem=\"actions\">\n <rt-icon-button\n qa-dataid=\"pdf-viewer-print\"\n icon=\"print\"\n variant=\"ghost\"\n [ariaLabel]=\"t().pdfViewerPrint\"\n [tooltip]=\"t().pdfViewerPrint\"\n [disabled]=\"status() !== 'ready'\"\n [loading]=\"printing()\"\n (clicked)=\"print()\" />\n <rt-icon-button\n qa-dataid=\"pdf-viewer-download\"\n icon=\"ico-download\"\n variant=\"ghost\"\n [ariaLabel]=\"t().pdfViewerDownload\"\n [tooltip]=\"t().pdfViewerDownload\"\n (clicked)=\"download()\" />\n <rt-icon-button\n qa-dataid=\"pdf-viewer-close\"\n icon=\"close\"\n variant=\"ghost\"\n [ariaLabel]=\"t().pdfViewerClose\"\n [tooltip]=\"t().pdfViewerClose\"\n (clicked)=\"close()\" />\n </div>\n </header>\n\n <div rtElem=\"scroller\" qa-dataid=\"pdf-viewer-pages\" #scroller (scroll)=\"onScroll()\">\n <!-- Столбец стоит и до загрузки: по его ширине выбирается начальный масштаб -->\n <div rtElem=\"column\" #column>\n @if (status() === 'ready') {\n @for (box of boxes(); track box.index) {\n <div\n rtElem=\"page\"\n qa-dataid=\"pdf-viewer-page\"\n #page\n [attr.data-page-index]=\"box.index\"\n [style.width.px]=\"box.width\"\n [style.height.px]=\"box.height\">\n <canvas rtElem=\"canvas\" #canvas></canvas>\n </div>\n }\n }\n </div>\n </div>\n\n @switch (status()) {\n @case ('loading') {\n <div rtElem=\"center\">\n <rt-spinner qa-dataid=\"pdf-viewer-spinner\" color=\"on-primary\" [diameter]=\"40\" />\n </div>\n }\n\n @case ('error') {\n <div rtElem=\"center\">\n <rt-empty-state\n rtElem=\"error\"\n qa-dataid=\"pdf-viewer-error\"\n [title]=\"t().pdfViewerErrorTitle\"\n [description]=\"t().pdfViewerErrorText\">\n <button\n rtButton\n rtElem=\"error-download\"\n qa-dataid=\"pdf-viewer-error-download\"\n type=\"button\"\n icon=\"ico-download\"\n [label]=\"t().pdfViewerDownload\"\n [attr.aria-label]=\"t().pdfViewerDownload\"\n (click)=\"download()\"></button>\n </rt-empty-state>\n </div>\n }\n\n @case ('ready') {\n <div rtElem=\"toolbar\" qa-dataid=\"pdf-viewer-toolbar\">\n <span rtElem=\"counter\" qa-dataid=\"pdf-viewer-counter\" role=\"status\" aria-live=\"off\" [attr.aria-label]=\"pageOfLabel()\">\n {{ counter() }}\n </span>\n <span rtElem=\"divider\" aria-hidden=\"true\"></span>\n <rt-icon-button\n qa-dataid=\"pdf-viewer-zoom-out\"\n icon=\"minus\"\n variant=\"ghost\"\n size=\"sm\"\n [ariaLabel]=\"t().pdfViewerZoomOut\"\n [disabled]=\"!canZoomOut()\"\n (clicked)=\"zoomOut()\" />\n <span rtElem=\"zoom\" qa-dataid=\"pdf-viewer-zoom\">{{ zoomLabel() }}</span>\n <rt-icon-button\n qa-dataid=\"pdf-viewer-zoom-in\"\n icon=\"ico-plus\"\n variant=\"ghost\"\n size=\"sm\"\n [ariaLabel]=\"t().pdfViewerZoomIn\"\n [disabled]=\"!canZoomIn()\"\n (clicked)=\"zoomIn()\" />\n <span rtElem=\"fit-divider\" aria-hidden=\"true\"></span>\n <button\n rtButton\n rtElem=\"fit\"\n qa-dataid=\"pdf-viewer-fit\"\n type=\"button\"\n appearance=\"text\"\n size=\"sm\"\n [label]=\"t().pdfViewerFitWidth\"\n [attr.aria-label]=\"t().pdfViewerFitWidth\"\n [pressed]=\"isFit()\"\n (click)=\"fitWidth()\"></button>\n </div>\n }\n }\n </div>\n</ng-container>\n",
652
+ styles: ["@charset \"UTF-8\";@layer rt-kit.components{.rt-pdf-viewer{--rt-pdf-viewer-bg: var(--rt-neutral-900);--rt-pdf-viewer-bar-bg: color-mix(in srgb, var(--rt-neutral-900) 35%, var(--rt-neutral-950));--rt-pdf-viewer-bar-height: var(--rt-control-height-2xl);--rt-pdf-viewer-text-color: var(--rt-neutral-0);--rt-pdf-viewer-muted-color: var(--rt-neutral-200);--rt-pdf-viewer-page-bg: var(--rt-neutral-0);--rt-pdf-viewer-page-shadow: var(--rt-shadow-md);--rt-pdf-viewer-page-gap: var(--rt-space-4);--rt-pdf-viewer-toolbar-bg: var(--rt-neutral-800);--rt-pdf-viewer-toolbar-radius: var(--rt-radius-full);--rt-pdf-viewer-divider-width: var(--rt-border-width-thin);--rt-pdf-viewer-divider-color: color-mix(in srgb, var(--rt-neutral-0) 20%, transparent);--rt-pdf-viewer-control-radius: var(--rt-radius-md);--rt-pdf-viewer-control-bg: color-mix(in srgb, var(--rt-neutral-0) 10%, transparent);--rt-pdf-viewer-control-bg-hover: color-mix(in srgb, var(--rt-neutral-0) 24%, transparent);display:block;width:100vw;height:100vh;height:100dvh;background:var(--rt-pdf-viewer-bg);color:var(--rt-pdf-viewer-text-color)}.rt-pdf-viewer__surface{position:absolute;display:flex;flex-direction:column;inset:0}.rt-pdf-viewer__bar{display:flex;height:var(--rt-pdf-viewer-bar-height);flex:none;align-items:center;justify-content:space-between;padding:0 var(--rt-space-4);background:var(--rt-pdf-viewer-bar-bg);gap:var(--rt-space-4)}.rt-pdf-viewer__title{display:flex;min-width:0;align-items:center;gap:var(--rt-space-2)}.rt-pdf-viewer__file-icon{flex:none;color:var(--rt-pdf-viewer-text-color)}.rt-pdf-viewer__file-name{overflow:hidden;min-width:0;font-size:var(--rt-text-sm);text-overflow:ellipsis;white-space:nowrap}.rt-pdf-viewer__actions{display:flex;flex:none;align-items:center;gap:var(--rt-space-2)}.rt-pdf-viewer__actions rt-icon-button{--rt-icon-button-color: var(--rt-pdf-viewer-text-color);--rt-icon-button-color-bg-hover: var(--rt-pdf-viewer-control-bg-hover);border-radius:var(--rt-pdf-viewer-control-radius);background:var(--rt-pdf-viewer-control-bg)}.rt-pdf-viewer__scroller{position:relative;overflow:auto;flex:1 1 auto;overscroll-behavior:contain;scrollbar-gutter:stable}.rt-pdf-viewer__column{display:flex;width:max-content;min-width:100%;box-sizing:border-box;flex-direction:column;align-items:center;padding:var(--rt-space-4) var(--rt-space-4) var(--rt-space-24);gap:var(--rt-pdf-viewer-page-gap)}.rt-pdf-viewer__page{flex:none;background:var(--rt-pdf-viewer-page-bg);box-shadow:var(--rt-pdf-viewer-page-shadow)}.rt-pdf-viewer__canvas{display:block;width:100%;height:100%}.rt-pdf-viewer__center{position:absolute;display:flex;align-items:center;justify-content:center;padding:var(--rt-space-4);inset:var(--rt-pdf-viewer-bar-height) 0 0}.rt-pdf-viewer .rt-pdf-viewer__error{--rt-empty-state-title-color: var(--rt-pdf-viewer-text-color)}.rt-pdf-viewer .rt-pdf-viewer__error .rt-empty-state__description{color:var(--rt-pdf-viewer-muted-color)}.rt-pdf-viewer .rt-pdf-viewer__error-download{--rt-btn-bg: var(--rt-pdf-viewer-page-bg);--rt-btn-bg-hover: var(--rt-neutral-100);--rt-btn-bg-active: var(--rt-neutral-200);--rt-btn-color: var(--rt-neutral-900)}.rt-pdf-viewer__toolbar{position:absolute;bottom:var(--rt-space-6);left:50%;display:flex;align-items:center;padding:var(--rt-space-1) var(--rt-space-2);border-radius:var(--rt-pdf-viewer-toolbar-radius);background:var(--rt-pdf-viewer-toolbar-bg);gap:var(--rt-space-1);transform:translate(-50%);white-space:nowrap}.rt-pdf-viewer__toolbar rt-icon-button{--rt-icon-button-color: var(--rt-pdf-viewer-text-color);--rt-icon-button-color-bg-hover: var(--rt-pdf-viewer-control-bg-hover)}.rt-pdf-viewer__counter,.rt-pdf-viewer__zoom{padding:0 var(--rt-space-2);font-size:var(--rt-text-sm);font-variant-numeric:tabular-nums}.rt-pdf-viewer__zoom{min-width:var(--rt-size-12);text-align:center}.rt-pdf-viewer__divider,.rt-pdf-viewer__fit-divider{width:var(--rt-pdf-viewer-divider-width);height:var(--rt-size-5);margin:0 var(--rt-space-1);background:var(--rt-pdf-viewer-divider-color)}.rt-pdf-viewer .rt-pdf-viewer__fit{--rt-btn-color: var(--rt-pdf-viewer-text-color);--rt-btn-bg-hover: var(--rt-pdf-viewer-control-bg-hover)}@media(width<=480px){.rt-pdf-viewer{--rt-pdf-viewer-bar-height: var(--rt-control-height-xl)}.rt-pdf-viewer__fit,.rt-pdf-viewer__fit-divider{display:none}}.rt-pdf-viewer-print{display:none}.rt-pdf-viewer-print__page{display:block;width:100%;break-after:page;break-inside:avoid}@media print{.rt-pdf-viewer-printing body>:not(.rt-pdf-viewer-print){display:none}.rt-pdf-viewer-printing .rt-pdf-viewer-print{display:block}}}\n"]
653
+ }]
654
+ }],
655
+ ctorParameters: () => [],
656
+ propDecorators: {
657
+ scroller: [{
658
+ type: i0.ViewChild,
659
+ args: ["scroller", { isSignal: true }]
660
+ }],
661
+ column: [{
662
+ type: i0.ViewChild,
663
+ args: ["column", { isSignal: true }]
664
+ }],
665
+ pageNodes: [{
666
+ type: i0.ViewChildren,
667
+ args: ["page", { isSignal: true }]
668
+ }],
669
+ canvases: [{
670
+ type: i0.ViewChildren,
671
+ args: ["canvas", { isSignal: true }]
672
+ }]
673
+ }
674
+ });
675
+ export { RT_PDF_CSS_UNITS, RT_PDF_NARROW_WIDTH, RT_PDF_VIEWER_CONFIG, RT_PDF_VIEWER_WORKER_SRC, RT_PDF_ZOOM_MAX, RT_PDF_ZOOM_MIN, RT_PDF_ZOOM_STEPS, RtPdfViewerComponent, anchoredScrollTop, canZoomIn, canZoomOut, fitWidthPercent, initialZoom, nextZoomStep, pageBoxes, pagesToRender, provideRtPdfViewer, visiblePageIndex, zoomPercentLabel };
676
+
677
+ //# sourceMappingURL=rt-tools-ui-kit-v2-pdf-viewer.mjs.map