Compare commits

...

29 Commits
v2.0.1 ... main

Author SHA1 Message Date
b43baccd62 v2.2.3
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-12-11 20:34:27 +00:00
035c6ab621 fix(contentinvoice): Use shared translation.TranslationKey type in DeContentInvoice.translateKey and remove local import 2025-12-11 20:34:27 +00:00
3617caec1f 2.2.2
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-12-11 20:06:34 +00:00
9e879893af 2.2.1
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-12-11 20:05:08 +00:00
c487ac341e v2.2.0
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-12-11 20:00:56 +00:00
393a235526 feat(viewer): Add pagination metadata and thumbnail offset rendering for viewer thumbnails 2025-12-11 20:00:56 +00:00
52b215b9d3 v2.1.1
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-12-11 19:16:12 +00:00
34278c4b04 fix(viewer): Improve sidebar resizing UX and update deps 2025-12-11 19:16:12 +00:00
6726969010 v2.1.0
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-12-11 16:56:30 +00:00
8a434d3ba9 feat(viewer): Add smooth zoom and scroll animations to viewer 2025-12-11 16:56:30 +00:00
560f4d667a make scroll listener passive 2025-12-11 15:19:49 +00:00
382af070fc update 2025-12-11 15:14:23 +00:00
de464461e6 add page scrolling 2025-12-11 14:58:19 +00:00
f86aebc00b update 2025-12-11 14:55:20 +00:00
802a2004e9 v2.0.6
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-12-11 14:50:46 +00:00
6328a2783e fix(DeDocumentViewer): Account for toolbar and padding when calculating Fit Page zoom in viewer 2025-12-11 14:50:45 +00:00
79db99e919 update 2025-12-11 14:48:22 +00:00
7bcbacc85f update 2025-12-11 10:42:07 +00:00
7df1e7cc7a update 2025-12-11 10:06:26 +00:00
c892dff841 update 2025-12-11 09:45:09 +00:00
4951a8cdfe update 2025-12-11 09:43:17 +00:00
4db6ffb367 update 2025-12-11 09:42:20 +00:00
c013e4edfe 2.0.5
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-12-11 09:26:51 +00:00
d1b99242a9 update 2025-12-11 09:26:49 +00:00
8c0bf94035 2.0.4
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-12-11 09:22:10 +00:00
894cef0f5e 2.0.3
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-12-11 09:16:56 +00:00
57a5fa6d18 v2.0.2
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-12-11 02:38:18 +00:00
0e30684c2f fix(page): Use theme variables for page styling, make pagecontainer background theme-aware, and use accent background for footer separator 2025-12-11 02:38:18 +00:00
3be8de28c6 update 2025-12-11 02:31:18 +00:00
14 changed files with 1673 additions and 74 deletions

1
.npmrc
View File

@@ -1 +0,0 @@
registry=https://registry.npmjs.org/

View File

@@ -1,5 +1,55 @@
# Changelog
## 2025-12-11 - 2.2.3 - fix(contentinvoice)
Use shared translation.TranslationKey type in DeContentInvoice.translateKey and remove local import
- Replaced local TranslationKey import with plugins.shared.translation.TranslationKey to ensure type consistency
- Updated DeContentInvoice.translateKey parameter type to reference the shared translation type
- Removed an unused type import from ts_web/elements/contentinvoice.ts
## 2025-12-11 - 2.2.0 - feat(viewer)
Add pagination metadata and thumbnail offset rendering for viewer thumbnails
- Expose per-page pagination metadata (IPagePaginationInfo) from DeDocument during rendering (pageNumber, startOffset, contentLength).
- DeDocument now collects pagination info while paginating and dispatches a 'pagination-complete' CustomEvent with pageCount and paginationInfo (bubbled & composed).
- DeContentInvoice: add renderStartOffset and renderContentLength properties and applyOffsetTrimming to support rendering trimmed content (used for thumbnails).
- DeDocumentViewer: listen for 'pagination-complete', store paginationInfo, and render thumbnail previews by mounting DeContentInvoice instances with precomputed offsets to produce accurate thumbnails.
- Viewer: wire thumbnail generation to use per-page offsets so thumbnails show exactly the content slice for each page.
- Demo data: extended demo invoice items in ts_shared/demoletter.ts to better exercise pagination and thumbnail rendering.
- Remove registry override from .npmrc (previously pointed to registry.npmjs.org).
## 2025-12-11 - 2.1.1 - fix(viewer)
Improve sidebar resizing UX and update deps
- Add smooth width transition for the thumbnail sidebar to improve resize visuals
- Disable viewport CSS transitions while user is actively resizing the sidebar to avoid janky animations
- Mark viewport as resizing in classes so layout updates skip transitions during drag
- Make sidebar resize mousemove listener passive to improve scrolling/interaction performance
- Bump @design.estate/dees-wcctools to ^2.0.0 and @git.zone/tswatch to ^2.3.11
## 2025-12-11 - 2.1.0 - feat(viewer)
Add smooth zoom and scroll animations to viewer
- Introduce smooth zoom animation: new private animateZoomTo(targetZoom, duration) method and zoomAnimationId to track/cancel running animations
- Animate transitions for numeric zoom presets and zoom step changes (handleZoomStep now uses animateZoomTo)
- Cancel ongoing zoom animation when user manipulates the zoom slider
- Make fit-to-width and fit-to-page calculations optionally animate (calculateFitWidth/ calculateFitPage accept animate flag)
- Add animated scrolling helper animateScrollTo for smooth page scrolling when requested (used when smooth=true)
## 2025-12-11 - 2.0.6 - fix(DeDocumentViewer)
Account for toolbar and padding when calculating Fit Page zoom in viewer
- calculateFitPage now subtracts explicit top (toolbar + padding), bottom, and side paddings from viewport dimensions before computing scale.
- This produces a more accurate zoom level for the Fit Page preset by considering toolbar height and page margins.
## 2025-12-11 - 2.0.2 - fix(page)
Use theme variables for page styling, make pagecontainer background theme-aware, and use accent background for footer separator
- Extract documentSettings.theme to a local variable in dedocument-page and use safe optional checks when emitting CSS custom properties
- Use theme pageBackground / coverPageBackground values consistently for page background-image fallback logic
- Make pagecontainer background follow the --text-bg-color CSS variable instead of a hard #ffffff color
- Switch footer separator color variable to --color-accent-bg so the footer stripe uses the theme accent background
## 2025-12-10 - 2.0.1 - fix(core)
Migrate file I/O to @push.rocks/smartfs, adopt TC39 decorators v3 accessor in web components, and update docs/tests

View File

@@ -1,6 +1,6 @@
{
"name": "@design.estate/dees-document",
"version": "2.0.1",
"version": "2.2.3",
"private": false,
"description": "A sophisticated framework for dynamically generating and rendering business documents like invoices with modern web technologies, featuring PDF creation, templating, and automation.",
"main": "dist_ts_web/index.js",
@@ -24,7 +24,7 @@
"@design.estate/dees-catalog": "^3.3.0",
"@design.estate/dees-domtools": "^2.3.6",
"@design.estate/dees-element": "^2.1.3",
"@design.estate/dees-wcctools": "^1.2.1",
"@design.estate/dees-wcctools": "^2.0.0",
"@git.zone/tsrun": "^2.0.0",
"@push.rocks/smartfile": "^13.1.0",
"@push.rocks/smartfs": "^1.2.0",
@@ -42,7 +42,7 @@
"@git.zone/tsbuild": "^3.1.2",
"@git.zone/tsbundle": "^2.6.3",
"@git.zone/tstest": "^3.1.3",
"@git.zone/tswatch": "^2.3.7",
"@git.zone/tswatch": "^2.3.11",
"@push.rocks/projectinfo": "^5.0.2"
},
"files": [

54
pnpm-lock.yaml generated
View File

@@ -18,8 +18,8 @@ importers:
specifier: ^2.1.3
version: 2.1.3
'@design.estate/dees-wcctools':
specifier: ^1.2.1
version: 1.2.1
specifier: ^2.0.0
version: 2.0.0
'@git.zone/tsrun':
specifier: ^2.0.0
version: 2.0.0
@@ -67,8 +67,8 @@ importers:
specifier: ^3.1.3
version: 3.1.3(@push.rocks/smartserve@1.4.0)(socks@2.8.7)(typescript@5.9.3)
'@git.zone/tswatch':
specifier: ^2.3.7
version: 2.3.7(@tiptap/pm@2.27.1)
specifier: ^2.3.11
version: 2.3.11(@tiptap/pm@2.27.1)
'@push.rocks/projectinfo':
specifier: ^5.0.2
version: 5.0.2
@@ -283,6 +283,9 @@ packages:
'@cloudflare/workers-types@4.20251210.0':
resolution: {integrity: sha512-EGf2lWqeVO48LjDYFl1peSbi/AvQFDJ1vj+etwRAGqLjGWgq+R1fwFfLCjXr7tMsX8aHykE17XpCAVuroKpZoQ==}
'@cloudflare/workers-types@4.20251211.0':
resolution: {integrity: sha512-e87o6KbelCz7dnI5ngrGT2ca15vJZ+COb2eqJ52iDHmOaujyC6aYZ71e2vor8X6V9T6tcDElC5sAqPR93j09EA==}
'@configvault.io/interfaces@1.0.17':
resolution: {integrity: sha512-bEcCUR2VBDJsTin8HQh8Uw/mlYl2v8A3jMIaQ+MTB9Hrqd6CZL2dL7iJdWyFl/3EIX+LDxWFR+Oq7liIq7w+1Q==}
@@ -298,8 +301,11 @@ packages:
'@design.estate/dees-element@2.1.3':
resolution: {integrity: sha512-TjXWxVcdSPaT1IOk31ckfxvAZnJLuTxhFGsNCKoh63/UE2FVf6slp8//UFvN+ADigiA9ZsY0azkY99XbJCwDDA==}
'@design.estate/dees-wcctools@1.2.1':
resolution: {integrity: sha512-ESFas1MPPwDUcXRssyHRsc63XPTBJSTBA+5RhYXDZx8mbV6HxEKiJR8Oz1Mv7DBdW+ZSuUTD/fA6Aa/fCxGYTQ==}
'@design.estate/dees-wcctools@1.3.0':
resolution: {integrity: sha512-+yd8c1gTIKNRQYCvG0xu6Am8dHsRm7ymluX2gnoBQN4aFOpZgIBi/v9CvGyPhTD1p/VRouIBz1wsUCejnwrFCA==}
'@design.estate/dees-wcctools@2.0.0':
resolution: {integrity: sha512-+JXzU/FzOs48NcynbozX0lPfvszhp0mODdZU2ECCTkwOQi+0smhYAlFTUNZ8JcWSLDq3g5HqRMv7XoJELMk4Zw==}
'@emnapi/core@1.7.1':
resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==}
@@ -506,8 +512,8 @@ packages:
resolution: {integrity: sha512-t+/cKV21JHK8X7NGAmihs5M/eMm+V+jn4R5rzfwGG97WJFAcP5qE1Os9VYtyZw3tx/NZXA2yA4abo/ELluTuRA==}
hasBin: true
'@git.zone/tswatch@2.3.7':
resolution: {integrity: sha512-cykbA1rwsh88H5k1/irkVKpecU9vJKOFuSZmcPYWdo2UJQN4IweLFU+IeWwiFHaHR3QqKpR1wyiKcKEGbf7mrQ==}
'@git.zone/tswatch@2.3.11':
resolution: {integrity: sha512-FJWOsPQ9i0INn1i7uqMD0ECrZ6bwwGQC8oFDEx9PLcaS+qHpGsYj3P9UscpW1N78P+6Yd1WFUfBh9sUQiKm+KA==}
hasBin: true
'@happy-dom/global-registrator@15.11.7':
@@ -1185,8 +1191,8 @@ packages:
'@push.rocks/smartversion@3.0.5':
resolution: {integrity: sha512-8MZSo1yqyaKxKq0Q5N188l4un++9GFWVbhCAX5mXJwewZHn97ujffTeL+eOQYpWFTEpUhaq1QhL4NhqObBCt1Q==}
'@push.rocks/smartwatch@6.2.1':
resolution: {integrity: sha512-mVLf3hFc9L73douQ6w3kRFTt2qSwM2cSncxByfSSxk9pFrEwUL0/+Ff4hw5OMg5lgaowFa5FGRJsXzZAVaZgEw==}
'@push.rocks/smartwatch@6.2.4':
resolution: {integrity: sha512-cxGx/RJXSU45cfyJn0DNgXA1jPwmzraJhy+8J8hL2Bjn0K+DxatQRyeIvRVCSLLgBhVTN6yYaUjUtjs19gJLkA==}
engines: {node: '>=20.0.0'}
'@push.rocks/smartxml@2.0.0':
@@ -4331,7 +4337,7 @@ snapshots:
'@api.global/typedrequest': 3.2.5
'@api.global/typedrequest-interfaces': 3.0.19
'@api.global/typedsocket': 4.1.0(@push.rocks/smartserve@1.4.0)
'@cloudflare/workers-types': 4.20251210.0
'@cloudflare/workers-types': 4.20251211.0
'@design.estate/dees-catalog': 3.3.0(@tiptap/pm@2.27.1)
'@design.estate/dees-comms': 1.0.30
'@push.rocks/lik': 6.2.2
@@ -4357,7 +4363,7 @@ snapshots:
'@push.rocks/smartsitemap': 2.0.4
'@push.rocks/smartstream': 3.2.5
'@push.rocks/smarttime': 4.1.1
'@push.rocks/smartwatch': 6.2.1
'@push.rocks/smartwatch': 6.2.4
'@push.rocks/taskbuffer': 3.5.0
'@push.rocks/webrequest': 4.0.1
'@push.rocks/webstore': 2.0.20
@@ -4900,6 +4906,8 @@ snapshots:
'@cloudflare/workers-types@4.20251210.0': {}
'@cloudflare/workers-types@4.20251211.0': {}
'@configvault.io/interfaces@1.0.17':
dependencies:
'@api.global/typedrequest-interfaces': 3.0.19
@@ -4908,7 +4916,7 @@ snapshots:
dependencies:
'@design.estate/dees-domtools': 2.3.6
'@design.estate/dees-element': 2.1.3
'@design.estate/dees-wcctools': 1.2.1
'@design.estate/dees-wcctools': 1.3.0
'@fortawesome/fontawesome-svg-core': 7.1.0
'@fortawesome/free-brands-svg-icons': 7.1.0
'@fortawesome/free-regular-svg-icons': 7.1.0
@@ -4985,7 +4993,19 @@ snapshots:
- supports-color
- vue
'@design.estate/dees-wcctools@1.2.1':
'@design.estate/dees-wcctools@1.3.0':
dependencies:
'@design.estate/dees-domtools': 2.3.6
'@design.estate/dees-element': 2.1.3
'@push.rocks/smartdelay': 3.0.5
lit: 3.3.1
transitivePeerDependencies:
- '@nuxt/kit'
- react
- supports-color
- vue
'@design.estate/dees-wcctools@2.0.0':
dependencies:
'@design.estate/dees-domtools': 2.3.6
'@design.estate/dees-element': 2.1.3
@@ -5225,7 +5245,7 @@ snapshots:
- utf-8-validate
- vue
'@git.zone/tswatch@2.3.7(@tiptap/pm@2.27.1)':
'@git.zone/tswatch@2.3.11(@tiptap/pm@2.27.1)':
dependencies:
'@api.global/typedserver': 7.11.1(@tiptap/pm@2.27.1)
'@git.zone/tsbundle': 2.6.3
@@ -5238,7 +5258,7 @@ snapshots:
'@push.rocks/smartlog': 3.1.10
'@push.rocks/smartlog-destination-local': 9.0.2
'@push.rocks/smartshell': 3.3.0
'@push.rocks/smartwatch': 6.2.1
'@push.rocks/smartwatch': 6.2.4
'@push.rocks/taskbuffer': 3.5.0
transitivePeerDependencies:
- '@nuxt/kit'
@@ -6534,7 +6554,7 @@ snapshots:
'@types/semver': 7.7.1
semver: 7.7.3
'@push.rocks/smartwatch@6.2.1':
'@push.rocks/smartwatch@6.2.4':
dependencies:
'@push.rocks/lik': 6.2.2
'@push.rocks/smartenv': 6.0.0

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@design.estate/dees-document',
version: '2.0.1',
version: '2.2.3',
description: 'A sophisticated framework for dynamically generating and rendering business documents like invoices with modern web technologies, featuring PDF creation, templating, and automation.'
}

View File

@@ -237,6 +237,86 @@ export const demoLetter: plugins.tsclass.finance.TInvoice = {
vatPercentage: 0,
position: 20,
},
{
name: "Consulting Services",
unitQuantity: 5,
unitNetPrice: 150,
unitType: "hours",
vatPercentage: 19,
position: 21,
},
{
name: "Development Work",
unitQuantity: 12,
unitNetPrice: 120,
unitType: "hours",
vatPercentage: 19,
position: 22,
},
{
name: "Project Management",
unitQuantity: 3,
unitNetPrice: 180,
unitType: "hours",
vatPercentage: 19,
position: 23,
},
{
name: "Technical Support",
unitQuantity: 8,
unitNetPrice: 90,
unitType: "hours",
vatPercentage: 7,
position: 24,
},
{
name: "Documentation",
unitQuantity: 4,
unitNetPrice: 75,
unitType: "hours",
vatPercentage: 7,
position: 25,
},
{
name: "Code Review",
unitQuantity: 6,
unitNetPrice: 110,
unitType: "hours",
vatPercentage: 19,
position: 26,
},
{
name: "Testing & QA",
unitQuantity: 10,
unitNetPrice: 95,
unitType: "hours",
vatPercentage: 19,
position: 27,
},
{
name: "Infrastructure Setup",
unitQuantity: 2,
unitNetPrice: 250,
unitType: "hours",
vatPercentage: 19,
position: 28,
},
{
name: "Training Session",
unitQuantity: 4,
unitNetPrice: 200,
unitType: "hours",
vatPercentage: 7,
position: 29,
},
{
name: "Maintenance Package",
unitQuantity: 1,
unitNetPrice: 500,
unitType: "units",
vatPercentage: 19,
position: 30,
},
],
};

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@design.estate/dees-document',
version: '2.0.1',
version: '2.2.3',
description: 'A sophisticated framework for dynamically generating and rendering business documents like invoices with modern web technologies, featuring PDF creation, templating, and automation.'
}

View File

@@ -15,7 +15,6 @@ import {
import * as plugins from "../plugins.js";
import { dedocumentSharedStyle } from "../style.js";
import type { TranslationKey } from "ts_shared/translation.js";
declare global {
interface HTMLElementTagNameMap {
@@ -49,6 +48,13 @@ export class DeContentInvoice extends DeesElement {
})
accessor documentSettings: plugins.shared.interfaces.IDocumentSettings;
// Offset-based rendering properties for thumbnails
@property({ type: Number })
accessor renderStartOffset: number = null;
@property({ type: Number })
accessor renderContentLength: number = null;
constructor() {
super();
domtools.DomTools.setupDomTools();
@@ -296,7 +302,7 @@ export class DeContentInvoice extends DeesElement {
}
}
public translateKey(key: TranslationKey): string {
public translateKey(key: plugins.shared.translation.TranslationKey): string {
return plugins.shared.translation.translate(
this.documentSettings.languageCode,
key
@@ -307,7 +313,29 @@ export class DeContentInvoice extends DeesElement {
_changedProperties: Map<string | number | symbol, unknown>
) {
super.firstUpdated(_changedProperties);
this.attachInvoiceDom();
await this.attachInvoiceDom();
// Apply offset-based trimming if specified (used for thumbnails)
if (this.renderStartOffset !== null && this.renderContentLength !== null) {
await this.applyOffsetTrimming();
}
}
/**
* Apply pre-computed pagination offsets for thumbnail rendering
*/
private async applyOffsetTrimming(): Promise<void> {
// Trim from start
if (this.renderStartOffset > 0) {
await this.trimStartToOffset(this.renderStartOffset);
}
// Trim from end to match content length
let currentLength = await this.getContentLength();
while (currentLength > this.renderContentLength) {
await this.trimEndByOne();
currentLength = await this.getContentLength();
}
}
private renderPaymentTerms(): TemplateResult {

View File

@@ -25,7 +25,12 @@ import { DePage } from "./page.js";
import { DeContentInvoice } from "./contentinvoice.js";
import { demoFunc } from "./document.demo.js";
import { dedocumentSharedStyle } from "../style.js";
export interface IPagePaginationInfo {
pageNumber: number;
startOffset: number;
contentLength: number;
}
declare global {
interface HTMLElementTagNameMap {
@@ -88,6 +93,12 @@ export class DeDocument extends DeesElement {
accessor documentSettings: plugins.shared.interfaces.IDocumentSettings =
defaultDocumentSettings;
@property({ type: Number })
accessor zoomLevel: number = null; // null = auto-fit, otherwise percentage (e.g., 100 = 100%)
@property({ type: Number })
accessor pageGap: number = 16; // pixels between pages
constructor() {
super();
domtools.DomTools.setupDomTools();
@@ -95,7 +106,6 @@ export class DeDocument extends DeesElement {
public static styles = [
domtools.elementBasic.staticStyles,
dedocumentSharedStyle,
css`
:host {
display: block;
@@ -138,10 +148,12 @@ export class DeDocument extends DeesElement {
null;
public latestRenderedLetterData: plugins.tsclass.business.TLetter = null;
public cleanupStore: any[] = [];
public paginationInfo: IPagePaginationInfo[] = [];
public async renderDocument() {
this.latestDocumentSettings = this.documentSettings;
this.latestRenderedLetterData = this.letterData;
this.paginationInfo = [];
const cleanUpStoreCurrentRender = [];
const cleanUpStoreNextRender = [];
@@ -194,7 +206,16 @@ export class DeDocument extends DeesElement {
newPageOverflows = await newPage.checkOverflow();
}
currentContentOffset = await currentContent.getContentLength();
const pageStartOffset = overallContentOffset;
overallContentOffset = overallContentOffset + currentContentOffset;
// Track pagination info for this page
this.paginationInfo.push({
pageNumber: pageCounter,
startOffset: pageStartOffset,
contentLength: currentContentOffset,
});
if (trimmed === 0) {
complete = true;
}
@@ -225,10 +246,21 @@ export class DeDocument extends DeesElement {
if (!this.printMode) {
const betweenPagesSpacerDiv = document.createElement("div");
betweenPagesSpacerDiv.classList.add("betweenPagesSpacer");
betweenPagesSpacerDiv.style.height = `${this.pageGap}px`;
documentContainer.appendChild(betweenPagesSpacerDiv);
}
}
this.adjustDePageScaling();
// Emit event with pagination info for thumbnails
this.dispatchEvent(new CustomEvent('pagination-complete', {
detail: {
pageCount: pageCounter,
paginationInfo: this.paginationInfo,
},
bubbles: true,
composed: true,
}));
}
async updated(
@@ -251,10 +283,25 @@ export class DeDocument extends DeesElement {
if (
changedProperties.has("viewHeight") ||
changedProperties.has("viewWidth")
changedProperties.has("viewWidth") ||
changedProperties.has("zoomLevel")
) {
this.adjustDePageScaling();
}
if (changedProperties.has("pageGap")) {
this.updatePageGaps();
}
}
/**
* Update page gap spacing without re-rendering document
*/
private updatePageGaps(): void {
const spacers = this.shadowRoot.querySelectorAll(".betweenPagesSpacer");
spacers.forEach((spacer: HTMLElement) => {
spacer.style.height = `${this.pageGap}px`;
});
}
private adjustDePageScaling() {
@@ -265,8 +312,11 @@ export class DeDocument extends DeesElement {
// Find all DePage instances within this DeDocument
const pages = this.shadowRoot.querySelectorAll("dedocument-page");
// Update each DePage instance's viewHeight and viewWidth
// Update each DePage instance's viewHeight, viewWidth, and zoomLevel
pages.forEach((page: DePage) => {
// Pass manual zoom level if set
page.manualZoomLevel = this.zoomLevel;
if (this.viewHeight) {
page.viewHeight = this.viewHeight;
}
@@ -275,4 +325,25 @@ export class DeDocument extends DeesElement {
}
});
}
/**
* Set zoom level manually. Pass null to return to auto-fit mode.
* @param level - Zoom percentage (e.g., 100 for 100%) or null for auto-fit
*/
public setZoomLevel(level: number | null): void {
this.zoomLevel = level;
this.adjustDePageScaling();
}
/**
* Get the current effective zoom percentage
*/
public getEffectiveZoom(): number {
if (this.zoomLevel !== null) {
return this.zoomLevel;
}
// Calculate auto-fit zoom percentage
const scale = this.viewWidth / plugins.shared.A4_WIDTH;
return Math.round(scale * 100);
}
}

View File

@@ -12,7 +12,6 @@ import {
import * as plugins from "../plugins.js";
import { defaultDocumentSettings } from "./document.js";
import { dedocumentSharedStyle } from "../style.js";
declare global {
interface HTMLElementTagNameMap {
@@ -68,6 +67,9 @@ export class DePage extends DeesElement {
accessor documentSettings: plugins.shared.interfaces.IDocumentSettings =
defaultDocumentSettings;
@property({ type: Number })
accessor manualZoomLevel: number = null; // null = auto-fit, otherwise percentage
constructor() {
super();
domtools.DomTools.setupDomTools();
@@ -75,7 +77,6 @@ export class DePage extends DeesElement {
public static styles = [
domtools.elementBasic.staticStyles,
dedocumentSharedStyle,
css`
:host {
display: block;
@@ -134,17 +135,14 @@ export class DePage extends DeesElement {
];
public render(): TemplateResult {
const theme = this.documentSettings.theme;
return html`
<style>
:host {
--theme-color-primary-fg: ${this.documentSettings.theme
?.colorPrimaryForeground};
--theme-color-primary-bg: ${this.documentSettings.theme
?.colorPrimaryBackground};
--theme-color-accent-fg: ${this.documentSettings.theme
?.colorAccentForeground};
--theme-color-accent-bg: ${this.documentSettings.theme
?.colorAccentBackground};
${theme?.colorPrimaryForeground ? `--theme-color-primary-fg: ${theme.colorPrimaryForeground};` : ''}
${theme?.colorPrimaryBackground ? `--theme-color-primary-bg: ${theme.colorPrimaryBackground};` : ''}
${theme?.colorAccentForeground ? `--theme-color-accent-fg: ${theme.colorAccentForeground};` : ''}
${theme?.colorAccentBackground ? `--theme-color-accent-bg: ${theme.colorAccentBackground};` : ''}
}
.page {
@@ -153,21 +151,17 @@ export class DePage extends DeesElement {
}
.page:not(.page--first) {
background-image: ${this.documentSettings.theme?.pageBackground ??
"none"};
background-image: ${theme?.pageBackground ?? "none"};
}
.page.page--first {
background-image: ${this.documentSettings.theme
?.coverPageBackground ??
this.documentSettings.theme?.pageBackground ??
"none"};
background-image: ${theme?.coverPageBackground ?? theme?.pageBackground ?? "none"};
}
</style>
<div id="scaleWrapper">
<dedocument-pagecontainer .printMode=${this.printMode}>
<div
class="page page__background ${this.pageNumber === 1
class="page ${this.pageNumber === 1
? "page--first"
: ""}"
></div>
@@ -255,7 +249,8 @@ export class DePage extends DeesElement {
super.updated(changedProperties);
if (
changedProperties.has("viewHeight") ||
changedProperties.has("viewWidth")
changedProperties.has("viewWidth") ||
changedProperties.has("manualZoomLevel")
) {
this.adjustScaling();
}
@@ -268,15 +263,21 @@ export class DePage extends DeesElement {
if (!scaleWrapper) return;
let scale = 1;
if (this.viewHeight) {
// If manual zoom is set, use it directly
if (this.manualZoomLevel !== null) {
scale = this.manualZoomLevel / 100;
} else if (this.viewHeight) {
// Auto-fit to height
scale = this.viewHeight / plugins.shared.A4_HEIGHT;
} else if (this.viewWidth) {
// Auto-fit to width
scale = this.viewWidth / plugins.shared.A4_WIDTH;
}
scaleWrapper.style.transform = `scale(${scale})`;
// Adjust the outer dimensions so they match the scaled content
this.style.width = `${plugins.shared.A4_WIDTH * scale}px`;
this.style.height = `${plugins.shared.A4_HEIGHT * scale}px`;
}

View File

@@ -50,6 +50,7 @@ export class DePageContainer extends DeesElement {
position: relative;
border-radius: 3px;
overflow: hidden;
background: var(--text-bg-color, #ffffff);
}
`,
];

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,7 @@ export const dedocumentSharedStyle = css`
--text-bg-color: var(--color-primary-bg);
--label-fg: var(--color-dark);
--label-bg: var(--color-grey);
--footer-separator-bg-color: var(--color-accent);
--footer-separator-bg-color: var(--color-accent-bg);
--footer-separator-fg-color: var(--color-light);
/* Functional variables */
@@ -32,7 +32,6 @@ export const dedocumentSharedStyle = css`
--text-font-size: var(--theme-text-font-size, 12px);
color: var(--text-fg-color);
background: var(--text-bg-color);
font-family: var(--text-font-family);
font-size: var(--text-font-size);
}

View File

@@ -5,7 +5,6 @@
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"verbatimModuleSyntax": true,
"baseUrl": ".",
"paths": {
"undefined": [
"./ts_web/index.js"