@design.estate/dees-document 5.4.0 → 5.6.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.
@@ -1,8 +1,21 @@
1
1
  import * as plugins from "./plugins.js";
2
2
  /** A colour written as `#` and three or six hex digits. */
3
3
  const HEX_COLOR_PATTERN = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
4
- /** The relative luminance of a hex colour (WCAG 2.x), from 0 (black) to 1 (white). */
5
- const relativeLuminanceOf = (hexArg) => {
4
+ /** Whether a value is a hex colour: `#` and three or six hex digits, in either case (`#abc`, `#0A5C8F`). */
5
+ export const isHexColor = (valueArg) => HEX_COLOR_PATTERN.test(valueArg);
6
+ /** Refuses a value that is no hex colour, naming the function that was asked. */
7
+ const requireHexColor = (functionArg, valueArg) => {
8
+ if (!isHexColor(valueArg)) {
9
+ throw new Error(`${functionArg}: "${valueArg}" is no hex colour`);
10
+ }
11
+ };
12
+ /**
13
+ * The relative luminance of a hex colour (WCAG 2.x), from 0 (black) to 1
14
+ * (white); `#RGB` is read as `#RRGGBB`. A value that is no hex colour is
15
+ * refused.
16
+ */
17
+ export const relativeLuminanceOf = (hexArg) => {
18
+ requireHexColor("relativeLuminanceOf", hexArg);
6
19
  const digits = hexArg.length === 4 ? hexArg.slice(1).replace(/./g, "$&$&") : hexArg.slice(1);
7
20
  const channel = (offsetArg) => {
8
21
  const value = Number.parseInt(digits.slice(offsetArg, offsetArg + 2), 16) / 255;
@@ -10,17 +23,20 @@ const relativeLuminanceOf = (hexArg) => {
10
23
  };
11
24
  return 0.2126 * channel(0) + 0.7152 * channel(2) + 0.0722 * channel(4);
12
25
  };
13
- /** The WCAG contrast of two luminances, from 1 to 21. */
14
- const contrastOf = (leftArg, rightArg) => (Math.max(leftArg, rightArg) + 0.05) / (Math.min(leftArg, rightArg) + 0.05);
26
+ /** The WCAG contrast of two relative luminances, from 1 (the same) to 21 (black on white), in either order. */
27
+ export const contrastOf = (leftArg, rightArg) => (Math.max(leftArg, rightArg) + 0.05) / (Math.min(leftArg, rightArg) + 0.05);
28
+ /** The WCAG contrast of a hex colour against white, from 1 (white) to 21 (black). A value that is no hex colour is refused. */
29
+ export const contrastOnWhiteOf = (hexArg) => {
30
+ requireHexColor("contrastOnWhiteOf", hexArg);
31
+ return contrastOf(relativeLuminanceOf(hexArg), 1);
32
+ };
15
33
  /**
16
34
  * The text colour that reads better on an accent: the document's dark grey
17
35
  * (`#333333`) or white, whichever has the higher WCAG contrast against it. A
18
36
  * light accent (a yellow, a pastel) gets dark text, a strong or dark one white.
19
37
  */
20
38
  export const accentForegroundOf = (hexArg) => {
21
- if (!HEX_COLOR_PATTERN.test(hexArg)) {
22
- throw new Error(`accentForegroundOf: "${hexArg}" is no hex colour`);
23
- }
39
+ requireHexColor("accentForegroundOf", hexArg);
24
40
  const accent = relativeLuminanceOf(hexArg);
25
41
  return contrastOf(accent, relativeLuminanceOf("#333333")) > contrastOf(accent, 1) ? "#333333" : "#ffffff";
26
42
  };
@@ -39,15 +55,15 @@ export const accentForegroundOf = (hexArg) => {
39
55
  */
40
56
  export const resolvedAccentOf = (themeArg, letterArg) => {
41
57
  const stated = letterArg?.appearance?.accentColor;
42
- if (stated !== undefined && !HEX_COLOR_PATTERN.test(stated)) {
58
+ if (stated !== undefined && !isHexColor(stated)) {
43
59
  throw new Error(`appearance.accentColor: "${stated}" is no hex colour (#RGB or #RRGGBB); the document is not printed.`);
44
60
  }
45
61
  const background = themeArg?.colorAccentBackground ?? stated;
46
62
  const foreground = themeArg?.colorAccentForeground
47
- ?? (background !== undefined && HEX_COLOR_PATTERN.test(background) ? accentForegroundOf(background) : undefined);
63
+ ?? (background !== undefined && isHexColor(background) ? accentForegroundOf(background) : undefined);
48
64
  return {
49
65
  ...(background !== undefined ? { background } : {}),
50
66
  ...(foreground !== undefined ? { foreground } : {}),
51
67
  };
52
68
  };
53
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwZWFyYW5jZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX3NoYXJlZC9hcHBlYXJhbmNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBR3hDLDJEQUEyRDtBQUMzRCxNQUFNLGlCQUFpQixHQUFHLHNDQUFzQyxDQUFDO0FBS2pFLHNGQUFzRjtBQUN0RixNQUFNLG1CQUFtQixHQUFHLENBQUMsTUFBYyxFQUFVLEVBQUU7SUFDckQsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM3RixNQUFNLE9BQU8sR0FBRyxDQUFDLFNBQWlCLEVBQVUsRUFBRTtRQUM1QyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLFNBQVMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUM7UUFDaEYsT0FBTyxLQUFLLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxHQUFHLEtBQUssQ0FBQyxJQUFJLEdBQUcsQ0FBQztJQUM3RSxDQUFDLENBQUM7SUFDRixPQUFPLE1BQU0sR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3pFLENBQUMsQ0FBQztBQUVGLHlEQUF5RDtBQUN6RCxNQUFNLFVBQVUsR0FBRyxDQUFDLE9BQWUsRUFBRSxRQUFnQixFQUFVLEVBQUUsQ0FDL0QsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO0FBRTlFOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxDQUFDLE1BQWMsRUFBcUIsRUFBRTtJQUN0RSxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDcEMsTUFBTSxJQUFJLEtBQUssQ0FBQyx3QkFBd0IsTUFBTSxvQkFBb0IsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7SUFDRCxNQUFNLE1BQU0sR0FBRyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMzQyxPQUFPLFVBQVUsQ0FBQyxNQUFNLEVBQUUsbUJBQW1CLENBQUMsU0FBUyxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUM1RyxDQUFDLENBQUM7QUFRRjs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRyxDQUM5QixRQUFvQyxFQUNwQyxTQUE4RCxFQUM3QyxFQUFFO0lBQ25CLE1BQU0sTUFBTSxHQUFHLFNBQVMsRUFBRSxVQUFVLEVBQUUsV0FBVyxDQUFDO0lBQ2xELElBQUksTUFBTSxLQUFLLFNBQVMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQzVELE1BQU0sSUFBSSxLQUFLLENBQUMsNEJBQTRCLE1BQU0sb0VBQW9FLENBQUMsQ0FBQztJQUMxSCxDQUFDO0lBQ0QsTUFBTSxVQUFVLEdBQUcsUUFBUSxFQUFFLHFCQUFxQixJQUFJLE1BQU0sQ0FBQztJQUM3RCxNQUFNLFVBQVUsR0FBRyxRQUFRLEVBQUUscUJBQXFCO1dBQzdDLENBQUMsVUFBVSxLQUFLLFNBQVMsSUFBSSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNuSCxPQUFPO1FBQ0wsR0FBRyxDQUFDLFVBQVUsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNuRCxHQUFHLENBQUMsVUFBVSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0tBQ3BELENBQUM7QUFDSixDQUFDLENBQUMifQ==
69
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwZWFyYW5jZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX3NoYXJlZC9hcHBlYXJhbmNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBR3hDLDJEQUEyRDtBQUMzRCxNQUFNLGlCQUFpQixHQUFHLHNDQUFzQyxDQUFDO0FBRWpFLDRHQUE0RztBQUM1RyxNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsQ0FBQyxRQUFnQixFQUFXLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7QUFFMUYsaUZBQWlGO0FBQ2pGLE1BQU0sZUFBZSxHQUFHLENBQUMsV0FBbUIsRUFBRSxRQUFnQixFQUFRLEVBQUU7SUFDdEUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1FBQzFCLE1BQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxXQUFXLE1BQU0sUUFBUSxvQkFBb0IsQ0FBQyxDQUFDO0lBQ3BFLENBQUM7QUFDSCxDQUFDLENBQUM7QUFLRjs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxNQUFjLEVBQVUsRUFBRTtJQUM1RCxlQUFlLENBQUMscUJBQXFCLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDL0MsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM3RixNQUFNLE9BQU8sR0FBRyxDQUFDLFNBQWlCLEVBQVUsRUFBRTtRQUM1QyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxF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
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@design.estate/dees-document',
6
- version: '5.4.0',
6
+ version: '5.6.0',
7
7
  description: 'A sophisticated framework for dynamically generating and rendering business documents like invoices with modern web technologies, featuring PDF creation, templating, and automation.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfd2ViLzAwX2NvbW1pdGluZm9fZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRztJQUN4QixJQUFJLEVBQUUsOEJBQThCO0lBQ3BDLE9BQU8sRUFBRSxPQUFPO0lBQ2hCLFdBQVcsRUFBRSx1TEFBdUw7Q0FDck0sQ0FBQSJ9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@design.estate/dees-document",
3
- "version": "5.4.0",
3
+ "version": "5.6.0",
4
4
  "private": false,
5
5
  "description": "A sophisticated framework for dynamically generating and rendering business documents like invoices with modern web technologies, featuring PDF creation, templating, and automation.",
6
6
  "main": "dist_ts_web/index.js",
@@ -15,7 +15,6 @@
15
15
  "author": "Lossless GmbH",
16
16
  "license": "MIT",
17
17
  "dependencies": {
18
- "@design.estate/dees-catalog": "^9.7.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
19
18
  "@design.estate/dees-domtools": "^3.0.0",
20
19
  "@design.estate/dees-element": "^3.2.0",
21
20
  "@fin.cx/calculation": "^1.4.0",
@@ -29,14 +28,18 @@
29
28
  "@types/qrcode": "^1.5.6",
30
29
  "qrcode": "^1.5.4"
31
30
  },
31
+ "peerDependencies": {
32
+ "@design.estate/dees-catalog": "^9.7.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
33
+ },
32
34
  "devDependencies": {
35
+ "@design.estate/dees-catalog": "^19.4.0",
33
36
  "@design.estate/dees-wcctools": "^3.9.4",
34
- "@git.zone/tsbuild": "^5.0.0",
35
- "@git.zone/tsbundle": "^3.1.0",
37
+ "@git.zone/tsbuild": "^5.1.2",
38
+ "@git.zone/tsbundle": "^3.1.3",
36
39
  "@git.zone/tsrun": "^3.0.2",
37
- "@git.zone/tstest": "^6.3.2",
38
- "@git.zone/tswatch": "^4.0.2",
39
- "@types/node": "^26.6.2"
40
+ "@git.zone/tstest": "^7.0.0",
41
+ "@git.zone/tswatch": "^6.0.0",
42
+ "@types/node": "^26.6.3"
40
43
  },
41
44
  "files": [
42
45
  "ts/**/*",
package/readme.md CHANGED
@@ -9,9 +9,11 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
9
9
  ## Installation
10
10
 
11
11
  ```shell
12
- pnpm install @design.estate/dees-document
12
+ pnpm install @design.estate/dees-document @design.estate/dees-catalog
13
13
  ```
14
14
 
15
+ `@design.estate/dees-catalog` is a peer dependency (9.7 to 19.x): the web components (`@design.estate/dees-document/web`) render the catalog's `dees-icon` and use the catalog copy your application installs. Custom elements are registered globally, so an application must hold one catalog copy, and a component library that brought its own would register each catalog element a second time. pnpm and npm 7+ install a missing peer automatically; Yarn reports it as missing, so list it yourself. The server side (`@design.estate/dees-document`, `/node`) and `/shared` do not load the catalog at runtime: `PdfService` renders with the bundle built into the package.
16
+
15
17
  ## Features
16
18
 
17
19
  - 📄 **PDF Generation** - Server-side PDF creation from structured data through smartpdf (system Chrome or Chromium)
@@ -179,6 +181,15 @@ const documentSettings = {
179
181
 
180
182
  The accent colour draws the rule above the footer and the page number's tab. It is the theme's `colorAccentBackground`, else the letter's own `appearance.accentColor` (the issuer's branding, `#RGB` or `#RRGGBB`; anything else is refused and nothing is printed), else the default red. The page number is written in the theme's `colorAccentForeground`, else in dark grey (`#333333`) or white, whichever has the higher WCAG contrast on the accent (`accentForegroundOf`, `resolvedAccentOf` in the shared module). The letter's `appearance.logoUrl` is printed in the head.
181
183
 
184
+ The checks the accent is drawn with are on `@design.estate/dees-document/shared` too, for an application that states or checks an accent colour itself: `isHexColor(value)` (`#RGB` or `#RRGGBB`, either case), `relativeLuminanceOf(hex)` (WCAG 2.x, 0 to 1), `contrastOf(left, right)` (the WCAG contrast of two luminances, 1 to 21) and `contrastOnWhiteOf(hex)`. The ones that take a colour refuse a value that is no hex colour.
185
+
186
+ ```typescript
187
+ import { contrastOnWhiteOf, isHexColor } from '@design.estate/dees-document/shared';
188
+
189
+ isHexColor('#FFD700'); // true
190
+ contrastOnWhiteOf('#FFD700'); // 1.40…: too light for a line on white by WCAG 1.4.11 (3:1)
191
+ ```
192
+
182
193
  ### Web Component Usage
183
194
 
184
195
  For browser-based document viewing:
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@design.estate/dees-document',
6
- version: '5.4.0',
6
+ version: '5.6.0',
7
7
  description: 'A sophisticated framework for dynamically generating and rendering business documents like invoices with modern web technologies, featuring PDF creation, templating, and automation.'
8
8
  }
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@design.estate/dees-document',
6
- version: '5.4.0',
6
+ version: '5.6.0',
7
7
  description: 'A sophisticated framework for dynamically generating and rendering business documents like invoices with modern web technologies, featuring PDF creation, templating, and automation.'
8
8
  }